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