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