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