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