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