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