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