084bbef44c4e1b012cb4c5234368b4633b274316
[ira/wip.git] / source3 / rpc_client / cli_pipe.c
1 /* 
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Largely rewritten by Jeremy Allison             2005.
5  *  
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 3 of the License, or
9  *  (at your option) any later version.
10  *  
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *  
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include "includes.h"
21 #include "../libcli/auth/libcli_auth.h"
22 #include "librpc/gen_ndr/cli_epmapper.h"
23 #include "../librpc/gen_ndr/ndr_schannel.h"
24 #include "../libcli/auth/schannel.h"
25 #include "../libcli/auth/schannel_proto.h"
26 #include "../libcli/auth/spnego.h"
27
28 #undef DBGC_CLASS
29 #define DBGC_CLASS DBGC_RPC_CLI
30
31 static const char *get_pipe_name_from_iface(
32         TALLOC_CTX *mem_ctx, const struct ndr_interface_table *interface)
33 {
34         int i;
35         const struct ndr_interface_string_array *ep = interface->endpoints;
36         char *p;
37
38         for (i=0; i<ep->count; i++) {
39                 if (strncmp(ep->names[i], "ncacn_np:[\\pipe\\", 16) == 0) {
40                         break;
41                 }
42         }
43         if (i == ep->count) {
44                 return NULL;
45         }
46
47         /*
48          * extract the pipe name without \\pipe from for example
49          * ncacn_np:[\\pipe\\epmapper]
50          */
51         p = strchr(ep->names[i]+15, ']');
52         if (p == NULL) {
53                 return "PIPE";
54         }
55         return talloc_strndup(mem_ctx, ep->names[i]+15, p - ep->names[i] - 15);
56 }
57
58 static const struct ndr_interface_table **interfaces;
59
60 bool smb_register_ndr_interface(const struct ndr_interface_table *interface)
61 {
62         int num_interfaces = talloc_array_length(interfaces);
63         const struct ndr_interface_table **tmp;
64         int i;
65
66         for (i=0; i<num_interfaces; i++) {
67                 if (ndr_syntax_id_equal(&interfaces[i]->syntax_id,
68                                         &interface->syntax_id)) {
69                         return true;
70                 }
71         }
72
73         tmp = talloc_realloc(NULL, interfaces,
74                              const struct ndr_interface_table *,
75                              num_interfaces + 1);
76         if (tmp == NULL) {
77                 DEBUG(1, ("smb_register_ndr_interface: talloc failed\n"));
78                 return false;
79         }
80         interfaces = tmp;
81         interfaces[num_interfaces] = interface;
82         return true;
83 }
84
85 static bool initialize_interfaces(void)
86 {
87         if (!smb_register_ndr_interface(&ndr_table_lsarpc)) {
88                 return false;
89         }
90         if (!smb_register_ndr_interface(&ndr_table_dssetup)) {
91                 return false;
92         }
93         if (!smb_register_ndr_interface(&ndr_table_samr)) {
94                 return false;
95         }
96         if (!smb_register_ndr_interface(&ndr_table_netlogon)) {
97                 return false;
98         }
99         if (!smb_register_ndr_interface(&ndr_table_srvsvc)) {
100                 return false;
101         }
102         if (!smb_register_ndr_interface(&ndr_table_wkssvc)) {
103                 return false;
104         }
105         if (!smb_register_ndr_interface(&ndr_table_winreg)) {
106                 return false;
107         }
108         if (!smb_register_ndr_interface(&ndr_table_spoolss)) {
109                 return false;
110         }
111         if (!smb_register_ndr_interface(&ndr_table_netdfs)) {
112                 return false;
113         }
114         if (!smb_register_ndr_interface(&ndr_table_rpcecho)) {
115                 return false;
116         }
117         if (!smb_register_ndr_interface(&ndr_table_initshutdown)) {
118                 return false;
119         }
120         if (!smb_register_ndr_interface(&ndr_table_svcctl)) {
121                 return false;
122         }
123         if (!smb_register_ndr_interface(&ndr_table_eventlog)) {
124                 return false;
125         }
126         if (!smb_register_ndr_interface(&ndr_table_ntsvcs)) {
127                 return false;
128         }
129         if (!smb_register_ndr_interface(&ndr_table_epmapper)) {
130                 return false;
131         }
132         if (!smb_register_ndr_interface(&ndr_table_drsuapi)) {
133                 return false;
134         }
135         return true;
136 }
137
138 const struct ndr_interface_table *get_iface_from_syntax(
139         const struct ndr_syntax_id *syntax)
140 {
141         int num_interfaces;
142         int i;
143
144         if (interfaces == NULL) {
145                 if (!initialize_interfaces()) {
146                         return NULL;
147                 }
148         }
149         num_interfaces = talloc_array_length(interfaces);
150
151         for (i=0; i<num_interfaces; i++) {
152                 if (ndr_syntax_id_equal(&interfaces[i]->syntax_id, syntax)) {
153                         return interfaces[i];
154                 }
155         }
156
157         return NULL;
158 }
159
160 /****************************************************************************
161  Return the pipe name from the interface.
162  ****************************************************************************/
163
164 const char *get_pipe_name_from_syntax(TALLOC_CTX *mem_ctx,
165                                       const struct ndr_syntax_id *syntax)
166 {
167         const struct ndr_interface_table *interface;
168         char *guid_str;
169         const char *result;
170
171         interface = get_iface_from_syntax(syntax);
172         if (interface != NULL) {
173                 result = get_pipe_name_from_iface(mem_ctx, interface);
174                 if (result != NULL) {
175                         return result;
176                 }
177         }
178
179         /*
180          * Here we should ask \\epmapper, but for now our code is only
181          * interested in the known pipes mentioned in pipe_names[]
182          */
183
184         guid_str = GUID_string(talloc_tos(), &syntax->uuid);
185         if (guid_str == NULL) {
186                 return NULL;
187         }
188         result = talloc_asprintf(mem_ctx, "Interface %s.%d", guid_str,
189                                  (int)syntax->if_version);
190         TALLOC_FREE(guid_str);
191
192         if (result == NULL) {
193                 return "PIPE";
194         }
195         return result;
196 }
197
198 /********************************************************************
199  Map internal value to wire value.
200  ********************************************************************/
201
202 static int map_pipe_auth_type_to_rpc_auth_type(enum pipe_auth_type auth_type)
203 {
204         switch (auth_type) {
205
206         case PIPE_AUTH_TYPE_NONE:
207                 return DCERPC_AUTH_TYPE_NONE;
208
209         case PIPE_AUTH_TYPE_NTLMSSP:
210                 return DCERPC_AUTH_TYPE_NTLMSSP;
211
212         case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
213         case PIPE_AUTH_TYPE_SPNEGO_KRB5:
214                 return DCERPC_AUTH_TYPE_SPNEGO;
215
216         case PIPE_AUTH_TYPE_SCHANNEL:
217                 return DCERPC_AUTH_TYPE_SCHANNEL;
218
219         case PIPE_AUTH_TYPE_KRB5:
220                 return DCERPC_AUTH_TYPE_KRB5;
221
222         default:
223                 DEBUG(0,("map_pipe_auth_type_to_rpc_type: unknown pipe "
224                         "auth type %u\n",
225                         (unsigned int)auth_type ));
226                 break;
227         }
228         return -1;
229 }
230
231 /********************************************************************
232  Pipe description for a DEBUG
233  ********************************************************************/
234 static const char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx,
235                                    struct rpc_pipe_client *cli)
236 {
237         char *result = talloc_asprintf(mem_ctx, "host %s", cli->desthost);
238         if (result == NULL) {
239                 return "pipe";
240         }
241         return result;
242 }
243
244 /********************************************************************
245  Rpc pipe call id.
246  ********************************************************************/
247
248 static uint32 get_rpc_call_id(void)
249 {
250         static uint32 call_id = 0;
251         return ++call_id;
252 }
253
254 /*
255  * Realloc pdu to have a least "size" bytes
256  */
257
258 static bool rpc_grow_buffer(prs_struct *pdu, size_t size)
259 {
260         size_t extra_size;
261
262         if (prs_data_size(pdu) >= size) {
263                 return true;
264         }
265
266         extra_size = size - prs_data_size(pdu);
267
268         if (!prs_force_grow(pdu, extra_size)) {
269                 DEBUG(0, ("rpc_grow_buffer: Failed to grow parse struct by "
270                           "%d bytes.\n", (int)extra_size));
271                 return false;
272         }
273
274         DEBUG(5, ("rpc_grow_buffer: grew buffer by %d bytes to %u\n",
275                   (int)extra_size, prs_data_size(pdu)));
276         return true;
277 }
278
279
280 /*******************************************************************
281  Use SMBreadX to get rest of one fragment's worth of rpc data.
282  Reads the whole size or give an error message
283  ********************************************************************/
284
285 struct rpc_read_state {
286         struct event_context *ev;
287         struct rpc_cli_transport *transport;
288         uint8_t *data;
289         size_t size;
290         size_t num_read;
291 };
292
293 static void rpc_read_done(struct tevent_req *subreq);
294
295 static struct tevent_req *rpc_read_send(TALLOC_CTX *mem_ctx,
296                                         struct event_context *ev,
297                                         struct rpc_cli_transport *transport,
298                                         uint8_t *data, size_t size)
299 {
300         struct tevent_req *req, *subreq;
301         struct rpc_read_state *state;
302
303         req = tevent_req_create(mem_ctx, &state, struct rpc_read_state);
304         if (req == NULL) {
305                 return NULL;
306         }
307         state->ev = ev;
308         state->transport = transport;
309         state->data = data;
310         state->size = size;
311         state->num_read = 0;
312
313         DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size));
314
315         subreq = transport->read_send(state, ev, (uint8_t *)data, size,
316                                       transport->priv);
317         if (subreq == NULL) {
318                 goto fail;
319         }
320         tevent_req_set_callback(subreq, rpc_read_done, req);
321         return req;
322
323  fail:
324         TALLOC_FREE(req);
325         return NULL;
326 }
327
328 static void rpc_read_done(struct tevent_req *subreq)
329 {
330         struct tevent_req *req = tevent_req_callback_data(
331                 subreq, struct tevent_req);
332         struct rpc_read_state *state = tevent_req_data(
333                 req, struct rpc_read_state);
334         NTSTATUS status;
335         ssize_t received;
336
337         status = state->transport->read_recv(subreq, &received);
338         TALLOC_FREE(subreq);
339         if (!NT_STATUS_IS_OK(status)) {
340                 tevent_req_nterror(req, status);
341                 return;
342         }
343
344         state->num_read += received;
345         if (state->num_read == state->size) {
346                 tevent_req_done(req);
347                 return;
348         }
349
350         subreq = state->transport->read_send(state, state->ev,
351                                              state->data + state->num_read,
352                                              state->size - state->num_read,
353                                              state->transport->priv);
354         if (tevent_req_nomem(subreq, req)) {
355                 return;
356         }
357         tevent_req_set_callback(subreq, rpc_read_done, req);
358 }
359
360 static NTSTATUS rpc_read_recv(struct tevent_req *req)
361 {
362         return tevent_req_simple_recv_ntstatus(req);
363 }
364
365 struct rpc_write_state {
366         struct event_context *ev;
367         struct rpc_cli_transport *transport;
368         const uint8_t *data;
369         size_t size;
370         size_t num_written;
371 };
372
373 static void rpc_write_done(struct tevent_req *subreq);
374
375 static struct tevent_req *rpc_write_send(TALLOC_CTX *mem_ctx,
376                                          struct event_context *ev,
377                                          struct rpc_cli_transport *transport,
378                                          const uint8_t *data, size_t size)
379 {
380         struct tevent_req *req, *subreq;
381         struct rpc_write_state *state;
382
383         req = tevent_req_create(mem_ctx, &state, struct rpc_write_state);
384         if (req == NULL) {
385                 return NULL;
386         }
387         state->ev = ev;
388         state->transport = transport;
389         state->data = data;
390         state->size = size;
391         state->num_written = 0;
392
393         DEBUG(5, ("rpc_write_send: data_to_write: %u\n", (unsigned int)size));
394
395         subreq = transport->write_send(state, ev, data, size, transport->priv);
396         if (subreq == NULL) {
397                 goto fail;
398         }
399         tevent_req_set_callback(subreq, rpc_write_done, req);
400         return req;
401  fail:
402         TALLOC_FREE(req);
403         return NULL;
404 }
405
406 static void rpc_write_done(struct tevent_req *subreq)
407 {
408         struct tevent_req *req = tevent_req_callback_data(
409                 subreq, struct tevent_req);
410         struct rpc_write_state *state = tevent_req_data(
411                 req, struct rpc_write_state);
412         NTSTATUS status;
413         ssize_t written;
414
415         status = state->transport->write_recv(subreq, &written);
416         TALLOC_FREE(subreq);
417         if (!NT_STATUS_IS_OK(status)) {
418                 tevent_req_nterror(req, status);
419                 return;
420         }
421
422         state->num_written += written;
423
424         if (state->num_written == state->size) {
425                 tevent_req_done(req);
426                 return;
427         }
428
429         subreq = state->transport->write_send(state, state->ev,
430                                               state->data + state->num_written,
431                                               state->size - state->num_written,
432                                               state->transport->priv);
433         if (tevent_req_nomem(subreq, req)) {
434                 return;
435         }
436         tevent_req_set_callback(subreq, rpc_write_done, req);
437 }
438
439 static NTSTATUS rpc_write_recv(struct tevent_req *req)
440 {
441         return tevent_req_simple_recv_ntstatus(req);
442 }
443
444
445 static NTSTATUS parse_rpc_header(struct rpc_pipe_client *cli,
446                                  struct rpc_hdr_info *prhdr,
447                                  prs_struct *pdu)
448 {
449         /*
450          * This next call sets the endian bit correctly in current_pdu. We
451          * will propagate this to rbuf later.
452          */
453
454         if(!smb_io_rpc_hdr("rpc_hdr   ", prhdr, pdu, 0)) {
455                 DEBUG(0, ("get_current_pdu: Failed to unmarshall RPC_HDR.\n"));
456                 return NT_STATUS_BUFFER_TOO_SMALL;
457         }
458
459         if (prhdr->frag_len > cli->max_recv_frag) {
460                 DEBUG(0, ("cli_pipe_get_current_pdu: Server sent fraglen %d,"
461                           " we only allow %d\n", (int)prhdr->frag_len,
462                           (int)cli->max_recv_frag));
463                 return NT_STATUS_BUFFER_TOO_SMALL;
464         }
465
466         return NT_STATUS_OK;
467 }
468
469 /****************************************************************************
470  Try and get a PDU's worth of data from current_pdu. If not, then read more
471  from the wire.
472  ****************************************************************************/
473
474 struct get_complete_frag_state {
475         struct event_context *ev;
476         struct rpc_pipe_client *cli;
477         struct rpc_hdr_info *prhdr;
478         prs_struct *pdu;
479 };
480
481 static void get_complete_frag_got_header(struct tevent_req *subreq);
482 static void get_complete_frag_got_rest(struct tevent_req *subreq);
483
484 static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
485                                                  struct event_context *ev,
486                                                  struct rpc_pipe_client *cli,
487                                                  struct rpc_hdr_info *prhdr,
488                                                  prs_struct *pdu)
489 {
490         struct tevent_req *req, *subreq;
491         struct get_complete_frag_state *state;
492         uint32_t pdu_len;
493         NTSTATUS status;
494
495         req = tevent_req_create(mem_ctx, &state,
496                                 struct get_complete_frag_state);
497         if (req == NULL) {
498                 return NULL;
499         }
500         state->ev = ev;
501         state->cli = cli;
502         state->prhdr = prhdr;
503         state->pdu = pdu;
504
505         pdu_len = prs_data_size(pdu);
506         if (pdu_len < RPC_HEADER_LEN) {
507                 if (!rpc_grow_buffer(pdu, RPC_HEADER_LEN)) {
508                         status = NT_STATUS_NO_MEMORY;
509                         goto post_status;
510                 }
511                 subreq = rpc_read_send(
512                         state, state->ev,
513                         state->cli->transport,
514                         (uint8_t *)(prs_data_p(state->pdu) + pdu_len),
515                         RPC_HEADER_LEN - pdu_len);
516                 if (subreq == NULL) {
517                         status = NT_STATUS_NO_MEMORY;
518                         goto post_status;
519                 }
520                 tevent_req_set_callback(subreq, get_complete_frag_got_header,
521                                         req);
522                 return req;
523         }
524
525         status = parse_rpc_header(cli, prhdr, pdu);
526         if (!NT_STATUS_IS_OK(status)) {
527                 goto post_status;
528         }
529
530         /*
531          * Ensure we have frag_len bytes of data.
532          */
533         if (pdu_len < prhdr->frag_len) {
534                 if (!rpc_grow_buffer(pdu, prhdr->frag_len)) {
535                         status = NT_STATUS_NO_MEMORY;
536                         goto post_status;
537                 }
538                 subreq = rpc_read_send(state, state->ev,
539                                        state->cli->transport,
540                                        (uint8_t *)(prs_data_p(pdu) + pdu_len),
541                                        prhdr->frag_len - pdu_len);
542                 if (subreq == NULL) {
543                         status = NT_STATUS_NO_MEMORY;
544                         goto post_status;
545                 }
546                 tevent_req_set_callback(subreq, get_complete_frag_got_rest,
547                                         req);
548                 return req;
549         }
550
551         status = NT_STATUS_OK;
552  post_status:
553         if (NT_STATUS_IS_OK(status)) {
554                 tevent_req_done(req);
555         } else {
556                 tevent_req_nterror(req, status);
557         }
558         return tevent_req_post(req, ev);
559 }
560
561 static void get_complete_frag_got_header(struct tevent_req *subreq)
562 {
563         struct tevent_req *req = tevent_req_callback_data(
564                 subreq, struct tevent_req);
565         struct get_complete_frag_state *state = tevent_req_data(
566                 req, struct get_complete_frag_state);
567         NTSTATUS status;
568
569         status = rpc_read_recv(subreq);
570         TALLOC_FREE(subreq);
571         if (!NT_STATUS_IS_OK(status)) {
572                 tevent_req_nterror(req, status);
573                 return;
574         }
575
576         status = parse_rpc_header(state->cli, state->prhdr, state->pdu);
577         if (!NT_STATUS_IS_OK(status)) {
578                 tevent_req_nterror(req, status);
579                 return;
580         }
581
582         if (!rpc_grow_buffer(state->pdu, state->prhdr->frag_len)) {
583                 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
584                 return;
585         }
586
587         /*
588          * We're here in this piece of code because we've read exactly
589          * RPC_HEADER_LEN bytes into state->pdu.
590          */
591
592         subreq = rpc_read_send(
593                 state, state->ev, state->cli->transport,
594                 (uint8_t *)(prs_data_p(state->pdu) + RPC_HEADER_LEN),
595                 state->prhdr->frag_len - RPC_HEADER_LEN);
596         if (tevent_req_nomem(subreq, req)) {
597                 return;
598         }
599         tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
600 }
601
602 static void get_complete_frag_got_rest(struct tevent_req *subreq)
603 {
604         struct tevent_req *req = tevent_req_callback_data(
605                 subreq, struct tevent_req);
606         NTSTATUS status;
607
608         status = rpc_read_recv(subreq);
609         TALLOC_FREE(subreq);
610         if (!NT_STATUS_IS_OK(status)) {
611                 tevent_req_nterror(req, status);
612                 return;
613         }
614         tevent_req_done(req);
615 }
616
617 static NTSTATUS get_complete_frag_recv(struct tevent_req *req)
618 {
619         return tevent_req_simple_recv_ntstatus(req);
620 }
621
622 /****************************************************************************
623  NTLMSSP specific sign/seal.
624  Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.
625  In fact I should probably abstract these into identical pieces of code... JRA.
626  ****************************************************************************/
627
628 static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
629                                 prs_struct *current_pdu,
630                                 uint8 *p_ss_padding_len)
631 {
632         RPC_HDR_AUTH auth_info;
633         uint32 save_offset = prs_offset(current_pdu);
634         uint32 auth_len = prhdr->auth_len;
635         NTLMSSP_STATE *ntlmssp_state = cli->auth->a_u.ntlmssp_state;
636         unsigned char *data = NULL;
637         size_t data_len;
638         unsigned char *full_packet_data = NULL;
639         size_t full_packet_data_len;
640         DATA_BLOB auth_blob;
641         NTSTATUS status;
642
643         if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE
644             || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
645                 return NT_STATUS_OK;
646         }
647
648         if (!ntlmssp_state) {
649                 return NT_STATUS_INVALID_PARAMETER;
650         }
651
652         /* Ensure there's enough data for an authenticated response. */
653         if ((auth_len > RPC_MAX_SIGN_SIZE) ||
654                         (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
655                 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
656                         (unsigned int)auth_len ));
657                 return NT_STATUS_BUFFER_TOO_SMALL;
658         }
659
660         /*
661          * We need the full packet data + length (minus auth stuff) as well as the packet data + length
662          * after the RPC header.
663          * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
664          * functions as NTLMv2 checks the rpc headers also.
665          */
666
667         data = (unsigned char *)(prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN);
668         data_len = (size_t)(prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len);
669
670         full_packet_data = (unsigned char *)prs_data_p(current_pdu);
671         full_packet_data_len = prhdr->frag_len - auth_len;
672
673         /* Pull the auth header and the following data into a blob. */
674         if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
675                 DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n",
676                         (unsigned int)RPC_HEADER_LEN + (unsigned int)RPC_HDR_RESP_LEN + (unsigned int)data_len ));
677                 return NT_STATUS_BUFFER_TOO_SMALL;
678         }
679
680         if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
681                 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall RPC_HDR_AUTH.\n"));
682                 return NT_STATUS_BUFFER_TOO_SMALL;
683         }
684
685         auth_blob.data = (unsigned char *)prs_data_p(current_pdu) + prs_offset(current_pdu);
686         auth_blob.length = auth_len;
687
688         switch (cli->auth->auth_level) {
689                 case DCERPC_AUTH_LEVEL_PRIVACY:
690                         /* Data is encrypted. */
691                         status = ntlmssp_unseal_packet(ntlmssp_state,
692                                                         data, data_len,
693                                                         full_packet_data,
694                                                         full_packet_data_len,
695                                                         &auth_blob);
696                         if (!NT_STATUS_IS_OK(status)) {
697                                 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal "
698                                         "packet from %s. Error was %s.\n",
699                                         rpccli_pipe_txt(talloc_tos(), cli),
700                                         nt_errstr(status) ));
701                                 return status;
702                         }
703                         break;
704                 case DCERPC_AUTH_LEVEL_INTEGRITY:
705                         /* Data is signed. */
706                         status = ntlmssp_check_packet(ntlmssp_state,
707                                                         data, data_len,
708                                                         full_packet_data,
709                                                         full_packet_data_len,
710                                                         &auth_blob);
711                         if (!NT_STATUS_IS_OK(status)) {
712                                 DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on "
713                                         "packet from %s. Error was %s.\n",
714                                         rpccli_pipe_txt(talloc_tos(), cli),
715                                         nt_errstr(status) ));
716                                 return status;
717                         }
718                         break;
719                 default:
720                         DEBUG(0, ("cli_pipe_verify_ntlmssp: unknown internal "
721                                   "auth level %d\n", cli->auth->auth_level));
722                         return NT_STATUS_INVALID_INFO_CLASS;
723         }
724
725         /*
726          * Return the current pointer to the data offset.
727          */
728
729         if(!prs_set_offset(current_pdu, save_offset)) {
730                 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
731                         (unsigned int)save_offset ));
732                 return NT_STATUS_BUFFER_TOO_SMALL;
733         }
734
735         /*
736          * Remember the padding length. We must remove it from the real data
737          * stream once the sign/seal is done.
738          */
739
740         *p_ss_padding_len = auth_info.auth_pad_len;
741
742         return NT_STATUS_OK;
743 }
744
745 /****************************************************************************
746  schannel specific sign/seal.
747  ****************************************************************************/
748
749 static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
750                                 prs_struct *current_pdu,
751                                 uint8 *p_ss_padding_len)
752 {
753         RPC_HDR_AUTH auth_info;
754         uint32 auth_len = prhdr->auth_len;
755         uint32 save_offset = prs_offset(current_pdu);
756         struct schannel_state *schannel_auth =
757                 cli->auth->a_u.schannel_auth;
758         uint8_t *data;
759         uint32 data_len;
760         DATA_BLOB blob;
761         NTSTATUS status;
762
763         if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE
764             || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
765                 return NT_STATUS_OK;
766         }
767
768         if (auth_len < RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) {
769                 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u.\n", (unsigned int)auth_len ));
770                 return NT_STATUS_INVALID_PARAMETER;
771         }
772
773         if (!schannel_auth) {
774                 return NT_STATUS_INVALID_PARAMETER;
775         }
776
777         /* Ensure there's enough data for an authenticated response. */
778         if ((auth_len > RPC_MAX_SIGN_SIZE) ||
779                         (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
780                 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u is too large.\n",
781                         (unsigned int)auth_len ));
782                 return NT_STATUS_INVALID_PARAMETER;
783         }
784
785         data_len = prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len;
786
787         if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
788                 DEBUG(0,("cli_pipe_verify_schannel: cannot move offset to %u.\n",
789                         (unsigned int)RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len ));
790                 return NT_STATUS_BUFFER_TOO_SMALL;
791         }
792
793         if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
794                 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshall RPC_HDR_AUTH.\n"));
795                 return NT_STATUS_BUFFER_TOO_SMALL;
796         }
797
798         if (auth_info.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
799                 DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n",
800                         auth_info.auth_type));
801                 return NT_STATUS_BUFFER_TOO_SMALL;
802         }
803
804         blob = data_blob_const(prs_data_p(current_pdu) + prs_offset(current_pdu), auth_len);
805
806         if (DEBUGLEVEL >= 10) {
807                 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
808         }
809
810         data = (uint8_t *)prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN;
811
812         switch (cli->auth->auth_level) {
813         case DCERPC_AUTH_LEVEL_PRIVACY:
814                 status = netsec_incoming_packet(schannel_auth,
815                                                 talloc_tos(),
816                                                 true,
817                                                 data,
818                                                 data_len,
819                                                 &blob);
820                 break;
821         case DCERPC_AUTH_LEVEL_INTEGRITY:
822                 status = netsec_incoming_packet(schannel_auth,
823                                                 talloc_tos(),
824                                                 false,
825                                                 data,
826                                                 data_len,
827                                                 &blob);
828                 break;
829         default:
830                 status = NT_STATUS_INTERNAL_ERROR;
831                 break;
832         }
833
834         if (!NT_STATUS_IS_OK(status)) {
835                 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
836                                 "Connection to %s (%s).\n",
837                                 rpccli_pipe_txt(talloc_tos(), cli),
838                                 nt_errstr(status)));
839                 return NT_STATUS_INVALID_PARAMETER;
840         }
841
842         /*
843          * Return the current pointer to the data offset.
844          */
845
846         if(!prs_set_offset(current_pdu, save_offset)) {
847                 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
848                         (unsigned int)save_offset ));
849                 return NT_STATUS_BUFFER_TOO_SMALL;
850         }
851
852         /*
853          * Remember the padding length. We must remove it from the real data
854          * stream once the sign/seal is done.
855          */
856
857         *p_ss_padding_len = auth_info.auth_pad_len;
858
859         return NT_STATUS_OK;
860 }
861
862 /****************************************************************************
863  Do the authentication checks on an incoming pdu. Check sign and unseal etc.
864  ****************************************************************************/
865
866 static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
867                                 prs_struct *current_pdu,
868                                 uint8 *p_ss_padding_len)
869 {
870         NTSTATUS ret = NT_STATUS_OK;
871
872         /* Paranioa checks for auth_len. */
873         if (prhdr->auth_len) {
874                 if (prhdr->auth_len > prhdr->frag_len) {
875                         return NT_STATUS_INVALID_PARAMETER;
876                 }
877
878                 if (prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < prhdr->auth_len ||
879                                 prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < (unsigned int)RPC_HDR_AUTH_LEN) {
880                         /* Integer wrap attempt. */
881                         return NT_STATUS_INVALID_PARAMETER;
882                 }
883         }
884
885         /*
886          * Now we have a complete RPC request PDU fragment, try and verify any auth data.
887          */
888
889         switch(cli->auth->auth_type) {
890                 case PIPE_AUTH_TYPE_NONE:
891                         if (prhdr->auth_len) {
892                                 DEBUG(3, ("cli_pipe_validate_rpc_response: "
893                                           "Connection to %s - got non-zero "
894                                           "auth len %u.\n",
895                                         rpccli_pipe_txt(talloc_tos(), cli),
896                                         (unsigned int)prhdr->auth_len ));
897                                 return NT_STATUS_INVALID_PARAMETER;
898                         }
899                         break;
900
901                 case PIPE_AUTH_TYPE_NTLMSSP:
902                 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
903                         ret = cli_pipe_verify_ntlmssp(cli, prhdr, current_pdu, p_ss_padding_len);
904                         if (!NT_STATUS_IS_OK(ret)) {
905                                 return ret;
906                         }
907                         break;
908
909                 case PIPE_AUTH_TYPE_SCHANNEL:
910                         ret = cli_pipe_verify_schannel(cli, prhdr, current_pdu, p_ss_padding_len);
911                         if (!NT_STATUS_IS_OK(ret)) {
912                                 return ret;
913                         }
914                         break;
915
916                 case PIPE_AUTH_TYPE_KRB5:
917                 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
918                 default:
919                         DEBUG(3, ("cli_pipe_validate_rpc_response: Connection "
920                                   "to %s - unknown internal auth type %u.\n",
921                                   rpccli_pipe_txt(talloc_tos(), cli),
922                                   cli->auth->auth_type ));
923                         return NT_STATUS_INVALID_INFO_CLASS;
924         }
925
926         return NT_STATUS_OK;
927 }
928
929 /****************************************************************************
930  Do basic authentication checks on an incoming pdu.
931  ****************************************************************************/
932
933 static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
934                         prs_struct *current_pdu,
935                         uint8 expected_pkt_type,
936                         char **ppdata,
937                         uint32 *pdata_len,
938                         prs_struct *return_data)
939 {
940
941         NTSTATUS ret = NT_STATUS_OK;
942         uint32 current_pdu_len = prs_data_size(current_pdu);
943
944         if (current_pdu_len != prhdr->frag_len) {
945                 DEBUG(5,("cli_pipe_validate_current_pdu: incorrect pdu length %u, expected %u\n",
946                         (unsigned int)current_pdu_len, (unsigned int)prhdr->frag_len ));
947                 return NT_STATUS_INVALID_PARAMETER;
948         }
949
950         /*
951          * Point the return values at the real data including the RPC
952          * header. Just in case the caller wants it.
953          */
954         *ppdata = prs_data_p(current_pdu);
955         *pdata_len = current_pdu_len;
956
957         /* Ensure we have the correct type. */
958         switch (prhdr->pkt_type) {
959                 case DCERPC_PKT_ALTER_RESP:
960                 case DCERPC_PKT_BIND_ACK:
961
962                         /* Alter context and bind ack share the same packet definitions. */
963                         break;
964
965
966                 case DCERPC_PKT_RESPONSE:
967                 {
968                         RPC_HDR_RESP rhdr_resp;
969                         uint8 ss_padding_len = 0;
970
971                         if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
972                                 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
973                                 return NT_STATUS_BUFFER_TOO_SMALL;
974                         }
975
976                         /* Here's where we deal with incoming sign/seal. */
977                         ret = cli_pipe_validate_rpc_response(cli, prhdr,
978                                         current_pdu, &ss_padding_len);
979                         if (!NT_STATUS_IS_OK(ret)) {
980                                 return ret;
981                         }
982
983                         /* Point the return values at the NDR data. Remember to remove any ss padding. */
984                         *ppdata = prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
985
986                         if (current_pdu_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN + ss_padding_len) {
987                                 return NT_STATUS_BUFFER_TOO_SMALL;
988                         }
989
990                         *pdata_len = current_pdu_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - ss_padding_len;
991
992                         /* Remember to remove the auth footer. */
993                         if (prhdr->auth_len) {
994                                 /* We've already done integer wrap tests on auth_len in
995                                         cli_pipe_validate_rpc_response(). */
996                                 if (*pdata_len < RPC_HDR_AUTH_LEN + prhdr->auth_len) {
997                                         return NT_STATUS_BUFFER_TOO_SMALL;
998                                 }
999                                 *pdata_len -= (RPC_HDR_AUTH_LEN + prhdr->auth_len);
1000                         }
1001
1002                         DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n",
1003                                 current_pdu_len, *pdata_len, ss_padding_len ));
1004
1005                         /*
1006                          * If this is the first reply, and the allocation hint is reasonably, try and
1007                          * set up the return_data parse_struct to the correct size.
1008                          */
1009
1010                         if ((prs_data_size(return_data) == 0) && rhdr_resp.alloc_hint && (rhdr_resp.alloc_hint < 15*1024*1024)) {
1011                                 if (!prs_set_buffer_size(return_data, rhdr_resp.alloc_hint)) {
1012                                         DEBUG(0,("cli_pipe_validate_current_pdu: reply alloc hint %u "
1013                                                 "too large to allocate\n",
1014                                                 (unsigned int)rhdr_resp.alloc_hint ));
1015                                         return NT_STATUS_NO_MEMORY;
1016                                 }
1017                         }
1018
1019                         break;
1020                 }
1021
1022                 case DCERPC_PKT_BIND_NAK:
1023                         DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK "
1024                                   "received from %s!\n",
1025                                   rpccli_pipe_txt(talloc_tos(), cli)));
1026                         /* Use this for now... */
1027                         return NT_STATUS_NETWORK_ACCESS_DENIED;
1028
1029                 case DCERPC_PKT_FAULT:
1030                 {
1031                         RPC_HDR_RESP rhdr_resp;
1032                         RPC_HDR_FAULT fault_resp;
1033
1034                         if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
1035                                 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
1036                                 return NT_STATUS_BUFFER_TOO_SMALL;
1037                         }
1038
1039                         if(!smb_io_rpc_hdr_fault("fault", &fault_resp, current_pdu, 0)) {
1040                                 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_FAULT.\n"));
1041                                 return NT_STATUS_BUFFER_TOO_SMALL;
1042                         }
1043
1044                         DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault "
1045                                   "code %s received from %s!\n",
1046                                 dcerpc_errstr(talloc_tos(), NT_STATUS_V(fault_resp.status)),
1047                                 rpccli_pipe_txt(talloc_tos(), cli)));
1048                         if (NT_STATUS_IS_OK(fault_resp.status)) {
1049                                 return NT_STATUS_UNSUCCESSFUL;
1050                         } else {
1051                                 return fault_resp.status;
1052                         }
1053                 }
1054
1055                 default:
1056                         DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
1057                                 "from %s!\n",
1058                                 (unsigned int)prhdr->pkt_type,
1059                                 rpccli_pipe_txt(talloc_tos(), cli)));
1060                         return NT_STATUS_INVALID_INFO_CLASS;
1061         }
1062
1063         if (prhdr->pkt_type != expected_pkt_type) {
1064                 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s "
1065                           "got an unexpected RPC packet type - %u, not %u\n",
1066                         rpccli_pipe_txt(talloc_tos(), cli),
1067                         prhdr->pkt_type,
1068                         expected_pkt_type));
1069                 return NT_STATUS_INVALID_INFO_CLASS;
1070         }
1071
1072         /* Do this just before return - we don't want to modify any rpc header
1073            data before now as we may have needed to do cryptographic actions on
1074            it before. */
1075
1076         if ((prhdr->pkt_type == DCERPC_PKT_BIND_ACK) && !(prhdr->flags & DCERPC_PFC_FLAG_LAST)) {
1077                 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
1078                         "setting fragment first/last ON.\n"));
1079                 prhdr->flags |= DCERPC_PFC_FLAG_FIRST|DCERPC_PFC_FLAG_LAST;
1080         }
1081
1082         return NT_STATUS_OK;
1083 }
1084
1085 /****************************************************************************
1086  Ensure we eat the just processed pdu from the current_pdu prs_struct.
1087  Normally the frag_len and buffer size will match, but on the first trans
1088  reply there is a theoretical chance that buffer size > frag_len, so we must
1089  deal with that.
1090  ****************************************************************************/
1091
1092 static NTSTATUS cli_pipe_reset_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
1093 {
1094         uint32 current_pdu_len = prs_data_size(current_pdu);
1095
1096         if (current_pdu_len < prhdr->frag_len) {
1097                 return NT_STATUS_BUFFER_TOO_SMALL;
1098         }
1099
1100         /* Common case. */
1101         if (current_pdu_len == (uint32)prhdr->frag_len) {
1102                 prs_mem_free(current_pdu);
1103                 prs_init_empty(current_pdu, prs_get_mem_context(current_pdu), UNMARSHALL);
1104                 /* Make current_pdu dynamic with no memory. */
1105                 prs_give_memory(current_pdu, 0, 0, True);
1106                 return NT_STATUS_OK;
1107         }
1108
1109         /*
1110          * Oh no ! More data in buffer than we processed in current pdu.
1111          * Cheat. Move the data down and shrink the buffer.
1112          */
1113
1114         memcpy(prs_data_p(current_pdu), prs_data_p(current_pdu) + prhdr->frag_len,
1115                         current_pdu_len - prhdr->frag_len);
1116
1117         /* Remember to set the read offset back to zero. */
1118         prs_set_offset(current_pdu, 0);
1119
1120         /* Shrink the buffer. */
1121         if (!prs_set_buffer_size(current_pdu, current_pdu_len - prhdr->frag_len)) {
1122                 return NT_STATUS_BUFFER_TOO_SMALL;
1123         }
1124
1125         return NT_STATUS_OK;
1126 }
1127
1128 /****************************************************************************
1129  Call a remote api on an arbitrary pipe.  takes param, data and setup buffers.
1130 ****************************************************************************/
1131
1132 struct cli_api_pipe_state {
1133         struct event_context *ev;
1134         struct rpc_cli_transport *transport;
1135         uint8_t *rdata;
1136         uint32_t rdata_len;
1137 };
1138
1139 static void cli_api_pipe_trans_done(struct tevent_req *subreq);
1140 static void cli_api_pipe_write_done(struct tevent_req *subreq);
1141 static void cli_api_pipe_read_done(struct tevent_req *subreq);
1142
1143 static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
1144                                             struct event_context *ev,
1145                                             struct rpc_cli_transport *transport,
1146                                             uint8_t *data, size_t data_len,
1147                                             uint32_t max_rdata_len)
1148 {
1149         struct tevent_req *req, *subreq;
1150         struct cli_api_pipe_state *state;
1151         NTSTATUS status;
1152
1153         req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state);
1154         if (req == NULL) {
1155                 return NULL;
1156         }
1157         state->ev = ev;
1158         state->transport = transport;
1159
1160         if (max_rdata_len < RPC_HEADER_LEN) {
1161                 /*
1162                  * For a RPC reply we always need at least RPC_HEADER_LEN
1163                  * bytes. We check this here because we will receive
1164                  * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
1165                  */
1166                 status = NT_STATUS_INVALID_PARAMETER;
1167                 goto post_status;
1168         }
1169
1170         if (transport->trans_send != NULL) {
1171                 subreq = transport->trans_send(state, ev, data, data_len,
1172                                                max_rdata_len, transport->priv);
1173                 if (subreq == NULL) {
1174                         goto fail;
1175                 }
1176                 tevent_req_set_callback(subreq, cli_api_pipe_trans_done, req);
1177                 return req;
1178         }
1179
1180         /*
1181          * If the transport does not provide a "trans" routine, i.e. for
1182          * example the ncacn_ip_tcp transport, do the write/read step here.
1183          */
1184
1185         subreq = rpc_write_send(state, ev, transport, data, data_len);
1186         if (subreq == NULL) {
1187                 goto fail;
1188         }
1189         tevent_req_set_callback(subreq, cli_api_pipe_write_done, req);
1190         return req;
1191
1192         status = NT_STATUS_INVALID_PARAMETER;
1193
1194  post_status:
1195         tevent_req_nterror(req, status);
1196         return tevent_req_post(req, ev);
1197  fail:
1198         TALLOC_FREE(req);
1199         return NULL;
1200 }
1201
1202 static void cli_api_pipe_trans_done(struct tevent_req *subreq)
1203 {
1204         struct tevent_req *req = tevent_req_callback_data(
1205                 subreq, struct tevent_req);
1206         struct cli_api_pipe_state *state = tevent_req_data(
1207                 req, struct cli_api_pipe_state);
1208         NTSTATUS status;
1209
1210         status = state->transport->trans_recv(subreq, state, &state->rdata,
1211                                               &state->rdata_len);
1212         TALLOC_FREE(subreq);
1213         if (!NT_STATUS_IS_OK(status)) {
1214                 tevent_req_nterror(req, status);
1215                 return;
1216         }
1217         tevent_req_done(req);
1218 }
1219
1220 static void cli_api_pipe_write_done(struct tevent_req *subreq)
1221 {
1222         struct tevent_req *req = tevent_req_callback_data(
1223                 subreq, struct tevent_req);
1224         struct cli_api_pipe_state *state = tevent_req_data(
1225                 req, struct cli_api_pipe_state);
1226         NTSTATUS status;
1227
1228         status = rpc_write_recv(subreq);
1229         TALLOC_FREE(subreq);
1230         if (!NT_STATUS_IS_OK(status)) {
1231                 tevent_req_nterror(req, status);
1232                 return;
1233         }
1234
1235         state->rdata = TALLOC_ARRAY(state, uint8_t, RPC_HEADER_LEN);
1236         if (tevent_req_nomem(state->rdata, req)) {
1237                 return;
1238         }
1239
1240         /*
1241          * We don't need to use rpc_read_send here, the upper layer will cope
1242          * with a short read, transport->trans_send could also return less
1243          * than state->max_rdata_len.
1244          */
1245         subreq = state->transport->read_send(state, state->ev, state->rdata,
1246                                              RPC_HEADER_LEN,
1247                                              state->transport->priv);
1248         if (tevent_req_nomem(subreq, req)) {
1249                 return;
1250         }
1251         tevent_req_set_callback(subreq, cli_api_pipe_read_done, req);
1252 }
1253
1254 static void cli_api_pipe_read_done(struct tevent_req *subreq)
1255 {
1256         struct tevent_req *req = tevent_req_callback_data(
1257                 subreq, struct tevent_req);
1258         struct cli_api_pipe_state *state = tevent_req_data(
1259                 req, struct cli_api_pipe_state);
1260         NTSTATUS status;
1261         ssize_t received;
1262
1263         status = state->transport->read_recv(subreq, &received);
1264         TALLOC_FREE(subreq);
1265         if (!NT_STATUS_IS_OK(status)) {
1266                 tevent_req_nterror(req, status);
1267                 return;
1268         }
1269         state->rdata_len = received;
1270         tevent_req_done(req);
1271 }
1272
1273 static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1274                                   uint8_t **prdata, uint32_t *prdata_len)
1275 {
1276         struct cli_api_pipe_state *state = tevent_req_data(
1277                 req, struct cli_api_pipe_state);
1278         NTSTATUS status;
1279
1280         if (tevent_req_is_nterror(req, &status)) {
1281                 return status;
1282         }
1283
1284         *prdata = talloc_move(mem_ctx, &state->rdata);
1285         *prdata_len = state->rdata_len;
1286         return NT_STATUS_OK;
1287 }
1288
1289 /****************************************************************************
1290  Send data on an rpc pipe via trans. The prs_struct data must be the last
1291  pdu fragment of an NDR data stream.
1292
1293  Receive response data from an rpc pipe, which may be large...
1294
1295  Read the first fragment: unfortunately have to use SMBtrans for the first
1296  bit, then SMBreadX for subsequent bits.
1297
1298  If first fragment received also wasn't the last fragment, continue
1299  getting fragments until we _do_ receive the last fragment.
1300
1301  Request/Response PDU's look like the following...
1302
1303  |<------------------PDU len----------------------------------------------->|
1304  |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
1305
1306  +------------+-----------------+-------------+---------------+-------------+
1307  | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR      | AUTH DATA   |
1308  +------------+-----------------+-------------+---------------+-------------+
1309
1310  Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
1311  signing & sealing being negotiated.
1312
1313  ****************************************************************************/
1314
1315 struct rpc_api_pipe_state {
1316         struct event_context *ev;
1317         struct rpc_pipe_client *cli;
1318         uint8_t expected_pkt_type;
1319
1320         prs_struct incoming_frag;
1321         struct rpc_hdr_info rhdr;
1322
1323         prs_struct incoming_pdu;        /* Incoming reply */
1324         uint32_t incoming_pdu_offset;
1325 };
1326
1327 static int rpc_api_pipe_state_destructor(struct rpc_api_pipe_state *state)
1328 {
1329         prs_mem_free(&state->incoming_frag);
1330         prs_mem_free(&state->incoming_pdu);
1331         return 0;
1332 }
1333
1334 static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
1335 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
1336
1337 static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
1338                                             struct event_context *ev,
1339                                             struct rpc_pipe_client *cli,
1340                                             prs_struct *data, /* Outgoing PDU */
1341                                             uint8_t expected_pkt_type)
1342 {
1343         struct tevent_req *req, *subreq;
1344         struct rpc_api_pipe_state *state;
1345         uint16_t max_recv_frag;
1346         NTSTATUS status;
1347
1348         req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
1349         if (req == NULL) {
1350                 return NULL;
1351         }
1352         state->ev = ev;
1353         state->cli = cli;
1354         state->expected_pkt_type = expected_pkt_type;
1355         state->incoming_pdu_offset = 0;
1356
1357         prs_init_empty(&state->incoming_frag, state, UNMARSHALL);
1358
1359         prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1360         /* Make incoming_pdu dynamic with no memory. */
1361         prs_give_memory(&state->incoming_pdu, NULL, 0, true);
1362
1363         talloc_set_destructor(state, rpc_api_pipe_state_destructor);
1364
1365         /*
1366          * Ensure we're not sending too much.
1367          */
1368         if (prs_offset(data) > cli->max_xmit_frag) {
1369                 status = NT_STATUS_INVALID_PARAMETER;
1370                 goto post_status;
1371         }
1372
1373         DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli)));
1374
1375         max_recv_frag = cli->max_recv_frag;
1376
1377 #if 0
1378         max_recv_frag = RPC_HEADER_LEN + 10 + (sys_random() % 32);
1379 #endif
1380
1381         subreq = cli_api_pipe_send(state, ev, cli->transport,
1382                                    (uint8_t *)prs_data_p(data),
1383                                    prs_offset(data), max_recv_frag);
1384         if (subreq == NULL) {
1385                 goto fail;
1386         }
1387         tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
1388         return req;
1389
1390  post_status:
1391         tevent_req_nterror(req, status);
1392         return tevent_req_post(req, ev);
1393  fail:
1394         TALLOC_FREE(req);
1395         return NULL;
1396 }
1397
1398 static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
1399 {
1400         struct tevent_req *req = tevent_req_callback_data(
1401                 subreq, struct tevent_req);
1402         struct rpc_api_pipe_state *state = tevent_req_data(
1403                 req, struct rpc_api_pipe_state);
1404         NTSTATUS status;
1405         uint8_t *rdata = NULL;
1406         uint32_t rdata_len = 0;
1407         char *rdata_copy;
1408
1409         status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
1410         TALLOC_FREE(subreq);
1411         if (!NT_STATUS_IS_OK(status)) {
1412                 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
1413                 tevent_req_nterror(req, status);
1414                 return;
1415         }
1416
1417         if (rdata == NULL) {
1418                 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
1419                          rpccli_pipe_txt(talloc_tos(), state->cli)));
1420                 tevent_req_done(req);
1421                 return;
1422         }
1423
1424         /*
1425          * Give the memory received from cli_trans as dynamic to the current
1426          * pdu. Duplicating it sucks, but prs_struct doesn't know about talloc
1427          * :-(
1428          */
1429         rdata_copy = (char *)memdup(rdata, rdata_len);
1430         TALLOC_FREE(rdata);
1431         if (tevent_req_nomem(rdata_copy, req)) {
1432                 return;
1433         }
1434         prs_give_memory(&state->incoming_frag, rdata_copy, rdata_len, true);
1435
1436         /* Ensure we have enough data for a pdu. */
1437         subreq = get_complete_frag_send(state, state->ev, state->cli,
1438                                         &state->rhdr, &state->incoming_frag);
1439         if (tevent_req_nomem(subreq, req)) {
1440                 return;
1441         }
1442         tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1443 }
1444
1445 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
1446 {
1447         struct tevent_req *req = tevent_req_callback_data(
1448                 subreq, struct tevent_req);
1449         struct rpc_api_pipe_state *state = tevent_req_data(
1450                 req, struct rpc_api_pipe_state);
1451         NTSTATUS status;
1452         char *rdata = NULL;
1453         uint32_t rdata_len = 0;
1454
1455         status = get_complete_frag_recv(subreq);
1456         TALLOC_FREE(subreq);
1457         if (!NT_STATUS_IS_OK(status)) {
1458                 DEBUG(5, ("get_complete_frag failed: %s\n",
1459                           nt_errstr(status)));
1460                 tevent_req_nterror(req, status);
1461                 return;
1462         }
1463
1464         status = cli_pipe_validate_current_pdu(
1465                 state->cli, &state->rhdr, &state->incoming_frag,
1466                 state->expected_pkt_type, &rdata, &rdata_len,
1467                 &state->incoming_pdu);
1468
1469         DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
1470                   (unsigned)prs_data_size(&state->incoming_frag),
1471                   (unsigned)state->incoming_pdu_offset,
1472                   nt_errstr(status)));
1473
1474         if (!NT_STATUS_IS_OK(status)) {
1475                 tevent_req_nterror(req, status);
1476                 return;
1477         }
1478
1479         if ((state->rhdr.flags & DCERPC_PFC_FLAG_FIRST)
1480             && (state->rhdr.pack_type[0] == 0)) {
1481                 /*
1482                  * Set the data type correctly for big-endian data on the
1483                  * first packet.
1484                  */
1485                 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
1486                           "big-endian.\n",
1487                           rpccli_pipe_txt(talloc_tos(), state->cli)));
1488                 prs_set_endian_data(&state->incoming_pdu, RPC_BIG_ENDIAN);
1489         }
1490         /*
1491          * Check endianness on subsequent packets.
1492          */
1493         if (state->incoming_frag.bigendian_data
1494             != state->incoming_pdu.bigendian_data) {
1495                 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
1496                          "%s\n",
1497                          state->incoming_pdu.bigendian_data?"big":"little",
1498                          state->incoming_frag.bigendian_data?"big":"little"));
1499                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1500                 return;
1501         }
1502
1503         /* Now copy the data portion out of the pdu into rbuf. */
1504         if (!prs_force_grow(&state->incoming_pdu, rdata_len)) {
1505                 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1506                 return;
1507         }
1508
1509         memcpy(prs_data_p(&state->incoming_pdu) + state->incoming_pdu_offset,
1510                rdata, (size_t)rdata_len);
1511         state->incoming_pdu_offset += rdata_len;
1512
1513         status = cli_pipe_reset_current_pdu(state->cli, &state->rhdr,
1514                                             &state->incoming_frag);
1515         if (!NT_STATUS_IS_OK(status)) {
1516                 tevent_req_nterror(req, status);
1517                 return;
1518         }
1519
1520         if (state->rhdr.flags & DCERPC_PFC_FLAG_LAST) {
1521                 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1522                           rpccli_pipe_txt(talloc_tos(), state->cli),
1523                           (unsigned)prs_data_size(&state->incoming_pdu)));
1524                 tevent_req_done(req);
1525                 return;
1526         }
1527
1528         subreq = get_complete_frag_send(state, state->ev, state->cli,
1529                                         &state->rhdr, &state->incoming_frag);
1530         if (tevent_req_nomem(subreq, req)) {
1531                 return;
1532         }
1533         tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1534 }
1535
1536 static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1537                                   prs_struct *reply_pdu)
1538 {
1539         struct rpc_api_pipe_state *state = tevent_req_data(
1540                 req, struct rpc_api_pipe_state);
1541         NTSTATUS status;
1542
1543         if (tevent_req_is_nterror(req, &status)) {
1544                 return status;
1545         }
1546
1547         *reply_pdu = state->incoming_pdu;
1548         reply_pdu->mem_ctx = mem_ctx;
1549
1550         /*
1551          * Prevent state->incoming_pdu from being freed in
1552          * rpc_api_pipe_state_destructor()
1553          */
1554         prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1555
1556         return NT_STATUS_OK;
1557 }
1558
1559 /*******************************************************************
1560  Creates krb5 auth bind.
1561  ********************************************************************/
1562
1563 static NTSTATUS create_krb5_auth_bind_req( struct rpc_pipe_client *cli,
1564                                                 enum dcerpc_AuthLevel auth_level,
1565                                                 RPC_HDR_AUTH *pauth_out,
1566                                                 prs_struct *auth_data)
1567 {
1568 #ifdef HAVE_KRB5
1569         int ret;
1570         struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth;
1571         DATA_BLOB tkt = data_blob_null;
1572         DATA_BLOB tkt_wrapped = data_blob_null;
1573
1574         /* We may change the pad length before marshalling. */
1575         init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_KRB5, (int)auth_level, 0, 1);
1576
1577         DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
1578                 a->service_principal ));
1579
1580         /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
1581
1582         ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
1583                         &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL, NULL);
1584
1585         if (ret) {
1586                 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
1587                         "failed with %s\n",
1588                         a->service_principal,
1589                         error_message(ret) ));
1590
1591                 data_blob_free(&tkt);
1592                 prs_mem_free(auth_data);
1593                 return NT_STATUS_INVALID_PARAMETER;
1594         }
1595
1596         /* wrap that up in a nice GSS-API wrapping */
1597         tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
1598
1599         data_blob_free(&tkt);
1600
1601         /* Auth len in the rpc header doesn't include auth_header. */
1602         if (!prs_copy_data_in(auth_data, (char *)tkt_wrapped.data, tkt_wrapped.length)) {
1603                 data_blob_free(&tkt_wrapped);
1604                 prs_mem_free(auth_data);
1605                 return NT_STATUS_NO_MEMORY;
1606         }
1607
1608         DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1609         dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
1610
1611         data_blob_free(&tkt_wrapped);
1612         return NT_STATUS_OK;
1613 #else
1614         return NT_STATUS_INVALID_PARAMETER;
1615 #endif
1616 }
1617
1618 /*******************************************************************
1619  Creates SPNEGO NTLMSSP auth bind.
1620  ********************************************************************/
1621
1622 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1623                                                 enum dcerpc_AuthLevel auth_level,
1624                                                 RPC_HDR_AUTH *pauth_out,
1625                                                 prs_struct *auth_data)
1626 {
1627         NTSTATUS nt_status;
1628         DATA_BLOB null_blob = data_blob_null;
1629         DATA_BLOB request = data_blob_null;
1630         DATA_BLOB spnego_msg = data_blob_null;
1631
1632         /* We may change the pad length before marshalling. */
1633         init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_SPNEGO, (int)auth_level, 0, 1);
1634
1635         DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1636         nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1637                                         null_blob,
1638                                         &request);
1639
1640         if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1641                 data_blob_free(&request);
1642                 prs_mem_free(auth_data);
1643                 return nt_status;
1644         }
1645
1646         /* Wrap this in SPNEGO. */
1647         spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
1648
1649         data_blob_free(&request);
1650
1651         /* Auth len in the rpc header doesn't include auth_header. */
1652         if (!prs_copy_data_in(auth_data, (char *)spnego_msg.data, spnego_msg.length)) {
1653                 data_blob_free(&spnego_msg);
1654                 prs_mem_free(auth_data);
1655                 return NT_STATUS_NO_MEMORY;
1656         }
1657
1658         DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1659         dump_data(5, spnego_msg.data, spnego_msg.length);
1660
1661         data_blob_free(&spnego_msg);
1662         return NT_STATUS_OK;
1663 }
1664
1665 /*******************************************************************
1666  Creates NTLMSSP auth bind.
1667  ********************************************************************/
1668
1669 static NTSTATUS create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1670                                                 enum dcerpc_AuthLevel auth_level,
1671                                                 RPC_HDR_AUTH *pauth_out,
1672                                                 prs_struct *auth_data)
1673 {
1674         NTSTATUS nt_status;
1675         DATA_BLOB null_blob = data_blob_null;
1676         DATA_BLOB request = data_blob_null;
1677
1678         /* We may change the pad length before marshalling. */
1679         init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_NTLMSSP, (int)auth_level, 0, 1);
1680
1681         DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1682         nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1683                                         null_blob,
1684                                         &request);
1685
1686         if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1687                 data_blob_free(&request);
1688                 prs_mem_free(auth_data);
1689                 return nt_status;
1690         }
1691
1692         /* Auth len in the rpc header doesn't include auth_header. */
1693         if (!prs_copy_data_in(auth_data, (char *)request.data, request.length)) {
1694                 data_blob_free(&request);
1695                 prs_mem_free(auth_data);
1696                 return NT_STATUS_NO_MEMORY;
1697         }
1698
1699         DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1700         dump_data(5, request.data, request.length);
1701
1702         data_blob_free(&request);
1703         return NT_STATUS_OK;
1704 }
1705
1706 /*******************************************************************
1707  Creates schannel auth bind.
1708  ********************************************************************/
1709
1710 static NTSTATUS create_schannel_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1711                                                 enum dcerpc_AuthLevel auth_level,
1712                                                 RPC_HDR_AUTH *pauth_out,
1713                                                 prs_struct *auth_data)
1714 {
1715         struct NL_AUTH_MESSAGE r;
1716         enum ndr_err_code ndr_err;
1717         DATA_BLOB blob;
1718
1719         /* We may change the pad length before marshalling. */
1720         init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_SCHANNEL, (int)auth_level, 0, 1);
1721
1722         /* Use lp_workgroup() if domain not specified */
1723
1724         if (!cli->auth->domain || !cli->auth->domain[0]) {
1725                 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1726                 if (cli->auth->domain == NULL) {
1727                         return NT_STATUS_NO_MEMORY;
1728                 }
1729         }
1730
1731         /*
1732          * Now marshall the data into the auth parse_struct.
1733          */
1734
1735         r.MessageType                   = NL_NEGOTIATE_REQUEST;
1736         r.Flags                         = NL_FLAG_OEM_NETBIOS_DOMAIN_NAME |
1737                                           NL_FLAG_OEM_NETBIOS_COMPUTER_NAME;
1738         r.oem_netbios_domain.a          = cli->auth->domain;
1739         r.oem_netbios_computer.a        = global_myname();
1740
1741         ndr_err = ndr_push_struct_blob(&blob, talloc_tos(), NULL, &r,
1742                        (ndr_push_flags_fn_t)ndr_push_NL_AUTH_MESSAGE);
1743         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1744                 DEBUG(0,("Failed to marshall NL_AUTH_MESSAGE.\n"));
1745                 prs_mem_free(auth_data);
1746                 return ndr_map_error2ntstatus(ndr_err);
1747         }
1748
1749         if (DEBUGLEVEL >= 10) {
1750                 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, &r);
1751         }
1752
1753         if (!prs_copy_data_in(auth_data, (const char *)blob.data, blob.length))
1754         {
1755                 prs_mem_free(auth_data);
1756                 return NT_STATUS_NO_MEMORY;
1757         }
1758
1759         return NT_STATUS_OK;
1760 }
1761
1762 /*******************************************************************
1763  Creates the internals of a DCE/RPC bind request or alter context PDU.
1764  ********************************************************************/
1765
1766 static NTSTATUS create_bind_or_alt_ctx_internal(enum dcerpc_pkt_type pkt_type,
1767                                                 prs_struct *rpc_out, 
1768                                                 uint32 rpc_call_id,
1769                                                 const struct ndr_syntax_id *abstract,
1770                                                 const struct ndr_syntax_id *transfer,
1771                                                 RPC_HDR_AUTH *phdr_auth,
1772                                                 prs_struct *pauth_info)
1773 {
1774         RPC_HDR hdr;
1775         RPC_HDR_RB hdr_rb;
1776         RPC_CONTEXT rpc_ctx;
1777         uint16 auth_len = prs_offset(pauth_info);
1778         uint8 ss_padding_len = 0;
1779         uint16 frag_len = 0;
1780
1781         /* create the RPC context. */
1782         init_rpc_context(&rpc_ctx, 0 /* context id */, abstract, transfer);
1783
1784         /* create the bind request RPC_HDR_RB */
1785         init_rpc_hdr_rb(&hdr_rb, RPC_MAX_PDU_FRAG_LEN, RPC_MAX_PDU_FRAG_LEN, 0x0, &rpc_ctx);
1786
1787         /* Start building the frag length. */
1788         frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1789
1790         /* Do we need to pad ? */
1791         if (auth_len) {
1792                 uint16 data_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1793                 if (data_len % 8) {
1794                         ss_padding_len = 8 - (data_len % 8);
1795                         phdr_auth->auth_pad_len = ss_padding_len;
1796                 }
1797                 frag_len += RPC_HDR_AUTH_LEN + auth_len + ss_padding_len;
1798         }
1799
1800         /* Create the request RPC_HDR */
1801         init_rpc_hdr(&hdr, pkt_type, DCERPC_PFC_FLAG_FIRST|DCERPC_PFC_FLAG_LAST, rpc_call_id, frag_len, auth_len);
1802
1803         /* Marshall the RPC header */
1804         if(!smb_io_rpc_hdr("hdr"   , &hdr, rpc_out, 0)) {
1805                 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR.\n"));
1806                 return NT_STATUS_NO_MEMORY;
1807         }
1808
1809         /* Marshall the bind request data */
1810         if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_out, 0)) {
1811                 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1812                 return NT_STATUS_NO_MEMORY;
1813         }
1814
1815         /*
1816          * Grow the outgoing buffer to store any auth info.
1817          */
1818
1819         if(auth_len != 0) {
1820                 if (ss_padding_len) {
1821                         char pad[8];
1822                         memset(pad, '\0', 8);
1823                         if (!prs_copy_data_in(rpc_out, pad, ss_padding_len)) {
1824                                 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n"));
1825                                 return NT_STATUS_NO_MEMORY;
1826                         }
1827                 }
1828
1829                 if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth, rpc_out, 0)) {
1830                         DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n"));
1831                         return NT_STATUS_NO_MEMORY;
1832                 }
1833
1834
1835                 if(!prs_append_prs_data( rpc_out, pauth_info)) {
1836                         DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n"));
1837                         return NT_STATUS_NO_MEMORY;
1838                 }
1839         }
1840
1841         return NT_STATUS_OK;
1842 }
1843
1844 /*******************************************************************
1845  Creates a DCE/RPC bind request.
1846  ********************************************************************/
1847
1848 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
1849                                 prs_struct *rpc_out, 
1850                                 uint32 rpc_call_id,
1851                                 const struct ndr_syntax_id *abstract,
1852                                 const struct ndr_syntax_id *transfer,
1853                                 enum pipe_auth_type auth_type,
1854                                 enum dcerpc_AuthLevel auth_level)
1855 {
1856         RPC_HDR_AUTH hdr_auth;
1857         prs_struct auth_info;
1858         NTSTATUS ret = NT_STATUS_OK;
1859
1860         ZERO_STRUCT(hdr_auth);
1861         if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
1862                 return NT_STATUS_NO_MEMORY;
1863
1864         switch (auth_type) {
1865                 case PIPE_AUTH_TYPE_SCHANNEL:
1866                         ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1867                         if (!NT_STATUS_IS_OK(ret)) {
1868                                 prs_mem_free(&auth_info);
1869                                 return ret;
1870                         }
1871                         break;
1872
1873                 case PIPE_AUTH_TYPE_NTLMSSP:
1874                         ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1875                         if (!NT_STATUS_IS_OK(ret)) {
1876                                 prs_mem_free(&auth_info);
1877                                 return ret;
1878                         }
1879                         break;
1880
1881                 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1882                         ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1883                         if (!NT_STATUS_IS_OK(ret)) {
1884                                 prs_mem_free(&auth_info);
1885                                 return ret;
1886                         }
1887                         break;
1888
1889                 case PIPE_AUTH_TYPE_KRB5:
1890                         ret = create_krb5_auth_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1891                         if (!NT_STATUS_IS_OK(ret)) {
1892                                 prs_mem_free(&auth_info);
1893                                 return ret;
1894                         }
1895                         break;
1896
1897                 case PIPE_AUTH_TYPE_NONE:
1898                         break;
1899
1900                 default:
1901                         /* "Can't" happen. */
1902                         return NT_STATUS_INVALID_INFO_CLASS;
1903         }
1904
1905         ret = create_bind_or_alt_ctx_internal(DCERPC_PKT_BIND,
1906                                                 rpc_out, 
1907                                                 rpc_call_id,
1908                                                 abstract,
1909                                                 transfer,
1910                                                 &hdr_auth,
1911                                                 &auth_info);
1912
1913         prs_mem_free(&auth_info);
1914         return ret;
1915 }
1916
1917 /*******************************************************************
1918  Create and add the NTLMSSP sign/seal auth header and data.
1919  ********************************************************************/
1920
1921 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
1922                                         RPC_HDR *phdr,
1923                                         uint32 ss_padding_len,
1924                                         prs_struct *outgoing_pdu)
1925 {
1926         RPC_HDR_AUTH auth_info;
1927         NTSTATUS status;
1928         DATA_BLOB auth_blob = data_blob_null;
1929         uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1930
1931         if (!cli->auth->a_u.ntlmssp_state) {
1932                 return NT_STATUS_INVALID_PARAMETER;
1933         }
1934
1935         /* Init and marshall the auth header. */
1936         init_rpc_hdr_auth(&auth_info,
1937                         map_pipe_auth_type_to_rpc_auth_type(
1938                                 cli->auth->auth_type),
1939                         cli->auth->auth_level,
1940                         ss_padding_len,
1941                         1 /* context id. */);
1942
1943         if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1944                 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1945                 data_blob_free(&auth_blob);
1946                 return NT_STATUS_NO_MEMORY;
1947         }
1948
1949         switch (cli->auth->auth_level) {
1950                 case DCERPC_AUTH_LEVEL_PRIVACY:
1951                         /* Data portion is encrypted. */
1952                         status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state,
1953                                         (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1954                                         data_and_pad_len,
1955                                         (unsigned char *)prs_data_p(outgoing_pdu),
1956                                         (size_t)prs_offset(outgoing_pdu),
1957                                         &auth_blob);
1958                         if (!NT_STATUS_IS_OK(status)) {
1959                                 data_blob_free(&auth_blob);
1960                                 return status;
1961                         }
1962                         break;
1963
1964                 case DCERPC_AUTH_LEVEL_INTEGRITY:
1965                         /* Data is signed. */
1966                         status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state,
1967                                         (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1968                                         data_and_pad_len,
1969                                         (unsigned char *)prs_data_p(outgoing_pdu),
1970                                         (size_t)prs_offset(outgoing_pdu),
1971                                         &auth_blob);
1972                         if (!NT_STATUS_IS_OK(status)) {
1973                                 data_blob_free(&auth_blob);
1974                                 return status;
1975                         }
1976                         break;
1977
1978                 default:
1979                         /* Can't happen. */
1980                         smb_panic("bad auth level");
1981                         /* Notreached. */
1982                         return NT_STATUS_INVALID_PARAMETER;
1983         }
1984
1985         /* Finally marshall the blob. */
1986
1987         if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {
1988                 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
1989                         (unsigned int)NTLMSSP_SIG_SIZE));
1990                 data_blob_free(&auth_blob);
1991                 return NT_STATUS_NO_MEMORY;
1992         }
1993
1994         data_blob_free(&auth_blob);
1995         return NT_STATUS_OK;
1996 }
1997
1998 /*******************************************************************
1999  Create and add the schannel sign/seal auth header and data.
2000  ********************************************************************/
2001
2002 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
2003                                         RPC_HDR *phdr,
2004                                         uint32 ss_padding_len,
2005                                         prs_struct *outgoing_pdu)
2006 {
2007         RPC_HDR_AUTH auth_info;
2008         struct schannel_state *sas = cli->auth->a_u.schannel_auth;
2009         char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
2010         size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
2011         DATA_BLOB blob;
2012         NTSTATUS status;
2013
2014         if (!sas) {
2015                 return NT_STATUS_INVALID_PARAMETER;
2016         }
2017
2018         /* Init and marshall the auth header. */
2019         init_rpc_hdr_auth(&auth_info,
2020                         map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
2021                         cli->auth->auth_level,
2022                         ss_padding_len,
2023                         1 /* context id. */);
2024
2025         if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
2026                 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
2027                 return NT_STATUS_NO_MEMORY;
2028         }
2029
2030         DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
2031                         sas->seq_num));
2032
2033         switch (cli->auth->auth_level) {
2034         case DCERPC_AUTH_LEVEL_PRIVACY:
2035                 status = netsec_outgoing_packet(sas,
2036                                                 talloc_tos(),
2037                                                 true,
2038                                                 (uint8_t *)data_p,
2039                                                 data_and_pad_len,
2040                                                 &blob);
2041                 break;
2042         case DCERPC_AUTH_LEVEL_INTEGRITY:
2043                 status = netsec_outgoing_packet(sas,
2044                                                 talloc_tos(),
2045                                                 false,
2046                                                 (uint8_t *)data_p,
2047                                                 data_and_pad_len,
2048                                                 &blob);
2049                 break;
2050         default:
2051                 status = NT_STATUS_INTERNAL_ERROR;
2052                 break;
2053         }
2054
2055         if (!NT_STATUS_IS_OK(status)) {
2056                 DEBUG(1,("add_schannel_auth_footer: failed to process packet: %s\n",
2057                         nt_errstr(status)));
2058                 return status;
2059         }
2060
2061         if (DEBUGLEVEL >= 10) {
2062                 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
2063         }
2064
2065         /* Finally marshall the blob. */
2066         if (!prs_copy_data_in(outgoing_pdu, (const char *)blob.data, blob.length)) {
2067                 return NT_STATUS_NO_MEMORY;
2068         }
2069
2070         return NT_STATUS_OK;
2071 }
2072
2073 /*******************************************************************
2074  Calculate how much data we're going to send in this packet, also
2075  work out any sign/seal padding length.
2076  ********************************************************************/
2077
2078 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
2079                                         uint32 data_left,
2080                                         uint16 *p_frag_len,
2081                                         uint16 *p_auth_len,
2082                                         uint32 *p_ss_padding)
2083 {
2084         uint32 data_space, data_len;
2085
2086 #if 0
2087         if ((data_left > 0) && (sys_random() % 2)) {
2088                 data_left = MAX(data_left/2, 1);
2089         }
2090 #endif
2091
2092         switch (cli->auth->auth_level) {
2093                 case DCERPC_AUTH_LEVEL_NONE:
2094                 case DCERPC_AUTH_LEVEL_CONNECT:
2095                         data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
2096                         data_len = MIN(data_space, data_left);
2097                         *p_ss_padding = 0;
2098                         *p_auth_len = 0;
2099                         *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
2100                         return data_len;
2101
2102                 case DCERPC_AUTH_LEVEL_INTEGRITY:
2103                 case DCERPC_AUTH_LEVEL_PRIVACY:
2104                         /* Treat the same for all authenticated rpc requests. */
2105                         switch(cli->auth->auth_type) {
2106                                 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2107                                 case PIPE_AUTH_TYPE_NTLMSSP:
2108                                         *p_auth_len = NTLMSSP_SIG_SIZE;
2109                                         break;
2110                                 case PIPE_AUTH_TYPE_SCHANNEL:
2111                                         *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
2112                                         break;
2113                                 default:
2114                                         smb_panic("bad auth type");
2115                                         break;
2116                         }
2117
2118                         data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
2119                                                 RPC_HDR_AUTH_LEN - *p_auth_len;
2120
2121                         data_len = MIN(data_space, data_left);
2122                         *p_ss_padding = 0;
2123                         if (data_len % 8) {
2124                                 *p_ss_padding = 8 - (data_len % 8);
2125                         }
2126                         *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN +                /* Normal headers. */
2127                                         data_len + *p_ss_padding +              /* data plus padding. */
2128                                         RPC_HDR_AUTH_LEN + *p_auth_len;         /* Auth header and auth data. */
2129                         return data_len;
2130
2131                 default:
2132                         smb_panic("bad auth level");
2133                         /* Notreached. */
2134                         return 0;
2135         }
2136 }
2137
2138 /*******************************************************************
2139  External interface.
2140  Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
2141  Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
2142  and deals with signing/sealing details.
2143  ********************************************************************/
2144
2145 struct rpc_api_pipe_req_state {
2146         struct event_context *ev;
2147         struct rpc_pipe_client *cli;
2148         uint8_t op_num;
2149         uint32_t call_id;
2150         prs_struct *req_data;
2151         uint32_t req_data_sent;
2152         prs_struct outgoing_frag;
2153         prs_struct reply_pdu;
2154 };
2155
2156 static int rpc_api_pipe_req_state_destructor(struct rpc_api_pipe_req_state *s)
2157 {
2158         prs_mem_free(&s->outgoing_frag);
2159         prs_mem_free(&s->reply_pdu);
2160         return 0;
2161 }
2162
2163 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
2164 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
2165 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2166                                   bool *is_last_frag);
2167
2168 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
2169                                          struct event_context *ev,
2170                                          struct rpc_pipe_client *cli,
2171                                          uint8_t op_num,
2172                                          prs_struct *req_data)
2173 {
2174         struct tevent_req *req, *subreq;
2175         struct rpc_api_pipe_req_state *state;
2176         NTSTATUS status;
2177         bool is_last_frag;
2178
2179         req = tevent_req_create(mem_ctx, &state,
2180                                 struct rpc_api_pipe_req_state);
2181         if (req == NULL) {
2182                 return NULL;
2183         }
2184         state->ev = ev;
2185         state->cli = cli;
2186         state->op_num = op_num;
2187         state->req_data = req_data;
2188         state->req_data_sent = 0;
2189         state->call_id = get_rpc_call_id();
2190
2191         if (cli->max_xmit_frag
2192             < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
2193                 /* Server is screwed up ! */
2194                 status = NT_STATUS_INVALID_PARAMETER;
2195                 goto post_status;
2196         }
2197
2198         prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2199
2200         if (!prs_init(&state->outgoing_frag, cli->max_xmit_frag,
2201                       state, MARSHALL)) {
2202                 goto fail;
2203         }
2204
2205         talloc_set_destructor(state, rpc_api_pipe_req_state_destructor);
2206
2207         status = prepare_next_frag(state, &is_last_frag);
2208         if (!NT_STATUS_IS_OK(status)) {
2209                 goto post_status;
2210         }
2211
2212         if (is_last_frag) {
2213                 subreq = rpc_api_pipe_send(state, ev, state->cli,
2214                                            &state->outgoing_frag,
2215                                            DCERPC_PKT_RESPONSE);
2216                 if (subreq == NULL) {
2217                         goto fail;
2218                 }
2219                 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2220         } else {
2221                 subreq = rpc_write_send(
2222                         state, ev, cli->transport,
2223                         (uint8_t *)prs_data_p(&state->outgoing_frag),
2224                         prs_offset(&state->outgoing_frag));
2225                 if (subreq == NULL) {
2226                         goto fail;
2227                 }
2228                 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2229                                         req);
2230         }
2231         return req;
2232
2233  post_status:
2234         tevent_req_nterror(req, status);
2235         return tevent_req_post(req, ev);
2236  fail:
2237         TALLOC_FREE(req);
2238         return NULL;
2239 }
2240
2241 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2242                                   bool *is_last_frag)
2243 {
2244         RPC_HDR hdr;
2245         RPC_HDR_REQ hdr_req;
2246         uint32_t data_sent_thistime;
2247         uint16_t auth_len;
2248         uint16_t frag_len;
2249         uint8_t flags = 0;
2250         uint32_t ss_padding;
2251         uint32_t data_left;
2252         char pad[8] = { 0, };
2253         NTSTATUS status;
2254
2255         data_left = prs_offset(state->req_data) - state->req_data_sent;
2256
2257         data_sent_thistime = calculate_data_len_tosend(
2258                 state->cli, data_left, &frag_len, &auth_len, &ss_padding);
2259
2260         if (state->req_data_sent == 0) {
2261                 flags = DCERPC_PFC_FLAG_FIRST;
2262         }
2263
2264         if (data_sent_thistime == data_left) {
2265                 flags |= DCERPC_PFC_FLAG_LAST;
2266         }
2267
2268         if (!prs_set_offset(&state->outgoing_frag, 0)) {
2269                 return NT_STATUS_NO_MEMORY;
2270         }
2271
2272         /* Create and marshall the header and request header. */
2273         init_rpc_hdr(&hdr, DCERPC_PKT_REQUEST, flags, state->call_id, frag_len,
2274                      auth_len);
2275
2276         if (!smb_io_rpc_hdr("hdr    ", &hdr, &state->outgoing_frag, 0)) {
2277                 return NT_STATUS_NO_MEMORY;
2278         }
2279
2280         /* Create the rpc request RPC_HDR_REQ */
2281         init_rpc_hdr_req(&hdr_req, prs_offset(state->req_data),
2282                          state->op_num);
2283
2284         if (!smb_io_rpc_hdr_req("hdr_req", &hdr_req,
2285                                 &state->outgoing_frag, 0)) {
2286                 return NT_STATUS_NO_MEMORY;
2287         }
2288
2289         /* Copy in the data, plus any ss padding. */
2290         if (!prs_append_some_prs_data(&state->outgoing_frag,
2291                                       state->req_data, state->req_data_sent,
2292                                       data_sent_thistime)) {
2293                 return NT_STATUS_NO_MEMORY;
2294         }
2295
2296         /* Copy the sign/seal padding data. */
2297         if (!prs_copy_data_in(&state->outgoing_frag, pad, ss_padding)) {
2298                 return NT_STATUS_NO_MEMORY;
2299         }
2300
2301         /* Generate any auth sign/seal and add the auth footer. */
2302         switch (state->cli->auth->auth_type) {
2303         case PIPE_AUTH_TYPE_NONE:
2304                 status = NT_STATUS_OK;
2305                 break;
2306         case PIPE_AUTH_TYPE_NTLMSSP:
2307         case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2308                 status = add_ntlmssp_auth_footer(state->cli, &hdr, ss_padding,
2309                                                  &state->outgoing_frag);
2310                 break;
2311         case PIPE_AUTH_TYPE_SCHANNEL:
2312                 status = add_schannel_auth_footer(state->cli, &hdr, ss_padding,
2313                                                   &state->outgoing_frag);
2314                 break;
2315         default:
2316                 status = NT_STATUS_INVALID_PARAMETER;
2317                 break;
2318         }
2319
2320         state->req_data_sent += data_sent_thistime;
2321         *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
2322
2323         return status;
2324 }
2325
2326 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
2327 {
2328         struct tevent_req *req = tevent_req_callback_data(
2329                 subreq, struct tevent_req);
2330         struct rpc_api_pipe_req_state *state = tevent_req_data(
2331                 req, struct rpc_api_pipe_req_state);
2332         NTSTATUS status;
2333         bool is_last_frag;
2334
2335         status = rpc_write_recv(subreq);
2336         TALLOC_FREE(subreq);
2337         if (!NT_STATUS_IS_OK(status)) {
2338                 tevent_req_nterror(req, status);
2339                 return;
2340         }
2341
2342         status = prepare_next_frag(state, &is_last_frag);
2343         if (!NT_STATUS_IS_OK(status)) {
2344                 tevent_req_nterror(req, status);
2345                 return;
2346         }
2347
2348         if (is_last_frag) {
2349                 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2350                                            &state->outgoing_frag,
2351                                            DCERPC_PKT_RESPONSE);
2352                 if (tevent_req_nomem(subreq, req)) {
2353                         return;
2354                 }
2355                 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2356         } else {
2357                 subreq = rpc_write_send(
2358                         state, state->ev,
2359                         state->cli->transport,
2360                         (uint8_t *)prs_data_p(&state->outgoing_frag),
2361                         prs_offset(&state->outgoing_frag));
2362                 if (tevent_req_nomem(subreq, req)) {
2363                         return;
2364                 }
2365                 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2366                                         req);
2367         }
2368 }
2369
2370 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
2371 {
2372         struct tevent_req *req = tevent_req_callback_data(
2373                 subreq, struct tevent_req);
2374         struct rpc_api_pipe_req_state *state = tevent_req_data(
2375                 req, struct rpc_api_pipe_req_state);
2376         NTSTATUS status;
2377
2378         status = rpc_api_pipe_recv(subreq, state, &state->reply_pdu);
2379         TALLOC_FREE(subreq);
2380         if (!NT_STATUS_IS_OK(status)) {
2381                 tevent_req_nterror(req, status);
2382                 return;
2383         }
2384         tevent_req_done(req);
2385 }
2386
2387 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2388                                prs_struct *reply_pdu)
2389 {
2390         struct rpc_api_pipe_req_state *state = tevent_req_data(
2391                 req, struct rpc_api_pipe_req_state);
2392         NTSTATUS status;
2393
2394         if (tevent_req_is_nterror(req, &status)) {
2395                 /*
2396                  * We always have to initialize to reply pdu, even if there is
2397                  * none. The rpccli_* caller routines expect this.
2398                  */
2399                 prs_init_empty(reply_pdu, mem_ctx, UNMARSHALL);
2400                 return status;
2401         }
2402
2403         *reply_pdu = state->reply_pdu;
2404         reply_pdu->mem_ctx = mem_ctx;
2405
2406         /*
2407          * Prevent state->req_pdu from being freed in
2408          * rpc_api_pipe_req_state_destructor()
2409          */
2410         prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2411
2412         return NT_STATUS_OK;
2413 }
2414
2415 #if 0
2416 /****************************************************************************
2417  Set the handle state.
2418 ****************************************************************************/
2419
2420 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
2421                                    const char *pipe_name, uint16 device_state)
2422 {
2423         bool state_set = False;
2424         char param[2];
2425         uint16 setup[2]; /* only need 2 uint16 setup parameters */
2426         char *rparam = NULL;
2427         char *rdata = NULL;
2428         uint32 rparam_len, rdata_len;
2429
2430         if (pipe_name == NULL)
2431                 return False;
2432
2433         DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
2434                  cli->fnum, pipe_name, device_state));
2435
2436         /* create parameters: device state */
2437         SSVAL(param, 0, device_state);
2438
2439         /* create setup parameters. */
2440         setup[0] = 0x0001; 
2441         setup[1] = cli->fnum; /* pipe file handle.  got this from an SMBOpenX. */
2442
2443         /* send the data on \PIPE\ */
2444         if (cli_api_pipe(cli->cli, "\\PIPE\\",
2445                     setup, 2, 0,                /* setup, length, max */
2446                     param, 2, 0,                /* param, length, max */
2447                     NULL, 0, 1024,              /* data, length, max */
2448                     &rparam, &rparam_len,        /* return param, length */
2449                     &rdata, &rdata_len))         /* return data, length */
2450         {
2451                 DEBUG(5, ("Set Handle state: return OK\n"));
2452                 state_set = True;
2453         }
2454
2455         SAFE_FREE(rparam);
2456         SAFE_FREE(rdata);
2457
2458         return state_set;
2459 }
2460 #endif
2461
2462 /****************************************************************************
2463  Check the rpc bind acknowledge response.
2464 ****************************************************************************/
2465
2466 static bool check_bind_response(RPC_HDR_BA *hdr_ba,
2467                                 const struct ndr_syntax_id *transfer)
2468 {
2469         if ( hdr_ba->addr.len == 0) {
2470                 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
2471         }
2472
2473         /* check the transfer syntax */
2474         if ((hdr_ba->transfer.if_version != transfer->if_version) ||
2475              (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
2476                 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
2477                 return False;
2478         }
2479
2480         if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) {
2481                 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
2482                           hdr_ba->res.num_results, hdr_ba->res.reason));
2483         }
2484
2485         DEBUG(5,("check_bind_response: accepted!\n"));
2486         return True;
2487 }
2488
2489 /*******************************************************************
2490  Creates a DCE/RPC bind authentication response.
2491  This is the packet that is sent back to the server once we
2492  have received a BIND-ACK, to finish the third leg of
2493  the authentication handshake.
2494  ********************************************************************/
2495
2496 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
2497                                 uint32 rpc_call_id,
2498                                 enum pipe_auth_type auth_type,
2499                                 enum dcerpc_AuthLevel auth_level,
2500                                 DATA_BLOB *pauth_blob,
2501                                 prs_struct *rpc_out)
2502 {
2503         RPC_HDR hdr;
2504         RPC_HDR_AUTH hdr_auth;
2505         uint32 pad = 0;
2506
2507         /* Create the request RPC_HDR */
2508         init_rpc_hdr(&hdr, DCERPC_PKT_AUTH3, DCERPC_PFC_FLAG_FIRST|DCERPC_PFC_FLAG_LAST, rpc_call_id,
2509                      RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + pauth_blob->length,
2510                      pauth_blob->length );
2511
2512         /* Marshall it. */
2513         if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
2514                 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
2515                 return NT_STATUS_NO_MEMORY;
2516         }
2517
2518         /*
2519                 I'm puzzled about this - seems to violate the DCE RPC auth rules,
2520                 about padding - shouldn't this pad to length 8 ? JRA.
2521         */
2522
2523         /* 4 bytes padding. */
2524         if (!prs_uint32("pad", rpc_out, 0, &pad)) {
2525                 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
2526                 return NT_STATUS_NO_MEMORY;
2527         }
2528
2529         /* Create the request RPC_HDR_AUTHA */
2530         init_rpc_hdr_auth(&hdr_auth,
2531                         map_pipe_auth_type_to_rpc_auth_type(auth_type),
2532                         auth_level, 0, 1);
2533
2534         if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rpc_out, 0)) {
2535                 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
2536                 return NT_STATUS_NO_MEMORY;
2537         }
2538
2539         /*
2540          * Append the auth data to the outgoing buffer.
2541          */
2542
2543         if(!prs_copy_data_in(rpc_out, (char *)pauth_blob->data, pauth_blob->length)) {
2544                 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
2545                 return NT_STATUS_NO_MEMORY;
2546         }
2547
2548         return NT_STATUS_OK;
2549 }
2550
2551 /*******************************************************************
2552  Creates a DCE/RPC bind alter context authentication request which
2553  may contain a spnego auth blobl
2554  ********************************************************************/
2555
2556 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
2557                                         const struct ndr_syntax_id *abstract,
2558                                         const struct ndr_syntax_id *transfer,
2559                                         enum dcerpc_AuthLevel auth_level,
2560                                         const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
2561                                         prs_struct *rpc_out)
2562 {
2563         RPC_HDR_AUTH hdr_auth;
2564         prs_struct auth_info;
2565         NTSTATUS ret = NT_STATUS_OK;
2566
2567         ZERO_STRUCT(hdr_auth);
2568         if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
2569                 return NT_STATUS_NO_MEMORY;
2570
2571         /* We may change the pad length before marshalling. */
2572         init_rpc_hdr_auth(&hdr_auth, DCERPC_AUTH_TYPE_SPNEGO, (int)auth_level, 0, 1);
2573
2574         if (pauth_blob->length) {
2575                 if (!prs_copy_data_in(&auth_info, (const char *)pauth_blob->data, pauth_blob->length)) {
2576                         prs_mem_free(&auth_info);
2577                         return NT_STATUS_NO_MEMORY;
2578                 }
2579         }
2580
2581         ret = create_bind_or_alt_ctx_internal(DCERPC_PKT_ALTER,
2582                                                 rpc_out, 
2583                                                 rpc_call_id,
2584                                                 abstract,
2585                                                 transfer,
2586                                                 &hdr_auth,
2587                                                 &auth_info);
2588         prs_mem_free(&auth_info);
2589         return ret;
2590 }
2591
2592 /****************************************************************************
2593  Do an rpc bind.
2594 ****************************************************************************/
2595
2596 struct rpc_pipe_bind_state {
2597         struct event_context *ev;
2598         struct rpc_pipe_client *cli;
2599         prs_struct rpc_out;
2600         uint32_t rpc_call_id;
2601 };
2602
2603 static int rpc_pipe_bind_state_destructor(struct rpc_pipe_bind_state *state)
2604 {
2605         prs_mem_free(&state->rpc_out);
2606         return 0;
2607 }
2608
2609 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
2610 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2611                                            struct rpc_pipe_bind_state *state,
2612                                            struct rpc_hdr_info *phdr,
2613                                            prs_struct *reply_pdu);
2614 static void rpc_bind_auth3_write_done(struct tevent_req *subreq);
2615 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2616                                                     struct rpc_pipe_bind_state *state,
2617                                                     struct rpc_hdr_info *phdr,
2618                                                     prs_struct *reply_pdu);
2619 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq);
2620
2621 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
2622                                       struct event_context *ev,
2623                                       struct rpc_pipe_client *cli,
2624                                       struct cli_pipe_auth_data *auth)
2625 {
2626         struct tevent_req *req, *subreq;
2627         struct rpc_pipe_bind_state *state;
2628         NTSTATUS status;
2629
2630         req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
2631         if (req == NULL) {
2632                 return NULL;
2633         }
2634
2635         DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2636                 rpccli_pipe_txt(talloc_tos(), cli),
2637                 (unsigned int)auth->auth_type,
2638                 (unsigned int)auth->auth_level ));
2639
2640         state->ev = ev;
2641         state->cli = cli;
2642         state->rpc_call_id = get_rpc_call_id();
2643
2644         prs_init_empty(&state->rpc_out, state, MARSHALL);
2645         talloc_set_destructor(state, rpc_pipe_bind_state_destructor);
2646
2647         cli->auth = talloc_move(cli, &auth);
2648
2649         /* Marshall the outgoing data. */
2650         status = create_rpc_bind_req(cli, &state->rpc_out,
2651                                      state->rpc_call_id,
2652                                      &cli->abstract_syntax,
2653                                      &cli->transfer_syntax,
2654                                      cli->auth->auth_type,
2655                                      cli->auth->auth_level);
2656
2657         if (!NT_STATUS_IS_OK(status)) {
2658                 goto post_status;
2659         }
2660
2661         subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
2662                                    DCERPC_PKT_BIND_ACK);
2663         if (subreq == NULL) {
2664                 goto fail;
2665         }
2666         tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2667         return req;
2668
2669  post_status:
2670         tevent_req_nterror(req, status);
2671         return tevent_req_post(req, ev);
2672  fail:
2673         TALLOC_FREE(req);
2674         return NULL;
2675 }
2676
2677 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
2678 {
2679         struct tevent_req *req = tevent_req_callback_data(
2680                 subreq, struct tevent_req);
2681         struct rpc_pipe_bind_state *state = tevent_req_data(
2682                 req, struct rpc_pipe_bind_state);
2683         prs_struct reply_pdu;
2684         struct rpc_hdr_info hdr;
2685         struct rpc_hdr_ba_info hdr_ba;
2686         NTSTATUS status;
2687
2688         status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
2689         TALLOC_FREE(subreq);
2690         if (!NT_STATUS_IS_OK(status)) {
2691                 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
2692                           rpccli_pipe_txt(talloc_tos(), state->cli),
2693                           nt_errstr(status)));
2694                 tevent_req_nterror(req, status);
2695                 return;
2696         }
2697
2698         /* Unmarshall the RPC header */
2699         if (!smb_io_rpc_hdr("hdr", &hdr, &reply_pdu, 0)) {
2700                 DEBUG(0, ("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2701                 prs_mem_free(&reply_pdu);
2702                 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2703                 return;
2704         }
2705
2706         if (!smb_io_rpc_hdr_ba("", &hdr_ba, &reply_pdu, 0)) {
2707                 DEBUG(0, ("rpc_pipe_bind: Failed to unmarshall "
2708                           "RPC_HDR_BA.\n"));
2709                 prs_mem_free(&reply_pdu);
2710                 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2711                 return;
2712         }
2713
2714         if (!check_bind_response(&hdr_ba, &state->cli->transfer_syntax)) {
2715                 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
2716                 prs_mem_free(&reply_pdu);
2717                 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2718                 return;
2719         }
2720
2721         state->cli->max_xmit_frag = hdr_ba.bba.max_tsize;
2722         state->cli->max_recv_frag = hdr_ba.bba.max_rsize;
2723
2724         /*
2725          * For authenticated binds we may need to do 3 or 4 leg binds.
2726          */
2727
2728         switch(state->cli->auth->auth_type) {
2729
2730         case PIPE_AUTH_TYPE_NONE:
2731         case PIPE_AUTH_TYPE_SCHANNEL:
2732                 /* Bind complete. */
2733                 prs_mem_free(&reply_pdu);
2734                 tevent_req_done(req);
2735                 break;
2736
2737         case PIPE_AUTH_TYPE_NTLMSSP:
2738                 /* Need to send AUTH3 packet - no reply. */
2739                 status = rpc_finish_auth3_bind_send(req, state, &hdr,
2740                                                     &reply_pdu);
2741                 prs_mem_free(&reply_pdu);
2742                 if (!NT_STATUS_IS_OK(status)) {
2743                         tevent_req_nterror(req, status);
2744                 }
2745                 break;
2746
2747         case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2748                 /* Need to send alter context request and reply. */
2749                 status = rpc_finish_spnego_ntlmssp_bind_send(req, state, &hdr,
2750                                                              &reply_pdu);
2751                 prs_mem_free(&reply_pdu);
2752                 if (!NT_STATUS_IS_OK(status)) {
2753                         tevent_req_nterror(req, status);
2754                 }
2755                 break;
2756
2757         case PIPE_AUTH_TYPE_KRB5:
2758                 /* */
2759
2760         default:
2761                 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
2762                          (unsigned int)state->cli->auth->auth_type));
2763                 prs_mem_free(&reply_pdu);
2764                 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2765         }
2766 }
2767
2768 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2769                                            struct rpc_pipe_bind_state *state,
2770                                            struct rpc_hdr_info *phdr,
2771                                            prs_struct *reply_pdu)
2772 {
2773         DATA_BLOB server_response = data_blob_null;
2774         DATA_BLOB client_reply = data_blob_null;
2775         struct rpc_hdr_auth_info hdr_auth;
2776         struct tevent_req *subreq;
2777         NTSTATUS status;
2778
2779         if ((phdr->auth_len == 0)
2780             || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2781                 return NT_STATUS_INVALID_PARAMETER;
2782         }
2783
2784         if (!prs_set_offset(
2785                     reply_pdu,
2786                     phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2787                 return NT_STATUS_INVALID_PARAMETER;
2788         }
2789
2790         if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
2791                 return NT_STATUS_INVALID_PARAMETER;
2792         }
2793
2794         /* TODO - check auth_type/auth_level match. */
2795
2796         server_response = data_blob_talloc(talloc_tos(), NULL, phdr->auth_len);
2797         prs_copy_data_out((char *)server_response.data, reply_pdu,
2798                           phdr->auth_len);
2799
2800         status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2801                                 server_response, &client_reply);
2802
2803         if (!NT_STATUS_IS_OK(status)) {
2804                 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
2805                           "blob failed: %s.\n", nt_errstr(status)));
2806                 return status;
2807         }
2808
2809         prs_init_empty(&state->rpc_out, talloc_tos(), MARSHALL);
2810
2811         status = create_rpc_bind_auth3(state->cli, state->rpc_call_id,
2812                                        state->cli->auth->auth_type,
2813                                        state->cli->auth->auth_level,
2814                                        &client_reply, &state->rpc_out);
2815         data_blob_free(&client_reply);
2816
2817         if (!NT_STATUS_IS_OK(status)) {
2818                 return status;
2819         }
2820
2821         subreq = rpc_write_send(state, state->ev, state->cli->transport,
2822                                 (uint8_t *)prs_data_p(&state->rpc_out),
2823                                 prs_offset(&state->rpc_out));
2824         if (subreq == NULL) {
2825                 return NT_STATUS_NO_MEMORY;
2826         }
2827         tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
2828         return NT_STATUS_OK;
2829 }
2830
2831 static void rpc_bind_auth3_write_done(struct tevent_req *subreq)
2832 {
2833         struct tevent_req *req = tevent_req_callback_data(
2834                 subreq, struct tevent_req);
2835         NTSTATUS status;
2836
2837         status = rpc_write_recv(subreq);
2838         TALLOC_FREE(subreq);
2839         if (!NT_STATUS_IS_OK(status)) {
2840                 tevent_req_nterror(req, status);
2841                 return;
2842         }
2843         tevent_req_done(req);
2844 }
2845
2846 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2847                                                     struct rpc_pipe_bind_state *state,
2848                                                     struct rpc_hdr_info *phdr,
2849                                                     prs_struct *reply_pdu)
2850 {
2851         DATA_BLOB server_spnego_response = data_blob_null;
2852         DATA_BLOB server_ntlm_response = data_blob_null;
2853         DATA_BLOB client_reply = data_blob_null;
2854         DATA_BLOB tmp_blob = data_blob_null;
2855         RPC_HDR_AUTH hdr_auth;
2856         struct tevent_req *subreq;
2857         NTSTATUS status;
2858
2859         if ((phdr->auth_len == 0)
2860             || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2861                 return NT_STATUS_INVALID_PARAMETER;
2862         }
2863
2864         /* Process the returned NTLMSSP blob first. */
2865         if (!prs_set_offset(
2866                     reply_pdu,
2867                     phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2868                 return NT_STATUS_INVALID_PARAMETER;
2869         }
2870
2871         if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
2872                 return NT_STATUS_INVALID_PARAMETER;
2873         }
2874
2875         server_spnego_response = data_blob(NULL, phdr->auth_len);
2876         prs_copy_data_out((char *)server_spnego_response.data,
2877                           reply_pdu, phdr->auth_len);
2878
2879         /*
2880          * The server might give us back two challenges - tmp_blob is for the
2881          * second.
2882          */
2883         if (!spnego_parse_challenge(server_spnego_response,
2884                                     &server_ntlm_response, &tmp_blob)) {
2885                 data_blob_free(&server_spnego_response);
2886                 data_blob_free(&server_ntlm_response);
2887                 data_blob_free(&tmp_blob);
2888                 return NT_STATUS_INVALID_PARAMETER;
2889         }
2890
2891         /* We're finished with the server spnego response and the tmp_blob. */
2892         data_blob_free(&server_spnego_response);
2893         data_blob_free(&tmp_blob);
2894
2895         status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2896                                 server_ntlm_response, &client_reply);
2897
2898         /* Finished with the server_ntlm response */
2899         data_blob_free(&server_ntlm_response);
2900
2901         if (!NT_STATUS_IS_OK(status)) {
2902                 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "
2903                           "using server blob failed.\n"));
2904                 data_blob_free(&client_reply);
2905                 return status;
2906         }
2907
2908         /* SPNEGO wrap the client reply. */
2909         tmp_blob = spnego_gen_auth(client_reply);
2910         data_blob_free(&client_reply);
2911         client_reply = tmp_blob;
2912         tmp_blob = data_blob_null;
2913
2914         /* Now prepare the alter context pdu. */
2915         prs_init_empty(&state->rpc_out, state, MARSHALL);
2916
2917         status = create_rpc_alter_context(state->rpc_call_id,
2918                                           &state->cli->abstract_syntax,
2919                                           &state->cli->transfer_syntax,
2920                                           state->cli->auth->auth_level,
2921                                           &client_reply,
2922                                           &state->rpc_out);
2923         data_blob_free(&client_reply);
2924
2925         if (!NT_STATUS_IS_OK(status)) {
2926                 return status;
2927         }
2928
2929         subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2930                                    &state->rpc_out, DCERPC_PKT_ALTER_RESP);
2931         if (subreq == NULL) {
2932                 return NT_STATUS_NO_MEMORY;
2933         }
2934         tevent_req_set_callback(subreq, rpc_bind_ntlmssp_api_done, req);
2935         return NT_STATUS_OK;
2936 }
2937
2938 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq)
2939 {
2940         struct tevent_req *req = tevent_req_callback_data(
2941                 subreq, struct tevent_req);
2942         struct rpc_pipe_bind_state *state = tevent_req_data(
2943                 req, struct rpc_pipe_bind_state);
2944         DATA_BLOB server_spnego_response = data_blob_null;
2945         DATA_BLOB tmp_blob = data_blob_null;
2946         prs_struct reply_pdu;
2947         struct rpc_hdr_info hdr;
2948         struct rpc_hdr_auth_info hdr_auth;
2949         NTSTATUS status;
2950
2951         status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
2952         TALLOC_FREE(subreq);
2953         if (!NT_STATUS_IS_OK(status)) {
2954                 tevent_req_nterror(req, status);
2955                 return;
2956         }
2957
2958         /* Get the auth blob from the reply. */
2959         if (!smb_io_rpc_hdr("rpc_hdr   ", &hdr, &reply_pdu, 0)) {
2960                 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: Failed to "
2961                           "unmarshall RPC_HDR.\n"));
2962                 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2963                 return;
2964         }
2965
2966         if (!prs_set_offset(
2967                     &reply_pdu,
2968                     hdr.frag_len - hdr.auth_len - RPC_HDR_AUTH_LEN)) {
2969                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2970                 return;
2971         }
2972
2973         if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &reply_pdu, 0)) {
2974                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2975                 return;
2976         }
2977
2978         server_spnego_response = data_blob(NULL, hdr.auth_len);
2979         prs_copy_data_out((char *)server_spnego_response.data, &reply_pdu,
2980                           hdr.auth_len);
2981
2982         /* Check we got a valid auth response. */
2983         if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK,
2984                                         OID_NTLMSSP, &tmp_blob)) {
2985                 data_blob_free(&server_spnego_response);
2986                 data_blob_free(&tmp_blob);
2987                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2988                 return;
2989         }
2990
2991         data_blob_free(&server_spnego_response);
2992         data_blob_free(&tmp_blob);
2993
2994         DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
2995                  "%s.\n", rpccli_pipe_txt(talloc_tos(), state->cli)));
2996         tevent_req_done(req);
2997 }
2998
2999 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
3000 {
3001         return tevent_req_simple_recv_ntstatus(req);
3002 }
3003
3004 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
3005                        struct cli_pipe_auth_data *auth)
3006 {
3007         TALLOC_CTX *frame = talloc_stackframe();
3008         struct event_context *ev;
3009         struct tevent_req *req;
3010         NTSTATUS status = NT_STATUS_OK;
3011
3012         ev = event_context_init(frame);
3013         if (ev == NULL) {
3014                 status = NT_STATUS_NO_MEMORY;
3015                 goto fail;
3016         }
3017
3018         req = rpc_pipe_bind_send(frame, ev, cli, auth);
3019         if (req == NULL) {
3020                 status = NT_STATUS_NO_MEMORY;
3021                 goto fail;
3022         }
3023
3024         if (!tevent_req_poll(req, ev)) {
3025                 status = map_nt_error_from_unix(errno);
3026                 goto fail;
3027         }
3028
3029         status = rpc_pipe_bind_recv(req);
3030  fail:
3031         TALLOC_FREE(frame);
3032         return status;
3033 }
3034
3035 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
3036                                 unsigned int timeout)
3037 {
3038         struct cli_state *cli = rpc_pipe_np_smb_conn(rpc_cli);
3039
3040         if (cli == NULL) {
3041                 return 0;
3042         }
3043         return cli_set_timeout(cli, timeout);
3044 }
3045
3046 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
3047 {
3048         struct cli_state *cli;
3049
3050         if ((rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
3051             || (rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) {
3052                 memcpy(nt_hash, rpc_cli->auth->a_u.ntlmssp_state->nt_hash, 16);
3053                 return true;
3054         }
3055
3056         cli = rpc_pipe_np_smb_conn(rpc_cli);
3057         if (cli == NULL) {
3058                 return false;
3059         }
3060         E_md4hash(cli->password ? cli->password : "", nt_hash);
3061         return true;
3062 }
3063
3064 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
3065                                struct cli_pipe_auth_data **presult)
3066 {
3067         struct cli_pipe_auth_data *result;
3068
3069         result = talloc(mem_ctx, struct cli_pipe_auth_data);
3070         if (result == NULL) {
3071                 return NT_STATUS_NO_MEMORY;
3072         }
3073
3074         result->auth_type = PIPE_AUTH_TYPE_NONE;
3075         result->auth_level = DCERPC_AUTH_LEVEL_NONE;
3076
3077         result->user_name = talloc_strdup(result, "");
3078         result->domain = talloc_strdup(result, "");
3079         if ((result->user_name == NULL) || (result->domain == NULL)) {
3080                 TALLOC_FREE(result);
3081                 return NT_STATUS_NO_MEMORY;
3082         }
3083
3084         *presult = result;
3085         return NT_STATUS_OK;
3086 }
3087
3088 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth)
3089 {
3090         ntlmssp_end(&auth->a_u.ntlmssp_state);
3091         return 0;
3092 }
3093
3094 static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
3095                                   enum pipe_auth_type auth_type,
3096                                   enum dcerpc_AuthLevel auth_level,
3097                                   const char *domain,
3098                                   const char *username,
3099                                   const char *password,
3100                                   struct cli_pipe_auth_data **presult)
3101 {
3102         struct cli_pipe_auth_data *result;
3103         NTSTATUS status;
3104
3105         result = talloc(mem_ctx, struct cli_pipe_auth_data);
3106         if (result == NULL) {
3107                 return NT_STATUS_NO_MEMORY;
3108         }
3109
3110         result->auth_type = auth_type;
3111         result->auth_level = auth_level;
3112
3113         result->user_name = talloc_strdup(result, username);
3114         result->domain = talloc_strdup(result, domain);
3115         if ((result->user_name == NULL) || (result->domain == NULL)) {
3116                 status = NT_STATUS_NO_MEMORY;
3117                 goto fail;
3118         }
3119
3120         status = ntlmssp_client_start(&result->a_u.ntlmssp_state);
3121         if (!NT_STATUS_IS_OK(status)) {
3122                 goto fail;
3123         }
3124
3125         talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
3126
3127         status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);
3128         if (!NT_STATUS_IS_OK(status)) {
3129                 goto fail;
3130         }
3131
3132         status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);
3133         if (!NT_STATUS_IS_OK(status)) {
3134                 goto fail;
3135         }
3136
3137         status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);
3138         if (!NT_STATUS_IS_OK(status)) {
3139                 goto fail;
3140         }
3141
3142         /*
3143          * Turn off sign+seal to allow selected auth level to turn it back on.
3144          */
3145         result->a_u.ntlmssp_state->neg_flags &=
3146                 ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);
3147
3148         if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
3149                 result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
3150         } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
3151                 result->a_u.ntlmssp_state->neg_flags
3152                         |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
3153         }
3154
3155         *presult = result;
3156         return NT_STATUS_OK;
3157
3158  fail:
3159         TALLOC_FREE(result);
3160         return status;
3161 }
3162
3163 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
3164                                    enum dcerpc_AuthLevel auth_level,
3165                                    struct netlogon_creds_CredentialState *creds,
3166                                    struct cli_pipe_auth_data **presult)
3167 {
3168         struct cli_pipe_auth_data *result;
3169
3170         result = talloc(mem_ctx, struct cli_pipe_auth_data);
3171         if (result == NULL) {
3172                 return NT_STATUS_NO_MEMORY;
3173         }
3174
3175         result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
3176         result->auth_level = auth_level;
3177
3178         result->user_name = talloc_strdup(result, "");
3179         result->domain = talloc_strdup(result, domain);
3180         if ((result->user_name == NULL) || (result->domain == NULL)) {
3181                 goto fail;
3182         }
3183
3184         result->a_u.schannel_auth = talloc(result, struct schannel_state);
3185         if (result->a_u.schannel_auth == NULL) {
3186                 goto fail;
3187         }
3188
3189         result->a_u.schannel_auth->state = SCHANNEL_STATE_START;
3190         result->a_u.schannel_auth->seq_num = 0;
3191         result->a_u.schannel_auth->initiator = true;
3192         result->a_u.schannel_auth->creds = creds;
3193
3194         *presult = result;
3195         return NT_STATUS_OK;
3196
3197  fail:
3198         TALLOC_FREE(result);
3199         return NT_STATUS_NO_MEMORY;
3200 }
3201
3202 #ifdef HAVE_KRB5
3203 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
3204 {
3205         data_blob_free(&auth->session_key);
3206         return 0;
3207 }
3208 #endif
3209
3210 static NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
3211                                    enum dcerpc_AuthLevel auth_level,
3212                                    const char *service_princ,
3213                                    const char *username,
3214                                    const char *password,
3215                                    struct cli_pipe_auth_data **presult)
3216 {
3217 #ifdef HAVE_KRB5
3218         struct cli_pipe_auth_data *result;
3219
3220         if ((username != NULL) && (password != NULL)) {
3221                 int ret = kerberos_kinit_password(username, password, 0, NULL);
3222                 if (ret != 0) {
3223                         return NT_STATUS_ACCESS_DENIED;
3224                 }
3225         }
3226
3227         result = talloc(mem_ctx, struct cli_pipe_auth_data);
3228         if (result == NULL) {
3229                 return NT_STATUS_NO_MEMORY;
3230         }
3231
3232         result->auth_type = PIPE_AUTH_TYPE_KRB5;
3233         result->auth_level = auth_level;
3234
3235         /*
3236          * Username / domain need fixing!
3237          */
3238         result->user_name = talloc_strdup(result, "");
3239         result->domain = talloc_strdup(result, "");
3240         if ((result->user_name == NULL) || (result->domain == NULL)) {
3241                 goto fail;
3242         }
3243
3244         result->a_u.kerberos_auth = TALLOC_ZERO_P(
3245                 result, struct kerberos_auth_struct);
3246         if (result->a_u.kerberos_auth == NULL) {
3247                 goto fail;
3248         }
3249         talloc_set_destructor(result->a_u.kerberos_auth,
3250                               cli_auth_kerberos_data_destructor);
3251
3252         result->a_u.kerberos_auth->service_principal = talloc_strdup(
3253                 result, service_princ);
3254         if (result->a_u.kerberos_auth->service_principal == NULL) {
3255                 goto fail;
3256         }
3257
3258         *presult = result;
3259         return NT_STATUS_OK;
3260
3261  fail:
3262         TALLOC_FREE(result);
3263         return NT_STATUS_NO_MEMORY;
3264 #else
3265         return NT_STATUS_NOT_SUPPORTED;
3266 #endif
3267 }
3268
3269 /**
3270  * Create an rpc pipe client struct, connecting to a tcp port.
3271  */
3272 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
3273                                        uint16_t port,
3274                                        const struct ndr_syntax_id *abstract_syntax,
3275                                        struct rpc_pipe_client **presult)
3276 {
3277         struct rpc_pipe_client *result;
3278         struct sockaddr_storage addr;
3279         NTSTATUS status;
3280         int fd;
3281
3282         result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
3283         if (result == NULL) {
3284                 return NT_STATUS_NO_MEMORY;
3285         }
3286
3287         result->abstract_syntax = *abstract_syntax;
3288         result->transfer_syntax = ndr_transfer_syntax;
3289         result->dispatch = cli_do_rpc_ndr;
3290         result->dispatch_send = cli_do_rpc_ndr_send;
3291         result->dispatch_recv = cli_do_rpc_ndr_recv;
3292
3293         result->desthost = talloc_strdup(result, host);
3294         result->srv_name_slash = talloc_asprintf_strupper_m(
3295                 result, "\\\\%s", result->desthost);
3296         if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3297                 status = NT_STATUS_NO_MEMORY;
3298                 goto fail;
3299         }
3300
3301         result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3302         result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3303
3304         if (!resolve_name(host, &addr, 0, false)) {
3305                 status = NT_STATUS_NOT_FOUND;
3306                 goto fail;
3307         }
3308
3309         status = open_socket_out(&addr, port, 60, &fd);
3310         if (!NT_STATUS_IS_OK(status)) {
3311                 goto fail;
3312         }
3313         set_socket_options(fd, lp_socket_options());
3314
3315         status = rpc_transport_sock_init(result, fd, &result->transport);
3316         if (!NT_STATUS_IS_OK(status)) {
3317                 close(fd);
3318                 goto fail;
3319         }
3320
3321         result->transport->transport = NCACN_IP_TCP;
3322
3323         *presult = result;
3324         return NT_STATUS_OK;
3325
3326  fail:
3327         TALLOC_FREE(result);
3328         return status;
3329 }
3330
3331 /**
3332  * Determine the tcp port on which a dcerpc interface is listening
3333  * for the ncacn_ip_tcp transport via the endpoint mapper of the
3334  * target host.
3335  */
3336 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
3337                                       const struct ndr_syntax_id *abstract_syntax,
3338                                       uint16_t *pport)
3339 {
3340         NTSTATUS status;
3341         struct rpc_pipe_client *epm_pipe = NULL;
3342         struct cli_pipe_auth_data *auth = NULL;
3343         struct dcerpc_binding *map_binding = NULL;
3344         struct dcerpc_binding *res_binding = NULL;
3345         struct epm_twr_t *map_tower = NULL;
3346         struct epm_twr_t *res_towers = NULL;
3347         struct policy_handle *entry_handle = NULL;
3348         uint32_t num_towers = 0;
3349         uint32_t max_towers = 1;
3350         struct epm_twr_p_t towers;
3351         TALLOC_CTX *tmp_ctx = talloc_stackframe();
3352
3353         if (pport == NULL) {
3354                 status = NT_STATUS_INVALID_PARAMETER;
3355                 goto done;
3356         }
3357
3358         /* open the connection to the endpoint mapper */
3359         status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
3360                                         &ndr_table_epmapper.syntax_id,
3361                                         &epm_pipe);
3362
3363         if (!NT_STATUS_IS_OK(status)) {
3364                 goto done;
3365         }
3366
3367         status = rpccli_anon_bind_data(tmp_ctx, &auth);
3368         if (!NT_STATUS_IS_OK(status)) {
3369                 goto done;
3370         }
3371
3372         status = rpc_pipe_bind(epm_pipe, auth);
3373         if (!NT_STATUS_IS_OK(status)) {
3374                 goto done;
3375         }
3376
3377         /* create tower for asking the epmapper */
3378
3379         map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
3380         if (map_binding == NULL) {
3381                 status = NT_STATUS_NO_MEMORY;
3382                 goto done;
3383         }
3384
3385         map_binding->transport = NCACN_IP_TCP;
3386         map_binding->object = *abstract_syntax;
3387         map_binding->host = host; /* needed? */
3388         map_binding->endpoint = "0"; /* correct? needed? */
3389
3390         map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
3391         if (map_tower == NULL) {
3392                 status = NT_STATUS_NO_MEMORY;
3393                 goto done;
3394         }
3395
3396         status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
3397                                             &(map_tower->tower));
3398         if (!NT_STATUS_IS_OK(status)) {
3399                 goto done;
3400         }
3401
3402         /* allocate further parameters for the epm_Map call */
3403
3404         res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
3405         if (res_towers == NULL) {
3406                 status = NT_STATUS_NO_MEMORY;
3407                 goto done;
3408         }
3409         towers.twr = res_towers;
3410
3411         entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
3412         if (entry_handle == NULL) {
3413                 status = NT_STATUS_NO_MEMORY;
3414                 goto done;
3415         }
3416
3417         /* ask the endpoint mapper for the port */
3418
3419         status = rpccli_epm_Map(epm_pipe,
3420                                 tmp_ctx,
3421                                 CONST_DISCARD(struct GUID *,
3422                                               &(abstract_syntax->uuid)),
3423                                 map_tower,
3424                                 entry_handle,
3425                                 max_towers,
3426                                 &num_towers,
3427                                 &towers);
3428
3429         if (!NT_STATUS_IS_OK(status)) {
3430                 goto done;
3431         }
3432
3433         if (num_towers != 1) {
3434                 status = NT_STATUS_UNSUCCESSFUL;
3435                 goto done;
3436         }
3437
3438         /* extract the port from the answer */
3439
3440         status = dcerpc_binding_from_tower(tmp_ctx,
3441                                            &(towers.twr->tower),
3442                                            &res_binding);
3443         if (!NT_STATUS_IS_OK(status)) {
3444                 goto done;
3445         }
3446
3447         /* are further checks here necessary? */
3448         if (res_binding->transport != NCACN_IP_TCP) {
3449                 status = NT_STATUS_UNSUCCESSFUL;
3450                 goto done;
3451         }
3452
3453         *pport = (uint16_t)atoi(res_binding->endpoint);
3454
3455 done:
3456         TALLOC_FREE(tmp_ctx);
3457         return status;
3458 }
3459
3460 /**
3461  * Create a rpc pipe client struct, connecting to a host via tcp.
3462  * The port is determined by asking the endpoint mapper on the given
3463  * host.
3464  */
3465 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
3466                            const struct ndr_syntax_id *abstract_syntax,
3467                            struct rpc_pipe_client **presult)
3468 {
3469         NTSTATUS status;
3470         uint16_t port = 0;
3471
3472         status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
3473         if (!NT_STATUS_IS_OK(status)) {
3474                 return status;
3475         }
3476
3477         return rpc_pipe_open_tcp_port(mem_ctx, host, port,
3478                                         abstract_syntax, presult);
3479 }
3480
3481 /********************************************************************
3482  Create a rpc pipe client struct, connecting to a unix domain socket
3483  ********************************************************************/
3484 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
3485                                const struct ndr_syntax_id *abstract_syntax,
3486                                struct rpc_pipe_client **presult)
3487 {
3488         struct rpc_pipe_client *result;
3489         struct sockaddr_un addr;
3490         NTSTATUS status;
3491         int fd;
3492
3493         result = talloc_zero(mem_ctx, struct rpc_pipe_client);
3494         if (result == NULL) {
3495                 return NT_STATUS_NO_MEMORY;
3496         }
3497
3498         result->abstract_syntax = *abstract_syntax;
3499         result->transfer_syntax = ndr_transfer_syntax;
3500         result->dispatch = cli_do_rpc_ndr;
3501         result->dispatch_send = cli_do_rpc_ndr_send;
3502         result->dispatch_recv = cli_do_rpc_ndr_recv;
3503
3504         result->desthost = get_myname(result);
3505         result->srv_name_slash = talloc_asprintf_strupper_m(
3506                 result, "\\\\%s", result->desthost);
3507         if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3508                 status = NT_STATUS_NO_MEMORY;
3509                 goto fail;
3510         }
3511
3512         result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3513         result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3514
3515         fd = socket(AF_UNIX, SOCK_STREAM, 0);
3516         if (fd == -1) {
3517                 status = map_nt_error_from_unix(errno);
3518                 goto fail;
3519         }
3520
3521         ZERO_STRUCT(addr);
3522         addr.sun_family = AF_UNIX;
3523         strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
3524
3525         if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
3526                 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
3527                           strerror(errno)));
3528                 close(fd);
3529                 return map_nt_error_from_unix(errno);
3530         }
3531
3532         status = rpc_transport_sock_init(result, fd, &result->transport);
3533         if (!NT_STATUS_IS_OK(status)) {
3534                 close(fd);
3535                 goto fail;
3536         }
3537
3538         result->transport->transport = NCALRPC;
3539
3540         *presult = result;
3541         return NT_STATUS_OK;
3542
3543  fail:
3544         TALLOC_FREE(result);
3545         return status;
3546 }
3547
3548 static int rpc_pipe_client_np_destructor(struct rpc_pipe_client *p)
3549 {
3550         struct cli_state *cli;
3551
3552         cli = rpc_pipe_np_smb_conn(p);
3553         if (cli != NULL) {
3554                 DLIST_REMOVE(cli->pipe_list, p);
3555         }
3556         return 0;
3557 }
3558
3559 /****************************************************************************
3560  Open a named pipe over SMB to a remote server.
3561  *
3562  * CAVEAT CALLER OF THIS FUNCTION:
3563  *    The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
3564  *    so be sure that this function is called AFTER any structure (vs pointer)
3565  *    assignment of the cli.  In particular, libsmbclient does structure
3566  *    assignments of cli, which invalidates the data in the returned
3567  *    rpc_pipe_client if this function is called before the structure assignment
3568  *    of cli.
3569  * 
3570  ****************************************************************************/
3571
3572 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
3573                                  const struct ndr_syntax_id *abstract_syntax,
3574                                  struct rpc_pipe_client **presult)
3575 {
3576         struct rpc_pipe_client *result;
3577         NTSTATUS status;
3578
3579         /* sanity check to protect against crashes */
3580
3581         if ( !cli ) {
3582                 return NT_STATUS_INVALID_HANDLE;
3583         }
3584
3585         result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
3586         if (result == NULL) {
3587                 return NT_STATUS_NO_MEMORY;
3588         }
3589
3590         result->abstract_syntax = *abstract_syntax;
3591         result->transfer_syntax = ndr_transfer_syntax;
3592         result->dispatch = cli_do_rpc_ndr;
3593         result->dispatch_send = cli_do_rpc_ndr_send;
3594         result->dispatch_recv = cli_do_rpc_ndr_recv;
3595         result->desthost = talloc_strdup(result, cli->desthost);
3596         result->srv_name_slash = talloc_asprintf_strupper_m(
3597                 result, "\\\\%s", result->desthost);
3598
3599         result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3600         result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3601
3602         if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3603                 TALLOC_FREE(result);
3604                 return NT_STATUS_NO_MEMORY;
3605         }
3606
3607         status = rpc_transport_np_init(result, cli, abstract_syntax,
3608                                        &result->transport);
3609         if (!NT_STATUS_IS_OK(status)) {
3610                 TALLOC_FREE(result);
3611                 return status;
3612         }
3613
3614         result->transport->transport = NCACN_NP;
3615
3616         DLIST_ADD(cli->pipe_list, result);
3617         talloc_set_destructor(result, rpc_pipe_client_np_destructor);
3618
3619         *presult = result;
3620         return NT_STATUS_OK;
3621 }
3622
3623 NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx,
3624                              struct rpc_cli_smbd_conn *conn,
3625                              const struct ndr_syntax_id *syntax,
3626                              struct rpc_pipe_client **presult)
3627 {
3628         struct rpc_pipe_client *result;
3629         struct cli_pipe_auth_data *auth;
3630         NTSTATUS status;
3631
3632         result = talloc(mem_ctx, struct rpc_pipe_client);
3633         if (result == NULL) {
3634                 return NT_STATUS_NO_MEMORY;
3635         }
3636         result->abstract_syntax = *syntax;
3637         result->transfer_syntax = ndr_transfer_syntax;
3638         result->dispatch = cli_do_rpc_ndr;
3639         result->dispatch_send = cli_do_rpc_ndr_send;
3640         result->dispatch_recv = cli_do_rpc_ndr_recv;
3641         result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3642         result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3643
3644         result->desthost = talloc_strdup(result, global_myname());
3645         result->srv_name_slash = talloc_asprintf_strupper_m(
3646                 result, "\\\\%s", global_myname());
3647         if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3648                 TALLOC_FREE(result);
3649                 return NT_STATUS_NO_MEMORY;
3650         }
3651
3652         status = rpc_transport_smbd_init(result, conn, syntax,
3653                                          &result->transport);
3654         if (!NT_STATUS_IS_OK(status)) {
3655                 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
3656                           nt_errstr(status)));
3657                 TALLOC_FREE(result);
3658                 return status;
3659         }
3660
3661         status = rpccli_anon_bind_data(result, &auth);
3662         if (!NT_STATUS_IS_OK(status)) {
3663                 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
3664                           nt_errstr(status)));
3665                 TALLOC_FREE(result);
3666                 return status;
3667         }
3668
3669         status = rpc_pipe_bind(result, auth);
3670         if (!NT_STATUS_IS_OK(status)) {
3671                 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status)));
3672                 TALLOC_FREE(result);
3673                 return status;
3674         }
3675
3676         result->transport->transport = NCACN_INTERNAL;
3677
3678         *presult = result;
3679         return NT_STATUS_OK;
3680 }
3681
3682 /****************************************************************************
3683  Open a pipe to a remote server.
3684  ****************************************************************************/
3685
3686 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
3687                                   enum dcerpc_transport_t transport,
3688                                   const struct ndr_syntax_id *interface,
3689                                   struct rpc_pipe_client **presult)
3690 {
3691         switch (transport) {
3692         case NCACN_IP_TCP:
3693                 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
3694                                          presult);
3695         case NCACN_NP:
3696                 return rpc_pipe_open_np(cli, interface, presult);
3697         default:
3698                 return NT_STATUS_NOT_IMPLEMENTED;
3699         }
3700 }
3701
3702 /****************************************************************************
3703  Open a named pipe to an SMB server and bind anonymously.
3704  ****************************************************************************/
3705
3706 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
3707                                             enum dcerpc_transport_t transport,
3708                                             const struct ndr_syntax_id *interface,
3709                                             struct rpc_pipe_client **presult)
3710 {
3711         struct rpc_pipe_client *result;
3712         struct cli_pipe_auth_data *auth;
3713         NTSTATUS status;
3714
3715         status = cli_rpc_pipe_open(cli, transport, interface, &result);
3716         if (!NT_STATUS_IS_OK(status)) {
3717                 return status;
3718         }
3719
3720         status = rpccli_anon_bind_data(result, &auth);
3721         if (!NT_STATUS_IS_OK(status)) {
3722                 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3723                           nt_errstr(status)));
3724                 TALLOC_FREE(result);
3725                 return status;
3726         }
3727
3728         /*
3729          * This is a bit of an abstraction violation due to the fact that an
3730          * anonymous bind on an authenticated SMB inherits the user/domain
3731          * from the enclosing SMB creds
3732          */
3733
3734         TALLOC_FREE(auth->user_name);
3735         TALLOC_FREE(auth->domain);
3736
3737         auth->user_name = talloc_strdup(auth, cli->user_name);
3738         auth->domain = talloc_strdup(auth, cli->domain);
3739         auth->user_session_key = data_blob_talloc(auth,
3740                 cli->user_session_key.data,
3741                 cli->user_session_key.length);
3742
3743         if ((auth->user_name == NULL) || (auth->domain == NULL)) {
3744                 TALLOC_FREE(result);
3745                 return NT_STATUS_NO_MEMORY;
3746         }
3747
3748         status = rpc_pipe_bind(result, auth);
3749         if (!NT_STATUS_IS_OK(status)) {
3750                 int lvl = 0;
3751                 if (ndr_syntax_id_equal(interface,
3752                                         &ndr_table_dssetup.syntax_id)) {
3753                         /* non AD domains just don't have this pipe, avoid
3754                          * level 0 statement in that case - gd */
3755                         lvl = 3;
3756                 }
3757                 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3758                             "%s failed with error %s\n",
3759                             get_pipe_name_from_syntax(talloc_tos(), interface),
3760                             nt_errstr(status) ));
3761                 TALLOC_FREE(result);
3762                 return status;
3763         }
3764
3765         DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3766                   "%s and bound anonymously.\n",
3767                   get_pipe_name_from_syntax(talloc_tos(), interface),
3768                   cli->desthost));
3769
3770         *presult = result;
3771         return NT_STATUS_OK;
3772 }
3773
3774 /****************************************************************************
3775  ****************************************************************************/
3776
3777 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
3778                                   const struct ndr_syntax_id *interface,
3779                                   struct rpc_pipe_client **presult)
3780 {
3781         return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
3782                                                   interface, presult);
3783 }
3784
3785 /****************************************************************************
3786  Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
3787  ****************************************************************************/
3788
3789 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
3790                                                    const struct ndr_syntax_id *interface,
3791                                                    enum dcerpc_transport_t transport,
3792                                                    enum pipe_auth_type auth_type,
3793                                                    enum dcerpc_AuthLevel auth_level,
3794                                                    const char *domain,
3795                                                    const char *username,
3796                                                    const char *password,
3797                                                    struct rpc_pipe_client **presult)
3798 {
3799         struct rpc_pipe_client *result;
3800         struct cli_pipe_auth_data *auth;
3801         NTSTATUS status;
3802
3803         status = cli_rpc_pipe_open(cli, transport, interface, &result);
3804         if (!NT_STATUS_IS_OK(status)) {
3805                 return status;
3806         }
3807
3808         status = rpccli_ntlmssp_bind_data(
3809                 result, auth_type, auth_level, domain, username,
3810                 password, &auth);
3811         if (!NT_STATUS_IS_OK(status)) {
3812                 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
3813                           nt_errstr(status)));
3814                 goto err;
3815         }
3816
3817         status = rpc_pipe_bind(result, auth);
3818         if (!NT_STATUS_IS_OK(status)) {
3819                 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
3820                         nt_errstr(status) ));
3821                 goto err;
3822         }
3823
3824         DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
3825                 "machine %s and bound NTLMSSP as user %s\\%s.\n",
3826                   get_pipe_name_from_syntax(talloc_tos(), interface),
3827                   cli->desthost, domain, username ));
3828
3829         *presult = result;
3830         return NT_STATUS_OK;
3831
3832   err:
3833
3834         TALLOC_FREE(result);
3835         return status;
3836 }
3837
3838 /****************************************************************************
3839  External interface.
3840  Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
3841  ****************************************************************************/
3842
3843 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
3844                                    const struct ndr_syntax_id *interface,
3845                                    enum dcerpc_transport_t transport,
3846                                    enum dcerpc_AuthLevel auth_level,
3847                                    const char *domain,
3848                                    const char *username,
3849                                    const char *password,
3850                                    struct rpc_pipe_client **presult)
3851 {
3852         return cli_rpc_pipe_open_ntlmssp_internal(cli,
3853                                                 interface,
3854                                                 transport,
3855                                                 PIPE_AUTH_TYPE_NTLMSSP,
3856                                                 auth_level,
3857                                                 domain,
3858                                                 username,
3859                                                 password,
3860                                                 presult);
3861 }
3862
3863 /****************************************************************************
3864  External interface.
3865  Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
3866  ****************************************************************************/
3867
3868 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3869                                           const struct ndr_syntax_id *interface,
3870                                           enum dcerpc_transport_t transport,
3871                                           enum dcerpc_AuthLevel auth_level,
3872                                           const char *domain,
3873                                           const char *username,
3874                                           const char *password,
3875                                           struct rpc_pipe_client **presult)
3876 {
3877         return cli_rpc_pipe_open_ntlmssp_internal(cli,
3878                                                 interface,
3879                                                 transport,
3880                                                 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
3881                                                 auth_level,
3882                                                 domain,
3883                                                 username,
3884                                                 password,
3885                                                 presult);
3886 }
3887
3888 /****************************************************************************
3889   Get a the schannel session key out of an already opened netlogon pipe.
3890  ****************************************************************************/
3891 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
3892                                                 struct cli_state *cli,
3893                                                 const char *domain,
3894                                                 uint32 *pneg_flags)
3895 {
3896         enum netr_SchannelType sec_chan_type = 0;
3897         unsigned char machine_pwd[16];
3898         const char *machine_account;
3899         NTSTATUS status;
3900
3901         /* Get the machine account credentials from secrets.tdb. */
3902         if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
3903                                &sec_chan_type))
3904         {
3905                 DEBUG(0, ("get_schannel_session_key: could not fetch "
3906                         "trust account password for domain '%s'\n",
3907                         domain));
3908                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3909         }
3910
3911         status = rpccli_netlogon_setup_creds(netlogon_pipe,
3912                                         cli->desthost, /* server name */
3913                                         domain,        /* domain */
3914                                         global_myname(), /* client name */
3915                                         machine_account, /* machine account name */
3916                                         machine_pwd,
3917                                         sec_chan_type,
3918                                         pneg_flags);
3919
3920         if (!NT_STATUS_IS_OK(status)) {
3921                 DEBUG(3, ("get_schannel_session_key_common: "
3922                           "rpccli_netlogon_setup_creds failed with result %s "
3923                           "to server %s, domain %s, machine account %s.\n",
3924                           nt_errstr(status), cli->desthost, domain,
3925                           machine_account ));
3926                 return status;
3927         }
3928
3929         if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
3930                 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
3931                         cli->desthost));
3932                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3933         }
3934
3935         return NT_STATUS_OK;;
3936 }
3937
3938 /****************************************************************************
3939  Open a netlogon pipe and get the schannel session key.
3940  Now exposed to external callers.
3941  ****************************************************************************/
3942
3943
3944 NTSTATUS get_schannel_session_key(struct cli_state *cli,
3945                                   const char *domain,
3946                                   uint32 *pneg_flags,
3947                                   struct rpc_pipe_client **presult)
3948 {
3949         struct rpc_pipe_client *netlogon_pipe = NULL;
3950         NTSTATUS status;
3951
3952         status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
3953                                           &netlogon_pipe);
3954         if (!NT_STATUS_IS_OK(status)) {
3955                 return status;
3956         }
3957
3958         status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3959                                                  pneg_flags);
3960         if (!NT_STATUS_IS_OK(status)) {
3961                 TALLOC_FREE(netlogon_pipe);
3962                 return status;
3963         }
3964
3965         *presult = netlogon_pipe;
3966         return NT_STATUS_OK;
3967 }
3968
3969 /****************************************************************************
3970  External interface.
3971  Open a named pipe to an SMB server and bind using schannel (bind type 68)
3972  using session_key. sign and seal.
3973
3974  The *pdc will be stolen onto this new pipe
3975  ****************************************************************************/
3976
3977 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
3978                                              const struct ndr_syntax_id *interface,
3979                                              enum dcerpc_transport_t transport,
3980                                              enum dcerpc_AuthLevel auth_level,
3981                                              const char *domain,
3982                                              struct netlogon_creds_CredentialState **pdc,
3983                                              struct rpc_pipe_client **presult)
3984 {
3985         struct rpc_pipe_client *result;
3986         struct cli_pipe_auth_data *auth;
3987         NTSTATUS status;
3988
3989         status = cli_rpc_pipe_open(cli, transport, interface, &result);
3990         if (!NT_STATUS_IS_OK(status)) {
3991                 return status;
3992         }
3993
3994         status = rpccli_schannel_bind_data(result, domain, auth_level,
3995                                            *pdc, &auth);
3996         if (!NT_STATUS_IS_OK(status)) {
3997                 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
3998                           nt_errstr(status)));
3999                 TALLOC_FREE(result);
4000                 return status;
4001         }
4002
4003         status = rpc_pipe_bind(result, auth);
4004         if (!NT_STATUS_IS_OK(status)) {
4005                 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
4006                           "cli_rpc_pipe_bind failed with error %s\n",
4007                           nt_errstr(status) ));
4008                 TALLOC_FREE(result);
4009                 return status;
4010         }
4011
4012         /*
4013          * The credentials on a new netlogon pipe are the ones we are passed
4014          * in - reference them in
4015          */
4016         result->dc = talloc_move(result, pdc);
4017
4018         DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
4019                   "for domain %s and bound using schannel.\n",
4020                   get_pipe_name_from_syntax(talloc_tos(), interface),
4021                   cli->desthost, domain ));
4022
4023         *presult = result;
4024         return NT_STATUS_OK;
4025 }
4026
4027 /****************************************************************************
4028  Open a named pipe to an SMB server and bind using schannel (bind type 68).
4029  Fetch the session key ourselves using a temporary netlogon pipe. This
4030  version uses an ntlmssp auth bound netlogon pipe to get the key.
4031  ****************************************************************************/
4032
4033 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
4034                                                       const char *domain,
4035                                                       const char *username,
4036                                                       const char *password,
4037                                                       uint32 *pneg_flags,
4038                                                       struct rpc_pipe_client **presult)
4039 {
4040         struct rpc_pipe_client *netlogon_pipe = NULL;
4041         NTSTATUS status;
4042
4043         status = cli_rpc_pipe_open_spnego_ntlmssp(
4044                 cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
4045                 DCERPC_AUTH_LEVEL_PRIVACY,
4046                 domain, username, password, &netlogon_pipe);
4047         if (!NT_STATUS_IS_OK(status)) {
4048                 return status;
4049         }
4050
4051         status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
4052                                                  pneg_flags);
4053         if (!NT_STATUS_IS_OK(status)) {
4054                 TALLOC_FREE(netlogon_pipe);
4055                 return status;
4056         }
4057
4058         *presult = netlogon_pipe;
4059         return NT_STATUS_OK;
4060 }
4061
4062 /****************************************************************************
4063  Open a named pipe to an SMB server and bind using schannel (bind type 68).
4064  Fetch the session key ourselves using a temporary netlogon pipe. This version
4065  uses an ntlmssp bind to get the session key.
4066  ****************************************************************************/
4067
4068 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
4069                                                  const struct ndr_syntax_id *interface,
4070                                                  enum dcerpc_transport_t transport,
4071                                                  enum dcerpc_AuthLevel auth_level,
4072                                                  const char *domain,
4073                                                  const char *username,
4074                                                  const char *password,
4075                                                  struct rpc_pipe_client **presult)
4076 {
4077         uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4078         struct rpc_pipe_client *netlogon_pipe = NULL;
4079         struct rpc_pipe_client *result = NULL;
4080         NTSTATUS status;
4081
4082         status = get_schannel_session_key_auth_ntlmssp(
4083                 cli, domain, username, password, &neg_flags, &netlogon_pipe);
4084         if (!NT_STATUS_IS_OK(status)) {
4085                 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
4086                         "key from server %s for domain %s.\n",
4087                         cli->desthost, domain ));
4088                 return status;
4089         }
4090
4091         status = cli_rpc_pipe_open_schannel_with_key(
4092                 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4093                 &result);
4094
4095         /* Now we've bound using the session key we can close the netlog pipe. */
4096         TALLOC_FREE(netlogon_pipe);
4097
4098         if (NT_STATUS_IS_OK(status)) {
4099                 *presult = result;
4100         }
4101         return status;
4102 }
4103
4104 /****************************************************************************
4105  Open a named pipe to an SMB server and bind using schannel (bind type 68).
4106  Fetch the session key ourselves using a temporary netlogon pipe.
4107  ****************************************************************************/
4108
4109 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
4110                                     const struct ndr_syntax_id *interface,
4111                                     enum dcerpc_transport_t transport,
4112                                     enum dcerpc_AuthLevel auth_level,
4113                                     const char *domain,
4114                                     struct rpc_pipe_client **presult)
4115 {
4116         uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4117         struct rpc_pipe_client *netlogon_pipe = NULL;
4118         struct rpc_pipe_client *result = NULL;
4119         NTSTATUS status;
4120
4121         status = get_schannel_session_key(cli, domain, &neg_flags,
4122                                           &netlogon_pipe);
4123         if (!NT_STATUS_IS_OK(status)) {
4124                 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
4125                         "key from server %s for domain %s.\n",
4126                         cli->desthost, domain ));
4127                 return status;
4128         }
4129
4130         status = cli_rpc_pipe_open_schannel_with_key(
4131                 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4132                 &result);
4133
4134         /* Now we've bound using the session key we can close the netlog pipe. */
4135         TALLOC_FREE(netlogon_pipe);
4136
4137         if (NT_STATUS_IS_OK(status)) {
4138                 *presult = result;
4139         }
4140
4141         return status;
4142 }
4143
4144 /****************************************************************************
4145  Open a named pipe to an SMB server and bind using krb5 (bind type 16).
4146  The idea is this can be called with service_princ, username and password all
4147  NULL so long as the caller has a TGT.
4148  ****************************************************************************/
4149
4150 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
4151                                 const struct ndr_syntax_id *interface,
4152                                 enum dcerpc_AuthLevel auth_level,
4153                                 const char *service_princ,
4154                                 const char *username,
4155                                 const char *password,
4156                                 struct rpc_pipe_client **presult)
4157 {
4158 #ifdef HAVE_KRB5
4159         struct rpc_pipe_client *result;
4160         struct cli_pipe_auth_data *auth;
4161         NTSTATUS status;
4162
4163         status = cli_rpc_pipe_open(cli, NCACN_NP, interface, &result);
4164         if (!NT_STATUS_IS_OK(status)) {
4165                 return status;
4166         }
4167
4168         status = rpccli_kerberos_bind_data(result, auth_level, service_princ,
4169                                            username, password, &auth);
4170         if (!NT_STATUS_IS_OK(status)) {
4171                 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
4172                           nt_errstr(status)));
4173                 TALLOC_FREE(result);
4174                 return status;
4175         }
4176
4177         status = rpc_pipe_bind(result, auth);
4178         if (!NT_STATUS_IS_OK(status)) {
4179                 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
4180                           "with error %s\n", nt_errstr(status)));
4181                 TALLOC_FREE(result);
4182                 return status;
4183         }
4184
4185         *presult = result;
4186         return NT_STATUS_OK;
4187 #else
4188         DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
4189         return NT_STATUS_NOT_IMPLEMENTED;
4190 #endif
4191 }
4192
4193 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
4194                              struct rpc_pipe_client *cli,
4195                              DATA_BLOB *session_key)
4196 {
4197         if (!session_key || !cli) {
4198                 return NT_STATUS_INVALID_PARAMETER;
4199         }
4200
4201         if (!cli->auth) {
4202                 return NT_STATUS_INVALID_PARAMETER;
4203         }
4204
4205         switch (cli->auth->auth_type) {
4206                 case PIPE_AUTH_TYPE_SCHANNEL:
4207                         *session_key = data_blob_talloc(mem_ctx,
4208                                 cli->auth->a_u.schannel_auth->creds->session_key, 16);
4209                         break;
4210                 case PIPE_AUTH_TYPE_NTLMSSP:
4211                 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
4212                         *session_key = data_blob_talloc(mem_ctx,
4213                                 cli->auth->a_u.ntlmssp_state->session_key.data,
4214                                 cli->auth->a_u.ntlmssp_state->session_key.length);
4215                         break;
4216                 case PIPE_AUTH_TYPE_KRB5:
4217                 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
4218                         *session_key = data_blob_talloc(mem_ctx,
4219                                 cli->auth->a_u.kerberos_auth->session_key.data,
4220                                 cli->auth->a_u.kerberos_auth->session_key.length);
4221                         break;
4222                 case PIPE_AUTH_TYPE_NONE:
4223                         *session_key = data_blob_talloc(mem_ctx,
4224                                 cli->auth->user_session_key.data,
4225                                 cli->auth->user_session_key.length);
4226                         break;
4227                 default:
4228                         return NT_STATUS_NO_USER_SESSION_KEY;
4229         }
4230
4231         return NT_STATUS_OK;
4232 }