Added prefer_ipv4 bool parameter to resolve_name().
[nivanova/samba-autobuild/.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
3163         result->desthost = talloc_strdup(result, host);
3164         result->srv_name_slash = talloc_asprintf_strupper_m(
3165                 result, "\\\\%s", result->desthost);
3166         if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3167                 status = NT_STATUS_NO_MEMORY;
3168                 goto fail;
3169         }
3170
3171         result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3172         result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3173
3174         if (!resolve_name(host, &addr, 0, false)) {
3175                 status = NT_STATUS_NOT_FOUND;
3176                 goto fail;
3177         }
3178
3179         status = open_socket_out(&addr, port, 60, &fd);
3180         if (!NT_STATUS_IS_OK(status)) {
3181                 goto fail;
3182         }
3183         set_socket_options(fd, lp_socket_options());
3184
3185         status = rpc_transport_sock_init(result, fd, &result->transport);
3186         if (!NT_STATUS_IS_OK(status)) {
3187                 close(fd);
3188                 goto fail;
3189         }
3190
3191         *presult = result;
3192         return NT_STATUS_OK;
3193
3194  fail:
3195         TALLOC_FREE(result);
3196         return status;
3197 }
3198
3199 /**
3200  * Determine the tcp port on which a dcerpc interface is listening
3201  * for the ncacn_ip_tcp transport via the endpoint mapper of the
3202  * target host.
3203  */
3204 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
3205                                       const struct ndr_syntax_id *abstract_syntax,
3206                                       uint16_t *pport)
3207 {
3208         NTSTATUS status;
3209         struct rpc_pipe_client *epm_pipe = NULL;
3210         struct cli_pipe_auth_data *auth = NULL;
3211         struct dcerpc_binding *map_binding = NULL;
3212         struct dcerpc_binding *res_binding = NULL;
3213         struct epm_twr_t *map_tower = NULL;
3214         struct epm_twr_t *res_towers = NULL;
3215         struct policy_handle *entry_handle = NULL;
3216         uint32_t num_towers = 0;
3217         uint32_t max_towers = 1;
3218         struct epm_twr_p_t towers;
3219         TALLOC_CTX *tmp_ctx = talloc_stackframe();
3220
3221         if (pport == NULL) {
3222                 status = NT_STATUS_INVALID_PARAMETER;
3223                 goto done;
3224         }
3225
3226         /* open the connection to the endpoint mapper */
3227         status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
3228                                         &ndr_table_epmapper.syntax_id,
3229                                         &epm_pipe);
3230
3231         if (!NT_STATUS_IS_OK(status)) {
3232                 goto done;
3233         }
3234
3235         status = rpccli_anon_bind_data(tmp_ctx, &auth);
3236         if (!NT_STATUS_IS_OK(status)) {
3237                 goto done;
3238         }
3239
3240         status = rpc_pipe_bind(epm_pipe, auth);
3241         if (!NT_STATUS_IS_OK(status)) {
3242                 goto done;
3243         }
3244
3245         /* create tower for asking the epmapper */
3246
3247         map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
3248         if (map_binding == NULL) {
3249                 status = NT_STATUS_NO_MEMORY;
3250                 goto done;
3251         }
3252
3253         map_binding->transport = NCACN_IP_TCP;
3254         map_binding->object = *abstract_syntax;
3255         map_binding->host = host; /* needed? */
3256         map_binding->endpoint = "0"; /* correct? needed? */
3257
3258         map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
3259         if (map_tower == NULL) {
3260                 status = NT_STATUS_NO_MEMORY;
3261                 goto done;
3262         }
3263
3264         status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
3265                                             &(map_tower->tower));
3266         if (!NT_STATUS_IS_OK(status)) {
3267                 goto done;
3268         }
3269
3270         /* allocate further parameters for the epm_Map call */
3271
3272         res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
3273         if (res_towers == NULL) {
3274                 status = NT_STATUS_NO_MEMORY;
3275                 goto done;
3276         }
3277         towers.twr = res_towers;
3278
3279         entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
3280         if (entry_handle == NULL) {
3281                 status = NT_STATUS_NO_MEMORY;
3282                 goto done;
3283         }
3284
3285         /* ask the endpoint mapper for the port */
3286
3287         status = rpccli_epm_Map(epm_pipe,
3288                                 tmp_ctx,
3289                                 CONST_DISCARD(struct GUID *,
3290                                               &(abstract_syntax->uuid)),
3291                                 map_tower,
3292                                 entry_handle,
3293                                 max_towers,
3294                                 &num_towers,
3295                                 &towers);
3296
3297         if (!NT_STATUS_IS_OK(status)) {
3298                 goto done;
3299         }
3300
3301         if (num_towers != 1) {
3302                 status = NT_STATUS_UNSUCCESSFUL;
3303                 goto done;
3304         }
3305
3306         /* extract the port from the answer */
3307
3308         status = dcerpc_binding_from_tower(tmp_ctx,
3309                                            &(towers.twr->tower),
3310                                            &res_binding);
3311         if (!NT_STATUS_IS_OK(status)) {
3312                 goto done;
3313         }
3314
3315         /* are further checks here necessary? */
3316         if (res_binding->transport != NCACN_IP_TCP) {
3317                 status = NT_STATUS_UNSUCCESSFUL;
3318                 goto done;
3319         }
3320
3321         *pport = (uint16_t)atoi(res_binding->endpoint);
3322
3323 done:
3324         TALLOC_FREE(tmp_ctx);
3325         return status;
3326 }
3327
3328 /**
3329  * Create a rpc pipe client struct, connecting to a host via tcp.
3330  * The port is determined by asking the endpoint mapper on the given
3331  * host.
3332  */
3333 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
3334                            const struct ndr_syntax_id *abstract_syntax,
3335                            struct rpc_pipe_client **presult)
3336 {
3337         NTSTATUS status;
3338         uint16_t port = 0;
3339
3340         *presult = NULL;
3341
3342         status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
3343         if (!NT_STATUS_IS_OK(status)) {
3344                 goto done;
3345         }
3346
3347         status = rpc_pipe_open_tcp_port(mem_ctx, host, port,
3348                                         abstract_syntax, presult);
3349
3350 done:
3351         return status;
3352 }
3353
3354 /********************************************************************
3355  Create a rpc pipe client struct, connecting to a unix domain socket
3356  ********************************************************************/
3357 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
3358                                const struct ndr_syntax_id *abstract_syntax,
3359                                struct rpc_pipe_client **presult)
3360 {
3361         struct rpc_pipe_client *result;
3362         struct sockaddr_un addr;
3363         NTSTATUS status;
3364         int fd;
3365
3366         result = talloc_zero(mem_ctx, struct rpc_pipe_client);
3367         if (result == NULL) {
3368                 return NT_STATUS_NO_MEMORY;
3369         }
3370
3371         result->abstract_syntax = *abstract_syntax;
3372         result->transfer_syntax = ndr_transfer_syntax;
3373         result->dispatch = cli_do_rpc_ndr;
3374
3375         result->desthost = get_myname(result);
3376         result->srv_name_slash = talloc_asprintf_strupper_m(
3377                 result, "\\\\%s", result->desthost);
3378         if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3379                 status = NT_STATUS_NO_MEMORY;
3380                 goto fail;
3381         }
3382
3383         result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3384         result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3385
3386         fd = socket(AF_UNIX, SOCK_STREAM, 0);
3387         if (fd == -1) {
3388                 status = map_nt_error_from_unix(errno);
3389                 goto fail;
3390         }
3391
3392         ZERO_STRUCT(addr);
3393         addr.sun_family = AF_UNIX;
3394         strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
3395
3396         if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
3397                 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
3398                           strerror(errno)));
3399                 close(fd);
3400                 return map_nt_error_from_unix(errno);
3401         }
3402
3403         status = rpc_transport_sock_init(result, fd, &result->transport);
3404         if (!NT_STATUS_IS_OK(status)) {
3405                 close(fd);
3406                 goto fail;
3407         }
3408
3409         *presult = result;
3410         return NT_STATUS_OK;
3411
3412  fail:
3413         TALLOC_FREE(result);
3414         return status;
3415 }
3416
3417 static int rpc_pipe_client_np_destructor(struct rpc_pipe_client *p)
3418 {
3419         struct cli_state *cli;
3420
3421         cli = rpc_pipe_np_smb_conn(p);
3422         if (cli != NULL) {
3423                 DLIST_REMOVE(cli->pipe_list, p);
3424         }
3425         return 0;
3426 }
3427
3428 /****************************************************************************
3429  Open a named pipe over SMB to a remote server.
3430  *
3431  * CAVEAT CALLER OF THIS FUNCTION:
3432  *    The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
3433  *    so be sure that this function is called AFTER any structure (vs pointer)
3434  *    assignment of the cli.  In particular, libsmbclient does structure
3435  *    assignments of cli, which invalidates the data in the returned
3436  *    rpc_pipe_client if this function is called before the structure assignment
3437  *    of cli.
3438  * 
3439  ****************************************************************************/
3440
3441 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
3442                                  const struct ndr_syntax_id *abstract_syntax,
3443                                  struct rpc_pipe_client **presult)
3444 {
3445         struct rpc_pipe_client *result;
3446         NTSTATUS status;
3447
3448         /* sanity check to protect against crashes */
3449
3450         if ( !cli ) {
3451                 return NT_STATUS_INVALID_HANDLE;
3452         }
3453
3454         result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
3455         if (result == NULL) {
3456                 return NT_STATUS_NO_MEMORY;
3457         }
3458
3459         result->abstract_syntax = *abstract_syntax;
3460         result->transfer_syntax = ndr_transfer_syntax;
3461         result->dispatch = cli_do_rpc_ndr;
3462         result->desthost = talloc_strdup(result, cli->desthost);
3463         result->srv_name_slash = talloc_asprintf_strupper_m(
3464                 result, "\\\\%s", result->desthost);
3465
3466         result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3467         result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3468
3469         if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3470                 TALLOC_FREE(result);
3471                 return NT_STATUS_NO_MEMORY;
3472         }
3473
3474         status = rpc_transport_np_init(result, cli, abstract_syntax,
3475                                        &result->transport);
3476         if (!NT_STATUS_IS_OK(status)) {
3477                 TALLOC_FREE(result);
3478                 return status;
3479         }
3480
3481         DLIST_ADD(cli->pipe_list, result);
3482         talloc_set_destructor(result, rpc_pipe_client_np_destructor);
3483
3484         *presult = result;
3485         return NT_STATUS_OK;
3486 }
3487
3488 NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx,
3489                              struct rpc_cli_smbd_conn *conn,
3490                              const struct ndr_syntax_id *syntax,
3491                              struct rpc_pipe_client **presult)
3492 {
3493         struct rpc_pipe_client *result;
3494         struct cli_pipe_auth_data *auth;
3495         NTSTATUS status;
3496
3497         result = talloc(mem_ctx, struct rpc_pipe_client);
3498         if (result == NULL) {
3499                 return NT_STATUS_NO_MEMORY;
3500         }
3501         result->abstract_syntax = *syntax;
3502         result->transfer_syntax = ndr_transfer_syntax;
3503         result->dispatch = cli_do_rpc_ndr;
3504         result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3505         result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3506
3507         result->desthost = talloc_strdup(result, global_myname());
3508         result->srv_name_slash = talloc_asprintf_strupper_m(
3509                 result, "\\\\%s", global_myname());
3510         if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3511                 TALLOC_FREE(result);
3512                 return NT_STATUS_NO_MEMORY;
3513         }
3514
3515         status = rpc_transport_smbd_init(result, conn, syntax,
3516                                          &result->transport);
3517         if (!NT_STATUS_IS_OK(status)) {
3518                 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
3519                           nt_errstr(status)));
3520                 TALLOC_FREE(result);
3521                 return status;
3522         }
3523
3524         status = rpccli_anon_bind_data(result, &auth);
3525         if (!NT_STATUS_IS_OK(status)) {
3526                 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
3527                           nt_errstr(status)));
3528                 TALLOC_FREE(result);
3529                 return status;
3530         }
3531
3532         status = rpc_pipe_bind(result, auth);
3533         if (!NT_STATUS_IS_OK(status)) {
3534                 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status)));
3535                 TALLOC_FREE(result);
3536                 return status;
3537         }
3538
3539         *presult = result;
3540         return NT_STATUS_OK;
3541 }
3542
3543 /****************************************************************************
3544  Open a pipe to a remote server.
3545  ****************************************************************************/
3546
3547 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
3548                                   const struct ndr_syntax_id *interface,
3549                                   struct rpc_pipe_client **presult)
3550 {
3551         if (ndr_syntax_id_equal(interface, &ndr_table_drsuapi.syntax_id)) {
3552                 /*
3553                  * We should have a better way to figure out this drsuapi
3554                  * speciality...
3555                  */
3556                 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
3557                                          presult);
3558         }
3559
3560         return rpc_pipe_open_np(cli, interface, presult);
3561 }
3562
3563 /****************************************************************************
3564  Open a named pipe to an SMB server and bind anonymously.
3565  ****************************************************************************/
3566
3567 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
3568                                   const struct ndr_syntax_id *interface,
3569                                   struct rpc_pipe_client **presult)
3570 {
3571         struct rpc_pipe_client *result;
3572         struct cli_pipe_auth_data *auth;
3573         NTSTATUS status;
3574
3575         status = cli_rpc_pipe_open(cli, interface, &result);
3576         if (!NT_STATUS_IS_OK(status)) {
3577                 return status;
3578         }
3579
3580         status = rpccli_anon_bind_data(result, &auth);
3581         if (!NT_STATUS_IS_OK(status)) {
3582                 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3583                           nt_errstr(status)));
3584                 TALLOC_FREE(result);
3585                 return status;
3586         }
3587
3588         /*
3589          * This is a bit of an abstraction violation due to the fact that an
3590          * anonymous bind on an authenticated SMB inherits the user/domain
3591          * from the enclosing SMB creds
3592          */
3593
3594         TALLOC_FREE(auth->user_name);
3595         TALLOC_FREE(auth->domain);
3596
3597         auth->user_name = talloc_strdup(auth, cli->user_name);
3598         auth->domain = talloc_strdup(auth, cli->domain);
3599         auth->user_session_key = data_blob_talloc(auth,
3600                 cli->user_session_key.data,
3601                 cli->user_session_key.length);
3602
3603         if ((auth->user_name == NULL) || (auth->domain == NULL)) {
3604                 TALLOC_FREE(result);
3605                 return NT_STATUS_NO_MEMORY;
3606         }
3607
3608         status = rpc_pipe_bind(result, auth);
3609         if (!NT_STATUS_IS_OK(status)) {
3610                 int lvl = 0;
3611                 if (ndr_syntax_id_equal(interface,
3612                                         &ndr_table_dssetup.syntax_id)) {
3613                         /* non AD domains just don't have this pipe, avoid
3614                          * level 0 statement in that case - gd */
3615                         lvl = 3;
3616                 }
3617                 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3618                             "%s failed with error %s\n",
3619                             get_pipe_name_from_iface(interface),
3620                             nt_errstr(status) ));
3621                 TALLOC_FREE(result);
3622                 return status;
3623         }
3624
3625         DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3626                   "%s and bound anonymously.\n",
3627                   get_pipe_name_from_iface(interface), cli->desthost));
3628
3629         *presult = result;
3630         return NT_STATUS_OK;
3631 }
3632
3633 /****************************************************************************
3634  Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
3635  ****************************************************************************/
3636
3637 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
3638                                                    const struct ndr_syntax_id *interface,
3639                                                    enum pipe_auth_type auth_type,
3640                                                    enum pipe_auth_level auth_level,
3641                                                    const char *domain,
3642                                                    const char *username,
3643                                                    const char *password,
3644                                                    struct rpc_pipe_client **presult)
3645 {
3646         struct rpc_pipe_client *result;
3647         struct cli_pipe_auth_data *auth;
3648         NTSTATUS status;
3649
3650         status = cli_rpc_pipe_open(cli, interface, &result);
3651         if (!NT_STATUS_IS_OK(status)) {
3652                 return status;
3653         }
3654
3655         status = rpccli_ntlmssp_bind_data(
3656                 result, auth_type, auth_level, domain, username,
3657                 password, &auth);
3658         if (!NT_STATUS_IS_OK(status)) {
3659                 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
3660                           nt_errstr(status)));
3661                 goto err;
3662         }
3663
3664         status = rpc_pipe_bind(result, auth);
3665         if (!NT_STATUS_IS_OK(status)) {
3666                 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
3667                         nt_errstr(status) ));
3668                 goto err;
3669         }
3670
3671         DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
3672                 "machine %s and bound NTLMSSP as user %s\\%s.\n",
3673                   get_pipe_name_from_iface(interface), cli->desthost, domain,
3674                   username ));
3675
3676         *presult = result;
3677         return NT_STATUS_OK;
3678
3679   err:
3680
3681         TALLOC_FREE(result);
3682         return status;
3683 }
3684
3685 /****************************************************************************
3686  External interface.
3687  Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
3688  ****************************************************************************/
3689
3690 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
3691                                    const struct ndr_syntax_id *interface,
3692                                    enum pipe_auth_level auth_level,
3693                                    const char *domain,
3694                                    const char *username,
3695                                    const char *password,
3696                                    struct rpc_pipe_client **presult)
3697 {
3698         return cli_rpc_pipe_open_ntlmssp_internal(cli,
3699                                                 interface,
3700                                                 PIPE_AUTH_TYPE_NTLMSSP,
3701                                                 auth_level,
3702                                                 domain,
3703                                                 username,
3704                                                 password,
3705                                                 presult);
3706 }
3707
3708 /****************************************************************************
3709  External interface.
3710  Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
3711  ****************************************************************************/
3712
3713 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3714                                           const struct ndr_syntax_id *interface,
3715                                           enum pipe_auth_level auth_level,
3716                                           const char *domain,
3717                                           const char *username,
3718                                           const char *password,
3719                                           struct rpc_pipe_client **presult)
3720 {
3721         return cli_rpc_pipe_open_ntlmssp_internal(cli,
3722                                                 interface,
3723                                                 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
3724                                                 auth_level,
3725                                                 domain,
3726                                                 username,
3727                                                 password,
3728                                                 presult);
3729 }
3730
3731 /****************************************************************************
3732   Get a the schannel session key out of an already opened netlogon pipe.
3733  ****************************************************************************/
3734 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
3735                                                 struct cli_state *cli,
3736                                                 const char *domain,
3737                                                 uint32 *pneg_flags)
3738 {
3739         uint32 sec_chan_type = 0;
3740         unsigned char machine_pwd[16];
3741         const char *machine_account;
3742         NTSTATUS status;
3743
3744         /* Get the machine account credentials from secrets.tdb. */
3745         if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
3746                                &sec_chan_type))
3747         {
3748                 DEBUG(0, ("get_schannel_session_key: could not fetch "
3749                         "trust account password for domain '%s'\n",
3750                         domain));
3751                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3752         }
3753
3754         status = rpccli_netlogon_setup_creds(netlogon_pipe,
3755                                         cli->desthost, /* server name */
3756                                         domain,        /* domain */
3757                                         global_myname(), /* client name */
3758                                         machine_account, /* machine account name */
3759                                         machine_pwd,
3760                                         sec_chan_type,
3761                                         pneg_flags);
3762
3763         if (!NT_STATUS_IS_OK(status)) {
3764                 DEBUG(3, ("get_schannel_session_key_common: "
3765                           "rpccli_netlogon_setup_creds failed with result %s "
3766                           "to server %s, domain %s, machine account %s.\n",
3767                           nt_errstr(status), cli->desthost, domain,
3768                           machine_account ));
3769                 return status;
3770         }
3771
3772         if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
3773                 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
3774                         cli->desthost));
3775                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3776         }
3777
3778         return NT_STATUS_OK;;
3779 }
3780
3781 /****************************************************************************
3782  Open a netlogon pipe and get the schannel session key.
3783  Now exposed to external callers.
3784  ****************************************************************************/
3785
3786
3787 NTSTATUS get_schannel_session_key(struct cli_state *cli,
3788                                   const char *domain,
3789                                   uint32 *pneg_flags,
3790                                   struct rpc_pipe_client **presult)
3791 {
3792         struct rpc_pipe_client *netlogon_pipe = NULL;
3793         NTSTATUS status;
3794
3795         status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
3796                                           &netlogon_pipe);
3797         if (!NT_STATUS_IS_OK(status)) {
3798                 return status;
3799         }
3800
3801         status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3802                                                  pneg_flags);
3803         if (!NT_STATUS_IS_OK(status)) {
3804                 TALLOC_FREE(netlogon_pipe);
3805                 return status;
3806         }
3807
3808         *presult = netlogon_pipe;
3809         return NT_STATUS_OK;
3810 }
3811
3812 /****************************************************************************
3813  External interface.
3814  Open a named pipe to an SMB server and bind using schannel (bind type 68)
3815  using session_key. sign and seal.
3816
3817  The *pdc will be stolen onto this new pipe
3818  ****************************************************************************/
3819
3820 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
3821                                              const struct ndr_syntax_id *interface,
3822                                              enum pipe_auth_level auth_level,
3823                                              const char *domain,
3824                                              struct netlogon_creds_CredentialState **pdc,
3825                                              struct rpc_pipe_client **presult)
3826 {
3827         struct rpc_pipe_client *result;
3828         struct cli_pipe_auth_data *auth;
3829         NTSTATUS status;
3830
3831         status = cli_rpc_pipe_open(cli, interface, &result);
3832         if (!NT_STATUS_IS_OK(status)) {
3833                 return status;
3834         }
3835
3836         status = rpccli_schannel_bind_data(result, domain, auth_level,
3837                                            (*pdc)->session_key, &auth);
3838         if (!NT_STATUS_IS_OK(status)) {
3839                 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
3840                           nt_errstr(status)));
3841                 TALLOC_FREE(result);
3842                 return status;
3843         }
3844
3845         status = rpc_pipe_bind(result, auth);
3846         if (!NT_STATUS_IS_OK(status)) {
3847                 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
3848                           "cli_rpc_pipe_bind failed with error %s\n",
3849                           nt_errstr(status) ));
3850                 TALLOC_FREE(result);
3851                 return status;
3852         }
3853
3854         /*
3855          * The credentials on a new netlogon pipe are the ones we are passed
3856          * in - reference them in
3857          */
3858         result->dc = talloc_move(result, pdc);
3859         if (result->dc == NULL) {
3860                 DEBUG(0, ("talloc reference failed\n"));
3861                 TALLOC_FREE(result);
3862                 return NT_STATUS_NO_MEMORY;
3863         }
3864
3865         DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
3866                   "for domain %s and bound using schannel.\n",
3867                   get_pipe_name_from_iface(interface),
3868                   cli->desthost, domain ));
3869
3870         *presult = result;
3871         return NT_STATUS_OK;
3872 }
3873
3874 /****************************************************************************
3875  Open a named pipe to an SMB server and bind using schannel (bind type 68).
3876  Fetch the session key ourselves using a temporary netlogon pipe. This
3877  version uses an ntlmssp auth bound netlogon pipe to get the key.
3878  ****************************************************************************/
3879
3880 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
3881                                                       const char *domain,
3882                                                       const char *username,
3883                                                       const char *password,
3884                                                       uint32 *pneg_flags,
3885                                                       struct rpc_pipe_client **presult)
3886 {
3887         struct rpc_pipe_client *netlogon_pipe = NULL;
3888         NTSTATUS status;
3889
3890         status = cli_rpc_pipe_open_spnego_ntlmssp(
3891                 cli, &ndr_table_netlogon.syntax_id, PIPE_AUTH_LEVEL_PRIVACY,
3892                 domain, username, password, &netlogon_pipe);
3893         if (!NT_STATUS_IS_OK(status)) {
3894                 return status;
3895         }
3896
3897         status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3898                                                  pneg_flags);
3899         if (!NT_STATUS_IS_OK(status)) {
3900                 TALLOC_FREE(netlogon_pipe);
3901                 return status;
3902         }
3903
3904         *presult = netlogon_pipe;
3905         return NT_STATUS_OK;
3906 }
3907
3908 /****************************************************************************
3909  Open a named pipe to an SMB server and bind using schannel (bind type 68).
3910  Fetch the session key ourselves using a temporary netlogon pipe. This version
3911  uses an ntlmssp bind to get the session key.
3912  ****************************************************************************/
3913
3914 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
3915                                                  const struct ndr_syntax_id *interface,
3916                                                  enum pipe_auth_level auth_level,
3917                                                  const char *domain,
3918                                                  const char *username,
3919                                                  const char *password,
3920                                                  struct rpc_pipe_client **presult)
3921 {
3922         uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3923         struct rpc_pipe_client *netlogon_pipe = NULL;
3924         struct rpc_pipe_client *result = NULL;
3925         NTSTATUS status;
3926
3927         status = get_schannel_session_key_auth_ntlmssp(
3928                 cli, domain, username, password, &neg_flags, &netlogon_pipe);
3929         if (!NT_STATUS_IS_OK(status)) {
3930                 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
3931                         "key from server %s for domain %s.\n",
3932                         cli->desthost, domain ));
3933                 return status;
3934         }
3935
3936         status = cli_rpc_pipe_open_schannel_with_key(
3937                 cli, interface, auth_level, domain, &netlogon_pipe->dc,
3938                 &result);
3939
3940         /* Now we've bound using the session key we can close the netlog pipe. */
3941         TALLOC_FREE(netlogon_pipe);
3942
3943         if (NT_STATUS_IS_OK(status)) {
3944                 *presult = result;
3945         }
3946         return status;
3947 }
3948
3949 /****************************************************************************
3950  Open a named pipe to an SMB server and bind using schannel (bind type 68).
3951  Fetch the session key ourselves using a temporary netlogon pipe.
3952  ****************************************************************************/
3953
3954 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
3955                                     const struct ndr_syntax_id *interface,
3956                                     enum pipe_auth_level auth_level,
3957                                     const char *domain,
3958                                     struct rpc_pipe_client **presult)
3959 {
3960         uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3961         struct rpc_pipe_client *netlogon_pipe = NULL;
3962         struct rpc_pipe_client *result = NULL;
3963         NTSTATUS status;
3964
3965         status = get_schannel_session_key(cli, domain, &neg_flags,
3966                                           &netlogon_pipe);
3967         if (!NT_STATUS_IS_OK(status)) {
3968                 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
3969                         "key from server %s for domain %s.\n",
3970                         cli->desthost, domain ));
3971                 return status;
3972         }
3973
3974         status = cli_rpc_pipe_open_schannel_with_key(
3975                 cli, interface, auth_level, domain, &netlogon_pipe->dc,
3976                 &result);
3977
3978         /* Now we've bound using the session key we can close the netlog pipe. */
3979         TALLOC_FREE(netlogon_pipe);
3980
3981         if (NT_STATUS_IS_OK(status)) {
3982                 *presult = result;
3983         }
3984
3985         return NT_STATUS_OK;
3986 }
3987
3988 /****************************************************************************
3989  Open a named pipe to an SMB server and bind using krb5 (bind type 16).
3990  The idea is this can be called with service_princ, username and password all
3991  NULL so long as the caller has a TGT.
3992  ****************************************************************************/
3993
3994 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
3995                                 const struct ndr_syntax_id *interface,
3996                                 enum pipe_auth_level auth_level,
3997                                 const char *service_princ,
3998                                 const char *username,
3999                                 const char *password,
4000                                 struct rpc_pipe_client **presult)
4001 {
4002 #ifdef HAVE_KRB5
4003         struct rpc_pipe_client *result;
4004         struct cli_pipe_auth_data *auth;
4005         NTSTATUS status;
4006
4007         status = cli_rpc_pipe_open(cli, interface, &result);
4008         if (!NT_STATUS_IS_OK(status)) {
4009                 return status;
4010         }
4011
4012         status = rpccli_kerberos_bind_data(result, auth_level, service_princ,
4013                                            username, password, &auth);
4014         if (!NT_STATUS_IS_OK(status)) {
4015                 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
4016                           nt_errstr(status)));
4017                 TALLOC_FREE(result);
4018                 return status;
4019         }
4020
4021         status = rpc_pipe_bind(result, auth);
4022         if (!NT_STATUS_IS_OK(status)) {
4023                 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
4024                           "with error %s\n", nt_errstr(status)));
4025                 TALLOC_FREE(result);
4026                 return status;
4027         }
4028
4029         *presult = result;
4030         return NT_STATUS_OK;
4031 #else
4032         DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
4033         return NT_STATUS_NOT_IMPLEMENTED;
4034 #endif
4035 }
4036
4037 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
4038                              struct rpc_pipe_client *cli,
4039                              DATA_BLOB *session_key)
4040 {
4041         if (!session_key || !cli) {
4042                 return NT_STATUS_INVALID_PARAMETER;
4043         }
4044
4045         if (!cli->auth) {
4046                 return NT_STATUS_INVALID_PARAMETER;
4047         }
4048
4049         switch (cli->auth->auth_type) {
4050                 case PIPE_AUTH_TYPE_SCHANNEL:
4051                         *session_key = data_blob_talloc(mem_ctx,
4052                                 cli->auth->a_u.schannel_auth->sess_key, 16);
4053                         break;
4054                 case PIPE_AUTH_TYPE_NTLMSSP:
4055                 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
4056                         *session_key = data_blob_talloc(mem_ctx,
4057                                 cli->auth->a_u.ntlmssp_state->session_key.data,
4058                                 cli->auth->a_u.ntlmssp_state->session_key.length);
4059                         break;
4060                 case PIPE_AUTH_TYPE_KRB5:
4061                 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
4062                         *session_key = data_blob_talloc(mem_ctx,
4063                                 cli->auth->a_u.kerberos_auth->session_key.data,
4064                                 cli->auth->a_u.kerberos_auth->session_key.length);
4065                         break;
4066                 case PIPE_AUTH_TYPE_NONE:
4067                         *session_key = data_blob_talloc(mem_ctx,
4068                                 cli->auth->user_session_key.data,
4069                                 cli->auth->user_session_key.length);
4070                         break;
4071                 default:
4072                         return NT_STATUS_NO_USER_SESSION_KEY;
4073         }
4074
4075         return NT_STATUS_OK;
4076 }