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