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