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