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