a659785896b1653863e8e3fe31212aec0df15f28
[ira/wip.git] / source3 / rpc_client / cli_pipe.c
1 /* 
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Largely rewritten by Jeremy Allison             2005.
5  *  
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 3 of the License, or
9  *  (at your option) any later version.
10  *  
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *  
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, 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 = (unsigned char *)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 = (unsigned char *)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                                 dcerpc_errstr(NT_STATUS_V(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 = prs_data_p(data);
748         uint32 data_len = prs_offset(data);
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                 SAFE_FREE(rparam);
793                 SAFE_FREE(prdata);
794                 goto err;
795         }
796
797         /* Throw away returned params - we know we won't use them. */
798
799         SAFE_FREE(rparam);
800
801         if (prdata == NULL) {
802                 DEBUG(3,("rpc_api_pipe: Remote machine %s pipe %s "
803                         "fnum 0x%x failed to return data.\n",
804                         cli->cli->desthost,
805                         cli->pipe_name,
806                         (unsigned int)cli->fnum));
807                 /* Yes - some calls can truely return no data... */
808                 prs_mem_free(&current_pdu);
809                 return NT_STATUS_OK;
810         }
811
812         /*
813          * Give this memory as dynamic to the current pdu.
814          */
815
816         prs_give_memory(&current_pdu, prdata, rdata_len, True);
817
818         /* Ensure we can mess with the return prs_struct. */
819         SMB_ASSERT(UNMARSHALLING(rbuf));
820         SMB_ASSERT(prs_data_size(rbuf) == 0);
821
822         /* Make rbuf dynamic with no memory. */
823         prs_give_memory(rbuf, 0, 0, True);
824
825         while(1) {
826                 RPC_HDR rhdr;
827                 char *ret_data;
828                 uint32 ret_data_len;
829
830                 /* Ensure we have enough data for a pdu. */
831                 ret = cli_pipe_get_current_pdu(cli, &rhdr, &current_pdu);
832                 if (!NT_STATUS_IS_OK(ret)) {
833                         goto err;
834                 }
835
836                 /* We pass in rbuf here so if the alloc hint is set correctly 
837                    we can set the output size and avoid reallocs. */
838
839                 ret = cli_pipe_validate_current_pdu(cli, &rhdr, &current_pdu, expected_pkt_type,
840                                 &ret_data, &ret_data_len, rbuf);
841
842                 DEBUG(10,("rpc_api_pipe: got PDU len of %u at offset %u\n",
843                         prs_data_size(&current_pdu), current_rbuf_offset ));
844
845                 if (!NT_STATUS_IS_OK(ret)) {
846                         goto err;
847                 }
848
849                 if ((rhdr.flags & RPC_FLG_FIRST)) {
850                         if (rhdr.pack_type[0] == 0) {
851                                 /* Set the data type correctly for big-endian data on the first packet. */
852                                 DEBUG(10,("rpc_api_pipe: On machine %s pipe %s fnum 0x%x "
853                                         "PDU data format is big-endian.\n",
854                                         cli->cli->desthost,
855                                         cli->pipe_name,
856                                         (unsigned int)cli->fnum));
857
858                                 prs_set_endian_data(rbuf, RPC_BIG_ENDIAN);
859                         } else {
860                                 /* Check endianness on subsequent packets. */
861                                 if (current_pdu.bigendian_data != rbuf->bigendian_data) {
862                                         DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to %s\n",
863                                                 rbuf->bigendian_data ? "big" : "little",
864                                                 current_pdu.bigendian_data ? "big" : "little" ));
865                                         ret = NT_STATUS_INVALID_PARAMETER;
866                                         goto err;
867                                 }
868                         }
869                 }
870
871                 /* Now copy the data portion out of the pdu into rbuf. */
872                 if (!prs_force_grow(rbuf, ret_data_len)) {
873                         ret = NT_STATUS_NO_MEMORY;
874                         goto err;
875                 }
876                 memcpy(prs_data_p(rbuf)+current_rbuf_offset, ret_data, (size_t)ret_data_len);
877                 current_rbuf_offset += ret_data_len;
878
879                 /* See if we've finished with all the data in current_pdu yet ? */
880                 ret = cli_pipe_reset_current_pdu(cli, &rhdr, &current_pdu);
881                 if (!NT_STATUS_IS_OK(ret)) {
882                         goto err;
883                 }
884
885                 if (rhdr.flags & RPC_FLG_LAST) {
886                         break; /* We're done. */
887                 }
888         }
889
890         DEBUG(10,("rpc_api_pipe: Remote machine %s pipe %s fnum 0x%x returned %u bytes.\n",
891                 cli->cli->desthost,
892                 cli->pipe_name,
893                 (unsigned int)cli->fnum,
894                 (unsigned int)prs_data_size(rbuf) ));
895
896         prs_mem_free(&current_pdu);
897         return NT_STATUS_OK;
898
899   err:
900
901         prs_mem_free(&current_pdu);
902         prs_mem_free(rbuf);
903         return ret;
904 }
905
906 /*******************************************************************
907  Creates krb5 auth bind.
908  ********************************************************************/
909
910 static NTSTATUS create_krb5_auth_bind_req( struct rpc_pipe_client *cli,
911                                                 enum pipe_auth_level auth_level,
912                                                 RPC_HDR_AUTH *pauth_out,
913                                                 prs_struct *auth_data)
914 {
915 #ifdef HAVE_KRB5
916         int ret;
917         struct kerberos_auth_struct *a = cli->auth.a_u.kerberos_auth;
918         DATA_BLOB tkt = data_blob_null;
919         DATA_BLOB tkt_wrapped = data_blob_null;
920
921         /* We may change the pad length before marshalling. */
922         init_rpc_hdr_auth(pauth_out, RPC_KRB5_AUTH_TYPE, (int)auth_level, 0, 1);
923
924         DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
925                 a->service_principal ));
926
927         /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
928
929         ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
930                         &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL);
931
932         if (ret) {
933                 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
934                         "failed with %s\n",
935                         a->service_principal,
936                         error_message(ret) ));
937
938                 data_blob_free(&tkt);
939                 prs_mem_free(auth_data);
940                 return NT_STATUS_INVALID_PARAMETER;
941         }
942
943         /* wrap that up in a nice GSS-API wrapping */
944         tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
945
946         data_blob_free(&tkt);
947
948         /* Auth len in the rpc header doesn't include auth_header. */
949         if (!prs_copy_data_in(auth_data, (char *)tkt_wrapped.data, tkt_wrapped.length)) {
950                 data_blob_free(&tkt_wrapped);
951                 prs_mem_free(auth_data);
952                 return NT_STATUS_NO_MEMORY;
953         }
954
955         DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
956         dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
957
958         data_blob_free(&tkt_wrapped);
959         return NT_STATUS_OK;
960 #else
961         return NT_STATUS_INVALID_PARAMETER;
962 #endif
963 }
964
965 /*******************************************************************
966  Creates SPNEGO NTLMSSP auth bind.
967  ********************************************************************/
968
969 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
970                                                 enum pipe_auth_level auth_level,
971                                                 RPC_HDR_AUTH *pauth_out,
972                                                 prs_struct *auth_data)
973 {
974         NTSTATUS nt_status;
975         DATA_BLOB null_blob = data_blob_null;
976         DATA_BLOB request = data_blob_null;
977         DATA_BLOB spnego_msg = data_blob_null;
978
979         /* We may change the pad length before marshalling. */
980         init_rpc_hdr_auth(pauth_out, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
981
982         DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
983         nt_status = ntlmssp_update(cli->auth.a_u.ntlmssp_state,
984                                         null_blob,
985                                         &request);
986
987         if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
988                 data_blob_free(&request);
989                 prs_mem_free(auth_data);
990                 return nt_status;
991         }
992
993         /* Wrap this in SPNEGO. */
994         spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
995
996         data_blob_free(&request);
997
998         /* Auth len in the rpc header doesn't include auth_header. */
999         if (!prs_copy_data_in(auth_data, (char *)spnego_msg.data, spnego_msg.length)) {
1000                 data_blob_free(&spnego_msg);
1001                 prs_mem_free(auth_data);
1002                 return NT_STATUS_NO_MEMORY;
1003         }
1004
1005         DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1006         dump_data(5, spnego_msg.data, spnego_msg.length);
1007
1008         data_blob_free(&spnego_msg);
1009         return NT_STATUS_OK;
1010 }
1011
1012 /*******************************************************************
1013  Creates NTLMSSP auth bind.
1014  ********************************************************************/
1015
1016 static NTSTATUS create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1017                                                 enum pipe_auth_level auth_level,
1018                                                 RPC_HDR_AUTH *pauth_out,
1019                                                 prs_struct *auth_data)
1020 {
1021         NTSTATUS nt_status;
1022         DATA_BLOB null_blob = data_blob_null;
1023         DATA_BLOB request = data_blob_null;
1024
1025         /* We may change the pad length before marshalling. */
1026         init_rpc_hdr_auth(pauth_out, RPC_NTLMSSP_AUTH_TYPE, (int)auth_level, 0, 1);
1027
1028         DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1029         nt_status = ntlmssp_update(cli->auth.a_u.ntlmssp_state,
1030                                         null_blob,
1031                                         &request);
1032
1033         if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1034                 data_blob_free(&request);
1035                 prs_mem_free(auth_data);
1036                 return nt_status;
1037         }
1038
1039         /* Auth len in the rpc header doesn't include auth_header. */
1040         if (!prs_copy_data_in(auth_data, (char *)request.data, request.length)) {
1041                 data_blob_free(&request);
1042                 prs_mem_free(auth_data);
1043                 return NT_STATUS_NO_MEMORY;
1044         }
1045
1046         DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1047         dump_data(5, request.data, request.length);
1048
1049         data_blob_free(&request);
1050         return NT_STATUS_OK;
1051 }
1052
1053 /*******************************************************************
1054  Creates schannel auth bind.
1055  ********************************************************************/
1056
1057 static NTSTATUS create_schannel_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1058                                                 enum pipe_auth_level auth_level,
1059                                                 RPC_HDR_AUTH *pauth_out,
1060                                                 prs_struct *auth_data)
1061 {
1062         RPC_AUTH_SCHANNEL_NEG schannel_neg;
1063
1064         /* We may change the pad length before marshalling. */
1065         init_rpc_hdr_auth(pauth_out, RPC_SCHANNEL_AUTH_TYPE, (int)auth_level, 0, 1);
1066
1067         /* Use lp_workgroup() if domain not specified */
1068
1069         if (!cli->domain || !cli->domain[0]) {
1070                 cli->domain = lp_workgroup();
1071         }
1072
1073         init_rpc_auth_schannel_neg(&schannel_neg, cli->domain, global_myname());
1074
1075         /*
1076          * Now marshall the data into the auth parse_struct.
1077          */
1078
1079         if(!smb_io_rpc_auth_schannel_neg("schannel_neg",
1080                                        &schannel_neg, auth_data, 0)) {
1081                 DEBUG(0,("Failed to marshall RPC_AUTH_SCHANNEL_NEG.\n"));
1082                 prs_mem_free(auth_data);
1083                 return NT_STATUS_NO_MEMORY;
1084         }
1085
1086         return NT_STATUS_OK;
1087 }
1088
1089 /*******************************************************************
1090  Creates the internals of a DCE/RPC bind request or alter context PDU.
1091  ********************************************************************/
1092
1093 static NTSTATUS create_bind_or_alt_ctx_internal(enum RPC_PKT_TYPE pkt_type,
1094                                                 prs_struct *rpc_out, 
1095                                                 uint32 rpc_call_id,
1096                                                 RPC_IFACE *abstract,
1097                                                 RPC_IFACE *transfer,
1098                                                 RPC_HDR_AUTH *phdr_auth,
1099                                                 prs_struct *pauth_info)
1100 {
1101         RPC_HDR hdr;
1102         RPC_HDR_RB hdr_rb;
1103         RPC_CONTEXT rpc_ctx;
1104         uint16 auth_len = prs_offset(pauth_info);
1105         uint8 ss_padding_len = 0;
1106         uint16 frag_len = 0;
1107
1108         /* create the RPC context. */
1109         init_rpc_context(&rpc_ctx, 0 /* context id */, abstract, transfer);
1110
1111         /* create the bind request RPC_HDR_RB */
1112         init_rpc_hdr_rb(&hdr_rb, RPC_MAX_PDU_FRAG_LEN, RPC_MAX_PDU_FRAG_LEN, 0x0, &rpc_ctx);
1113
1114         /* Start building the frag length. */
1115         frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1116
1117         /* Do we need to pad ? */
1118         if (auth_len) {
1119                 uint16 data_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1120                 if (data_len % 8) {
1121                         ss_padding_len = 8 - (data_len % 8);
1122                         phdr_auth->auth_pad_len = ss_padding_len;
1123                 }
1124                 frag_len += RPC_HDR_AUTH_LEN + auth_len + ss_padding_len;
1125         }
1126
1127         /* Create the request RPC_HDR */
1128         init_rpc_hdr(&hdr, pkt_type, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id, frag_len, auth_len);
1129
1130         /* Marshall the RPC header */
1131         if(!smb_io_rpc_hdr("hdr"   , &hdr, rpc_out, 0)) {
1132                 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR.\n"));
1133                 return NT_STATUS_NO_MEMORY;
1134         }
1135
1136         /* Marshall the bind request data */
1137         if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_out, 0)) {
1138                 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1139                 return NT_STATUS_NO_MEMORY;
1140         }
1141
1142         /*
1143          * Grow the outgoing buffer to store any auth info.
1144          */
1145
1146         if(auth_len != 0) {
1147                 if (ss_padding_len) {
1148                         char pad[8];
1149                         memset(pad, '\0', 8);
1150                         if (!prs_copy_data_in(rpc_out, pad, ss_padding_len)) {
1151                                 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n"));
1152                                 return NT_STATUS_NO_MEMORY;
1153                         }
1154                 }
1155
1156                 if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth, rpc_out, 0)) {
1157                         DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n"));
1158                         return NT_STATUS_NO_MEMORY;
1159                 }
1160
1161
1162                 if(!prs_append_prs_data( rpc_out, pauth_info)) {
1163                         DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n"));
1164                         return NT_STATUS_NO_MEMORY;
1165                 }
1166         }
1167
1168         return NT_STATUS_OK;
1169 }
1170
1171 /*******************************************************************
1172  Creates a DCE/RPC bind request.
1173  ********************************************************************/
1174
1175 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
1176                                 prs_struct *rpc_out, 
1177                                 uint32 rpc_call_id,
1178                                 RPC_IFACE *abstract, RPC_IFACE *transfer,
1179                                 enum pipe_auth_type auth_type,
1180                                 enum pipe_auth_level auth_level)
1181 {
1182         RPC_HDR_AUTH hdr_auth;
1183         prs_struct auth_info;
1184         NTSTATUS ret = NT_STATUS_OK;
1185
1186         ZERO_STRUCT(hdr_auth);
1187         prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL);
1188
1189         switch (auth_type) {
1190                 case PIPE_AUTH_TYPE_SCHANNEL:
1191                         ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1192                         if (!NT_STATUS_IS_OK(ret)) {
1193                                 prs_mem_free(&auth_info);
1194                                 return ret;
1195                         }
1196                         break;
1197
1198                 case PIPE_AUTH_TYPE_NTLMSSP:
1199                         ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1200                         if (!NT_STATUS_IS_OK(ret)) {
1201                                 prs_mem_free(&auth_info);
1202                                 return ret;
1203                         }
1204                         break;
1205
1206                 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1207                         ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1208                         if (!NT_STATUS_IS_OK(ret)) {
1209                                 prs_mem_free(&auth_info);
1210                                 return ret;
1211                         }
1212                         break;
1213
1214                 case PIPE_AUTH_TYPE_KRB5:
1215                         ret = create_krb5_auth_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1216                         if (!NT_STATUS_IS_OK(ret)) {
1217                                 prs_mem_free(&auth_info);
1218                                 return ret;
1219                         }
1220                         break;
1221
1222                 case PIPE_AUTH_TYPE_NONE:
1223                         break;
1224
1225                 default:
1226                         /* "Can't" happen. */
1227                         return NT_STATUS_INVALID_INFO_CLASS;
1228         }
1229
1230         ret = create_bind_or_alt_ctx_internal(RPC_BIND,
1231                                                 rpc_out, 
1232                                                 rpc_call_id,
1233                                                 abstract,
1234                                                 transfer,
1235                                                 &hdr_auth,
1236                                                 &auth_info);
1237
1238         prs_mem_free(&auth_info);
1239         return ret;
1240 }
1241
1242 /*******************************************************************
1243  Create and add the NTLMSSP sign/seal auth header and data.
1244  ********************************************************************/
1245
1246 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
1247                                         RPC_HDR *phdr,
1248                                         uint32 ss_padding_len,
1249                                         prs_struct *outgoing_pdu)
1250 {
1251         RPC_HDR_AUTH auth_info;
1252         NTSTATUS status;
1253         DATA_BLOB auth_blob = data_blob_null;
1254         uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1255
1256         if (!cli->auth.a_u.ntlmssp_state) {
1257                 return NT_STATUS_INVALID_PARAMETER;
1258         }
1259
1260         /* Init and marshall the auth header. */
1261         init_rpc_hdr_auth(&auth_info,
1262                         map_pipe_auth_type_to_rpc_auth_type(cli->auth.auth_type),
1263                         cli->auth.auth_level,
1264                         ss_padding_len,
1265                         1 /* context id. */);
1266
1267         if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1268                 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1269                 data_blob_free(&auth_blob);
1270                 return NT_STATUS_NO_MEMORY;
1271         }
1272
1273         switch (cli->auth.auth_level) {
1274                 case PIPE_AUTH_LEVEL_PRIVACY:
1275                         /* Data portion is encrypted. */
1276                         status = ntlmssp_seal_packet(cli->auth.a_u.ntlmssp_state,
1277                                         (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1278                                         data_and_pad_len,
1279                                         (unsigned char *)prs_data_p(outgoing_pdu),
1280                                         (size_t)prs_offset(outgoing_pdu),
1281                                         &auth_blob);
1282                         if (!NT_STATUS_IS_OK(status)) {
1283                                 data_blob_free(&auth_blob);
1284                                 return status;
1285                         }
1286                         break;
1287
1288                 case PIPE_AUTH_LEVEL_INTEGRITY:
1289                         /* Data is signed. */
1290                         status = ntlmssp_sign_packet(cli->auth.a_u.ntlmssp_state,
1291                                         (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1292                                         data_and_pad_len,
1293                                         (unsigned char *)prs_data_p(outgoing_pdu),
1294                                         (size_t)prs_offset(outgoing_pdu),
1295                                         &auth_blob);
1296                         if (!NT_STATUS_IS_OK(status)) {
1297                                 data_blob_free(&auth_blob);
1298                                 return status;
1299                         }
1300                         break;
1301
1302                 default:
1303                         /* Can't happen. */
1304                         smb_panic("bad auth level");
1305                         /* Notreached. */
1306                         return NT_STATUS_INVALID_PARAMETER;
1307         }
1308
1309         /* Finally marshall the blob. */
1310                                                                                                        
1311         if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {
1312                 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
1313                         (unsigned int)NTLMSSP_SIG_SIZE));
1314                 data_blob_free(&auth_blob);
1315                 return NT_STATUS_NO_MEMORY;
1316         }
1317                                                                                                                                 
1318         data_blob_free(&auth_blob);
1319         return NT_STATUS_OK;
1320 }
1321
1322 /*******************************************************************
1323  Create and add the schannel sign/seal auth header and data.
1324  ********************************************************************/
1325
1326 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
1327                                         RPC_HDR *phdr,
1328                                         uint32 ss_padding_len,
1329                                         prs_struct *outgoing_pdu)
1330 {
1331         RPC_HDR_AUTH auth_info;
1332         RPC_AUTH_SCHANNEL_CHK verf;
1333         struct schannel_auth_struct *sas = cli->auth.a_u.schannel_auth;
1334         char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
1335         size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1336
1337         if (!sas) {
1338                 return NT_STATUS_INVALID_PARAMETER;
1339         }
1340
1341         /* Init and marshall the auth header. */
1342         init_rpc_hdr_auth(&auth_info,
1343                         map_pipe_auth_type_to_rpc_auth_type(cli->auth.auth_type),
1344                         cli->auth.auth_level,
1345                         ss_padding_len,
1346                         1 /* context id. */);
1347
1348         if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1349                 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1350                 return NT_STATUS_NO_MEMORY;
1351         }
1352
1353         switch (cli->auth.auth_level) {
1354                 case PIPE_AUTH_LEVEL_PRIVACY:
1355                 case PIPE_AUTH_LEVEL_INTEGRITY:
1356                         DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
1357                                 sas->seq_num));
1358
1359                         schannel_encode(sas,
1360                                         cli->auth.auth_level,
1361                                         SENDER_IS_INITIATOR,
1362                                         &verf,
1363                                         data_p,
1364                                         data_and_pad_len);
1365
1366                         sas->seq_num++;
1367                         break;
1368
1369                 default:
1370                         /* Can't happen. */
1371                         smb_panic("bad auth level");
1372                         /* Notreached. */
1373                         return NT_STATUS_INVALID_PARAMETER;
1374         }
1375
1376         /* Finally marshall the blob. */
1377         smb_io_rpc_auth_schannel_chk("",
1378                         RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN,
1379                         &verf,
1380                         outgoing_pdu,
1381                         0);
1382                                                                                                
1383         return NT_STATUS_OK;
1384 }
1385
1386 /*******************************************************************
1387  Calculate how much data we're going to send in this packet, also
1388  work out any sign/seal padding length.
1389  ********************************************************************/
1390
1391 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
1392                                         uint32 data_left,
1393                                         uint16 *p_frag_len,
1394                                         uint16 *p_auth_len,
1395                                         uint32 *p_ss_padding)
1396 {
1397         uint32 data_space, data_len;
1398
1399         switch (cli->auth.auth_level) {
1400                 case PIPE_AUTH_LEVEL_NONE:
1401                 case PIPE_AUTH_LEVEL_CONNECT:
1402                         data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
1403                         data_len = MIN(data_space, data_left);
1404                         *p_ss_padding = 0;
1405                         *p_auth_len = 0;
1406                         *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
1407                         return data_len;
1408
1409                 case PIPE_AUTH_LEVEL_INTEGRITY:
1410                 case PIPE_AUTH_LEVEL_PRIVACY:
1411                         /* Treat the same for all authenticated rpc requests. */
1412                         switch(cli->auth.auth_type) {
1413                                 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1414                                 case PIPE_AUTH_TYPE_NTLMSSP:
1415                                         *p_auth_len = NTLMSSP_SIG_SIZE;
1416                                         break;
1417                                 case PIPE_AUTH_TYPE_SCHANNEL:
1418                                         *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
1419                                         break;
1420                                 default:
1421                                         smb_panic("bad auth type");
1422                                         break;
1423                         }
1424
1425                         data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
1426                                                 RPC_HDR_AUTH_LEN - *p_auth_len;
1427
1428                         data_len = MIN(data_space, data_left);
1429                         if (data_len % 8) {
1430                                 *p_ss_padding = 8 - (data_len % 8);
1431                         }
1432                         *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN +                /* Normal headers. */
1433                                         data_len + *p_ss_padding +              /* data plus padding. */
1434                                         RPC_HDR_AUTH_LEN + *p_auth_len;         /* Auth header and auth data. */
1435                         return data_len;
1436
1437                 default:
1438                         smb_panic("bad auth level");
1439                         /* Notreached. */
1440                         return 0;
1441         }
1442 }
1443
1444 /*******************************************************************
1445  External interface.
1446  Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1447  Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1448  and deals with signing/sealing details.
1449  ********************************************************************/
1450
1451 NTSTATUS rpc_api_pipe_req(struct rpc_pipe_client *cli,
1452                         uint8 op_num,
1453                         prs_struct *in_data,
1454                         prs_struct *out_data)
1455 {
1456         NTSTATUS ret;
1457         uint32 data_left = prs_offset(in_data);
1458         uint32 alloc_hint = prs_offset(in_data);
1459         uint32 data_sent_thistime = 0;
1460         uint32 current_data_offset = 0;
1461         uint32 call_id = get_rpc_call_id();
1462         char pad[8];
1463         prs_struct outgoing_pdu;
1464
1465         memset(pad, '\0', 8);
1466
1467         if (cli->max_xmit_frag < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
1468                 /* Server is screwed up ! */
1469                 return NT_STATUS_INVALID_PARAMETER;
1470         }
1471
1472         prs_init(&outgoing_pdu, cli->max_xmit_frag, prs_get_mem_context(in_data), MARSHALL);
1473
1474         while (1) {
1475                 RPC_HDR hdr;
1476                 RPC_HDR_REQ hdr_req;
1477                 uint16 auth_len = 0;
1478                 uint16 frag_len = 0;
1479                 uint8 flags = 0;
1480                 uint32 ss_padding = 0;
1481
1482                 data_sent_thistime = calculate_data_len_tosend(cli, data_left,
1483                                                 &frag_len, &auth_len, &ss_padding);
1484
1485                 if (current_data_offset == 0) {
1486                         flags = RPC_FLG_FIRST;
1487                 }
1488
1489                 if (data_sent_thistime == data_left) {
1490                         flags |= RPC_FLG_LAST;
1491                 }
1492
1493                 /* Create and marshall the header and request header. */
1494                 init_rpc_hdr(&hdr, RPC_REQUEST, flags, call_id, frag_len, auth_len);
1495
1496                 if(!smb_io_rpc_hdr("hdr    ", &hdr, &outgoing_pdu, 0)) {
1497                         prs_mem_free(&outgoing_pdu);
1498                         return NT_STATUS_NO_MEMORY;
1499                 }
1500
1501                 /* Create the rpc request RPC_HDR_REQ */
1502                 init_rpc_hdr_req(&hdr_req, alloc_hint, op_num);
1503
1504                 if(!smb_io_rpc_hdr_req("hdr_req", &hdr_req, &outgoing_pdu, 0)) {
1505                         prs_mem_free(&outgoing_pdu);
1506                         return NT_STATUS_NO_MEMORY;
1507                 }
1508
1509                 /* Copy in the data, plus any ss padding. */
1510                 if (!prs_append_some_prs_data(&outgoing_pdu, in_data, current_data_offset, data_sent_thistime)) {
1511                         prs_mem_free(&outgoing_pdu);
1512                         return NT_STATUS_NO_MEMORY;
1513                 }
1514
1515                 /* Copy the sign/seal padding data. */
1516                 if (ss_padding) {
1517                         if (!prs_copy_data_in(&outgoing_pdu, pad, ss_padding)) {
1518                                 prs_mem_free(&outgoing_pdu);
1519                                 return NT_STATUS_NO_MEMORY;
1520                         }
1521                 }
1522
1523                 /* Generate any auth sign/seal and add the auth footer. */
1524                 if (auth_len) {
1525                         switch (cli->auth.auth_type) {
1526                                 case PIPE_AUTH_TYPE_NONE:
1527                                         break;
1528                                 case PIPE_AUTH_TYPE_NTLMSSP:
1529                                 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1530                                         ret = add_ntlmssp_auth_footer(cli, &hdr, ss_padding, &outgoing_pdu);
1531                                         if (!NT_STATUS_IS_OK(ret)) {
1532                                                 prs_mem_free(&outgoing_pdu);
1533                                                 return ret;
1534                                         }
1535                                         break;
1536                                 case PIPE_AUTH_TYPE_SCHANNEL:
1537                                         ret = add_schannel_auth_footer(cli, &hdr, ss_padding, &outgoing_pdu);
1538                                         if (!NT_STATUS_IS_OK(ret)) {
1539                                                 prs_mem_free(&outgoing_pdu);
1540                                                 return ret;
1541                                         }
1542                                         break;
1543                                 default:
1544                                         smb_panic("bad auth type");
1545                                         break; /* notreached */
1546                         }
1547                 }
1548
1549                 /* Actually send the packet. */
1550                 if (flags & RPC_FLG_LAST) {
1551                         /* Last packet - send the data, get the reply and return. */
1552                         ret = rpc_api_pipe(cli, &outgoing_pdu, out_data, RPC_RESPONSE);
1553                         prs_mem_free(&outgoing_pdu);
1554
1555                         
1556                         if (DEBUGLEVEL >= 50) {
1557                                 pstring dump_name;
1558                                 /* Also capture received data */
1559                                 slprintf(dump_name, sizeof(dump_name) - 1, "%s/reply_%s_%d",
1560                                         dyn_LOGFILEBASE, cli->pipe_name, op_num);
1561                                 prs_dump(dump_name, op_num, out_data);
1562                         }
1563
1564                         return ret;
1565                 } else {
1566                         /* More packets to come - write and continue. */
1567                         ssize_t num_written = cli_write(cli->cli, cli->fnum, 8, /* 8 means message mode. */
1568                                                         prs_data_p(&outgoing_pdu),
1569                                                         (off_t)0,
1570                                                         (size_t)hdr.frag_len);
1571
1572                         if (num_written != hdr.frag_len) {
1573                                 prs_mem_free(&outgoing_pdu);
1574                                 return cli_get_nt_error(cli->cli);
1575                         }
1576                 }
1577
1578                 current_data_offset += data_sent_thistime;
1579                 data_left -= data_sent_thistime;
1580
1581                 /* Reset the marshalling position back to zero. */
1582                 if (!prs_set_offset(&outgoing_pdu, 0)) {
1583                         prs_mem_free(&outgoing_pdu);
1584                         return NT_STATUS_NO_MEMORY;
1585                 }
1586         }
1587 }
1588 #if 0
1589 /****************************************************************************
1590  Set the handle state.
1591 ****************************************************************************/
1592
1593 static BOOL rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
1594                                    const char *pipe_name, uint16 device_state)
1595 {
1596         BOOL state_set = False;
1597         char param[2];
1598         uint16 setup[2]; /* only need 2 uint16 setup parameters */
1599         char *rparam = NULL;
1600         char *rdata = NULL;
1601         uint32 rparam_len, rdata_len;
1602
1603         if (pipe_name == NULL)
1604                 return False;
1605
1606         DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
1607                  cli->fnum, pipe_name, device_state));
1608
1609         /* create parameters: device state */
1610         SSVAL(param, 0, device_state);
1611
1612         /* create setup parameters. */
1613         setup[0] = 0x0001; 
1614         setup[1] = cli->fnum; /* pipe file handle.  got this from an SMBOpenX. */
1615
1616         /* send the data on \PIPE\ */
1617         if (cli_api_pipe(cli->cli, "\\PIPE\\",
1618                     setup, 2, 0,                /* setup, length, max */
1619                     param, 2, 0,                /* param, length, max */
1620                     NULL, 0, 1024,              /* data, length, max */
1621                     &rparam, &rparam_len,        /* return param, length */
1622                     &rdata, &rdata_len))         /* return data, length */
1623         {
1624                 DEBUG(5, ("Set Handle state: return OK\n"));
1625                 state_set = True;
1626         }
1627
1628         SAFE_FREE(rparam);
1629         SAFE_FREE(rdata);
1630
1631         return state_set;
1632 }
1633 #endif
1634
1635 /****************************************************************************
1636  Check the rpc bind acknowledge response.
1637 ****************************************************************************/
1638
1639 static BOOL valid_pipe_name(const int pipe_idx, RPC_IFACE *abstract, RPC_IFACE *transfer)
1640 {
1641         if ( pipe_idx >= PI_MAX_PIPES ) {
1642                 DEBUG(0,("valid_pipe_name: Programmer error!  Invalid pipe index [%d]\n",
1643                         pipe_idx));
1644                 return False;
1645         }
1646
1647         DEBUG(5,("Bind Abstract Syntax: "));    
1648         dump_data(5, (uint8 *)&pipe_names[pipe_idx].abstr_syntax, 
1649                   sizeof(pipe_names[pipe_idx].abstr_syntax));
1650         DEBUG(5,("Bind Transfer Syntax: "));
1651         dump_data(5, (uint8 *)&pipe_names[pipe_idx].trans_syntax,
1652                   sizeof(pipe_names[pipe_idx].trans_syntax));
1653
1654         /* copy the required syntaxes out so we can do the right bind */
1655         
1656         *transfer = pipe_names[pipe_idx].trans_syntax;
1657         *abstract = pipe_names[pipe_idx].abstr_syntax;
1658
1659         return True;
1660 }
1661
1662 /****************************************************************************
1663  Check the rpc bind acknowledge response.
1664 ****************************************************************************/
1665
1666 static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, const int pipe_idx, RPC_IFACE *transfer)
1667 {
1668         if ( hdr_ba->addr.len == 0) {
1669                 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1670         }
1671
1672 # if 0  /* JERRY -- apparently ASU forgets to fill in the server pipe name sometimes */
1673         if ( !strequal(hdr_ba->addr.str, pipe_names[pipe_idx].client_pipe) &&
1674              !strequal(hdr_ba->addr.str, pipe_names[pipe_idx].server_pipe) )
1675         {
1676                 DEBUG(4,("bind_rpc_pipe: pipe_name %s != expected pipe %s.  oh well!\n",
1677                          pipe_names[i].server_pipe ,hdr_ba->addr.str));
1678                 return False;
1679         }
1680         
1681         DEBUG(5,("bind_rpc_pipe: server pipe_name found: %s\n", pipe_names[i].server_pipe ));
1682
1683         if (pipe_names[pipe_idx].server_pipe == NULL) {
1684                 DEBUG(2,("bind_rpc_pipe: pipe name %s unsupported\n", hdr_ba->addr.str));
1685                 return False;
1686         }
1687 #endif  /* JERRY */
1688
1689         /* check the transfer syntax */
1690         if ((hdr_ba->transfer.version != transfer->version) ||
1691              (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
1692                 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1693                 return False;
1694         }
1695
1696         if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) {
1697                 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1698                           hdr_ba->res.num_results, hdr_ba->res.reason));
1699         }
1700
1701         DEBUG(5,("check_bind_response: accepted!\n"));
1702         return True;
1703 }
1704
1705 /*******************************************************************
1706  Creates a DCE/RPC bind authentication response.
1707  This is the packet that is sent back to the server once we
1708  have received a BIND-ACK, to finish the third leg of
1709  the authentication handshake.
1710  ********************************************************************/
1711
1712 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
1713                                 uint32 rpc_call_id,
1714                                 enum pipe_auth_type auth_type,
1715                                 enum pipe_auth_level auth_level,
1716                                 DATA_BLOB *pauth_blob,
1717                                 prs_struct *rpc_out)
1718 {
1719         RPC_HDR hdr;
1720         RPC_HDR_AUTH hdr_auth;
1721         uint32 pad = 0;
1722
1723         /* Create the request RPC_HDR */
1724         init_rpc_hdr(&hdr, RPC_AUTH3, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id,
1725                      RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + pauth_blob->length,
1726                      pauth_blob->length );
1727         
1728         /* Marshall it. */
1729         if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
1730                 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
1731                 return NT_STATUS_NO_MEMORY;
1732         }
1733
1734         /*
1735                 I'm puzzled about this - seems to violate the DCE RPC auth rules,
1736                 about padding - shouldn't this pad to length 8 ? JRA.
1737         */
1738
1739         /* 4 bytes padding. */
1740         if (!prs_uint32("pad", rpc_out, 0, &pad)) {
1741                 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
1742                 return NT_STATUS_NO_MEMORY;
1743         }
1744
1745         /* Create the request RPC_HDR_AUTHA */
1746         init_rpc_hdr_auth(&hdr_auth,
1747                         map_pipe_auth_type_to_rpc_auth_type(auth_type),
1748                         auth_level, 0, 1);
1749
1750         if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rpc_out, 0)) {
1751                 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
1752                 return NT_STATUS_NO_MEMORY;
1753         }
1754
1755         /*
1756          * Append the auth data to the outgoing buffer.
1757          */
1758
1759         if(!prs_copy_data_in(rpc_out, (char *)pauth_blob->data, pauth_blob->length)) {
1760                 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
1761                 return NT_STATUS_NO_MEMORY;
1762         }
1763
1764         return NT_STATUS_OK;
1765 }
1766
1767 /****************************************************************************
1768  Create and send the third packet in an RPC auth.
1769 ****************************************************************************/
1770
1771 static NTSTATUS rpc_finish_auth3_bind(struct rpc_pipe_client *cli,
1772                                 RPC_HDR *phdr,
1773                                 prs_struct *rbuf,
1774                                 uint32 rpc_call_id,
1775                                 enum pipe_auth_type auth_type,
1776                                 enum pipe_auth_level auth_level)
1777 {
1778         DATA_BLOB server_response = data_blob_null;
1779         DATA_BLOB client_reply = data_blob_null;
1780         RPC_HDR_AUTH hdr_auth;
1781         NTSTATUS nt_status;
1782         prs_struct rpc_out;
1783         ssize_t ret;
1784
1785         if (!phdr->auth_len || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
1786                 return NT_STATUS_INVALID_PARAMETER;
1787         }
1788
1789         /* Process the returned NTLMSSP blob first. */
1790         if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
1791                 return NT_STATUS_INVALID_PARAMETER;
1792         }
1793
1794         if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
1795                 return NT_STATUS_INVALID_PARAMETER;
1796         }
1797
1798         /* TODO - check auth_type/auth_level match. */
1799
1800         server_response = data_blob(NULL, phdr->auth_len);
1801         prs_copy_data_out((char *)server_response.data, rbuf, phdr->auth_len);
1802         
1803         nt_status = ntlmssp_update(cli->auth.a_u.ntlmssp_state,
1804                                    server_response,
1805                                    &client_reply);
1806         
1807         if (!NT_STATUS_IS_OK(nt_status)) {
1808                 DEBUG(0,("rpc_finish_auth3_bind: NTLMSSP update using server blob failed.\n"));
1809                 return nt_status;
1810         }
1811
1812         prs_init(&rpc_out, 0, prs_get_mem_context(rbuf), MARSHALL);
1813
1814         nt_status = create_rpc_bind_auth3(cli, rpc_call_id,
1815                                 auth_type, auth_level,
1816                                 &client_reply, &rpc_out);
1817
1818         if (!NT_STATUS_IS_OK(nt_status)) {
1819                 prs_mem_free(&rpc_out);
1820                 data_blob_free(&client_reply);
1821                 data_blob_free(&server_response);
1822                 return nt_status;
1823         }
1824
1825         /* 8 here is named pipe message mode. */
1826         ret = cli_write(cli->cli, cli->fnum, 0x8, prs_data_p(&rpc_out), 0,
1827                                 (size_t)prs_offset(&rpc_out));
1828
1829         if (ret != (ssize_t)prs_offset(&rpc_out)) {
1830                 DEBUG(0,("rpc_send_auth_auth3: cli_write failed. Return was %d\n", (int)ret));
1831                 prs_mem_free(&rpc_out);
1832                 data_blob_free(&client_reply);
1833                 data_blob_free(&server_response);
1834                 return cli_get_nt_error(cli->cli);
1835         }
1836
1837         DEBUG(5,("rpc_send_auth_auth3: Remote machine %s pipe %s "
1838                 "fnum 0x%x sent auth3 response ok.\n",
1839                 cli->cli->desthost,
1840                 cli->pipe_name,
1841                 (unsigned int)cli->fnum));
1842
1843         prs_mem_free(&rpc_out);
1844         data_blob_free(&client_reply);
1845         data_blob_free(&server_response);
1846         return NT_STATUS_OK;
1847 }
1848
1849 /*******************************************************************
1850  Creates a DCE/RPC bind alter context authentication request which
1851  may contain a spnego auth blobl
1852  ********************************************************************/
1853
1854 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
1855                                         RPC_IFACE *abstract,
1856                                         RPC_IFACE *transfer,
1857                                         enum pipe_auth_level auth_level,
1858                                         const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
1859                                         prs_struct *rpc_out)
1860 {
1861         RPC_HDR_AUTH hdr_auth;
1862         prs_struct auth_info;
1863         NTSTATUS ret = NT_STATUS_OK;
1864
1865         ZERO_STRUCT(hdr_auth);
1866         prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL);
1867
1868         /* We may change the pad length before marshalling. */
1869         init_rpc_hdr_auth(&hdr_auth, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
1870
1871         if (pauth_blob->length) {
1872                 if (!prs_copy_data_in(&auth_info, (const char *)pauth_blob->data, pauth_blob->length)) {
1873                         prs_mem_free(&auth_info);
1874                         return NT_STATUS_NO_MEMORY;
1875                 }
1876         }
1877
1878         ret = create_bind_or_alt_ctx_internal(RPC_ALTCONT,
1879                                                 rpc_out, 
1880                                                 rpc_call_id,
1881                                                 abstract,
1882                                                 transfer,
1883                                                 &hdr_auth,
1884                                                 &auth_info);
1885         prs_mem_free(&auth_info);
1886         return ret;
1887 }
1888
1889 /*******************************************************************
1890  Third leg of the SPNEGO bind mechanism - sends alter context PDU
1891  and gets a response.
1892  ********************************************************************/
1893
1894 static NTSTATUS rpc_finish_spnego_ntlmssp_bind(struct rpc_pipe_client *cli,
1895                                 RPC_HDR *phdr,
1896                                 prs_struct *rbuf,
1897                                 uint32 rpc_call_id,
1898                                 RPC_IFACE *abstract,
1899                                 RPC_IFACE *transfer,
1900                                 enum pipe_auth_type auth_type,
1901                                 enum pipe_auth_level auth_level)
1902 {
1903         DATA_BLOB server_spnego_response = data_blob_null;
1904         DATA_BLOB server_ntlm_response = data_blob_null;
1905         DATA_BLOB client_reply = data_blob_null;
1906         DATA_BLOB tmp_blob = data_blob_null;
1907         RPC_HDR_AUTH hdr_auth;
1908         NTSTATUS nt_status;
1909         prs_struct rpc_out;
1910
1911         if (!phdr->auth_len || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
1912                 return NT_STATUS_INVALID_PARAMETER;
1913         }
1914
1915         /* Process the returned NTLMSSP blob first. */
1916         if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
1917                 return NT_STATUS_INVALID_PARAMETER;
1918         }
1919
1920         if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
1921                 return NT_STATUS_INVALID_PARAMETER;
1922         }
1923
1924         server_spnego_response = data_blob(NULL, phdr->auth_len);
1925         prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len);
1926         
1927         /* The server might give us back two challenges - tmp_blob is for the second. */
1928         if (!spnego_parse_challenge(server_spnego_response, &server_ntlm_response, &tmp_blob)) {
1929                 data_blob_free(&server_spnego_response);
1930                 data_blob_free(&server_ntlm_response);
1931                 data_blob_free(&tmp_blob);
1932                 return NT_STATUS_INVALID_PARAMETER;
1933         }
1934
1935         /* We're finished with the server spnego response and the tmp_blob. */
1936         data_blob_free(&server_spnego_response);
1937         data_blob_free(&tmp_blob);
1938
1939         nt_status = ntlmssp_update(cli->auth.a_u.ntlmssp_state,
1940                                    server_ntlm_response,
1941                                    &client_reply);
1942         
1943         /* Finished with the server_ntlm response */
1944         data_blob_free(&server_ntlm_response);
1945
1946         if (!NT_STATUS_IS_OK(nt_status)) {
1947                 DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update using server blob failed.\n"));
1948                 data_blob_free(&client_reply);
1949                 return nt_status;
1950         }
1951
1952         /* SPNEGO wrap the client reply. */
1953         tmp_blob = spnego_gen_auth(client_reply);
1954         data_blob_free(&client_reply);
1955         client_reply = tmp_blob;
1956         tmp_blob = data_blob_null; /* Ensure it's safe to free this just in case. */
1957
1958         /* Now prepare the alter context pdu. */
1959         prs_init(&rpc_out, 0, prs_get_mem_context(rbuf), MARSHALL);
1960
1961         nt_status = create_rpc_alter_context(rpc_call_id,
1962                                                 abstract,
1963                                                 transfer,
1964                                                 auth_level,
1965                                                 &client_reply,
1966                                                 &rpc_out);
1967
1968         data_blob_free(&client_reply);
1969
1970         if (!NT_STATUS_IS_OK(nt_status)) {
1971                 prs_mem_free(&rpc_out);
1972                 return nt_status;
1973         }
1974
1975         /* Initialize the returning data struct. */
1976         prs_mem_free(rbuf);
1977         prs_init(rbuf, 0, cli->cli->mem_ctx, UNMARSHALL);
1978
1979         nt_status = rpc_api_pipe(cli, &rpc_out, rbuf, RPC_ALTCONTRESP);
1980         if (!NT_STATUS_IS_OK(nt_status)) {
1981                 prs_mem_free(&rpc_out);
1982                 return nt_status;
1983         }
1984
1985         prs_mem_free(&rpc_out);
1986
1987         /* Get the auth blob from the reply. */
1988         if(!smb_io_rpc_hdr("rpc_hdr   ", phdr, rbuf, 0)) {
1989                 DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: Failed to unmarshall RPC_HDR.\n"));
1990                 return NT_STATUS_BUFFER_TOO_SMALL;
1991         }
1992
1993         if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
1994                 return NT_STATUS_INVALID_PARAMETER;
1995         }
1996
1997         if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
1998                 return NT_STATUS_INVALID_PARAMETER;
1999         }
2000
2001         server_spnego_response = data_blob(NULL, phdr->auth_len);
2002         prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len);
2003
2004         /* Check we got a valid auth response. */
2005         if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK, OID_NTLMSSP, &tmp_blob)) {
2006                 data_blob_free(&server_spnego_response);
2007                 data_blob_free(&tmp_blob);
2008                 return NT_STATUS_INVALID_PARAMETER;
2009         }
2010
2011         data_blob_free(&server_spnego_response);
2012         data_blob_free(&tmp_blob);
2013
2014         DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
2015                 "remote machine %s pipe %s fnum 0x%x.\n",
2016                 cli->cli->desthost,
2017                 cli->pipe_name,
2018                 (unsigned int)cli->fnum));
2019
2020         return NT_STATUS_OK;
2021 }
2022
2023 /****************************************************************************
2024  Do an rpc bind.
2025 ****************************************************************************/
2026
2027 static NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
2028                         enum pipe_auth_type auth_type,
2029                         enum pipe_auth_level auth_level)
2030 {
2031         RPC_HDR hdr;
2032         RPC_HDR_BA hdr_ba;
2033         RPC_IFACE abstract;
2034         RPC_IFACE transfer;
2035         prs_struct rpc_out;
2036         prs_struct rbuf;
2037         uint32 rpc_call_id;
2038         NTSTATUS status;
2039
2040         DEBUG(5,("Bind RPC Pipe[%x]: %s auth_type %u, auth_level %u\n",
2041                 (unsigned int)cli->fnum,
2042                 cli->pipe_name,
2043                 (unsigned int)auth_type,
2044                 (unsigned int)auth_level ));
2045
2046         if (!valid_pipe_name(cli->pipe_idx, &abstract, &transfer)) {
2047                 return NT_STATUS_INVALID_PARAMETER;
2048         }
2049
2050         prs_init(&rpc_out, 0, cli->cli->mem_ctx, MARSHALL);
2051
2052         rpc_call_id = get_rpc_call_id();
2053
2054         /* Marshall the outgoing data. */
2055         status = create_rpc_bind_req(cli, &rpc_out, rpc_call_id,
2056                                 &abstract, &transfer,
2057                                 auth_type,
2058                                 auth_level);
2059
2060         if (!NT_STATUS_IS_OK(status)) {
2061                 prs_mem_free(&rpc_out);
2062                 return status;
2063         }
2064
2065         /* Initialize the incoming data struct. */
2066         prs_init(&rbuf, 0, cli->cli->mem_ctx, UNMARSHALL);
2067
2068         /* send data on \PIPE\.  receive a response */
2069         status = rpc_api_pipe(cli, &rpc_out, &rbuf, RPC_BINDACK);
2070         if (!NT_STATUS_IS_OK(status)) {
2071                 prs_mem_free(&rpc_out);
2072                 return status;
2073         }
2074
2075         prs_mem_free(&rpc_out);
2076
2077         DEBUG(3,("rpc_pipe_bind: Remote machine %s pipe %s "
2078                 "fnum 0x%x bind request returned ok.\n",
2079                 cli->cli->desthost,
2080                 cli->pipe_name,
2081                 (unsigned int)cli->fnum));
2082
2083         /* Unmarshall the RPC header */
2084         if(!smb_io_rpc_hdr("hdr"   , &hdr, &rbuf, 0)) {
2085                 DEBUG(0,("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2086                 prs_mem_free(&rbuf);
2087                 return NT_STATUS_BUFFER_TOO_SMALL;
2088         }
2089
2090         if(!smb_io_rpc_hdr_ba("", &hdr_ba, &rbuf, 0)) {
2091                 DEBUG(0,("rpc_pipe_bind: Failed to unmarshall RPC_HDR_BA.\n"));
2092                 prs_mem_free(&rbuf);
2093                 return NT_STATUS_BUFFER_TOO_SMALL;
2094         }
2095
2096         if(!check_bind_response(&hdr_ba, cli->pipe_idx, &transfer)) {
2097                 DEBUG(2,("rpc_pipe_bind: check_bind_response failed.\n"));
2098                 prs_mem_free(&rbuf);
2099                 return NT_STATUS_BUFFER_TOO_SMALL;
2100         }
2101
2102         cli->max_xmit_frag = hdr_ba.bba.max_tsize;
2103         cli->max_recv_frag = hdr_ba.bba.max_rsize;
2104
2105         /* For authenticated binds we may need to do 3 or 4 leg binds. */
2106         switch(auth_type) {
2107
2108                 case PIPE_AUTH_TYPE_NONE:
2109                 case PIPE_AUTH_TYPE_SCHANNEL:
2110                         /* Bind complete. */
2111                         break;
2112
2113                 case PIPE_AUTH_TYPE_NTLMSSP:
2114                         /* Need to send AUTH3 packet - no reply. */
2115                         status = rpc_finish_auth3_bind(cli, &hdr, &rbuf, rpc_call_id,
2116                                                 auth_type, auth_level);
2117                         if (!NT_STATUS_IS_OK(status)) {
2118                                 prs_mem_free(&rbuf);
2119                                 return status;
2120                         }
2121                         break;
2122
2123                 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2124                         /* Need to send alter context request and reply. */
2125                         status = rpc_finish_spnego_ntlmssp_bind(cli, &hdr, &rbuf, rpc_call_id,
2126                                                 &abstract, &transfer,
2127                                                 auth_type, auth_level);
2128                         if (!NT_STATUS_IS_OK(status)) {
2129                                 prs_mem_free(&rbuf);
2130                                 return status;
2131                         }
2132                         break;
2133
2134                 case PIPE_AUTH_TYPE_KRB5:
2135                         /* */
2136
2137                 default:
2138                         DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
2139                                 (unsigned int)auth_type ));
2140                         prs_mem_free(&rbuf);
2141                         return NT_STATUS_INVALID_INFO_CLASS;
2142         }
2143
2144         /* For NTLMSSP ensure the server gave us the auth_level we wanted. */
2145         if (auth_type == PIPE_AUTH_TYPE_NTLMSSP || auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2146                 if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2147                         if (!(cli->auth.a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN)) {
2148                                 DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP signing and server refused.\n"));
2149                                 prs_mem_free(&rbuf);
2150                                 return NT_STATUS_INVALID_PARAMETER;
2151                         }
2152                 }
2153                 if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2154                         if (!(cli->auth.a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL)) {
2155                                 DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP sealing and server refused.\n"));
2156                                 prs_mem_free(&rbuf);
2157                                 return NT_STATUS_INVALID_PARAMETER;
2158                         }
2159                 }
2160         }
2161
2162         /* Pipe is bound - set up auth_type and auth_level data. */
2163
2164         cli->auth.auth_type = auth_type;
2165         cli->auth.auth_level = auth_level;
2166
2167         prs_mem_free(&rbuf);
2168         return NT_STATUS_OK;
2169 }
2170
2171 /****************************************************************************
2172  Open a named pipe over SMB to a remote server.
2173  *
2174  * CAVEAT CALLER OF THIS FUNCTION:
2175  *    The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2176  *    so be sure that this function is called AFTER any structure (vs pointer)
2177  *    assignment of the cli.  In particular, libsmbclient does structure
2178  *    assignments of cli, which invalidates the data in the returned
2179  *    rpc_pipe_client if this function is called before the structure assignment
2180  *    of cli.
2181  * 
2182  ****************************************************************************/
2183
2184 static struct rpc_pipe_client *cli_rpc_pipe_open(struct cli_state *cli, int pipe_idx, NTSTATUS *perr)
2185 {
2186         TALLOC_CTX *mem_ctx;
2187         struct rpc_pipe_client *result;
2188         int fnum;
2189
2190         *perr = NT_STATUS_NO_MEMORY;
2191
2192         /* sanity check to protect against crashes */
2193
2194         if ( !cli ) {
2195                 *perr = NT_STATUS_INVALID_HANDLE;
2196                 return NULL;
2197         }
2198
2199         /* The pipe name index must fall within our array */
2200         SMB_ASSERT((pipe_idx >= 0) && (pipe_idx < PI_MAX_PIPES));
2201
2202         mem_ctx = talloc_init("struct rpc_pipe_client");
2203         if (mem_ctx == NULL) {
2204                 return NULL;
2205         }
2206
2207         result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
2208         if (result == NULL) {
2209                 return NULL;
2210         }
2211
2212         result->mem_ctx = mem_ctx;
2213
2214         result->pipe_name = cli_get_pipe_name(pipe_idx);
2215
2216         fnum = cli_nt_create(cli, result->pipe_name, DESIRED_ACCESS_PIPE);
2217
2218         if (fnum == -1) {
2219                 DEBUG(1,("cli_rpc_pipe_open: cli_nt_create failed on pipe %s "
2220                          "to machine %s.  Error was %s\n",
2221                          result->pipe_name, cli->desthost,
2222                          cli_errstr(cli)));
2223                 *perr = cli_get_nt_error(cli);
2224                 talloc_destroy(result->mem_ctx);
2225                 return NULL;
2226         }
2227
2228         result->fnum = fnum;
2229         result->cli = cli;
2230         result->pipe_idx = pipe_idx;
2231         result->auth.auth_type = PIPE_AUTH_TYPE_NONE;
2232         result->auth.auth_level = PIPE_AUTH_LEVEL_NONE;
2233
2234         if (pipe_idx == PI_NETLOGON) {
2235                 /* Set up a netlogon credential chain for a netlogon pipe. */
2236                 result->dc = TALLOC_ZERO_P(mem_ctx, struct dcinfo);
2237                 if (result->dc == NULL) {
2238                         talloc_destroy(result->mem_ctx);
2239                         return NULL;
2240                 }
2241         }
2242
2243         DLIST_ADD(cli->pipe_list, result);
2244         *perr = NT_STATUS_OK;
2245
2246         return result;
2247 }
2248
2249 /****************************************************************************
2250  Open a named pipe to an SMB server and bind anonymously.
2251  ****************************************************************************/
2252
2253 struct rpc_pipe_client *cli_rpc_pipe_open_noauth(struct cli_state *cli, int pipe_idx, NTSTATUS *perr)
2254 {
2255         struct rpc_pipe_client *result;
2256
2257         result = cli_rpc_pipe_open(cli, pipe_idx, perr);
2258         if (result == NULL) {
2259                 return NULL;
2260         }
2261
2262         *perr = rpc_pipe_bind(result, PIPE_AUTH_TYPE_NONE, PIPE_AUTH_LEVEL_NONE);
2263         if (!NT_STATUS_IS_OK(*perr)) {
2264                 int lvl = 0;
2265                 if (pipe_idx == PI_LSARPC_DS) {
2266                         /* non AD domains just don't have this pipe, avoid
2267                          * level 0 statement in that case - gd */
2268                         lvl = 3;
2269                 }
2270                 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe %s failed with error %s\n",
2271                         cli_get_pipe_name(pipe_idx), nt_errstr(*perr) ));
2272                 cli_rpc_pipe_close(result);
2273                 return NULL;
2274         }
2275
2276         DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine %s and bound anonymously.\n",
2277                         result->pipe_name, cli->desthost ));
2278
2279         return result;
2280 }
2281
2282 /****************************************************************************
2283  Free function for NTLMSSP auth.
2284  ****************************************************************************/
2285
2286 static void cli_ntlmssp_auth_free(struct cli_pipe_auth_data *auth)
2287 {
2288         if (auth->a_u.ntlmssp_state) {
2289                 ntlmssp_end(&auth->a_u.ntlmssp_state);
2290                 auth->a_u.ntlmssp_state = NULL;
2291         }
2292 }
2293
2294 /****************************************************************************
2295  Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
2296  ****************************************************************************/
2297
2298 static struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
2299                                                 int pipe_idx,
2300                                                 enum pipe_auth_type auth_type,
2301                                                 enum pipe_auth_level auth_level,
2302                                                 const char *domain,
2303                                                 const char *username,
2304                                                 const char *password,
2305                                                 NTSTATUS *perr)
2306 {
2307         struct rpc_pipe_client *result;
2308         NTLMSSP_STATE *ntlmssp_state = NULL;
2309
2310         result = cli_rpc_pipe_open(cli, pipe_idx, perr);
2311         if (result == NULL) {
2312                 return NULL;
2313         }
2314         
2315         result->auth.cli_auth_data_free_func = cli_ntlmssp_auth_free;
2316
2317         result->domain = domain;
2318         result->user_name = username;
2319         pwd_set_cleartext(&result->pwd, password);
2320
2321         *perr = ntlmssp_client_start(&ntlmssp_state);
2322         if (!NT_STATUS_IS_OK(*perr)) {
2323                 goto err;
2324         }
2325
2326         result->auth.a_u.ntlmssp_state = ntlmssp_state;
2327
2328         *perr = ntlmssp_set_username(ntlmssp_state, cli->user_name);
2329         if (!NT_STATUS_IS_OK(*perr)) {
2330                 goto err;
2331         }
2332
2333         *perr = ntlmssp_set_domain(ntlmssp_state, cli->domain); 
2334         if (!NT_STATUS_IS_OK(*perr)) {
2335                 goto err;
2336         }
2337
2338         if (cli->pwd.null_pwd) {
2339                 *perr = ntlmssp_set_password(ntlmssp_state, NULL);
2340                 if (!NT_STATUS_IS_OK(*perr)) {
2341                         goto err;
2342                 }
2343         } else {
2344                 *perr = ntlmssp_set_password(ntlmssp_state, password);
2345                 if (!NT_STATUS_IS_OK(*perr)) {
2346                         goto err;
2347                 }
2348         }
2349
2350         /* Turn off sign+seal to allow selected auth level to turn it back on. */
2351         ntlmssp_state->neg_flags &= ~(NTLMSSP_NEGOTIATE_SIGN|NTLMSSP_NEGOTIATE_SEAL);
2352
2353         if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2354                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
2355         } else if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) {
2356                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
2357         }
2358         
2359         *perr = rpc_pipe_bind(result, auth_type, auth_level);
2360         if (!NT_STATUS_IS_OK(*perr)) {
2361                 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
2362                         nt_errstr(*perr) ));
2363                 goto err;
2364         }
2365
2366         DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to machine %s and"
2367                 "bound NTLMSSP as user %s\\%s.\n",
2368                 result->pipe_name, cli->desthost,
2369                 domain, username ));
2370
2371         return result;
2372
2373   err:
2374
2375         cli_rpc_pipe_close(result);
2376         return NULL;
2377 }
2378
2379 /****************************************************************************
2380  External interface.
2381  Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
2382  ****************************************************************************/
2383
2384 struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
2385                                                 int pipe_idx,
2386                                                 enum pipe_auth_level auth_level,
2387                                                 const char *domain,
2388                                                 const char *username,
2389                                                 const char *password,
2390                                                 NTSTATUS *perr)
2391 {
2392         return cli_rpc_pipe_open_ntlmssp_internal(cli,
2393                                                 pipe_idx,
2394                                                 PIPE_AUTH_TYPE_NTLMSSP,
2395                                                 auth_level,
2396                                                 domain,
2397                                                 username,
2398                                                 password,
2399                                                 perr);
2400 }
2401
2402 /****************************************************************************
2403  External interface.
2404  Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
2405  ****************************************************************************/
2406
2407 struct rpc_pipe_client *cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
2408                                                 int pipe_idx,
2409                                                 enum pipe_auth_level auth_level,
2410                                                 const char *domain,
2411                                                 const char *username,
2412                                                 const char *password,
2413                                                 NTSTATUS *perr)
2414 {
2415         return cli_rpc_pipe_open_ntlmssp_internal(cli,
2416                                                 pipe_idx,
2417                                                 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
2418                                                 auth_level,
2419                                                 domain,
2420                                                 username,
2421                                                 password,
2422                                                 perr);
2423 }
2424
2425 /****************************************************************************
2426  Open a netlogon pipe and get the schannel session key.
2427  Now exposed to external callers.
2428  ****************************************************************************/
2429
2430 struct rpc_pipe_client *get_schannel_session_key(struct cli_state *cli,
2431                                                         const char *domain,
2432                                                         uint32 *pneg_flags,
2433                                                         NTSTATUS *perr)
2434 {
2435         struct rpc_pipe_client *netlogon_pipe = NULL;
2436         uint32 sec_chan_type = 0;
2437         unsigned char machine_pwd[16];
2438         fstring machine_account;
2439
2440         netlogon_pipe = cli_rpc_pipe_open_noauth(cli, PI_NETLOGON, perr);
2441         if (!netlogon_pipe) {
2442                 return NULL;
2443         }
2444
2445         /* Get the machine account credentials from secrets.tdb. */
2446         if (!get_trust_pw(domain, machine_pwd, &sec_chan_type)) {
2447                 DEBUG(0, ("get_schannel_session_key: could not fetch "
2448                         "trust account password for domain '%s'\n",
2449                         domain));
2450                 cli_rpc_pipe_close(netlogon_pipe);
2451                 *perr = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2452                 return NULL;
2453         }
2454
2455         /* A DC should use DOMAIN$ as its account name.
2456            A member server can only use it's machine name since it
2457            does not have an account in a trusted domain.
2458
2459            We don't check the domain against lp_workgroup() here since
2460            'net ads join' has to continue to work with only the realm
2461            specified in smb.conf.  -- jerry */
2462
2463         if ( IS_DC && !strequal(domain, lp_workgroup()) && lp_allow_trusted_domains()) {
2464                 fstrcpy( machine_account, lp_workgroup() );
2465         } else {
2466                 fstrcpy(machine_account, global_myname());
2467         }
2468
2469         *perr = rpccli_netlogon_setup_creds(netlogon_pipe,
2470                                         cli->desthost, /* server name */
2471                                         domain,        /* domain */
2472                                         global_myname(), /* client name */
2473                                         machine_account, /* machine account name */
2474                                         machine_pwd,
2475                                         sec_chan_type,
2476                                         pneg_flags);
2477
2478         if (!NT_STATUS_IS_OK(*perr)) {
2479                 DEBUG(3,("get_schannel_session_key: rpccli_netlogon_setup_creds "
2480                         "failed with result %s to server %s, domain %s, machine account %s.\n",
2481                         nt_errstr(*perr), cli->desthost, domain, machine_account ));
2482                 cli_rpc_pipe_close(netlogon_pipe);
2483                 return NULL;
2484         }
2485
2486         if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
2487                 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
2488                         cli->desthost));
2489                 cli_rpc_pipe_close(netlogon_pipe);
2490                 *perr = NT_STATUS_INVALID_NETWORK_RESPONSE;
2491                 return NULL;
2492         }
2493
2494         return netlogon_pipe;
2495 }
2496
2497 /****************************************************************************
2498  External interface.
2499  Open a named pipe to an SMB server and bind using schannel (bind type 68)
2500  using session_key. sign and seal.
2501  ****************************************************************************/
2502
2503 struct rpc_pipe_client *cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
2504                                         int pipe_idx,
2505                                         enum pipe_auth_level auth_level,
2506                                         const char *domain,
2507                                         const struct dcinfo *pdc,
2508                                         NTSTATUS *perr)
2509 {
2510         struct rpc_pipe_client *result;
2511
2512         result = cli_rpc_pipe_open(cli, pipe_idx, perr);
2513         if (result == NULL) {
2514                 return NULL;
2515         }
2516
2517         result->auth.a_u.schannel_auth = TALLOC_ZERO_P(result->mem_ctx, struct schannel_auth_struct);
2518         if (!result->auth.a_u.schannel_auth) {
2519                 cli_rpc_pipe_close(result);
2520                 *perr = NT_STATUS_NO_MEMORY;
2521                 return NULL;
2522         }
2523
2524         result->domain = domain;
2525         memcpy(result->auth.a_u.schannel_auth->sess_key, pdc->sess_key, 16);
2526
2527         *perr = rpc_pipe_bind(result, PIPE_AUTH_TYPE_SCHANNEL, auth_level);
2528         if (!NT_STATUS_IS_OK(*perr)) {
2529                 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: cli_rpc_pipe_bind failed with error %s\n",
2530                         nt_errstr(*perr) ));
2531                 cli_rpc_pipe_close(result);
2532                 return NULL;
2533         }
2534
2535         /* The credentials on a new netlogon pipe are the ones we are passed in - copy them over. */
2536         if (result->dc) {
2537                 *result->dc = *pdc;
2538         }
2539
2540         DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
2541                 "for domain %s "
2542                 "and bound using schannel.\n",
2543                 result->pipe_name, cli->desthost, domain ));
2544
2545         return result;
2546 }
2547
2548 /****************************************************************************
2549  Open a named pipe to an SMB server and bind using schannel (bind type 68).
2550  Fetch the session key ourselves using a temporary netlogon pipe. This
2551  version uses an ntlmssp auth bound netlogon pipe to get the key.
2552  ****************************************************************************/
2553
2554 static struct rpc_pipe_client *get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
2555                                                         const char *domain,
2556                                                         const char *username,
2557                                                         const char *password,
2558                                                         uint32 *pneg_flags,
2559                                                         NTSTATUS *perr)
2560 {
2561         struct rpc_pipe_client *netlogon_pipe = NULL;
2562         uint32 sec_chan_type = 0;
2563         unsigned char machine_pwd[16];
2564         fstring machine_account;
2565
2566         netlogon_pipe = cli_rpc_pipe_open_spnego_ntlmssp(cli, PI_NETLOGON, PIPE_AUTH_LEVEL_PRIVACY, domain, username, password, perr);
2567         if (!netlogon_pipe) {
2568                 return NULL;
2569         }
2570
2571         /* Get the machine account credentials from secrets.tdb. */
2572         if (!get_trust_pw(domain, machine_pwd, &sec_chan_type)) {
2573                 DEBUG(0, ("get_schannel_session_key_auth_ntlmssp: could not fetch "
2574                         "trust account password for domain '%s'\n",
2575                         domain));
2576                 cli_rpc_pipe_close(netlogon_pipe);
2577                 *perr = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2578                 return NULL;
2579         }
2580
2581         /* if we are a DC and this is a trusted domain, then we need to use our
2582            domain name in the net_req_auth2() request */
2583
2584         if ( IS_DC && !strequal(domain, lp_workgroup()) && lp_allow_trusted_domains()) {
2585                 fstrcpy( machine_account, lp_workgroup() );
2586         } else {
2587                 /* Hmmm. Is this correct for trusted domains when we're a member server ? JRA. */
2588                 if (strequal(domain, lp_workgroup())) {
2589                         fstrcpy(machine_account, global_myname());
2590                 } else {
2591                         fstrcpy(machine_account, domain);
2592                 }
2593         }
2594
2595         *perr = rpccli_netlogon_setup_creds(netlogon_pipe,
2596                                         cli->desthost,     /* server name */
2597                                         domain,            /* domain */
2598                                         global_myname(),   /* client name */
2599                                         machine_account,   /* machine account name */
2600                                         machine_pwd,
2601                                         sec_chan_type,
2602                                         pneg_flags);
2603
2604         if (!NT_STATUS_IS_OK(*perr)) {
2605                 DEBUG(3,("get_schannel_session_key_auth_ntlmssp: rpccli_netlogon_setup_creds "
2606                         "failed with result %s\n",
2607                         nt_errstr(*perr) ));
2608                 cli_rpc_pipe_close(netlogon_pipe);
2609                 return NULL;
2610         }
2611
2612         if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
2613                 DEBUG(3, ("get_schannel_session_key_auth_ntlmssp: Server %s did not offer schannel\n",
2614                         cli->desthost));
2615                 cli_rpc_pipe_close(netlogon_pipe);
2616                 *perr = NT_STATUS_INVALID_NETWORK_RESPONSE;
2617                 return NULL;
2618         }
2619
2620         return netlogon_pipe;
2621 }
2622
2623 /****************************************************************************
2624  Open a named pipe to an SMB server and bind using schannel (bind type 68).
2625  Fetch the session key ourselves using a temporary netlogon pipe. This version
2626  uses an ntlmssp bind to get the session key.
2627  ****************************************************************************/
2628
2629 struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
2630                                                 int pipe_idx,
2631                                                 enum pipe_auth_level auth_level,
2632                                                 const char *domain,
2633                                                 const char *username,
2634                                                 const char *password,
2635                                                 NTSTATUS *perr)
2636 {
2637         uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL;
2638         struct rpc_pipe_client *netlogon_pipe = NULL;
2639         struct rpc_pipe_client *result = NULL;
2640
2641         netlogon_pipe = get_schannel_session_key_auth_ntlmssp(cli, domain, username,
2642                                                         password, &neg_flags, perr);
2643         if (!netlogon_pipe) {
2644                 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
2645                         "key from server %s for domain %s.\n",
2646                         cli->desthost, domain ));
2647                 return NULL;
2648         }
2649
2650         result = cli_rpc_pipe_open_schannel_with_key(cli, pipe_idx,
2651                                 auth_level,
2652                                 domain, netlogon_pipe->dc, perr);
2653
2654         /* Now we've bound using the session key we can close the netlog pipe. */
2655         cli_rpc_pipe_close(netlogon_pipe);
2656
2657         return result;
2658 }
2659
2660 /****************************************************************************
2661  Open a named pipe to an SMB server and bind using schannel (bind type 68).
2662  Fetch the session key ourselves using a temporary netlogon pipe.
2663  ****************************************************************************/
2664
2665 struct rpc_pipe_client *cli_rpc_pipe_open_schannel(struct cli_state *cli,
2666                                                 int pipe_idx,
2667                                                 enum pipe_auth_level auth_level,
2668                                                 const char *domain,
2669                                                 NTSTATUS *perr)
2670 {
2671         uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL;
2672         struct rpc_pipe_client *netlogon_pipe = NULL;
2673         struct rpc_pipe_client *result = NULL;
2674
2675         netlogon_pipe = get_schannel_session_key(cli, domain, &neg_flags, perr);
2676         if (!netlogon_pipe) {
2677                 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
2678                         "key from server %s for domain %s.\n",
2679                         cli->desthost, domain ));
2680                 return NULL;
2681         }
2682
2683         result = cli_rpc_pipe_open_schannel_with_key(cli, pipe_idx,
2684                                 auth_level,
2685                                 domain, netlogon_pipe->dc, perr);
2686
2687         /* Now we've bound using the session key we can close the netlog pipe. */
2688         cli_rpc_pipe_close(netlogon_pipe);
2689
2690         return result;
2691 }
2692
2693 #ifdef HAVE_KRB5
2694
2695 /****************************************************************************
2696  Free function for the kerberos spcific data.
2697  ****************************************************************************/
2698
2699 static void kerberos_auth_struct_free(struct cli_pipe_auth_data *a)
2700 {
2701         data_blob_free(&a->a_u.kerberos_auth->session_key);
2702 }
2703
2704 #endif
2705
2706 /****************************************************************************
2707  Open a named pipe to an SMB server and bind using krb5 (bind type 16).
2708  The idea is this can be called with service_princ, username and password all
2709  NULL so long as the caller has a TGT.
2710  ****************************************************************************/
2711
2712 struct rpc_pipe_client *cli_rpc_pipe_open_krb5(struct cli_state *cli,
2713                                                 int pipe_idx,
2714                                                 enum pipe_auth_level auth_level,
2715                                                 const char *service_princ,
2716                                                 const char *username,
2717                                                 const char *password,
2718                                                 NTSTATUS *perr)
2719 {
2720 #ifdef HAVE_KRB5
2721         struct rpc_pipe_client *result;
2722
2723         result = cli_rpc_pipe_open(cli, pipe_idx, perr);
2724         if (result == NULL) {
2725                 return NULL;
2726         }
2727
2728         /* Default service principal is "desthost$@realm" */
2729         if (!service_princ) {
2730                 service_princ = talloc_asprintf(result->mem_ctx, "%s$@%s",
2731                         cli->desthost, lp_realm() );
2732                 if (!service_princ) {
2733                         cli_rpc_pipe_close(result);
2734                         return NULL;
2735                 }
2736         }
2737
2738         /* Only get a new TGT if username/password are given. */
2739         if (username && password) {
2740                 int ret = kerberos_kinit_password(username, password, 0, NULL);
2741                 if (ret) {
2742                         cli_rpc_pipe_close(result);
2743                         return NULL;
2744                 }
2745         }
2746
2747         result->auth.a_u.kerberos_auth = TALLOC_ZERO_P(cli->mem_ctx, struct kerberos_auth_struct);
2748         if (!result->auth.a_u.kerberos_auth) {
2749                 cli_rpc_pipe_close(result);
2750                 *perr = NT_STATUS_NO_MEMORY;
2751                 return NULL;
2752         }
2753
2754         result->auth.a_u.kerberos_auth->service_principal = service_princ;
2755         result->auth.cli_auth_data_free_func = kerberos_auth_struct_free;
2756
2757         *perr = rpc_pipe_bind(result, PIPE_AUTH_TYPE_KRB5, auth_level);
2758         if (!NT_STATUS_IS_OK(*perr)) {
2759                 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed with error %s\n",
2760                         nt_errstr(*perr) ));
2761                 cli_rpc_pipe_close(result);
2762                 return NULL;
2763         }
2764
2765         return result;
2766 #else
2767         DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
2768         return NULL;
2769 #endif
2770 }
2771
2772 #if 0 /* Moved to libsmb/clientgen.c */
2773 /****************************************************************************
2774  External interface.
2775  Close an open named pipe over SMB. Free any authentication data.
2776  ****************************************************************************/
2777
2778  void cli_rpc_pipe_close(struct rpc_pipe_client *cli)
2779 {
2780         if (!cli_close(cli->cli, cli->fnum)) {
2781                 DEBUG(0,("cli_rpc_pipe_close: cli_close failed on pipe %s "
2782                          "to machine %s.  Error was %s\n",
2783                          cli->pipe_name),
2784                          cli->cli->desthost,
2785                          cli_errstr(cli->cli)));
2786         }
2787
2788         if (cli->auth.cli_auth_data_free_func) {
2789                 (*cli->auth.cli_auth_data_free_func)(&cli->auth);
2790         }
2791         DEBUG(10,("cli_rpc_pipe_close: closed pipe %s to machine %s\n",
2792                 cli->pipe_name, cli->cli->desthost ));
2793
2794         DLIST_REMOVE(cli->cli->pipe_list, cli);
2795         talloc_destroy(cli->mem_ctx);   
2796 }
2797 #endif