Replace cli_rpc_pipe_close by a talloc destructor on rpc_pipe_struct
[jra/samba/.git] / source3 / rpc_client / cli_pipe.c
1 /* 
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Largely rewritten by Jeremy Allison             2005.
5  *  
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 3 of the License, or
9  *  (at your option) any later version.
10  *  
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *  
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include "includes.h"
21
22 #undef DBGC_CLASS
23 #define DBGC_CLASS DBGC_RPC_CLI
24
25 extern struct pipe_id_info pipe_names[];
26
27 /********************************************************************
28  Map internal value to wire value.
29  ********************************************************************/
30
31 static int map_pipe_auth_type_to_rpc_auth_type(enum pipe_auth_type auth_type)
32 {
33         switch (auth_type) {
34
35         case PIPE_AUTH_TYPE_NONE:
36                 return RPC_ANONYMOUS_AUTH_TYPE;
37
38         case PIPE_AUTH_TYPE_NTLMSSP:
39                 return RPC_NTLMSSP_AUTH_TYPE;
40
41         case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
42         case PIPE_AUTH_TYPE_SPNEGO_KRB5:
43                 return RPC_SPNEGO_AUTH_TYPE;
44
45         case PIPE_AUTH_TYPE_SCHANNEL:
46                 return RPC_SCHANNEL_AUTH_TYPE;
47
48         case PIPE_AUTH_TYPE_KRB5:
49                 return RPC_KRB5_AUTH_TYPE;
50
51         default:
52                 DEBUG(0,("map_pipe_auth_type_to_rpc_type: unknown pipe "
53                         "auth type %u\n",
54                         (unsigned int)auth_type ));
55                 break;
56         }
57         return -1;
58 }
59
60 /********************************************************************
61  Rpc pipe call id.
62  ********************************************************************/
63
64 static uint32 get_rpc_call_id(void)
65 {
66         static uint32 call_id = 0;
67         return ++call_id;
68 }
69
70 /*******************************************************************
71  Use SMBreadX to get rest of one fragment's worth of rpc data.
72  Will expand the current_pdu struct to the correct size.
73  ********************************************************************/
74
75 static NTSTATUS rpc_read(struct rpc_pipe_client *cli,
76                         prs_struct *current_pdu,
77                         uint32 data_to_read,
78                         uint32 *current_pdu_offset)
79 {
80         size_t size = (size_t)cli->max_recv_frag;
81         uint32 stream_offset = 0;
82         ssize_t num_read;
83         char *pdata;
84         ssize_t extra_data_size = ((ssize_t)*current_pdu_offset) + ((ssize_t)data_to_read) - (ssize_t)prs_data_size(current_pdu);
85
86         DEBUG(5,("rpc_read: data_to_read: %u current_pdu offset: %u extra_data_size: %d\n",
87                 (unsigned int)data_to_read, (unsigned int)*current_pdu_offset, (int)extra_data_size ));
88
89         /*
90          * Grow the buffer if needed to accommodate the data to be read.
91          */
92
93         if (extra_data_size > 0) {
94                 if(!prs_force_grow(current_pdu, (uint32)extra_data_size)) {
95                         DEBUG(0,("rpc_read: Failed to grow parse struct by %d bytes.\n", (int)extra_data_size ));
96                         return NT_STATUS_NO_MEMORY;
97                 }
98                 DEBUG(5,("rpc_read: grew buffer by %d bytes to %u\n", (int)extra_data_size, prs_data_size(current_pdu) ));
99         }
100
101         pdata = prs_data_p(current_pdu) + *current_pdu_offset;
102
103         do {
104                 /* read data using SMBreadX */
105                 if (size > (size_t)data_to_read) {
106                         size = (size_t)data_to_read;
107                 }
108
109                 num_read = cli_read(cli->cli, cli->fnum, pdata,
110                                          (off_t)stream_offset, size);
111
112                 DEBUG(5,("rpc_read: num_read = %d, read offset: %u, to read: %u\n",
113                         (int)num_read, (unsigned int)stream_offset, (unsigned int)data_to_read));
114
115                 /*
116                  * A dos error of ERRDOS/ERRmoredata is not an error.
117                  */
118                 if (cli_is_dos_error(cli->cli)) {
119                         uint32 ecode;
120                         uint8 eclass;
121                         cli_dos_error(cli->cli, &eclass, &ecode);
122                         if (eclass != ERRDOS && ecode != ERRmoredata) {
123                                 DEBUG(0,("rpc_read: DOS Error %d/%u (%s) in cli_read on pipe %s\n",
124                                         eclass, (unsigned int)ecode,
125                                         cli_errstr(cli->cli),
126                                         cli->pipe_name ));
127                                 return dos_to_ntstatus(eclass, ecode);
128                         }
129                 }
130
131                 /*
132                  * Likewise for NT_STATUS_BUFFER_TOO_SMALL
133                  */
134                 if (cli_is_nt_error(cli->cli)) {
135                         if (!NT_STATUS_EQUAL(cli_nt_error(cli->cli), NT_STATUS_BUFFER_TOO_SMALL)) {
136                                 DEBUG(0,("rpc_read: Error (%s) in cli_read on pipe %s\n",
137                                         nt_errstr(cli_nt_error(cli->cli)),
138                                         cli->pipe_name ));
139                                 return cli_nt_error(cli->cli);
140                         }
141                 }
142
143                 if (num_read == -1) {
144                         DEBUG(0,("rpc_read: Error - cli_read on pipe %s returned -1\n",
145                                 cli->pipe_name ));
146                         return cli_get_nt_error(cli->cli);
147                 }
148
149                 data_to_read -= num_read;
150                 stream_offset += num_read;
151                 pdata += num_read;
152
153         } while (num_read > 0 && data_to_read > 0);
154         /* && err == (0x80000000 | STATUS_BUFFER_OVERFLOW)); */
155
156         /*
157          * Update the current offset into current_pdu by the amount read.
158          */
159         *current_pdu_offset += stream_offset;
160         return NT_STATUS_OK;
161 }
162
163 /****************************************************************************
164  Try and get a PDU's worth of data from current_pdu. If not, then read more
165  from the wire.
166  ****************************************************************************/
167
168 static NTSTATUS cli_pipe_get_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
169 {
170         NTSTATUS ret = NT_STATUS_OK;
171         uint32 current_pdu_len = prs_data_size(current_pdu);
172
173         /* Ensure we have at least RPC_HEADER_LEN worth of data to parse. */
174         if (current_pdu_len < RPC_HEADER_LEN) {
175                 /* rpc_read expands the current_pdu struct as neccessary. */
176                 ret = rpc_read(cli, current_pdu, RPC_HEADER_LEN - current_pdu_len, &current_pdu_len);
177                 if (!NT_STATUS_IS_OK(ret)) {
178                         return ret;
179                 }
180         }
181
182         /* This next call sets the endian bit correctly in current_pdu. */
183         /* We will propagate this to rbuf later. */
184         if(!smb_io_rpc_hdr("rpc_hdr   ", prhdr, current_pdu, 0)) {
185                 DEBUG(0,("cli_pipe_get_current_pdu: Failed to unmarshall RPC_HDR.\n"));
186                 return NT_STATUS_BUFFER_TOO_SMALL;
187         }
188
189         /* Ensure we have frag_len bytes of data. */
190         if (current_pdu_len < prhdr->frag_len) {
191                 /* rpc_read expands the current_pdu struct as neccessary. */
192                 ret = rpc_read(cli, current_pdu, (uint32)prhdr->frag_len - current_pdu_len, &current_pdu_len);
193                 if (!NT_STATUS_IS_OK(ret)) {
194                         return ret;
195                 }
196         }
197
198         if (current_pdu_len < prhdr->frag_len) {
199                 return NT_STATUS_BUFFER_TOO_SMALL;
200         }
201
202         return NT_STATUS_OK;
203 }
204
205 /****************************************************************************
206  NTLMSSP specific sign/seal.
207  Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.
208  In fact I should probably abstract these into identical pieces of code... JRA.
209  ****************************************************************************/
210
211 static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
212                                 prs_struct *current_pdu,
213                                 uint8 *p_ss_padding_len)
214 {
215         RPC_HDR_AUTH auth_info;
216         uint32 save_offset = prs_offset(current_pdu);
217         uint32 auth_len = prhdr->auth_len;
218         NTLMSSP_STATE *ntlmssp_state = cli->auth.a_u.ntlmssp_state;
219         unsigned char *data = NULL;
220         size_t data_len;
221         unsigned char *full_packet_data = NULL;
222         size_t full_packet_data_len;
223         DATA_BLOB auth_blob;
224         NTSTATUS status;
225
226         if (cli->auth.auth_level == PIPE_AUTH_LEVEL_NONE || cli->auth.auth_level == PIPE_AUTH_LEVEL_CONNECT) {
227                 return NT_STATUS_OK;
228         }
229
230         if (!ntlmssp_state) {
231                 return NT_STATUS_INVALID_PARAMETER;
232         }
233
234         /* Ensure there's enough data for an authenticated response. */
235         if ((auth_len > RPC_MAX_SIGN_SIZE) ||
236                         (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
237                 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
238                         (unsigned int)auth_len ));
239                 return NT_STATUS_BUFFER_TOO_SMALL;
240         }
241
242         /*
243          * We need the full packet data + length (minus auth stuff) as well as the packet data + length
244          * after the RPC header.
245          * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
246          * functions as NTLMv2 checks the rpc headers also.
247          */
248
249         data = (unsigned char *)(prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN);
250         data_len = (size_t)(prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len);
251
252         full_packet_data = (unsigned char *)prs_data_p(current_pdu);
253         full_packet_data_len = prhdr->frag_len - auth_len;
254
255         /* Pull the auth header and the following data into a blob. */
256         if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
257                 DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n",
258                         (unsigned int)RPC_HEADER_LEN + (unsigned int)RPC_HDR_RESP_LEN + (unsigned int)data_len ));
259                 return NT_STATUS_BUFFER_TOO_SMALL;
260         }
261
262         if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
263                 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall RPC_HDR_AUTH.\n"));
264                 return NT_STATUS_BUFFER_TOO_SMALL;
265         }
266
267         auth_blob.data = (unsigned char *)prs_data_p(current_pdu) + prs_offset(current_pdu);
268         auth_blob.length = auth_len;
269
270         switch (cli->auth.auth_level) {
271                 case PIPE_AUTH_LEVEL_PRIVACY:
272                         /* Data is encrypted. */
273                         status = ntlmssp_unseal_packet(ntlmssp_state,
274                                                         data, data_len,
275                                                         full_packet_data,
276                                                         full_packet_data_len,
277                                                         &auth_blob);
278                         if (!NT_STATUS_IS_OK(status)) {
279                                 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal "
280                                         "packet from remote machine %s on pipe %s "
281                                         "fnum 0x%x. Error was %s.\n",
282                                         cli->desthost,
283                                         cli->pipe_name,
284                                         (unsigned int)cli->fnum,
285                                         nt_errstr(status) ));
286                                 return status;
287                         }
288                         break;
289                 case PIPE_AUTH_LEVEL_INTEGRITY:
290                         /* Data is signed. */
291                         status = ntlmssp_check_packet(ntlmssp_state,
292                                                         data, data_len,
293                                                         full_packet_data,
294                                                         full_packet_data_len,
295                                                         &auth_blob);
296                         if (!NT_STATUS_IS_OK(status)) {
297                                 DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on "
298                                         "packet from remote machine %s on pipe %s "
299                                         "fnum 0x%x. Error was %s.\n",
300                                         cli->desthost,
301                                         cli->pipe_name,
302                                         (unsigned int)cli->fnum,
303                                         nt_errstr(status) ));
304                                 return status;
305                         }
306                         break;
307                 default:
308                         DEBUG(0,("cli_pipe_verify_ntlmssp: unknown internal auth level %d\n",
309                                 cli->auth.auth_level ));
310                         return NT_STATUS_INVALID_INFO_CLASS;
311         }
312
313         /*
314          * Return the current pointer to the data offset.
315          */
316
317         if(!prs_set_offset(current_pdu, save_offset)) {
318                 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
319                         (unsigned int)save_offset ));
320                 return NT_STATUS_BUFFER_TOO_SMALL;
321         }
322
323         /*
324          * Remember the padding length. We must remove it from the real data
325          * stream once the sign/seal is done.
326          */
327
328         *p_ss_padding_len = auth_info.auth_pad_len;
329
330         return NT_STATUS_OK;
331 }
332
333 /****************************************************************************
334  schannel specific sign/seal.
335  ****************************************************************************/
336
337 static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
338                                 prs_struct *current_pdu,
339                                 uint8 *p_ss_padding_len)
340 {
341         RPC_HDR_AUTH auth_info;
342         RPC_AUTH_SCHANNEL_CHK schannel_chk;
343         uint32 auth_len = prhdr->auth_len;
344         uint32 save_offset = prs_offset(current_pdu);
345         struct schannel_auth_struct *schannel_auth = cli->auth.a_u.schannel_auth;
346         uint32 data_len;
347
348         if (cli->auth.auth_level == PIPE_AUTH_LEVEL_NONE || cli->auth.auth_level == PIPE_AUTH_LEVEL_CONNECT) {
349                 return NT_STATUS_OK;
350         }
351
352         if (auth_len != RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) {
353                 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u.\n", (unsigned int)auth_len ));
354                 return NT_STATUS_INVALID_PARAMETER;
355         }
356
357         if (!schannel_auth) {
358                 return NT_STATUS_INVALID_PARAMETER;
359         }
360
361         /* Ensure there's enough data for an authenticated response. */
362         if ((auth_len > RPC_MAX_SIGN_SIZE) ||
363                         (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
364                 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u is too large.\n",
365                         (unsigned int)auth_len ));
366                 return NT_STATUS_INVALID_PARAMETER;
367         }
368
369         data_len = prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len;
370
371         if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
372                 DEBUG(0,("cli_pipe_verify_schannel: cannot move offset to %u.\n",
373                         (unsigned int)RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len ));
374                 return NT_STATUS_BUFFER_TOO_SMALL;
375         }
376                                                                                                                              
377         if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
378                 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshall RPC_HDR_AUTH.\n"));
379                 return NT_STATUS_BUFFER_TOO_SMALL;
380         }
381
382         if (auth_info.auth_type != RPC_SCHANNEL_AUTH_TYPE) {
383                 DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n",
384                         auth_info.auth_type));
385                 return NT_STATUS_BUFFER_TOO_SMALL;
386         }
387
388         if(!smb_io_rpc_auth_schannel_chk("", RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN,
389                                 &schannel_chk, current_pdu, 0)) {
390                 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshal RPC_AUTH_SCHANNEL_CHK.\n"));
391                 return NT_STATUS_BUFFER_TOO_SMALL;
392         }
393
394         if (!schannel_decode(schannel_auth,
395                         cli->auth.auth_level,
396                         SENDER_IS_ACCEPTOR,
397                         &schannel_chk,
398                         prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN,
399                         data_len)) {
400                 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
401                                 "Connection to remote machine %s "
402                                 "pipe %s fnum 0x%x.\n",
403                                 cli->desthost,
404                                 cli->pipe_name,
405                                 (unsigned int)cli->fnum ));
406                 return NT_STATUS_INVALID_PARAMETER;
407         }
408
409         /* The sequence number gets incremented on both send and receive. */
410         schannel_auth->seq_num++;
411
412         /*
413          * Return the current pointer to the data offset.
414          */
415
416         if(!prs_set_offset(current_pdu, save_offset)) {
417                 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
418                         (unsigned int)save_offset ));
419                 return NT_STATUS_BUFFER_TOO_SMALL;
420         }
421
422         /*
423          * Remember the padding length. We must remove it from the real data
424          * stream once the sign/seal is done.
425          */
426
427         *p_ss_padding_len = auth_info.auth_pad_len;
428
429         return NT_STATUS_OK;
430 }
431
432 /****************************************************************************
433  Do the authentication checks on an incoming pdu. Check sign and unseal etc.
434  ****************************************************************************/
435
436 static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
437                                 prs_struct *current_pdu,
438                                 uint8 *p_ss_padding_len)
439 {
440         NTSTATUS ret = NT_STATUS_OK;
441
442         /* Paranioa checks for auth_len. */
443         if (prhdr->auth_len) {
444                 if (prhdr->auth_len > prhdr->frag_len) {
445                         return NT_STATUS_INVALID_PARAMETER;
446                 }
447
448                 if (prhdr->auth_len + RPC_HDR_AUTH_LEN < prhdr->auth_len ||
449                                 prhdr->auth_len + RPC_HDR_AUTH_LEN < RPC_HDR_AUTH_LEN) {
450                         /* Integer wrap attempt. */
451                         return NT_STATUS_INVALID_PARAMETER;
452                 }
453         }
454
455         /*
456          * Now we have a complete RPC request PDU fragment, try and verify any auth data.
457          */
458
459         switch(cli->auth.auth_type) {
460                 case PIPE_AUTH_TYPE_NONE:
461                         if (prhdr->auth_len) {
462                                 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection to remote machine %s "
463                                         "pipe %s fnum 0x%x - got non-zero auth len %u.\n",
464                                         cli->desthost,
465                                         cli->pipe_name,
466                                         (unsigned int)cli->fnum,
467                                         (unsigned int)prhdr->auth_len ));
468                                 return NT_STATUS_INVALID_PARAMETER;
469                         }
470                         break;
471
472                 case PIPE_AUTH_TYPE_NTLMSSP:
473                 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
474                         ret = cli_pipe_verify_ntlmssp(cli, prhdr, current_pdu, p_ss_padding_len);
475                         if (!NT_STATUS_IS_OK(ret)) {
476                                 return ret;
477                         }
478                         break;
479
480                 case PIPE_AUTH_TYPE_SCHANNEL:
481                         ret = cli_pipe_verify_schannel(cli, prhdr, current_pdu, p_ss_padding_len);
482                         if (!NT_STATUS_IS_OK(ret)) {
483                                 return ret;
484                         }
485                         break;
486
487                 case PIPE_AUTH_TYPE_KRB5:
488                 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
489                 default:
490                         DEBUG(3, ("cli_pipe_validate_rpc_response: Connection to remote machine %s "
491                                 "pipe %s fnum %x - unknown internal auth type %u.\n",
492                                 cli->desthost,
493                                 cli->pipe_name,
494                                 (unsigned int)cli->fnum,
495                                 cli->auth.auth_type ));
496                         return NT_STATUS_INVALID_INFO_CLASS;
497         }
498
499         return NT_STATUS_OK;
500 }
501
502 /****************************************************************************
503  Do basic authentication checks on an incoming pdu.
504  ****************************************************************************/
505
506 static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
507                         prs_struct *current_pdu,
508                         uint8 expected_pkt_type,
509                         char **ppdata,
510                         uint32 *pdata_len,
511                         prs_struct *return_data)
512 {
513
514         NTSTATUS ret = NT_STATUS_OK;
515         uint32 current_pdu_len = prs_data_size(current_pdu);
516
517         if (current_pdu_len != prhdr->frag_len) {
518                 DEBUG(5,("cli_pipe_validate_current_pdu: incorrect pdu length %u, expected %u\n",
519                         (unsigned int)current_pdu_len, (unsigned int)prhdr->frag_len ));
520                 return NT_STATUS_INVALID_PARAMETER;
521         }
522
523         /*
524          * Point the return values at the real data including the RPC
525          * header. Just in case the caller wants it.
526          */
527         *ppdata = prs_data_p(current_pdu);
528         *pdata_len = current_pdu_len;
529
530         /* Ensure we have the correct type. */
531         switch (prhdr->pkt_type) {
532                 case RPC_ALTCONTRESP:
533                 case RPC_BINDACK:
534
535                         /* Alter context and bind ack share the same packet definitions. */
536                         break;
537
538
539                 case RPC_RESPONSE:
540                 {
541                         RPC_HDR_RESP rhdr_resp;
542                         uint8 ss_padding_len = 0;
543
544                         if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
545                                 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
546                                 return NT_STATUS_BUFFER_TOO_SMALL;
547                         }
548
549                         /* Here's where we deal with incoming sign/seal. */
550                         ret = cli_pipe_validate_rpc_response(cli, prhdr,
551                                         current_pdu, &ss_padding_len);
552                         if (!NT_STATUS_IS_OK(ret)) {
553                                 return ret;
554                         }
555
556                         /* Point the return values at the NDR data. Remember to remove any ss padding. */
557                         *ppdata = prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
558
559                         if (current_pdu_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN + ss_padding_len) {
560                                 return NT_STATUS_BUFFER_TOO_SMALL;
561                         }
562
563                         *pdata_len = current_pdu_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - ss_padding_len;
564
565                         /* Remember to remove the auth footer. */
566                         if (prhdr->auth_len) {
567                                 /* We've already done integer wrap tests on auth_len in
568                                         cli_pipe_validate_rpc_response(). */
569                                 if (*pdata_len < RPC_HDR_AUTH_LEN + prhdr->auth_len) {
570                                         return NT_STATUS_BUFFER_TOO_SMALL;
571                                 }
572                                 *pdata_len -= (RPC_HDR_AUTH_LEN + prhdr->auth_len);
573                         }
574
575                         DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n",
576                                 current_pdu_len, *pdata_len, ss_padding_len ));
577
578                         /*
579                          * If this is the first reply, and the allocation hint is reasonably, try and
580                          * set up the return_data parse_struct to the correct size.
581                          */
582
583                         if ((prs_data_size(return_data) == 0) && rhdr_resp.alloc_hint && (rhdr_resp.alloc_hint < 15*1024*1024)) {
584                                 if (!prs_set_buffer_size(return_data, rhdr_resp.alloc_hint)) {
585                                         DEBUG(0,("cli_pipe_validate_current_pdu: reply alloc hint %u "
586                                                 "too large to allocate\n",
587                                                 (unsigned int)rhdr_resp.alloc_hint ));
588                                         return NT_STATUS_NO_MEMORY;
589                                 }
590                         }
591
592                         break;
593                 }
594
595                 case RPC_BINDNACK:
596                         DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK received from remote machine %s "
597                                 "pipe %s fnum 0x%x!\n",
598                                 cli->desthost,
599                                 cli->pipe_name,
600                                 (unsigned int)cli->fnum));
601                         /* Use this for now... */
602                         return NT_STATUS_NETWORK_ACCESS_DENIED;
603
604                 case RPC_FAULT:
605                 {
606                         RPC_HDR_RESP rhdr_resp;
607                         RPC_HDR_FAULT fault_resp;
608
609                         if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
610                                 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
611                                 return NT_STATUS_BUFFER_TOO_SMALL;
612                         }
613
614                         if(!smb_io_rpc_hdr_fault("fault", &fault_resp, current_pdu, 0)) {
615                                 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_FAULT.\n"));
616                                 return NT_STATUS_BUFFER_TOO_SMALL;
617                         }
618
619                         DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault code %s received from remote machine %s "
620                                 "pipe %s fnum 0x%x!\n",
621                                 dcerpc_errstr(NT_STATUS_V(fault_resp.status)),
622                                 cli->desthost,
623                                 cli->pipe_name,
624                                 (unsigned int)cli->fnum));
625                         if (NT_STATUS_IS_OK(fault_resp.status)) {
626                                 return NT_STATUS_UNSUCCESSFUL;
627                         } else {
628                                 return fault_resp.status;
629                         }
630                         
631                 }
632
633                 default:
634                         DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
635                                 "from remote machine %s pipe %s fnum 0x%x!\n",
636                                 (unsigned int)prhdr->pkt_type,
637                                 cli->desthost,
638                                 cli->pipe_name,
639                                 (unsigned int)cli->fnum));
640                         return NT_STATUS_INVALID_INFO_CLASS;
641         }
642
643         if (prhdr->pkt_type != expected_pkt_type) {
644                 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to remote machine %s "
645                         "pipe %s fnum %x got an unexpected RPC packet "
646                         "type - %u, not %u\n",
647                         cli->desthost,
648                         cli->pipe_name,
649                         (unsigned int)cli->fnum,
650                         prhdr->pkt_type,
651                         expected_pkt_type));
652                 return NT_STATUS_INVALID_INFO_CLASS;
653         }
654
655         /* Do this just before return - we don't want to modify any rpc header
656            data before now as we may have needed to do cryptographic actions on
657            it before. */
658
659         if ((prhdr->pkt_type == RPC_BINDACK) && !(prhdr->flags & RPC_FLG_LAST)) {
660                 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
661                         "setting fragment first/last ON.\n"));
662                 prhdr->flags |= RPC_FLG_FIRST|RPC_FLG_LAST;
663         }
664
665         return NT_STATUS_OK;
666 }
667
668 /****************************************************************************
669  Ensure we eat the just processed pdu from the current_pdu prs_struct.
670  Normally the frag_len and buffer size will match, but on the first trans
671  reply there is a theoretical chance that buffer size > frag_len, so we must
672  deal with that.
673  ****************************************************************************/
674
675 static NTSTATUS cli_pipe_reset_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
676 {
677         uint32 current_pdu_len = prs_data_size(current_pdu);
678
679         if (current_pdu_len < prhdr->frag_len) {
680                 return NT_STATUS_BUFFER_TOO_SMALL;
681         }
682
683         /* Common case. */
684         if (current_pdu_len == (uint32)prhdr->frag_len) {
685                 prs_mem_free(current_pdu);
686                 prs_init_empty(current_pdu, prs_get_mem_context(current_pdu), UNMARSHALL);
687                 /* Make current_pdu dynamic with no memory. */
688                 prs_give_memory(current_pdu, 0, 0, True);
689                 return NT_STATUS_OK;
690         }
691
692         /*
693          * Oh no ! More data in buffer than we processed in current pdu.
694          * Cheat. Move the data down and shrink the buffer.
695          */
696
697         memcpy(prs_data_p(current_pdu), prs_data_p(current_pdu) + prhdr->frag_len,
698                         current_pdu_len - prhdr->frag_len);
699
700         /* Remember to set the read offset back to zero. */
701         prs_set_offset(current_pdu, 0);
702
703         /* Shrink the buffer. */
704         if (!prs_set_buffer_size(current_pdu, current_pdu_len - prhdr->frag_len)) {
705                 return NT_STATUS_BUFFER_TOO_SMALL;
706         }
707
708         return NT_STATUS_OK;
709 }
710
711 /****************************************************************************
712  Send data on an rpc pipe via trans. The prs_struct data must be the last
713  pdu fragment of an NDR data stream.
714
715  Receive response data from an rpc pipe, which may be large...
716
717  Read the first fragment: unfortunately have to use SMBtrans for the first
718  bit, then SMBreadX for subsequent bits.
719
720  If first fragment received also wasn't the last fragment, continue
721  getting fragments until we _do_ receive the last fragment.
722
723  Request/Response PDU's look like the following...
724
725  |<------------------PDU len----------------------------------------------->|
726  |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
727
728  +------------+-----------------+-------------+---------------+-------------+
729  | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR      | AUTH DATA   |
730  +------------+-----------------+-------------+---------------+-------------+
731
732  Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
733  signing & sealing being negotiated.
734
735  ****************************************************************************/
736
737 static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli,
738                         prs_struct *data, /* Outgoing pdu fragment, already formatted for send. */
739                         prs_struct *rbuf, /* Incoming reply - return as an NDR stream. */
740                         uint8 expected_pkt_type)
741 {
742         NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
743         char *rparam = NULL;
744         uint32 rparam_len = 0;
745         uint16 setup[2];
746         char *pdata = prs_data_p(data);
747         uint32 data_len = prs_offset(data);
748         char *prdata = NULL;
749         uint32 rdata_len = 0;
750         uint32 max_data = cli->max_xmit_frag ? cli->max_xmit_frag : RPC_MAX_PDU_FRAG_LEN;
751         uint32 current_rbuf_offset = 0;
752         prs_struct current_pdu;
753         
754 #ifdef DEVELOPER
755         /* Ensure we're not sending too much. */
756         SMB_ASSERT(data_len <= max_data);
757 #endif
758
759         /* Set up the current pdu parse struct. */
760         prs_init_empty(&current_pdu, prs_get_mem_context(rbuf), UNMARSHALL);
761
762         /* Create setup parameters - must be in native byte order. */
763         setup[0] = TRANSACT_DCERPCCMD; 
764         setup[1] = cli->fnum; /* Pipe file handle. */
765
766         DEBUG(5,("rpc_api_pipe: Remote machine %s pipe %s fnum 0x%x\n",
767                 cli->desthost,
768                 cli->pipe_name,
769                 (unsigned int)cli->fnum ));
770
771         /*
772          * Send the last (or only) fragment of an RPC request. For small
773          * amounts of data (about 1024 bytes or so) the RPC request and response
774          * appears in a SMBtrans request and response.
775          */
776
777         if (!cli_api_pipe(cli->cli, "\\PIPE\\",
778                   setup, 2, 0,                     /* Setup, length, max */
779                   NULL, 0, 0,                      /* Params, length, max */
780                   pdata, data_len, max_data,       /* data, length, max */
781                   &rparam, &rparam_len,            /* return params, len */
782                   &prdata, &rdata_len))            /* return data, len */
783         {
784                 DEBUG(0, ("rpc_api_pipe: Remote machine %s pipe %s fnum 0x%x "
785                         "returned critical error. Error was %s\n",
786                         cli->desthost,
787                         cli->pipe_name,
788                         (unsigned int)cli->fnum,
789                         cli_errstr(cli->cli)));
790                 ret = cli_get_nt_error(cli->cli);
791                 SAFE_FREE(rparam);
792                 SAFE_FREE(prdata);
793                 goto err;
794         }
795
796         /* Throw away returned params - we know we won't use them. */
797
798         SAFE_FREE(rparam);
799
800         if (prdata == NULL) {
801                 DEBUG(3,("rpc_api_pipe: Remote machine %s pipe %s "
802                         "fnum 0x%x failed to return data.\n",
803                         cli->desthost,
804                         cli->pipe_name,
805                         (unsigned int)cli->fnum));
806                 /* Yes - some calls can truely return no data... */
807                 prs_mem_free(&current_pdu);
808                 return NT_STATUS_OK;
809         }
810
811         /*
812          * Give this memory as dynamic to the current pdu.
813          */
814
815         prs_give_memory(&current_pdu, prdata, rdata_len, True);
816
817         /* Ensure we can mess with the return prs_struct. */
818         SMB_ASSERT(UNMARSHALLING(rbuf));
819         SMB_ASSERT(prs_data_size(rbuf) == 0);
820
821         /* Make rbuf dynamic with no memory. */
822         prs_give_memory(rbuf, 0, 0, True);
823
824         while(1) {
825                 RPC_HDR rhdr;
826                 char *ret_data;
827                 uint32 ret_data_len;
828
829                 /* Ensure we have enough data for a pdu. */
830                 ret = cli_pipe_get_current_pdu(cli, &rhdr, &current_pdu);
831                 if (!NT_STATUS_IS_OK(ret)) {
832                         goto err;
833                 }
834
835                 /* We pass in rbuf here so if the alloc hint is set correctly 
836                    we can set the output size and avoid reallocs. */
837
838                 ret = cli_pipe_validate_current_pdu(cli, &rhdr, &current_pdu, expected_pkt_type,
839                                 &ret_data, &ret_data_len, rbuf);
840
841                 DEBUG(10,("rpc_api_pipe: got PDU len of %u at offset %u\n",
842                         prs_data_size(&current_pdu), current_rbuf_offset ));
843
844                 if (!NT_STATUS_IS_OK(ret)) {
845                         goto err;
846                 }
847
848                 if ((rhdr.flags & RPC_FLG_FIRST)) {
849                         if (rhdr.pack_type[0] == 0) {
850                                 /* Set the data type correctly for big-endian data on the first packet. */
851                                 DEBUG(10,("rpc_api_pipe: On machine %s pipe %s fnum 0x%x "
852                                         "PDU data format is big-endian.\n",
853                                         cli->desthost,
854                                         cli->pipe_name,
855                                         (unsigned int)cli->fnum));
856
857                                 prs_set_endian_data(rbuf, RPC_BIG_ENDIAN);
858                         } else {
859                                 /* Check endianness on subsequent packets. */
860                                 if (current_pdu.bigendian_data != rbuf->bigendian_data) {
861                                         DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to %s\n",
862                                                 rbuf->bigendian_data ? "big" : "little",
863                                                 current_pdu.bigendian_data ? "big" : "little" ));
864                                         ret = NT_STATUS_INVALID_PARAMETER;
865                                         goto err;
866                                 }
867                         }
868                 }
869
870                 /* Now copy the data portion out of the pdu into rbuf. */
871                 if (!prs_force_grow(rbuf, ret_data_len)) {
872                         ret = NT_STATUS_NO_MEMORY;
873                         goto err;
874                 }
875                 memcpy(prs_data_p(rbuf)+current_rbuf_offset, ret_data, (size_t)ret_data_len);
876                 current_rbuf_offset += ret_data_len;
877
878                 /* See if we've finished with all the data in current_pdu yet ? */
879                 ret = cli_pipe_reset_current_pdu(cli, &rhdr, &current_pdu);
880                 if (!NT_STATUS_IS_OK(ret)) {
881                         goto err;
882                 }
883
884                 if (rhdr.flags & RPC_FLG_LAST) {
885                         break; /* We're done. */
886                 }
887         }
888
889         DEBUG(10,("rpc_api_pipe: Remote machine %s pipe %s fnum 0x%x returned %u bytes.\n",
890                 cli->desthost,
891                 cli->pipe_name,
892                 (unsigned int)cli->fnum,
893                 (unsigned int)prs_data_size(rbuf) ));
894
895         prs_mem_free(&current_pdu);
896         return NT_STATUS_OK;
897
898   err:
899
900         prs_mem_free(&current_pdu);
901         prs_mem_free(rbuf);
902         return ret;
903 }
904
905 /*******************************************************************
906  Creates krb5 auth bind.
907  ********************************************************************/
908
909 static NTSTATUS create_krb5_auth_bind_req( struct rpc_pipe_client *cli,
910                                                 enum pipe_auth_level auth_level,
911                                                 RPC_HDR_AUTH *pauth_out,
912                                                 prs_struct *auth_data)
913 {
914 #ifdef HAVE_KRB5
915         int ret;
916         struct kerberos_auth_struct *a = cli->auth.a_u.kerberos_auth;
917         DATA_BLOB tkt = data_blob_null;
918         DATA_BLOB tkt_wrapped = data_blob_null;
919
920         /* We may change the pad length before marshalling. */
921         init_rpc_hdr_auth(pauth_out, RPC_KRB5_AUTH_TYPE, (int)auth_level, 0, 1);
922
923         DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
924                 a->service_principal ));
925
926         /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
927
928         ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
929                         &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL);
930
931         if (ret) {
932                 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
933                         "failed with %s\n",
934                         a->service_principal,
935                         error_message(ret) ));
936
937                 data_blob_free(&tkt);
938                 prs_mem_free(auth_data);
939                 return NT_STATUS_INVALID_PARAMETER;
940         }
941
942         /* wrap that up in a nice GSS-API wrapping */
943         tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
944
945         data_blob_free(&tkt);
946
947         /* Auth len in the rpc header doesn't include auth_header. */
948         if (!prs_copy_data_in(auth_data, (char *)tkt_wrapped.data, tkt_wrapped.length)) {
949                 data_blob_free(&tkt_wrapped);
950                 prs_mem_free(auth_data);
951                 return NT_STATUS_NO_MEMORY;
952         }
953
954         DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
955         dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
956
957         data_blob_free(&tkt_wrapped);
958         return NT_STATUS_OK;
959 #else
960         return NT_STATUS_INVALID_PARAMETER;
961 #endif
962 }
963
964 /*******************************************************************
965  Creates SPNEGO NTLMSSP auth bind.
966  ********************************************************************/
967
968 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
969                                                 enum pipe_auth_level auth_level,
970                                                 RPC_HDR_AUTH *pauth_out,
971                                                 prs_struct *auth_data)
972 {
973         NTSTATUS nt_status;
974         DATA_BLOB null_blob = data_blob_null;
975         DATA_BLOB request = data_blob_null;
976         DATA_BLOB spnego_msg = data_blob_null;
977
978         /* We may change the pad length before marshalling. */
979         init_rpc_hdr_auth(pauth_out, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
980
981         DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
982         nt_status = ntlmssp_update(cli->auth.a_u.ntlmssp_state,
983                                         null_blob,
984                                         &request);
985
986         if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
987                 data_blob_free(&request);
988                 prs_mem_free(auth_data);
989                 return nt_status;
990         }
991
992         /* Wrap this in SPNEGO. */
993         spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
994
995         data_blob_free(&request);
996
997         /* Auth len in the rpc header doesn't include auth_header. */
998         if (!prs_copy_data_in(auth_data, (char *)spnego_msg.data, spnego_msg.length)) {
999                 data_blob_free(&spnego_msg);
1000                 prs_mem_free(auth_data);
1001                 return NT_STATUS_NO_MEMORY;
1002         }
1003
1004         DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1005         dump_data(5, spnego_msg.data, spnego_msg.length);
1006
1007         data_blob_free(&spnego_msg);
1008         return NT_STATUS_OK;
1009 }
1010
1011 /*******************************************************************
1012  Creates NTLMSSP auth bind.
1013  ********************************************************************/
1014
1015 static NTSTATUS create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1016                                                 enum pipe_auth_level auth_level,
1017                                                 RPC_HDR_AUTH *pauth_out,
1018                                                 prs_struct *auth_data)
1019 {
1020         NTSTATUS nt_status;
1021         DATA_BLOB null_blob = data_blob_null;
1022         DATA_BLOB request = data_blob_null;
1023
1024         /* We may change the pad length before marshalling. */
1025         init_rpc_hdr_auth(pauth_out, RPC_NTLMSSP_AUTH_TYPE, (int)auth_level, 0, 1);
1026
1027         DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1028         nt_status = ntlmssp_update(cli->auth.a_u.ntlmssp_state,
1029                                         null_blob,
1030                                         &request);
1031
1032         if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1033                 data_blob_free(&request);
1034                 prs_mem_free(auth_data);
1035                 return nt_status;
1036         }
1037
1038         /* Auth len in the rpc header doesn't include auth_header. */
1039         if (!prs_copy_data_in(auth_data, (char *)request.data, request.length)) {
1040                 data_blob_free(&request);
1041                 prs_mem_free(auth_data);
1042                 return NT_STATUS_NO_MEMORY;
1043         }
1044
1045         DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1046         dump_data(5, request.data, request.length);
1047
1048         data_blob_free(&request);
1049         return NT_STATUS_OK;
1050 }
1051
1052 /*******************************************************************
1053  Creates schannel auth bind.
1054  ********************************************************************/
1055
1056 static NTSTATUS create_schannel_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1057                                                 enum pipe_auth_level auth_level,
1058                                                 RPC_HDR_AUTH *pauth_out,
1059                                                 prs_struct *auth_data)
1060 {
1061         RPC_AUTH_SCHANNEL_NEG schannel_neg;
1062
1063         /* We may change the pad length before marshalling. */
1064         init_rpc_hdr_auth(pauth_out, RPC_SCHANNEL_AUTH_TYPE, (int)auth_level, 0, 1);
1065
1066         /* Use lp_workgroup() if domain not specified */
1067
1068         if (!cli->domain || !cli->domain[0]) {
1069                 cli->domain = talloc_strdup(cli, lp_workgroup());
1070                 if (cli->domain == NULL) {
1071                         return NT_STATUS_NO_MEMORY;
1072                 }
1073         }
1074
1075         init_rpc_auth_schannel_neg(&schannel_neg, cli->domain, global_myname());
1076
1077         /*
1078          * Now marshall the data into the auth parse_struct.
1079          */
1080
1081         if(!smb_io_rpc_auth_schannel_neg("schannel_neg",
1082                                        &schannel_neg, auth_data, 0)) {
1083                 DEBUG(0,("Failed to marshall RPC_AUTH_SCHANNEL_NEG.\n"));
1084                 prs_mem_free(auth_data);
1085                 return NT_STATUS_NO_MEMORY;
1086         }
1087
1088         return NT_STATUS_OK;
1089 }
1090
1091 /*******************************************************************
1092  Creates the internals of a DCE/RPC bind request or alter context PDU.
1093  ********************************************************************/
1094
1095 static NTSTATUS create_bind_or_alt_ctx_internal(enum RPC_PKT_TYPE pkt_type,
1096                                                 prs_struct *rpc_out, 
1097                                                 uint32 rpc_call_id,
1098                                                 const RPC_IFACE *abstract,
1099                                                 const RPC_IFACE *transfer,
1100                                                 RPC_HDR_AUTH *phdr_auth,
1101                                                 prs_struct *pauth_info)
1102 {
1103         RPC_HDR hdr;
1104         RPC_HDR_RB hdr_rb;
1105         RPC_CONTEXT rpc_ctx;
1106         uint16 auth_len = prs_offset(pauth_info);
1107         uint8 ss_padding_len = 0;
1108         uint16 frag_len = 0;
1109
1110         /* create the RPC context. */
1111         init_rpc_context(&rpc_ctx, 0 /* context id */, abstract, transfer);
1112
1113         /* create the bind request RPC_HDR_RB */
1114         init_rpc_hdr_rb(&hdr_rb, RPC_MAX_PDU_FRAG_LEN, RPC_MAX_PDU_FRAG_LEN, 0x0, &rpc_ctx);
1115
1116         /* Start building the frag length. */
1117         frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1118
1119         /* Do we need to pad ? */
1120         if (auth_len) {
1121                 uint16 data_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1122                 if (data_len % 8) {
1123                         ss_padding_len = 8 - (data_len % 8);
1124                         phdr_auth->auth_pad_len = ss_padding_len;
1125                 }
1126                 frag_len += RPC_HDR_AUTH_LEN + auth_len + ss_padding_len;
1127         }
1128
1129         /* Create the request RPC_HDR */
1130         init_rpc_hdr(&hdr, pkt_type, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id, frag_len, auth_len);
1131
1132         /* Marshall the RPC header */
1133         if(!smb_io_rpc_hdr("hdr"   , &hdr, rpc_out, 0)) {
1134                 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR.\n"));
1135                 return NT_STATUS_NO_MEMORY;
1136         }
1137
1138         /* Marshall the bind request data */
1139         if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_out, 0)) {
1140                 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1141                 return NT_STATUS_NO_MEMORY;
1142         }
1143
1144         /*
1145          * Grow the outgoing buffer to store any auth info.
1146          */
1147
1148         if(auth_len != 0) {
1149                 if (ss_padding_len) {
1150                         char pad[8];
1151                         memset(pad, '\0', 8);
1152                         if (!prs_copy_data_in(rpc_out, pad, ss_padding_len)) {
1153                                 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n"));
1154                                 return NT_STATUS_NO_MEMORY;
1155                         }
1156                 }
1157
1158                 if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth, rpc_out, 0)) {
1159                         DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n"));
1160                         return NT_STATUS_NO_MEMORY;
1161                 }
1162
1163
1164                 if(!prs_append_prs_data( rpc_out, pauth_info)) {
1165                         DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n"));
1166                         return NT_STATUS_NO_MEMORY;
1167                 }
1168         }
1169
1170         return NT_STATUS_OK;
1171 }
1172
1173 /*******************************************************************
1174  Creates a DCE/RPC bind request.
1175  ********************************************************************/
1176
1177 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
1178                                 prs_struct *rpc_out, 
1179                                 uint32 rpc_call_id,
1180                                 const RPC_IFACE *abstract,
1181                                 const RPC_IFACE *transfer,
1182                                 enum pipe_auth_type auth_type,
1183                                 enum pipe_auth_level auth_level)
1184 {
1185         RPC_HDR_AUTH hdr_auth;
1186         prs_struct auth_info;
1187         NTSTATUS ret = NT_STATUS_OK;
1188
1189         ZERO_STRUCT(hdr_auth);
1190         if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
1191                 return NT_STATUS_NO_MEMORY;
1192
1193         switch (auth_type) {
1194                 case PIPE_AUTH_TYPE_SCHANNEL:
1195                         ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1196                         if (!NT_STATUS_IS_OK(ret)) {
1197                                 prs_mem_free(&auth_info);
1198                                 return ret;
1199                         }
1200                         break;
1201
1202                 case PIPE_AUTH_TYPE_NTLMSSP:
1203                         ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1204                         if (!NT_STATUS_IS_OK(ret)) {
1205                                 prs_mem_free(&auth_info);
1206                                 return ret;
1207                         }
1208                         break;
1209
1210                 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1211                         ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1212                         if (!NT_STATUS_IS_OK(ret)) {
1213                                 prs_mem_free(&auth_info);
1214                                 return ret;
1215                         }
1216                         break;
1217
1218                 case PIPE_AUTH_TYPE_KRB5:
1219                         ret = create_krb5_auth_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1220                         if (!NT_STATUS_IS_OK(ret)) {
1221                                 prs_mem_free(&auth_info);
1222                                 return ret;
1223                         }
1224                         break;
1225
1226                 case PIPE_AUTH_TYPE_NONE:
1227                         break;
1228
1229                 default:
1230                         /* "Can't" happen. */
1231                         return NT_STATUS_INVALID_INFO_CLASS;
1232         }
1233
1234         ret = create_bind_or_alt_ctx_internal(RPC_BIND,
1235                                                 rpc_out, 
1236                                                 rpc_call_id,
1237                                                 abstract,
1238                                                 transfer,
1239                                                 &hdr_auth,
1240                                                 &auth_info);
1241
1242         prs_mem_free(&auth_info);
1243         return ret;
1244 }
1245
1246 /*******************************************************************
1247  Create and add the NTLMSSP sign/seal auth header and data.
1248  ********************************************************************/
1249
1250 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
1251                                         RPC_HDR *phdr,
1252                                         uint32 ss_padding_len,
1253                                         prs_struct *outgoing_pdu)
1254 {
1255         RPC_HDR_AUTH auth_info;
1256         NTSTATUS status;
1257         DATA_BLOB auth_blob = data_blob_null;
1258         uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1259
1260         if (!cli->auth.a_u.ntlmssp_state) {
1261                 return NT_STATUS_INVALID_PARAMETER;
1262         }
1263
1264         /* Init and marshall the auth header. */
1265         init_rpc_hdr_auth(&auth_info,
1266                         map_pipe_auth_type_to_rpc_auth_type(cli->auth.auth_type),
1267                         cli->auth.auth_level,
1268                         ss_padding_len,
1269                         1 /* context id. */);
1270
1271         if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1272                 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1273                 data_blob_free(&auth_blob);
1274                 return NT_STATUS_NO_MEMORY;
1275         }
1276
1277         switch (cli->auth.auth_level) {
1278                 case PIPE_AUTH_LEVEL_PRIVACY:
1279                         /* Data portion is encrypted. */
1280                         status = ntlmssp_seal_packet(cli->auth.a_u.ntlmssp_state,
1281                                         (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1282                                         data_and_pad_len,
1283                                         (unsigned char *)prs_data_p(outgoing_pdu),
1284                                         (size_t)prs_offset(outgoing_pdu),
1285                                         &auth_blob);
1286                         if (!NT_STATUS_IS_OK(status)) {
1287                                 data_blob_free(&auth_blob);
1288                                 return status;
1289                         }
1290                         break;
1291
1292                 case PIPE_AUTH_LEVEL_INTEGRITY:
1293                         /* Data is signed. */
1294                         status = ntlmssp_sign_packet(cli->auth.a_u.ntlmssp_state,
1295                                         (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1296                                         data_and_pad_len,
1297                                         (unsigned char *)prs_data_p(outgoing_pdu),
1298                                         (size_t)prs_offset(outgoing_pdu),
1299                                         &auth_blob);
1300                         if (!NT_STATUS_IS_OK(status)) {
1301                                 data_blob_free(&auth_blob);
1302                                 return status;
1303                         }
1304                         break;
1305
1306                 default:
1307                         /* Can't happen. */
1308                         smb_panic("bad auth level");
1309                         /* Notreached. */
1310                         return NT_STATUS_INVALID_PARAMETER;
1311         }
1312
1313         /* Finally marshall the blob. */
1314                                                                                                        
1315         if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {
1316                 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
1317                         (unsigned int)NTLMSSP_SIG_SIZE));
1318                 data_blob_free(&auth_blob);
1319                 return NT_STATUS_NO_MEMORY;
1320         }
1321                                                                                                                                 
1322         data_blob_free(&auth_blob);
1323         return NT_STATUS_OK;
1324 }
1325
1326 /*******************************************************************
1327  Create and add the schannel sign/seal auth header and data.
1328  ********************************************************************/
1329
1330 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
1331                                         RPC_HDR *phdr,
1332                                         uint32 ss_padding_len,
1333                                         prs_struct *outgoing_pdu)
1334 {
1335         RPC_HDR_AUTH auth_info;
1336         RPC_AUTH_SCHANNEL_CHK verf;
1337         struct schannel_auth_struct *sas = cli->auth.a_u.schannel_auth;
1338         char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
1339         size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1340
1341         if (!sas) {
1342                 return NT_STATUS_INVALID_PARAMETER;
1343         }
1344
1345         /* Init and marshall the auth header. */
1346         init_rpc_hdr_auth(&auth_info,
1347                         map_pipe_auth_type_to_rpc_auth_type(cli->auth.auth_type),
1348                         cli->auth.auth_level,
1349                         ss_padding_len,
1350                         1 /* context id. */);
1351
1352         if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1353                 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1354                 return NT_STATUS_NO_MEMORY;
1355         }
1356
1357         switch (cli->auth.auth_level) {
1358                 case PIPE_AUTH_LEVEL_PRIVACY:
1359                 case PIPE_AUTH_LEVEL_INTEGRITY:
1360                         DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
1361                                 sas->seq_num));
1362
1363                         schannel_encode(sas,
1364                                         cli->auth.auth_level,
1365                                         SENDER_IS_INITIATOR,
1366                                         &verf,
1367                                         data_p,
1368                                         data_and_pad_len);
1369
1370                         sas->seq_num++;
1371                         break;
1372
1373                 default:
1374                         /* Can't happen. */
1375                         smb_panic("bad auth level");
1376                         /* Notreached. */
1377                         return NT_STATUS_INVALID_PARAMETER;
1378         }
1379
1380         /* Finally marshall the blob. */
1381         smb_io_rpc_auth_schannel_chk("",
1382                         RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN,
1383                         &verf,
1384                         outgoing_pdu,
1385                         0);
1386                                                                                                
1387         return NT_STATUS_OK;
1388 }
1389
1390 /*******************************************************************
1391  Calculate how much data we're going to send in this packet, also
1392  work out any sign/seal padding length.
1393  ********************************************************************/
1394
1395 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
1396                                         uint32 data_left,
1397                                         uint16 *p_frag_len,
1398                                         uint16 *p_auth_len,
1399                                         uint32 *p_ss_padding)
1400 {
1401         uint32 data_space, data_len;
1402
1403         switch (cli->auth.auth_level) {
1404                 case PIPE_AUTH_LEVEL_NONE:
1405                 case PIPE_AUTH_LEVEL_CONNECT:
1406                         data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
1407                         data_len = MIN(data_space, data_left);
1408                         *p_ss_padding = 0;
1409                         *p_auth_len = 0;
1410                         *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
1411                         return data_len;
1412
1413                 case PIPE_AUTH_LEVEL_INTEGRITY:
1414                 case PIPE_AUTH_LEVEL_PRIVACY:
1415                         /* Treat the same for all authenticated rpc requests. */
1416                         switch(cli->auth.auth_type) {
1417                                 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1418                                 case PIPE_AUTH_TYPE_NTLMSSP:
1419                                         *p_auth_len = NTLMSSP_SIG_SIZE;
1420                                         break;
1421                                 case PIPE_AUTH_TYPE_SCHANNEL:
1422                                         *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
1423                                         break;
1424                                 default:
1425                                         smb_panic("bad auth type");
1426                                         break;
1427                         }
1428
1429                         data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
1430                                                 RPC_HDR_AUTH_LEN - *p_auth_len;
1431
1432                         data_len = MIN(data_space, data_left);
1433                         if (data_len % 8) {
1434                                 *p_ss_padding = 8 - (data_len % 8);
1435                         }
1436                         *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN +                /* Normal headers. */
1437                                         data_len + *p_ss_padding +              /* data plus padding. */
1438                                         RPC_HDR_AUTH_LEN + *p_auth_len;         /* Auth header and auth data. */
1439                         return data_len;
1440
1441                 default:
1442                         smb_panic("bad auth level");
1443                         /* Notreached. */
1444                         return 0;
1445         }
1446 }
1447
1448 /*******************************************************************
1449  External interface.
1450  Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1451  Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1452  and deals with signing/sealing details.
1453  ********************************************************************/
1454
1455 NTSTATUS rpc_api_pipe_req(struct rpc_pipe_client *cli,
1456                         uint8 op_num,
1457                         prs_struct *in_data,
1458                         prs_struct *out_data)
1459 {
1460         NTSTATUS ret;
1461         uint32 data_left = prs_offset(in_data);
1462         uint32 alloc_hint = prs_offset(in_data);
1463         uint32 data_sent_thistime = 0;
1464         uint32 current_data_offset = 0;
1465         uint32 call_id = get_rpc_call_id();
1466         char pad[8];
1467         prs_struct outgoing_pdu;
1468
1469         memset(pad, '\0', 8);
1470
1471         if (cli->max_xmit_frag < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
1472                 /* Server is screwed up ! */
1473                 return NT_STATUS_INVALID_PARAMETER;
1474         }
1475
1476         if (!prs_init(&outgoing_pdu, cli->max_xmit_frag, prs_get_mem_context(in_data), MARSHALL))
1477                 return NT_STATUS_NO_MEMORY;
1478
1479         while (1) {
1480                 RPC_HDR hdr;
1481                 RPC_HDR_REQ hdr_req;
1482                 uint16 auth_len = 0;
1483                 uint16 frag_len = 0;
1484                 uint8 flags = 0;
1485                 uint32 ss_padding = 0;
1486
1487                 data_sent_thistime = calculate_data_len_tosend(cli, data_left,
1488                                                 &frag_len, &auth_len, &ss_padding);
1489
1490                 if (current_data_offset == 0) {
1491                         flags = RPC_FLG_FIRST;
1492                 }
1493
1494                 if (data_sent_thistime == data_left) {
1495                         flags |= RPC_FLG_LAST;
1496                 }
1497
1498                 /* Create and marshall the header and request header. */
1499                 init_rpc_hdr(&hdr, RPC_REQUEST, flags, call_id, frag_len, auth_len);
1500
1501                 if(!smb_io_rpc_hdr("hdr    ", &hdr, &outgoing_pdu, 0)) {
1502                         prs_mem_free(&outgoing_pdu);
1503                         return NT_STATUS_NO_MEMORY;
1504                 }
1505
1506                 /* Create the rpc request RPC_HDR_REQ */
1507                 init_rpc_hdr_req(&hdr_req, alloc_hint, op_num);
1508
1509                 if(!smb_io_rpc_hdr_req("hdr_req", &hdr_req, &outgoing_pdu, 0)) {
1510                         prs_mem_free(&outgoing_pdu);
1511                         return NT_STATUS_NO_MEMORY;
1512                 }
1513
1514                 /* Copy in the data, plus any ss padding. */
1515                 if (!prs_append_some_prs_data(&outgoing_pdu, in_data, current_data_offset, data_sent_thistime)) {
1516                         prs_mem_free(&outgoing_pdu);
1517                         return NT_STATUS_NO_MEMORY;
1518                 }
1519
1520                 /* Copy the sign/seal padding data. */
1521                 if (ss_padding) {
1522                         if (!prs_copy_data_in(&outgoing_pdu, pad, ss_padding)) {
1523                                 prs_mem_free(&outgoing_pdu);
1524                                 return NT_STATUS_NO_MEMORY;
1525                         }
1526                 }
1527
1528                 /* Generate any auth sign/seal and add the auth footer. */
1529                 if (auth_len) {
1530                         switch (cli->auth.auth_type) {
1531                                 case PIPE_AUTH_TYPE_NONE:
1532                                         break;
1533                                 case PIPE_AUTH_TYPE_NTLMSSP:
1534                                 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1535                                         ret = add_ntlmssp_auth_footer(cli, &hdr, ss_padding, &outgoing_pdu);
1536                                         if (!NT_STATUS_IS_OK(ret)) {
1537                                                 prs_mem_free(&outgoing_pdu);
1538                                                 return ret;
1539                                         }
1540                                         break;
1541                                 case PIPE_AUTH_TYPE_SCHANNEL:
1542                                         ret = add_schannel_auth_footer(cli, &hdr, ss_padding, &outgoing_pdu);
1543                                         if (!NT_STATUS_IS_OK(ret)) {
1544                                                 prs_mem_free(&outgoing_pdu);
1545                                                 return ret;
1546                                         }
1547                                         break;
1548                                 default:
1549                                         smb_panic("bad auth type");
1550                                         break; /* notreached */
1551                         }
1552                 }
1553
1554                 /* Actually send the packet. */
1555                 if (flags & RPC_FLG_LAST) {
1556                         /* Last packet - send the data, get the reply and return. */
1557                         ret = rpc_api_pipe(cli, &outgoing_pdu, out_data, RPC_RESPONSE);
1558                         prs_mem_free(&outgoing_pdu);
1559
1560                         if (DEBUGLEVEL >= 50) {
1561                                 char *dump_name = NULL;
1562                                 /* Also capture received data */
1563                                 if (asprintf(&dump_name, "%s/reply_%s_%d",
1564                                                 get_dyn_LOGFILEBASE(), cli->pipe_name,
1565                                                 op_num) > 0) {
1566                                         prs_dump(dump_name, op_num, out_data);
1567                                         SAFE_FREE(dump_name);
1568                                 }
1569                         }
1570
1571                         return ret;
1572                 } else {
1573                         /* More packets to come - write and continue. */
1574                         ssize_t num_written = cli_write(cli->cli, cli->fnum, 8, /* 8 means message mode. */
1575                                                         prs_data_p(&outgoing_pdu),
1576                                                         (off_t)0,
1577                                                         (size_t)hdr.frag_len);
1578
1579                         if (num_written != hdr.frag_len) {
1580                                 prs_mem_free(&outgoing_pdu);
1581                                 return cli_get_nt_error(cli->cli);
1582                         }
1583                 }
1584
1585                 current_data_offset += data_sent_thistime;
1586                 data_left -= data_sent_thistime;
1587
1588                 /* Reset the marshalling position back to zero. */
1589                 if (!prs_set_offset(&outgoing_pdu, 0)) {
1590                         prs_mem_free(&outgoing_pdu);
1591                         return NT_STATUS_NO_MEMORY;
1592                 }
1593         }
1594 }
1595 #if 0
1596 /****************************************************************************
1597  Set the handle state.
1598 ****************************************************************************/
1599
1600 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
1601                                    const char *pipe_name, uint16 device_state)
1602 {
1603         bool state_set = False;
1604         char param[2];
1605         uint16 setup[2]; /* only need 2 uint16 setup parameters */
1606         char *rparam = NULL;
1607         char *rdata = NULL;
1608         uint32 rparam_len, rdata_len;
1609
1610         if (pipe_name == NULL)
1611                 return False;
1612
1613         DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
1614                  cli->fnum, pipe_name, device_state));
1615
1616         /* create parameters: device state */
1617         SSVAL(param, 0, device_state);
1618
1619         /* create setup parameters. */
1620         setup[0] = 0x0001; 
1621         setup[1] = cli->fnum; /* pipe file handle.  got this from an SMBOpenX. */
1622
1623         /* send the data on \PIPE\ */
1624         if (cli_api_pipe(cli->cli, "\\PIPE\\",
1625                     setup, 2, 0,                /* setup, length, max */
1626                     param, 2, 0,                /* param, length, max */
1627                     NULL, 0, 1024,              /* data, length, max */
1628                     &rparam, &rparam_len,        /* return param, length */
1629                     &rdata, &rdata_len))         /* return data, length */
1630         {
1631                 DEBUG(5, ("Set Handle state: return OK\n"));
1632                 state_set = True;
1633         }
1634
1635         SAFE_FREE(rparam);
1636         SAFE_FREE(rdata);
1637
1638         return state_set;
1639 }
1640 #endif
1641
1642 /****************************************************************************
1643  Check the rpc bind acknowledge response.
1644 ****************************************************************************/
1645
1646 static bool check_bind_response(RPC_HDR_BA *hdr_ba, const RPC_IFACE *transfer)
1647 {
1648         if ( hdr_ba->addr.len == 0) {
1649                 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1650         }
1651
1652         /* check the transfer syntax */
1653         if ((hdr_ba->transfer.if_version != transfer->if_version) ||
1654              (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
1655                 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1656                 return False;
1657         }
1658
1659         if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) {
1660                 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1661                           hdr_ba->res.num_results, hdr_ba->res.reason));
1662         }
1663
1664         DEBUG(5,("check_bind_response: accepted!\n"));
1665         return True;
1666 }
1667
1668 /*******************************************************************
1669  Creates a DCE/RPC bind authentication response.
1670  This is the packet that is sent back to the server once we
1671  have received a BIND-ACK, to finish the third leg of
1672  the authentication handshake.
1673  ********************************************************************/
1674
1675 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
1676                                 uint32 rpc_call_id,
1677                                 enum pipe_auth_type auth_type,
1678                                 enum pipe_auth_level auth_level,
1679                                 DATA_BLOB *pauth_blob,
1680                                 prs_struct *rpc_out)
1681 {
1682         RPC_HDR hdr;
1683         RPC_HDR_AUTH hdr_auth;
1684         uint32 pad = 0;
1685
1686         /* Create the request RPC_HDR */
1687         init_rpc_hdr(&hdr, RPC_AUTH3, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id,
1688                      RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + pauth_blob->length,
1689                      pauth_blob->length );
1690         
1691         /* Marshall it. */
1692         if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
1693                 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
1694                 return NT_STATUS_NO_MEMORY;
1695         }
1696
1697         /*
1698                 I'm puzzled about this - seems to violate the DCE RPC auth rules,
1699                 about padding - shouldn't this pad to length 8 ? JRA.
1700         */
1701
1702         /* 4 bytes padding. */
1703         if (!prs_uint32("pad", rpc_out, 0, &pad)) {
1704                 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
1705                 return NT_STATUS_NO_MEMORY;
1706         }
1707
1708         /* Create the request RPC_HDR_AUTHA */
1709         init_rpc_hdr_auth(&hdr_auth,
1710                         map_pipe_auth_type_to_rpc_auth_type(auth_type),
1711                         auth_level, 0, 1);
1712
1713         if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rpc_out, 0)) {
1714                 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
1715                 return NT_STATUS_NO_MEMORY;
1716         }
1717
1718         /*
1719          * Append the auth data to the outgoing buffer.
1720          */
1721
1722         if(!prs_copy_data_in(rpc_out, (char *)pauth_blob->data, pauth_blob->length)) {
1723                 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
1724                 return NT_STATUS_NO_MEMORY;
1725         }
1726
1727         return NT_STATUS_OK;
1728 }
1729
1730 /****************************************************************************
1731  Create and send the third packet in an RPC auth.
1732 ****************************************************************************/
1733
1734 static NTSTATUS rpc_finish_auth3_bind(struct rpc_pipe_client *cli,
1735                                 RPC_HDR *phdr,
1736                                 prs_struct *rbuf,
1737                                 uint32 rpc_call_id,
1738                                 enum pipe_auth_type auth_type,
1739                                 enum pipe_auth_level auth_level)
1740 {
1741         DATA_BLOB server_response = data_blob_null;
1742         DATA_BLOB client_reply = data_blob_null;
1743         RPC_HDR_AUTH hdr_auth;
1744         NTSTATUS nt_status;
1745         prs_struct rpc_out;
1746         ssize_t ret;
1747
1748         if (!phdr->auth_len || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
1749                 return NT_STATUS_INVALID_PARAMETER;
1750         }
1751
1752         /* Process the returned NTLMSSP blob first. */
1753         if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
1754                 return NT_STATUS_INVALID_PARAMETER;
1755         }
1756
1757         if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
1758                 return NT_STATUS_INVALID_PARAMETER;
1759         }
1760
1761         /* TODO - check auth_type/auth_level match. */
1762
1763         server_response = data_blob(NULL, phdr->auth_len);
1764         prs_copy_data_out((char *)server_response.data, rbuf, phdr->auth_len);
1765         
1766         nt_status = ntlmssp_update(cli->auth.a_u.ntlmssp_state,
1767                                    server_response,
1768                                    &client_reply);
1769         
1770         if (!NT_STATUS_IS_OK(nt_status)) {
1771                 DEBUG(0,("rpc_finish_auth3_bind: NTLMSSP update using server blob failed.\n"));
1772                 data_blob_free(&server_response);
1773                 return nt_status;
1774         }
1775
1776         prs_init_empty(&rpc_out, prs_get_mem_context(rbuf), MARSHALL);
1777
1778         nt_status = create_rpc_bind_auth3(cli, rpc_call_id,
1779                                 auth_type, auth_level,
1780                                 &client_reply, &rpc_out);
1781
1782         if (!NT_STATUS_IS_OK(nt_status)) {
1783                 prs_mem_free(&rpc_out);
1784                 data_blob_free(&client_reply);
1785                 data_blob_free(&server_response);
1786                 return nt_status;
1787         }
1788
1789         /* 8 here is named pipe message mode. */
1790         ret = cli_write(cli->cli, cli->fnum, 0x8, prs_data_p(&rpc_out), 0,
1791                                 (size_t)prs_offset(&rpc_out));
1792
1793         if (ret != (ssize_t)prs_offset(&rpc_out)) {
1794                 DEBUG(0,("rpc_send_auth_auth3: cli_write failed. Return was %d\n", (int)ret));
1795                 prs_mem_free(&rpc_out);
1796                 data_blob_free(&client_reply);
1797                 data_blob_free(&server_response);
1798                 return cli_get_nt_error(cli->cli);
1799         }
1800
1801         DEBUG(5,("rpc_send_auth_auth3: Remote machine %s pipe %s "
1802                 "fnum 0x%x sent auth3 response ok.\n",
1803                 cli->desthost,
1804                 cli->pipe_name,
1805                 (unsigned int)cli->fnum));
1806
1807         prs_mem_free(&rpc_out);
1808         data_blob_free(&client_reply);
1809         data_blob_free(&server_response);
1810         return NT_STATUS_OK;
1811 }
1812
1813 /*******************************************************************
1814  Creates a DCE/RPC bind alter context authentication request which
1815  may contain a spnego auth blobl
1816  ********************************************************************/
1817
1818 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
1819                                         const RPC_IFACE *abstract,
1820                                         const RPC_IFACE *transfer,
1821                                         enum pipe_auth_level auth_level,
1822                                         const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
1823                                         prs_struct *rpc_out)
1824 {
1825         RPC_HDR_AUTH hdr_auth;
1826         prs_struct auth_info;
1827         NTSTATUS ret = NT_STATUS_OK;
1828
1829         ZERO_STRUCT(hdr_auth);
1830         if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
1831                 return NT_STATUS_NO_MEMORY;
1832
1833         /* We may change the pad length before marshalling. */
1834         init_rpc_hdr_auth(&hdr_auth, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
1835
1836         if (pauth_blob->length) {
1837                 if (!prs_copy_data_in(&auth_info, (const char *)pauth_blob->data, pauth_blob->length)) {
1838                         prs_mem_free(&auth_info);
1839                         return NT_STATUS_NO_MEMORY;
1840                 }
1841         }
1842
1843         ret = create_bind_or_alt_ctx_internal(RPC_ALTCONT,
1844                                                 rpc_out, 
1845                                                 rpc_call_id,
1846                                                 abstract,
1847                                                 transfer,
1848                                                 &hdr_auth,
1849                                                 &auth_info);
1850         prs_mem_free(&auth_info);
1851         return ret;
1852 }
1853
1854 /*******************************************************************
1855  Third leg of the SPNEGO bind mechanism - sends alter context PDU
1856  and gets a response.
1857  ********************************************************************/
1858
1859 static NTSTATUS rpc_finish_spnego_ntlmssp_bind(struct rpc_pipe_client *cli,
1860                                 RPC_HDR *phdr,
1861                                 prs_struct *rbuf,
1862                                 uint32 rpc_call_id,
1863                                 const RPC_IFACE *abstract,
1864                                 const RPC_IFACE *transfer,
1865                                 enum pipe_auth_type auth_type,
1866                                 enum pipe_auth_level auth_level)
1867 {
1868         DATA_BLOB server_spnego_response = data_blob_null;
1869         DATA_BLOB server_ntlm_response = data_blob_null;
1870         DATA_BLOB client_reply = data_blob_null;
1871         DATA_BLOB tmp_blob = data_blob_null;
1872         RPC_HDR_AUTH hdr_auth;
1873         NTSTATUS nt_status;
1874         prs_struct rpc_out;
1875
1876         if (!phdr->auth_len || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
1877                 return NT_STATUS_INVALID_PARAMETER;
1878         }
1879
1880         /* Process the returned NTLMSSP blob first. */
1881         if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
1882                 return NT_STATUS_INVALID_PARAMETER;
1883         }
1884
1885         if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
1886                 return NT_STATUS_INVALID_PARAMETER;
1887         }
1888
1889         server_spnego_response = data_blob(NULL, phdr->auth_len);
1890         prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len);
1891         
1892         /* The server might give us back two challenges - tmp_blob is for the second. */
1893         if (!spnego_parse_challenge(server_spnego_response, &server_ntlm_response, &tmp_blob)) {
1894                 data_blob_free(&server_spnego_response);
1895                 data_blob_free(&server_ntlm_response);
1896                 data_blob_free(&tmp_blob);
1897                 return NT_STATUS_INVALID_PARAMETER;
1898         }
1899
1900         /* We're finished with the server spnego response and the tmp_blob. */
1901         data_blob_free(&server_spnego_response);
1902         data_blob_free(&tmp_blob);
1903
1904         nt_status = ntlmssp_update(cli->auth.a_u.ntlmssp_state,
1905                                    server_ntlm_response,
1906                                    &client_reply);
1907         
1908         /* Finished with the server_ntlm response */
1909         data_blob_free(&server_ntlm_response);
1910
1911         if (!NT_STATUS_IS_OK(nt_status)) {
1912                 DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update using server blob failed.\n"));
1913                 data_blob_free(&client_reply);
1914                 return nt_status;
1915         }
1916
1917         /* SPNEGO wrap the client reply. */
1918         tmp_blob = spnego_gen_auth(client_reply);
1919         data_blob_free(&client_reply);
1920         client_reply = tmp_blob;
1921         tmp_blob = data_blob_null; /* Ensure it's safe to free this just in case. */
1922
1923         /* Now prepare the alter context pdu. */
1924         prs_init_empty(&rpc_out, prs_get_mem_context(rbuf), MARSHALL);
1925
1926         nt_status = create_rpc_alter_context(rpc_call_id,
1927                                                 abstract,
1928                                                 transfer,
1929                                                 auth_level,
1930                                                 &client_reply,
1931                                                 &rpc_out);
1932
1933         data_blob_free(&client_reply);
1934
1935         if (!NT_STATUS_IS_OK(nt_status)) {
1936                 prs_mem_free(&rpc_out);
1937                 return nt_status;
1938         }
1939
1940         /* Initialize the returning data struct. */
1941         prs_mem_free(rbuf);
1942         prs_init_empty(rbuf, talloc_tos(), UNMARSHALL);
1943
1944         nt_status = rpc_api_pipe(cli, &rpc_out, rbuf, RPC_ALTCONTRESP);
1945         if (!NT_STATUS_IS_OK(nt_status)) {
1946                 prs_mem_free(&rpc_out);
1947                 return nt_status;
1948         }
1949
1950         prs_mem_free(&rpc_out);
1951
1952         /* Get the auth blob from the reply. */
1953         if(!smb_io_rpc_hdr("rpc_hdr   ", phdr, rbuf, 0)) {
1954                 DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: Failed to unmarshall RPC_HDR.\n"));
1955                 return NT_STATUS_BUFFER_TOO_SMALL;
1956         }
1957
1958         if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
1959                 return NT_STATUS_INVALID_PARAMETER;
1960         }
1961
1962         if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
1963                 return NT_STATUS_INVALID_PARAMETER;
1964         }
1965
1966         server_spnego_response = data_blob(NULL, phdr->auth_len);
1967         prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len);
1968
1969         /* Check we got a valid auth response. */
1970         if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK, OID_NTLMSSP, &tmp_blob)) {
1971                 data_blob_free(&server_spnego_response);
1972                 data_blob_free(&tmp_blob);
1973                 return NT_STATUS_INVALID_PARAMETER;
1974         }
1975
1976         data_blob_free(&server_spnego_response);
1977         data_blob_free(&tmp_blob);
1978
1979         DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
1980                 "remote machine %s pipe %s fnum 0x%x.\n",
1981                 cli->desthost,
1982                 cli->pipe_name,
1983                 (unsigned int)cli->fnum));
1984
1985         return NT_STATUS_OK;
1986 }
1987
1988 /****************************************************************************
1989  Do an rpc bind.
1990 ****************************************************************************/
1991
1992 static NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
1993                         enum pipe_auth_type auth_type,
1994                         enum pipe_auth_level auth_level)
1995 {
1996         RPC_HDR hdr;
1997         RPC_HDR_BA hdr_ba;
1998         prs_struct rpc_out;
1999         prs_struct rbuf;
2000         uint32 rpc_call_id;
2001         NTSTATUS status;
2002
2003         DEBUG(5,("Bind RPC Pipe[%x]: %s auth_type %u, auth_level %u\n",
2004                 (unsigned int)cli->fnum,
2005                 cli->pipe_name,
2006                 (unsigned int)auth_type,
2007                 (unsigned int)auth_level ));
2008
2009         prs_init_empty(&rpc_out, talloc_tos(), MARSHALL);
2010
2011         rpc_call_id = get_rpc_call_id();
2012
2013         /* Marshall the outgoing data. */
2014         status = create_rpc_bind_req(cli, &rpc_out, rpc_call_id,
2015                                 cli->abstract_syntax,
2016                                 cli->transfer_syntax,
2017                                 auth_type,
2018                                 auth_level);
2019
2020         if (!NT_STATUS_IS_OK(status)) {
2021                 prs_mem_free(&rpc_out);
2022                 return status;
2023         }
2024
2025         /* Initialize the incoming data struct. */
2026         prs_init_empty(&rbuf, talloc_tos(), UNMARSHALL);
2027
2028         /* send data on \PIPE\.  receive a response */
2029         status = rpc_api_pipe(cli, &rpc_out, &rbuf, RPC_BINDACK);
2030         if (!NT_STATUS_IS_OK(status)) {
2031                 prs_mem_free(&rpc_out);
2032                 return status;
2033         }
2034
2035         prs_mem_free(&rpc_out);
2036
2037         DEBUG(3,("rpc_pipe_bind: Remote machine %s pipe %s "
2038                 "fnum 0x%x bind request returned ok.\n",
2039                 cli->desthost,
2040                 cli->pipe_name,
2041                 (unsigned int)cli->fnum));
2042
2043         /* Unmarshall the RPC header */
2044         if(!smb_io_rpc_hdr("hdr"   , &hdr, &rbuf, 0)) {
2045                 DEBUG(0,("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2046                 prs_mem_free(&rbuf);
2047                 return NT_STATUS_BUFFER_TOO_SMALL;
2048         }
2049
2050         if(!smb_io_rpc_hdr_ba("", &hdr_ba, &rbuf, 0)) {
2051                 DEBUG(0,("rpc_pipe_bind: Failed to unmarshall RPC_HDR_BA.\n"));
2052                 prs_mem_free(&rbuf);
2053                 return NT_STATUS_BUFFER_TOO_SMALL;
2054         }
2055
2056         if(!check_bind_response(&hdr_ba, cli->transfer_syntax)) {
2057                 DEBUG(2,("rpc_pipe_bind: check_bind_response failed.\n"));
2058                 prs_mem_free(&rbuf);
2059                 return NT_STATUS_BUFFER_TOO_SMALL;
2060         }
2061
2062         cli->max_xmit_frag = hdr_ba.bba.max_tsize;
2063         cli->max_recv_frag = hdr_ba.bba.max_rsize;
2064
2065         /* For authenticated binds we may need to do 3 or 4 leg binds. */
2066         switch(auth_type) {
2067
2068                 case PIPE_AUTH_TYPE_NONE:
2069                 case PIPE_AUTH_TYPE_SCHANNEL:
2070                         /* Bind complete. */
2071                         break;
2072
2073                 case PIPE_AUTH_TYPE_NTLMSSP:
2074                         /* Need to send AUTH3 packet - no reply. */
2075                         status = rpc_finish_auth3_bind(cli, &hdr, &rbuf, rpc_call_id,
2076                                                 auth_type, auth_level);
2077                         if (!NT_STATUS_IS_OK(status)) {
2078                                 prs_mem_free(&rbuf);
2079                                 return status;
2080                         }
2081                         break;
2082
2083                 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2084                         /* Need to send alter context request and reply. */
2085                         status = rpc_finish_spnego_ntlmssp_bind(cli, &hdr, &rbuf, rpc_call_id,
2086                                                 cli->abstract_syntax,
2087                                                 cli->transfer_syntax,
2088                                                 auth_type, auth_level);
2089                         if (!NT_STATUS_IS_OK(status)) {
2090                                 prs_mem_free(&rbuf);
2091                                 return status;
2092                         }
2093                         break;
2094
2095                 case PIPE_AUTH_TYPE_KRB5:
2096                         /* */
2097
2098                 default:
2099                         DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
2100                                 (unsigned int)auth_type ));
2101                         prs_mem_free(&rbuf);
2102                         return NT_STATUS_INVALID_INFO_CLASS;
2103         }
2104
2105         /* For NTLMSSP ensure the server gave us the auth_level we wanted. */
2106         if (auth_type == PIPE_AUTH_TYPE_NTLMSSP || auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2107                 if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2108                         if (!(cli->auth.a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN)) {
2109                                 DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP signing and server refused.\n"));
2110                                 prs_mem_free(&rbuf);
2111                                 return NT_STATUS_INVALID_PARAMETER;
2112                         }
2113                 }
2114                 if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2115                         if (!(cli->auth.a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL)) {
2116                                 DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP sealing and server refused.\n"));
2117                                 prs_mem_free(&rbuf);
2118                                 return NT_STATUS_INVALID_PARAMETER;
2119                         }
2120                 }
2121         }
2122
2123         /* Pipe is bound - set up auth_type and auth_level data. */
2124
2125         cli->auth.auth_type = auth_type;
2126         cli->auth.auth_level = auth_level;
2127
2128         prs_mem_free(&rbuf);
2129         return NT_STATUS_OK;
2130 }
2131
2132 unsigned int rpccli_set_timeout(struct rpc_pipe_client *cli,
2133                                 unsigned int timeout)
2134 {
2135         return cli_set_timeout(cli->cli, timeout);
2136 }
2137
2138 bool rpccli_is_pipe_idx(struct rpc_pipe_client *cli, int pipe_idx)
2139 {
2140         return (cli->abstract_syntax == pipe_names[pipe_idx].abstr_syntax);
2141 }
2142
2143 static int rpc_pipe_destructor(struct rpc_pipe_client *p)
2144 {
2145         bool ret;
2146
2147         ret = cli_close(p->cli, p->fnum);
2148         if (!ret) {
2149                 DEBUG(1, ("rpc_pipe_destructor: cli_close failed on pipe %s, "
2150                           "fnum 0x%x to machine %s.  Error was %s\n",
2151                           p->pipe_name, (int) p->fnum,
2152                           p->desthost, cli_errstr(p->cli)));
2153         }
2154
2155         if (p->auth.cli_auth_data_free_func) {
2156                 (*p->auth.cli_auth_data_free_func)(&p->auth);
2157         }
2158
2159         DEBUG(10, ("rpc_pipe_destructor: closed pipe %s to machine %s\n",
2160                    p->pipe_name, p->desthost ));
2161
2162         DLIST_REMOVE(p->cli->pipe_list, p);
2163
2164         return ret ? -1 : 0;
2165 }
2166
2167 /****************************************************************************
2168  Open a named pipe over SMB to a remote server.
2169  *
2170  * CAVEAT CALLER OF THIS FUNCTION:
2171  *    The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2172  *    so be sure that this function is called AFTER any structure (vs pointer)
2173  *    assignment of the cli.  In particular, libsmbclient does structure
2174  *    assignments of cli, which invalidates the data in the returned
2175  *    rpc_pipe_client if this function is called before the structure assignment
2176  *    of cli.
2177  * 
2178  ****************************************************************************/
2179
2180 static struct rpc_pipe_client *cli_rpc_pipe_open(struct cli_state *cli, int pipe_idx, NTSTATUS *perr)
2181 {
2182         struct rpc_pipe_client *result;
2183         int fnum;
2184
2185         *perr = NT_STATUS_NO_MEMORY;
2186
2187         /* sanity check to protect against crashes */
2188
2189         if ( !cli ) {
2190                 *perr = NT_STATUS_INVALID_HANDLE;
2191                 return NULL;
2192         }
2193
2194         /* The pipe name index must fall within our array */
2195         SMB_ASSERT((pipe_idx >= 0) && (pipe_idx < PI_MAX_PIPES));
2196
2197         result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
2198         if (result == NULL) {
2199                 *perr = NT_STATUS_NO_MEMORY;
2200                 return NULL;
2201         }
2202
2203         result->pipe_name = cli_get_pipe_name(pipe_idx);
2204
2205         result->cli = cli;
2206         result->abstract_syntax = pipe_names[pipe_idx].abstr_syntax;
2207         result->transfer_syntax = pipe_names[pipe_idx].trans_syntax;
2208         result->auth.auth_type = PIPE_AUTH_TYPE_NONE;
2209         result->auth.auth_level = PIPE_AUTH_LEVEL_NONE;
2210
2211         result->domain = talloc_strdup(result, cli->domain);
2212         result->user_name = talloc_strdup(result, cli->user_name);
2213         result->desthost = talloc_strdup(result, cli->desthost);
2214         result->srv_name_slash = talloc_asprintf_strupper_m(
2215                 result, "\\\\%s", result->desthost);
2216
2217         if ((result->domain == NULL)
2218             || (result->user_name == NULL)
2219             || (result->desthost == NULL)
2220             || (result->srv_name_slash == NULL)) {
2221                 *perr = NT_STATUS_NO_MEMORY;
2222                 TALLOC_FREE(result);
2223                 return NULL;
2224         }
2225
2226         if (pipe_idx == PI_NETLOGON) {
2227                 /* Set up a netlogon credential chain for a netlogon pipe. */
2228                 result->dc = TALLOC_ZERO_P(result, struct dcinfo);
2229                 if (result->dc == NULL) {
2230                         *perr = NT_STATUS_NO_MEMORY;
2231                         TALLOC_FREE(result);
2232                         return NULL;
2233                 }
2234         }
2235
2236         fnum = cli_nt_create(cli, result->pipe_name, DESIRED_ACCESS_PIPE);
2237         if (fnum == -1) {
2238                 DEBUG(1,("cli_rpc_pipe_open: cli_nt_create failed on pipe %s "
2239                          "to machine %s.  Error was %s\n",
2240                          result->pipe_name, cli->desthost,
2241                          cli_errstr(cli)));
2242                 *perr = cli_get_nt_error(cli);
2243                 talloc_destroy(result);
2244                 return NULL;
2245         }
2246
2247         result->fnum = fnum;
2248
2249         DLIST_ADD(cli->pipe_list, result);
2250         talloc_set_destructor(result, rpc_pipe_destructor);
2251
2252         *perr = NT_STATUS_OK;
2253
2254         return result;
2255 }
2256
2257 /****************************************************************************
2258  Open a named pipe to an SMB server and bind anonymously.
2259  ****************************************************************************/
2260
2261 struct rpc_pipe_client *cli_rpc_pipe_open_noauth(struct cli_state *cli, int pipe_idx, NTSTATUS *perr)
2262 {
2263         struct rpc_pipe_client *result;
2264
2265         result = cli_rpc_pipe_open(cli, pipe_idx, perr);
2266         if (result == NULL) {
2267                 return NULL;
2268         }
2269
2270         *perr = rpc_pipe_bind(result, PIPE_AUTH_TYPE_NONE, PIPE_AUTH_LEVEL_NONE);
2271         if (!NT_STATUS_IS_OK(*perr)) {
2272                 int lvl = 0;
2273                 if (rpccli_is_pipe_idx(result, PI_DSSETUP)) {
2274                         /* non AD domains just don't have this pipe, avoid
2275                          * level 0 statement in that case - gd */
2276                         lvl = 3;
2277                 }
2278                 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe %s failed with error %s\n",
2279                         cli_get_pipe_name(pipe_idx), nt_errstr(*perr) ));
2280                 TALLOC_FREE(result);
2281                 return NULL;
2282         }
2283
2284         DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine %s and bound anonymously.\n",
2285                         result->pipe_name, cli->desthost ));
2286
2287         return result;
2288 }
2289
2290 /****************************************************************************
2291  Free function for NTLMSSP auth.
2292  ****************************************************************************/
2293
2294 static void cli_ntlmssp_auth_free(struct cli_pipe_auth_data *auth)
2295 {
2296         if (auth->a_u.ntlmssp_state) {
2297                 ntlmssp_end(&auth->a_u.ntlmssp_state);
2298                 auth->a_u.ntlmssp_state = NULL;
2299         }
2300 }
2301
2302 /****************************************************************************
2303  Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
2304  ****************************************************************************/
2305
2306 static struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
2307                                                 int pipe_idx,
2308                                                 enum pipe_auth_type auth_type,
2309                                                 enum pipe_auth_level auth_level,
2310                                                 const char *domain,
2311                                                 const char *username,
2312                                                 const char *password,
2313                                                 NTSTATUS *perr)
2314 {
2315         struct rpc_pipe_client *result;
2316         NTLMSSP_STATE *ntlmssp_state = NULL;
2317
2318         result = cli_rpc_pipe_open(cli, pipe_idx, perr);
2319         if (result == NULL) {
2320                 return NULL;
2321         }
2322         
2323         result->auth.cli_auth_data_free_func = cli_ntlmssp_auth_free;
2324
2325         TALLOC_FREE(result->domain);
2326         TALLOC_FREE(result->user_name);
2327
2328         result->domain = talloc_strdup(result, domain);
2329         result->user_name = talloc_strdup(result, username);
2330
2331         if ((result->domain == NULL) || (result->user_name == NULL)) {
2332                 *perr = NT_STATUS_NO_MEMORY;
2333                 goto err;
2334         }
2335
2336         pwd_set_cleartext(&result->pwd, password);
2337
2338         *perr = ntlmssp_client_start(&ntlmssp_state);
2339         if (!NT_STATUS_IS_OK(*perr)) {
2340                 goto err;
2341         }
2342
2343         result->auth.a_u.ntlmssp_state = ntlmssp_state;
2344
2345         *perr = ntlmssp_set_username(ntlmssp_state, username);
2346         if (!NT_STATUS_IS_OK(*perr)) {
2347                 goto err;
2348         }
2349
2350         *perr = ntlmssp_set_domain(ntlmssp_state, domain);
2351         if (!NT_STATUS_IS_OK(*perr)) {
2352                 goto err;
2353         }
2354
2355         if (cli->pwd.null_pwd) {
2356                 *perr = ntlmssp_set_password(ntlmssp_state, NULL);
2357                 if (!NT_STATUS_IS_OK(*perr)) {
2358                         goto err;
2359                 }
2360         } else {
2361                 *perr = ntlmssp_set_password(ntlmssp_state, password);
2362                 if (!NT_STATUS_IS_OK(*perr)) {
2363                         goto err;
2364                 }
2365         }
2366
2367         /* Turn off sign+seal to allow selected auth level to turn it back on. */
2368         ntlmssp_state->neg_flags &= ~(NTLMSSP_NEGOTIATE_SIGN|NTLMSSP_NEGOTIATE_SEAL);
2369
2370         if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2371                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
2372         } else if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) {
2373                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
2374         }
2375         
2376         *perr = rpc_pipe_bind(result, auth_type, auth_level);
2377         if (!NT_STATUS_IS_OK(*perr)) {
2378                 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
2379                         nt_errstr(*perr) ));
2380                 goto err;
2381         }
2382
2383         DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
2384                 "machine %s and bound NTLMSSP as user %s\\%s.\n",
2385                 result->pipe_name, cli->desthost,
2386                 domain, username ));
2387
2388         return result;
2389
2390   err:
2391
2392         TALLOC_FREE(result);
2393         return NULL;
2394 }
2395
2396 /****************************************************************************
2397  External interface.
2398  Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
2399  ****************************************************************************/
2400
2401 struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
2402                                                 int pipe_idx,
2403                                                 enum pipe_auth_level auth_level,
2404                                                 const char *domain,
2405                                                 const char *username,
2406                                                 const char *password,
2407                                                 NTSTATUS *perr)
2408 {
2409         return cli_rpc_pipe_open_ntlmssp_internal(cli,
2410                                                 pipe_idx,
2411                                                 PIPE_AUTH_TYPE_NTLMSSP,
2412                                                 auth_level,
2413                                                 domain,
2414                                                 username,
2415                                                 password,
2416                                                 perr);
2417 }
2418
2419 /****************************************************************************
2420  External interface.
2421  Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
2422  ****************************************************************************/
2423
2424 struct rpc_pipe_client *cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
2425                                                 int pipe_idx,
2426                                                 enum pipe_auth_level auth_level,
2427                                                 const char *domain,
2428                                                 const char *username,
2429                                                 const char *password,
2430                                                 NTSTATUS *perr)
2431 {
2432         return cli_rpc_pipe_open_ntlmssp_internal(cli,
2433                                                 pipe_idx,
2434                                                 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
2435                                                 auth_level,
2436                                                 domain,
2437                                                 username,
2438                                                 password,
2439                                                 perr);
2440 }
2441
2442 /****************************************************************************
2443   Get a the schannel session key out of an already opened netlogon pipe.
2444  ****************************************************************************/
2445 static bool get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
2446                                             struct cli_state *cli,
2447                                             const char *domain,
2448                                             uint32 *pneg_flags,
2449                                             NTSTATUS *perr)
2450 {
2451         uint32 sec_chan_type = 0;
2452         unsigned char machine_pwd[16];
2453         const char *machine_account;
2454
2455         /* Get the machine account credentials from secrets.tdb. */
2456         if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
2457                                &sec_chan_type))
2458         {
2459                 DEBUG(0, ("get_schannel_session_key: could not fetch "
2460                         "trust account password for domain '%s'\n",
2461                         domain));
2462                 *perr = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2463                 return false;
2464         }
2465
2466         *perr = rpccli_netlogon_setup_creds(netlogon_pipe,
2467                                         cli->desthost, /* server name */
2468                                         domain,        /* domain */
2469                                         global_myname(), /* client name */
2470                                         machine_account, /* machine account name */
2471                                         machine_pwd,
2472                                         sec_chan_type,
2473                                         pneg_flags);
2474
2475         if (!NT_STATUS_IS_OK(*perr)) {
2476                 DEBUG(3,("get_schannel_session_key_common: rpccli_netlogon_setup_creds "
2477                         "failed with result %s to server %s, domain %s, machine account %s.\n",
2478                         nt_errstr(*perr), cli->desthost, domain, machine_account ));
2479                 return false;
2480         }
2481
2482         if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
2483                 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
2484                         cli->desthost));
2485                 *perr = NT_STATUS_INVALID_NETWORK_RESPONSE;
2486                 return false;
2487         }
2488
2489         return true;
2490 }
2491
2492 /****************************************************************************
2493  Open a netlogon pipe and get the schannel session key.
2494  Now exposed to external callers.
2495  ****************************************************************************/
2496
2497
2498 struct rpc_pipe_client *get_schannel_session_key(struct cli_state *cli,
2499                                                         const char *domain,
2500                                                         uint32 *pneg_flags,
2501                                                         NTSTATUS *perr)
2502 {
2503         struct rpc_pipe_client *netlogon_pipe = NULL;
2504
2505         netlogon_pipe = cli_rpc_pipe_open_noauth(cli, PI_NETLOGON, perr);
2506         if (!netlogon_pipe) {
2507                 return NULL;
2508         }
2509
2510         if (!get_schannel_session_key_common(netlogon_pipe, cli, domain,
2511                                              pneg_flags, perr))
2512         {
2513                 TALLOC_FREE(netlogon_pipe);
2514                 return NULL;
2515         }
2516
2517         return netlogon_pipe;
2518 }
2519
2520 /****************************************************************************
2521  External interface.
2522  Open a named pipe to an SMB server and bind using schannel (bind type 68)
2523  using session_key. sign and seal.
2524  ****************************************************************************/
2525
2526 struct rpc_pipe_client *cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
2527                                         int pipe_idx,
2528                                         enum pipe_auth_level auth_level,
2529                                         const char *domain,
2530                                         const struct dcinfo *pdc,
2531                                         NTSTATUS *perr)
2532 {
2533         struct rpc_pipe_client *result;
2534
2535         result = cli_rpc_pipe_open(cli, pipe_idx, perr);
2536         if (result == NULL) {
2537                 return NULL;
2538         }
2539
2540         result->auth.a_u.schannel_auth = TALLOC_ZERO_P(
2541                 result, struct schannel_auth_struct);
2542         if (!result->auth.a_u.schannel_auth) {
2543                 TALLOC_FREE(result);
2544                 *perr = NT_STATUS_NO_MEMORY;
2545                 return NULL;
2546         }
2547
2548         TALLOC_FREE(result->domain);
2549         result->domain = talloc_strdup(result, domain);
2550         if (result->domain == NULL) {
2551                 TALLOC_FREE(result);
2552                 *perr = NT_STATUS_NO_MEMORY;
2553                 return NULL;
2554         }
2555
2556         memcpy(result->auth.a_u.schannel_auth->sess_key, pdc->sess_key, 16);
2557
2558         *perr = rpc_pipe_bind(result, PIPE_AUTH_TYPE_SCHANNEL, auth_level);
2559         if (!NT_STATUS_IS_OK(*perr)) {
2560                 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: cli_rpc_pipe_bind failed with error %s\n",
2561                         nt_errstr(*perr) ));
2562                 TALLOC_FREE(result);
2563                 return NULL;
2564         }
2565
2566         /* The credentials on a new netlogon pipe are the ones we are passed in - copy them over. */
2567         if (result->dc) {
2568                 *result->dc = *pdc;
2569         }
2570
2571         DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
2572                 "for domain %s "
2573                 "and bound using schannel.\n",
2574                 result->pipe_name, cli->desthost, domain ));
2575
2576         return result;
2577 }
2578
2579 /****************************************************************************
2580  Open a named pipe to an SMB server and bind using schannel (bind type 68).
2581  Fetch the session key ourselves using a temporary netlogon pipe. This
2582  version uses an ntlmssp auth bound netlogon pipe to get the key.
2583  ****************************************************************************/
2584
2585 static struct rpc_pipe_client *get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
2586                                                         const char *domain,
2587                                                         const char *username,
2588                                                         const char *password,
2589                                                         uint32 *pneg_flags,
2590                                                         NTSTATUS *perr)
2591 {
2592         struct rpc_pipe_client *netlogon_pipe = NULL;
2593
2594         netlogon_pipe = cli_rpc_pipe_open_spnego_ntlmssp(cli, PI_NETLOGON, PIPE_AUTH_LEVEL_PRIVACY, domain, username, password, perr);
2595         if (!netlogon_pipe) {
2596                 return NULL;
2597         }
2598
2599         if (!get_schannel_session_key_common(netlogon_pipe, cli, domain,
2600                                              pneg_flags, perr))
2601         {
2602                 TALLOC_FREE(netlogon_pipe);
2603                 return NULL;
2604         }
2605
2606         return netlogon_pipe;
2607 }
2608
2609 /****************************************************************************
2610  Open a named pipe to an SMB server and bind using schannel (bind type 68).
2611  Fetch the session key ourselves using a temporary netlogon pipe. This version
2612  uses an ntlmssp bind to get the session key.
2613  ****************************************************************************/
2614
2615 struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
2616                                                 int pipe_idx,
2617                                                 enum pipe_auth_level auth_level,
2618                                                 const char *domain,
2619                                                 const char *username,
2620                                                 const char *password,
2621                                                 NTSTATUS *perr)
2622 {
2623         uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
2624         struct rpc_pipe_client *netlogon_pipe = NULL;
2625         struct rpc_pipe_client *result = NULL;
2626
2627         netlogon_pipe = get_schannel_session_key_auth_ntlmssp(cli, domain, username,
2628                                                         password, &neg_flags, perr);
2629         if (!netlogon_pipe) {
2630                 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
2631                         "key from server %s for domain %s.\n",
2632                         cli->desthost, domain ));
2633                 return NULL;
2634         }
2635
2636         result = cli_rpc_pipe_open_schannel_with_key(cli, pipe_idx,
2637                                 auth_level,
2638                                 domain, netlogon_pipe->dc, perr);
2639
2640         /* Now we've bound using the session key we can close the netlog pipe. */
2641         TALLOC_FREE(netlogon_pipe);
2642
2643         return result;
2644 }
2645
2646 /****************************************************************************
2647  Open a named pipe to an SMB server and bind using schannel (bind type 68).
2648  Fetch the session key ourselves using a temporary netlogon pipe.
2649  ****************************************************************************/
2650
2651 struct rpc_pipe_client *cli_rpc_pipe_open_schannel(struct cli_state *cli,
2652                                                 int pipe_idx,
2653                                                 enum pipe_auth_level auth_level,
2654                                                 const char *domain,
2655                                                 NTSTATUS *perr)
2656 {
2657         uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
2658         struct rpc_pipe_client *netlogon_pipe = NULL;
2659         struct rpc_pipe_client *result = NULL;
2660
2661         netlogon_pipe = get_schannel_session_key(cli, domain, &neg_flags, perr);
2662         if (!netlogon_pipe) {
2663                 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
2664                         "key from server %s for domain %s.\n",
2665                         cli->desthost, domain ));
2666                 return NULL;
2667         }
2668
2669         result = cli_rpc_pipe_open_schannel_with_key(cli, pipe_idx,
2670                                 auth_level,
2671                                 domain, netlogon_pipe->dc, perr);
2672
2673         /* Now we've bound using the session key we can close the netlog pipe. */
2674         TALLOC_FREE(netlogon_pipe);
2675
2676         return result;
2677 }
2678
2679 #ifdef HAVE_KRB5
2680
2681 /****************************************************************************
2682  Free function for the kerberos spcific data.
2683  ****************************************************************************/
2684
2685 static void kerberos_auth_struct_free(struct cli_pipe_auth_data *a)
2686 {
2687         data_blob_free(&a->a_u.kerberos_auth->session_key);
2688 }
2689
2690 #endif
2691
2692 /****************************************************************************
2693  Open a named pipe to an SMB server and bind using krb5 (bind type 16).
2694  The idea is this can be called with service_princ, username and password all
2695  NULL so long as the caller has a TGT.
2696  ****************************************************************************/
2697
2698 struct rpc_pipe_client *cli_rpc_pipe_open_krb5(struct cli_state *cli,
2699                                                 int pipe_idx,
2700                                                 enum pipe_auth_level auth_level,
2701                                                 const char *service_princ,
2702                                                 const char *username,
2703                                                 const char *password,
2704                                                 NTSTATUS *perr)
2705 {
2706 #ifdef HAVE_KRB5
2707         struct rpc_pipe_client *result;
2708
2709         result = cli_rpc_pipe_open(cli, pipe_idx, perr);
2710         if (result == NULL) {
2711                 return NULL;
2712         }
2713
2714         /* Default service principal is "desthost$@realm" */
2715         if (!service_princ) {
2716                 service_princ = talloc_asprintf(result, "%s$@%s",
2717                                                 cli->desthost, lp_realm() );
2718                 if (!service_princ) {
2719                         TALLOC_FREE(result);
2720                         return NULL;
2721                 }
2722         }
2723
2724         /* Only get a new TGT if username/password are given. */
2725         if (username && password) {
2726                 int ret = kerberos_kinit_password(username, password, 0, NULL);
2727                 if (ret) {
2728                         TALLOC_FREE(result);
2729                         return NULL;
2730                 }
2731         }
2732
2733         result->auth.a_u.kerberos_auth = TALLOC_ZERO_P(
2734                 result, struct kerberos_auth_struct);
2735         if (!result->auth.a_u.kerberos_auth) {
2736                 TALLOC_FREE(result);
2737                 *perr = NT_STATUS_NO_MEMORY;
2738                 return NULL;
2739         }
2740
2741         result->auth.a_u.kerberos_auth->service_principal = service_princ;
2742         result->auth.cli_auth_data_free_func = kerberos_auth_struct_free;
2743
2744         *perr = rpc_pipe_bind(result, PIPE_AUTH_TYPE_KRB5, auth_level);
2745         if (!NT_STATUS_IS_OK(*perr)) {
2746                 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed with error %s\n",
2747                         nt_errstr(*perr) ));
2748                 TALLOC_FREE(result);
2749                 return NULL;
2750         }
2751
2752         return result;
2753 #else
2754         DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
2755         return NULL;
2756 #endif
2757 }