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