r13316: Let the carnage begin....
[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 2 of the License, or
9  *  (at your option) any later version.
10  *  
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *  
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  */
20
21 #include "includes.h"
22
23 #undef DBGC_CLASS
24 #define DBGC_CLASS DBGC_RPC_CLI
25
26 extern struct pipe_id_info pipe_names[];
27
28 /********************************************************************
29  Map internal value to wire value.
30  ********************************************************************/
31
32 static int map_pipe_auth_type_to_rpc_auth_type(enum pipe_auth_type auth_type)
33 {
34         switch (auth_type) {
35
36         case PIPE_AUTH_TYPE_NONE:
37                 return RPC_ANONYMOUS_AUTH_TYPE;
38
39         case PIPE_AUTH_TYPE_NTLMSSP:
40                 return RPC_NTLMSSP_AUTH_TYPE;
41
42         case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
43         case PIPE_AUTH_TYPE_SPNEGO_KRB5:
44                 return RPC_SPNEGO_AUTH_TYPE;
45
46         case PIPE_AUTH_TYPE_SCHANNEL:
47                 return RPC_SCHANNEL_AUTH_TYPE;
48
49         case PIPE_AUTH_TYPE_KRB5:
50                 return RPC_KRB5_AUTH_TYPE;
51
52         default:
53                 DEBUG(0,("map_pipe_auth_type_to_rpc_type: unknown pipe "
54                         "auth type %u\n",
55                         (unsigned int)auth_type ));
56                 break;
57         }
58         return -1;
59 }
60
61 /********************************************************************
62  Rpc pipe call id.
63  ********************************************************************/
64
65 static uint32 get_rpc_call_id(void)
66 {
67         static uint32 call_id = 0;
68         return ++call_id;
69 }
70
71 /*******************************************************************
72  Use SMBreadX to get rest of one fragment's worth of rpc data.
73  Will expand the current_pdu struct to the correct size.
74  ********************************************************************/
75
76 static NTSTATUS rpc_read(struct rpc_pipe_client *cli,
77                         prs_struct *current_pdu,
78                         uint32 data_to_read,
79                         uint32 *current_pdu_offset)
80 {
81         size_t size = (size_t)cli->max_recv_frag;
82         uint32 stream_offset = 0;
83         ssize_t num_read;
84         char *pdata;
85         ssize_t extra_data_size = ((ssize_t)*current_pdu_offset) + ((ssize_t)data_to_read) - (ssize_t)prs_data_size(current_pdu);
86
87         DEBUG(5,("rpc_read: data_to_read: %u current_pdu offset: %u extra_data_size: %d\n",
88                 (unsigned int)data_to_read, (unsigned int)*current_pdu_offset, (int)extra_data_size ));
89
90         /*
91          * Grow the buffer if needed to accommodate the data to be read.
92          */
93
94         if (extra_data_size > 0) {
95                 if(!prs_force_grow(current_pdu, (uint32)extra_data_size)) {
96                         DEBUG(0,("rpc_read: Failed to grow parse struct by %d bytes.\n", (int)extra_data_size ));
97                         return NT_STATUS_NO_MEMORY;
98                 }
99                 DEBUG(5,("rpc_read: grew buffer by %d bytes to %u\n", (int)extra_data_size, prs_data_size(current_pdu) ));
100         }
101
102         pdata = prs_data_p(current_pdu) + *current_pdu_offset;
103
104         do {
105                 /* read data using SMBreadX */
106                 if (size > (size_t)data_to_read) {
107                         size = (size_t)data_to_read;
108                 }
109
110                 num_read = cli_read(cli->cli, cli->fnum, pdata,
111                                          (off_t)stream_offset, size);
112
113                 DEBUG(5,("rpc_read: num_read = %d, read offset: %u, to read: %u\n",
114                         (int)num_read, (unsigned int)stream_offset, (unsigned int)data_to_read));
115
116                 /*
117                  * A dos error of ERRDOS/ERRmoredata is not an error.
118                  */
119                 if (cli_is_dos_error(cli->cli)) {
120                         uint32 ecode;
121                         uint8 eclass;
122                         cli_dos_error(cli->cli, &eclass, &ecode);
123                         if (eclass != ERRDOS && ecode != ERRmoredata) {
124                                 DEBUG(0,("rpc_read: DOS Error %d/%u (%s) in cli_read on pipe %s\n",
125                                         eclass, (unsigned int)ecode,
126                                         cli_errstr(cli->cli),
127                                         cli->pipe_name ));
128                                 return dos_to_ntstatus(eclass, ecode);
129                         }
130                 }
131
132                 /*
133                  * Likewise for NT_STATUS_BUFFER_TOO_SMALL
134                  */
135                 if (cli_is_nt_error(cli->cli)) {
136                         if (!NT_STATUS_EQUAL(cli_nt_error(cli->cli), NT_STATUS_BUFFER_TOO_SMALL)) {
137                                 DEBUG(0,("rpc_read: Error (%s) in cli_read on pipe %s\n",
138                                         nt_errstr(cli_nt_error(cli->cli)),
139                                         cli->pipe_name ));
140                                 return cli_nt_error(cli->cli);
141                         }
142                 }
143
144                 if (num_read == -1) {
145                         DEBUG(0,("rpc_read: Error - cli_read on pipe %s returned -1\n",
146                                 cli->pipe_name ));
147                         return cli_get_nt_error(cli->cli);
148                 }
149
150                 data_to_read -= num_read;
151                 stream_offset += num_read;
152                 pdata += num_read;
153
154         } while (num_read > 0 && data_to_read > 0);
155         /* && err == (0x80000000 | STATUS_BUFFER_OVERFLOW)); */
156
157         /*
158          * Update the current offset into current_pdu by the amount read.
159          */
160         *current_pdu_offset += stream_offset;
161         return NT_STATUS_OK;
162 }
163
164 /****************************************************************************
165  Try and get a PDU's worth of data from current_pdu. If not, then read more
166  from the wire.
167  ****************************************************************************/
168
169 static NTSTATUS cli_pipe_get_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
170 {
171         NTSTATUS ret = NT_STATUS_OK;
172         uint32 current_pdu_len = prs_data_size(current_pdu);
173
174         /* Ensure we have at least RPC_HEADER_LEN worth of data to parse. */
175         if (current_pdu_len < RPC_HEADER_LEN) {
176                 /* rpc_read expands the current_pdu struct as neccessary. */
177                 ret = rpc_read(cli, current_pdu, RPC_HEADER_LEN - current_pdu_len, &current_pdu_len);
178                 if (!NT_STATUS_IS_OK(ret)) {
179                         return ret;
180                 }
181         }
182
183         /* This next call sets the endian bit correctly in current_pdu. */
184         /* We will propagate this to rbuf later. */
185         if(!smb_io_rpc_hdr("rpc_hdr   ", prhdr, current_pdu, 0)) {
186                 DEBUG(0,("cli_pipe_get_current_pdu: Failed to unmarshall RPC_HDR.\n"));
187                 return NT_STATUS_BUFFER_TOO_SMALL;
188         }
189
190         /* Ensure we have frag_len bytes of data. */
191         if (current_pdu_len < prhdr->frag_len) {
192                 /* rpc_read expands the current_pdu struct as neccessary. */
193                 ret = rpc_read(cli, current_pdu, (uint32)prhdr->frag_len - current_pdu_len, &current_pdu_len);
194                 if (!NT_STATUS_IS_OK(ret)) {
195                         return ret;
196                 }
197         }
198
199         if (current_pdu_len < prhdr->frag_len) {
200                 return NT_STATUS_BUFFER_TOO_SMALL;
201         }
202
203         return NT_STATUS_OK;
204 }
205
206 /****************************************************************************
207  NTLMSSP specific sign/seal.
208  Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.
209  In fact I should probably abstract these into identical pieces of code... JRA.
210  ****************************************************************************/
211
212 static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
213                                 prs_struct *current_pdu,
214                                 uint8 *p_ss_padding_len)
215 {
216         RPC_HDR_AUTH auth_info;
217         uint32 save_offset = prs_offset(current_pdu);
218         uint32 auth_len = prhdr->auth_len;
219         NTLMSSP_STATE *ntlmssp_state = cli->auth.a_u.ntlmssp_state;
220         unsigned char *data = NULL;
221         size_t data_len;
222         unsigned char *full_packet_data = NULL;
223         size_t full_packet_data_len;
224         DATA_BLOB auth_blob;
225         NTSTATUS status;
226
227         if (cli->auth.auth_level == PIPE_AUTH_LEVEL_NONE || cli->auth.auth_level == PIPE_AUTH_LEVEL_CONNECT) {
228                 return NT_STATUS_OK;
229         }
230
231         if (!ntlmssp_state) {
232                 return NT_STATUS_INVALID_PARAMETER;
233         }
234
235         /* Ensure there's enough data for an authenticated response. */
236         if ((auth_len > RPC_MAX_SIGN_SIZE) ||
237                         (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
238                 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
239                         (unsigned int)auth_len ));
240                 return NT_STATUS_BUFFER_TOO_SMALL;
241         }
242
243         /*
244          * We need the full packet data + length (minus auth stuff) as well as the packet data + length
245          * after the RPC header.
246          * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
247          * functions as NTLMv2 checks the rpc headers also.
248          */
249
250         data = (unsigned char *)(prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN);
251         data_len = (size_t)(prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len);
252
253         full_packet_data = (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                                 nt_errstr(fault_resp.status),
623                                 cli->cli->desthost,
624                                 cli->pipe_name,
625                                 (unsigned int)cli->fnum));
626                         if (NT_STATUS_IS_OK(fault_resp.status)) {
627                                 return NT_STATUS_UNSUCCESSFUL;
628                         } else {
629                                 return fault_resp.status;
630                         }
631                         
632                 }
633
634                 default:
635                         DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
636                                 "from remote machine %s pipe %s fnum 0x%x!\n",
637                                 (unsigned int)prhdr->pkt_type,
638                                 cli->cli->desthost,
639                                 cli->pipe_name,
640                                 (unsigned int)cli->fnum));
641                         return NT_STATUS_INVALID_INFO_CLASS;
642         }
643
644         if (prhdr->pkt_type != expected_pkt_type) {
645                 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to remote machine %s "
646                         "pipe %s fnum %x got an unexpected RPC packet "
647                         "type - %u, not %u\n",
648                         cli->cli->desthost,
649                         cli->pipe_name,
650                         (unsigned int)cli->fnum,
651                         prhdr->pkt_type,
652                         expected_pkt_type));
653                 return NT_STATUS_INVALID_INFO_CLASS;
654         }
655
656         /* Do this just before return - we don't want to modify any rpc header
657            data before now as we may have needed to do cryptographic actions on
658            it before. */
659
660         if ((prhdr->pkt_type == RPC_BINDACK) && !(prhdr->flags & RPC_FLG_LAST)) {
661                 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
662                         "setting fragment first/last ON.\n"));
663                 prhdr->flags |= RPC_FLG_FIRST|RPC_FLG_LAST;
664         }
665
666         return NT_STATUS_OK;
667 }
668
669 /****************************************************************************
670  Ensure we eat the just processed pdu from the current_pdu prs_struct.
671  Normally the frag_len and buffer size will match, but on the first trans
672  reply there is a theoretical chance that buffer size > frag_len, so we must
673  deal with that.
674  ****************************************************************************/
675
676 static NTSTATUS cli_pipe_reset_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
677 {
678         uint32 current_pdu_len = prs_data_size(current_pdu);
679
680         if (current_pdu_len < prhdr->frag_len) {
681                 return NT_STATUS_BUFFER_TOO_SMALL;
682         }
683
684         /* Common case. */
685         if (current_pdu_len == (uint32)prhdr->frag_len) {
686                 prs_mem_free(current_pdu);
687                 prs_init(current_pdu, 0, prs_get_mem_context(current_pdu), UNMARSHALL);
688                 /* Make current_pdu dynamic with no memory. */
689                 prs_give_memory(current_pdu, 0, 0, True);
690                 return NT_STATUS_OK;
691         }
692
693         /*
694          * Oh no ! More data in buffer than we processed in current pdu.
695          * Cheat. Move the data down and shrink the buffer.
696          */
697
698         memcpy(prs_data_p(current_pdu), prs_data_p(current_pdu) + prhdr->frag_len,
699                         current_pdu_len - prhdr->frag_len);
700
701         /* Remember to set the read offset back to zero. */
702         prs_set_offset(current_pdu, 0);
703
704         /* Shrink the buffer. */
705         if (!prs_set_buffer_size(current_pdu, current_pdu_len - prhdr->frag_len)) {
706                 return NT_STATUS_BUFFER_TOO_SMALL;
707         }
708
709         return NT_STATUS_OK;
710 }
711
712 /****************************************************************************
713  Send data on an rpc pipe via trans. The prs_struct data must be the last
714  pdu fragment of an NDR data stream.
715
716  Receive response data from an rpc pipe, which may be large...
717
718  Read the first fragment: unfortunately have to use SMBtrans for the first
719  bit, then SMBreadX for subsequent bits.
720
721  If first fragment received also wasn't the last fragment, continue
722  getting fragments until we _do_ receive the last fragment.
723
724  Request/Response PDU's look like the following...
725
726  |<------------------PDU len----------------------------------------------->|
727  |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
728
729  +------------+-----------------+-------------+---------------+-------------+
730  | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR      | AUTH DATA   |
731  +------------+-----------------+-------------+---------------+-------------+
732
733  Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
734  signing & sealing being negotiated.
735
736  ****************************************************************************/
737
738 static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli,
739                         prs_struct *data, /* Outgoing pdu fragment, already formatted for send. */
740                         prs_struct *rbuf, /* Incoming reply - return as an NDR stream. */
741                         uint8 expected_pkt_type)
742 {
743         NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
744         char *rparam = NULL;
745         uint32 rparam_len = 0;
746         uint16 setup[2];
747         char *pdata = data ? prs_data_p(data) : NULL;
748         uint32 data_len = data ? prs_offset(data) : 0;
749         char *prdata = NULL;
750         uint32 rdata_len = 0;
751         uint32 max_data = cli->max_xmit_frag ? cli->max_xmit_frag : RPC_MAX_PDU_FRAG_LEN;
752         uint32 current_rbuf_offset = 0;
753         prs_struct current_pdu;
754         
755 #ifdef DEVELOPER
756         /* Ensure we're not sending too much. */
757         SMB_ASSERT(data_len <= max_data);
758 #endif
759
760         /* Set up the current pdu parse struct. */
761         prs_init(&current_pdu, 0, prs_get_mem_context(rbuf), UNMARSHALL);
762
763         /* Create setup parameters - must be in native byte order. */
764         setup[0] = TRANSACT_DCERPCCMD; 
765         setup[1] = cli->fnum; /* Pipe file handle. */
766
767         DEBUG(5,("rpc_api_pipe: Remote machine %s pipe %s fnum 0x%x\n",
768                 cli->cli->desthost,
769                 cli->pipe_name,
770                 (unsigned int)cli->fnum ));
771
772         /*
773          * Send the last (or only) fragment of an RPC request. For small
774          * amounts of data (about 1024 bytes or so) the RPC request and response
775          * appears in a SMBtrans request and response.
776          */
777
778         if (!cli_api_pipe(cli->cli, "\\PIPE\\",
779                   setup, 2, 0,                     /* Setup, length, max */
780                   NULL, 0, 0,                      /* Params, length, max */
781                   pdata, data_len, max_data,       /* data, length, max */
782                   &rparam, &rparam_len,            /* return params, len */
783                   &prdata, &rdata_len))            /* return data, len */
784         {
785                 DEBUG(0, ("rpc_api_pipe: Remote machine %s pipe %s fnum 0x%x"
786                         "returned critical error. Error was %s\n",
787                         cli->cli->desthost,
788                         cli->pipe_name,
789                         (unsigned int)cli->fnum,
790                         cli_errstr(cli->cli)));
791                 ret = cli_get_nt_error(cli->cli);
792                 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, 0);
919         DATA_BLOB tkt_wrapped = data_blob(NULL, 0);
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);
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, (const char *)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, 0);
976         DATA_BLOB request = data_blob(NULL, 0);
977         DATA_BLOB spnego_msg = data_blob(NULL, 0);
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, (const char *)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, 0);
1023         DATA_BLOB request = data_blob(NULL, 0);
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, (const char *)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(uint8 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, 0);
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, (char*)&pipe_names[pipe_idx].abstr_syntax, 
1649                   sizeof(pipe_names[pipe_idx].abstr_syntax));
1650         DEBUG(5,("Bind Transfer Syntax: "));
1651         dump_data(5, (char*)&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,0);
1779         DATA_BLOB client_reply = data_blob(NULL,0);
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,0);
1904         DATA_BLOB server_ntlm_response = data_blob(NULL,0);
1905         DATA_BLOB client_reply = data_blob(NULL,0);
1906         DATA_BLOB tmp_blob = data_blob(NULL, 0);
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,0); /* 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, &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         /* Pipe is bound - set up auth_type and auth_level data. */
2145
2146         cli->auth.auth_type = auth_type;
2147         cli->auth.auth_level = auth_level;
2148
2149         prs_mem_free(&rbuf);
2150         return NT_STATUS_OK;
2151 }
2152
2153 /****************************************************************************
2154  Open a named pipe over SMB to a remote server.
2155  *
2156  * CAVEAT CALLER OF THIS FUNCTION:
2157  *    The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2158  *    so be sure that this function is called AFTER any structure (vs pointer)
2159  *    assignment of the cli.  In particular, libsmbclient does structure
2160  *    assignments of cli, which invalidates the data in the returned
2161  *    rpc_pipe_client if this function is called before the structure assignment
2162  *    of cli.
2163  * 
2164  ****************************************************************************/
2165
2166 static struct rpc_pipe_client *cli_rpc_pipe_open(struct cli_state *cli, int pipe_idx, NTSTATUS *perr)
2167 {
2168         TALLOC_CTX *mem_ctx;
2169         struct rpc_pipe_client *result;
2170         int fnum;
2171
2172         *perr = NT_STATUS_NO_MEMORY;
2173
2174         /* The pipe name index must fall within our array */
2175         SMB_ASSERT((pipe_idx >= 0) && (pipe_idx < PI_MAX_PIPES));
2176
2177         mem_ctx = talloc_init("struct rpc_pipe_client");
2178         if (mem_ctx == NULL) {
2179                 return NULL;
2180         }
2181
2182         result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
2183         if (result == NULL) {
2184                 return NULL;
2185         }
2186
2187         result->mem_ctx = mem_ctx;
2188
2189         result->pipe_name = cli_get_pipe_name(pipe_idx);
2190
2191         fnum = cli_nt_create(cli, result->pipe_name, DESIRED_ACCESS_PIPE);
2192
2193         if (fnum == -1) {
2194                 DEBUG(1,("cli_rpc_pipe_open: cli_nt_create failed on pipe %s "
2195                          "to machine %s.  Error was %s\n",
2196                          result->pipe_name, cli->desthost,
2197                          cli_errstr(cli)));
2198                 *perr = cli_get_nt_error(cli);
2199                 talloc_destroy(result->mem_ctx);
2200                 return NULL;
2201         }
2202
2203         result->fnum = fnum;
2204         result->cli = cli;
2205         result->pipe_idx = pipe_idx;
2206         result->auth.auth_type = PIPE_AUTH_TYPE_NONE;
2207         result->auth.auth_level = PIPE_AUTH_LEVEL_NONE;
2208
2209         if (pipe_idx == PI_NETLOGON) {
2210                 /* Set up a netlogon credential chain for a netlogon pipe. */
2211                 result->dc = TALLOC_ZERO_P(mem_ctx, struct dcinfo);
2212                 if (result->dc == NULL) {
2213                         talloc_destroy(result->mem_ctx);
2214                         return NULL;
2215                 }
2216         }
2217
2218         DLIST_ADD(cli->pipe_list, result);
2219         *perr = NT_STATUS_OK;
2220
2221         return result;
2222 }
2223
2224 /****************************************************************************
2225  Open a named pipe to an SMB server and bind anonymously.
2226  ****************************************************************************/
2227
2228 struct rpc_pipe_client *cli_rpc_pipe_open_noauth(struct cli_state *cli, int pipe_idx, NTSTATUS *perr)
2229 {
2230         struct rpc_pipe_client *result;
2231
2232         result = cli_rpc_pipe_open(cli, pipe_idx, perr);
2233         if (result == NULL) {
2234                 return NULL;
2235         }
2236
2237         *perr = rpc_pipe_bind(result, PIPE_AUTH_TYPE_NONE, PIPE_AUTH_LEVEL_NONE);
2238         if (!NT_STATUS_IS_OK(*perr)) {
2239                 DEBUG(0, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe %s failed with error %s\n",
2240                         cli_get_pipe_name(pipe_idx), nt_errstr(*perr) ));
2241                 cli_rpc_pipe_close(result);
2242                 return NULL;
2243         }
2244
2245         DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine %s and bound anonymously.\n",
2246                         result->pipe_name, cli->desthost ));
2247
2248         return result;
2249 }
2250
2251 /****************************************************************************
2252  Free function for NTLMSSP auth.
2253  ****************************************************************************/
2254
2255 static void cli_ntlmssp_auth_free(struct cli_pipe_auth_data *auth)
2256 {
2257         if (auth->a_u.ntlmssp_state) {
2258                 ntlmssp_end(&auth->a_u.ntlmssp_state);
2259                 auth->a_u.ntlmssp_state = NULL;
2260         }
2261 }
2262
2263 /****************************************************************************
2264  Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
2265  ****************************************************************************/
2266
2267 static struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
2268                                                 int pipe_idx,
2269                                                 enum pipe_auth_type auth_type,
2270                                                 enum pipe_auth_level auth_level,
2271                                                 const char *domain,
2272                                                 const char *username,
2273                                                 const char *password,
2274                                                 NTSTATUS *perr)
2275 {
2276         struct rpc_pipe_client *result;
2277         NTLMSSP_STATE *ntlmssp_state = NULL;
2278
2279         result = cli_rpc_pipe_open(cli, pipe_idx, perr);
2280         if (result == NULL) {
2281                 return NULL;
2282         }
2283         
2284         result->auth.cli_auth_data_free_func = cli_ntlmssp_auth_free;
2285
2286         result->domain = domain;
2287         result->user_name = username;
2288         pwd_set_cleartext(&result->pwd, password);
2289
2290         *perr = ntlmssp_client_start(&ntlmssp_state);
2291         if (!NT_STATUS_IS_OK(*perr)) {
2292                 goto err;
2293         }
2294
2295         result->auth.a_u.ntlmssp_state = ntlmssp_state;
2296
2297         *perr = ntlmssp_set_username(ntlmssp_state, cli->user_name);
2298         if (!NT_STATUS_IS_OK(*perr)) {
2299                 goto err;
2300         }
2301
2302         *perr = ntlmssp_set_domain(ntlmssp_state, cli->domain); 
2303         if (!NT_STATUS_IS_OK(*perr)) {
2304                 goto err;
2305         }
2306
2307         if (cli->pwd.null_pwd) {
2308                 *perr = ntlmssp_set_password(ntlmssp_state, NULL);
2309                 if (!NT_STATUS_IS_OK(*perr)) {
2310                         goto err;
2311                 }
2312         } else {
2313                 *perr = ntlmssp_set_password(ntlmssp_state, password);
2314                 if (!NT_STATUS_IS_OK(*perr)) {
2315                         goto err;
2316                 }
2317         }
2318
2319         /* Turn off sign+seal to allow selected auth level to turn it back on. */
2320         ntlmssp_state->neg_flags &= ~(NTLMSSP_NEGOTIATE_SIGN|NTLMSSP_NEGOTIATE_SEAL);
2321
2322         if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2323                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
2324         } else if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) {
2325                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
2326         }
2327         
2328         *perr = rpc_pipe_bind(result, auth_type, auth_level);
2329         if (!NT_STATUS_IS_OK(*perr)) {
2330                 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
2331                         nt_errstr(*perr) ));
2332                 goto err;
2333         }
2334
2335         DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to machine %s and"
2336                 "bound NTLMSSP as user %s\\%s.\n",
2337                 result->pipe_name, cli->desthost,
2338                 domain, username ));
2339
2340         return result;
2341
2342   err:
2343
2344         cli_rpc_pipe_close(result);
2345         return NULL;
2346 }
2347
2348 /****************************************************************************
2349  External interface.
2350  Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
2351  ****************************************************************************/
2352
2353 struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
2354                                                 int pipe_idx,
2355                                                 enum pipe_auth_level auth_level,
2356                                                 const char *domain,
2357                                                 const char *username,
2358                                                 const char *password,
2359                                                 NTSTATUS *perr)
2360 {
2361         return cli_rpc_pipe_open_ntlmssp_internal(cli,
2362                                                 pipe_idx,
2363                                                 PIPE_AUTH_TYPE_NTLMSSP,
2364                                                 auth_level,
2365                                                 domain,
2366                                                 username,
2367                                                 password,
2368                                                 perr);
2369 }
2370
2371 /****************************************************************************
2372  External interface.
2373  Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
2374  ****************************************************************************/
2375
2376 struct rpc_pipe_client *cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
2377                                                 int pipe_idx,
2378                                                 enum pipe_auth_level auth_level,
2379                                                 const char *domain,
2380                                                 const char *username,
2381                                                 const char *password,
2382                                                 NTSTATUS *perr)
2383 {
2384         return cli_rpc_pipe_open_ntlmssp_internal(cli,
2385                                                 pipe_idx,
2386                                                 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
2387                                                 auth_level,
2388                                                 domain,
2389                                                 username,
2390                                                 password,
2391                                                 perr);
2392 }
2393
2394 /****************************************************************************
2395  Open a netlogon pipe and get the schannel session key.
2396  ****************************************************************************/
2397
2398 static struct rpc_pipe_client *get_schannel_session_key(struct cli_state *cli,
2399                                                         const char *domain,
2400                                                         NTSTATUS *perr)
2401 {
2402         uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL;
2403         struct rpc_pipe_client *netlogon_pipe = NULL;
2404         uint32 sec_chan_type = 0;
2405         unsigned char machine_pwd[16];
2406         fstring machine_account;
2407
2408         netlogon_pipe = cli_rpc_pipe_open_noauth(cli, PI_NETLOGON, perr);
2409         if (!netlogon_pipe) {
2410                 return NULL;
2411         }
2412
2413         /* Get the machine account credentials from secrets.tdb. */
2414         if (!get_trust_pw(domain, machine_pwd, &sec_chan_type)) {
2415                 DEBUG(0, ("get_schannel_session_key: could not fetch "
2416                         "trust account password for domain '%s'\n",
2417                         domain));
2418                 cli_rpc_pipe_close(netlogon_pipe);
2419                 *perr = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2420                 return NULL;
2421         }
2422
2423         if ( IS_DC && !strequal(domain, lp_workgroup()) && lp_allow_trusted_domains()) {
2424                 fstrcpy( machine_account, lp_workgroup() );
2425         } else {
2426                 /* Hmmm. Is this correct for trusted domains when we're a member server ? JRA. */
2427                 if (strequal(domain, lp_workgroup())) {
2428                         fstrcpy(machine_account, global_myname());
2429                 } else {
2430                         fstrcpy(machine_account, domain);
2431                 }
2432         }
2433
2434         *perr = rpccli_netlogon_setup_creds(netlogon_pipe,
2435                                         cli->desthost, /* server name */
2436                                         domain,        /* domain */
2437                                         global_myname(), /* client name */
2438                                         machine_account, /* machine account name */
2439                                         machine_pwd,
2440                                         sec_chan_type,
2441                                         &neg_flags);
2442
2443         if (!NT_STATUS_IS_OK(*perr)) {
2444                 DEBUG(3,("get_schannel_session_key: rpccli_netlogon_setup_creds "
2445                         "failed with result %s to server %s, domain %s, machine account %s.\n",
2446                         nt_errstr(*perr), cli->desthost, domain, machine_account ));
2447                 cli_rpc_pipe_close(netlogon_pipe);
2448                 return NULL;
2449         }
2450
2451         if ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0) {
2452                 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
2453                         cli->desthost));
2454                 cli_rpc_pipe_close(netlogon_pipe);
2455                 *perr = NT_STATUS_INVALID_NETWORK_RESPONSE;
2456                 return NULL;
2457         }
2458
2459         return netlogon_pipe;
2460 }
2461
2462 /****************************************************************************
2463  External interface.
2464  Open a named pipe to an SMB server and bind using schannel (bind type 68)
2465  using session_key. sign and seal.
2466  ****************************************************************************/
2467
2468 struct rpc_pipe_client *cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
2469                                         int pipe_idx,
2470                                         enum pipe_auth_level auth_level,
2471                                         const char *domain,
2472                                         const struct dcinfo *pdc,
2473                                         NTSTATUS *perr)
2474 {
2475         struct rpc_pipe_client *result;
2476
2477         result = cli_rpc_pipe_open(cli, pipe_idx, perr);
2478         if (result == NULL) {
2479                 return NULL;
2480         }
2481
2482         result->auth.a_u.schannel_auth = TALLOC_ZERO_P(result->mem_ctx, struct schannel_auth_struct);
2483         if (!result->auth.a_u.schannel_auth) {
2484                 cli_rpc_pipe_close(result);
2485                 *perr = NT_STATUS_NO_MEMORY;
2486                 return NULL;
2487         }
2488
2489         result->domain = domain;
2490         memcpy(result->auth.a_u.schannel_auth->sess_key, pdc->sess_key, 16);
2491
2492         *perr = rpc_pipe_bind(result, PIPE_AUTH_TYPE_SCHANNEL, auth_level);
2493         if (!NT_STATUS_IS_OK(*perr)) {
2494                 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: cli_rpc_pipe_bind failed with error %s\n",
2495                         nt_errstr(*perr) ));
2496                 cli_rpc_pipe_close(result);
2497                 return NULL;
2498         }
2499
2500         /* The credentials on a new netlogon pipe are the ones we are passed in - copy them over. */
2501         if (result->dc) {
2502                 *result->dc = *pdc;
2503         }
2504
2505         DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
2506                 "for domain %s "
2507                 "and bound using schannel.\n",
2508                 result->pipe_name, cli->desthost, domain ));
2509
2510         return result;
2511 }
2512
2513 /****************************************************************************
2514  Open a named pipe to an SMB server and bind using schannel (bind type 68).
2515  Fetch the session key ourselves using a temporary netlogon pipe. This
2516  version uses an ntlmssp auth bound netlogon pipe to get the key.
2517  ****************************************************************************/
2518
2519 static struct rpc_pipe_client *get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
2520                                                         const char *domain,
2521                                                         const char *username,
2522                                                         const char *password,
2523                                                         NTSTATUS *perr)
2524 {
2525         uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL;
2526         struct rpc_pipe_client *netlogon_pipe = NULL;
2527         uint32 sec_chan_type = 0;
2528         unsigned char machine_pwd[16];
2529         fstring machine_account;
2530
2531         netlogon_pipe = cli_rpc_pipe_open_spnego_ntlmssp(cli, PI_NETLOGON, PIPE_AUTH_LEVEL_PRIVACY, domain, username, password, perr);
2532         if (!netlogon_pipe) {
2533                 return NULL;
2534         }
2535
2536         /* Get the machine account credentials from secrets.tdb. */
2537         if (!get_trust_pw(domain, machine_pwd, &sec_chan_type)) {
2538                 DEBUG(0, ("get_schannel_session_key_auth_ntlmssp: could not fetch "
2539                         "trust account password for domain '%s'\n",
2540                         domain));
2541                 cli_rpc_pipe_close(netlogon_pipe);
2542                 *perr = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2543                 return NULL;
2544         }
2545
2546         /* if we are a DC and this is a trusted domain, then we need to use our
2547            domain name in the net_req_auth2() request */
2548
2549         if ( IS_DC && !strequal(domain, lp_workgroup()) && lp_allow_trusted_domains()) {
2550                 fstrcpy( machine_account, lp_workgroup() );
2551         } else {
2552                 /* Hmmm. Is this correct for trusted domains when we're a member server ? JRA. */
2553                 if (strequal(domain, lp_workgroup())) {
2554                         fstrcpy(machine_account, global_myname());
2555                 } else {
2556                         fstrcpy(machine_account, domain);
2557                 }
2558         }
2559
2560         *perr = rpccli_netlogon_setup_creds(netlogon_pipe,
2561                                         cli->desthost,     /* server name */
2562                                         domain,            /* domain */
2563                                         global_myname(),   /* client name */
2564                                         machine_account,   /* machine account name */
2565                                         machine_pwd,
2566                                         sec_chan_type,
2567                                         &neg_flags);
2568
2569         if (!NT_STATUS_IS_OK(*perr)) {
2570                 DEBUG(3,("get_schannel_session_key_auth_ntlmssp: rpccli_netlogon_setup_creds "
2571                         "failed with result %s\n",
2572                         nt_errstr(*perr) ));
2573                 cli_rpc_pipe_close(netlogon_pipe);
2574                 return NULL;
2575         }
2576
2577         if ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0) {
2578                 DEBUG(3, ("get_schannel_session_key_auth_ntlmssp: Server %s did not offer schannel\n",
2579                         cli->desthost));
2580                 cli_rpc_pipe_close(netlogon_pipe);
2581                 *perr = NT_STATUS_INVALID_NETWORK_RESPONSE;
2582                 return NULL;
2583         }
2584
2585         return netlogon_pipe;
2586 }
2587
2588 /****************************************************************************
2589  Open a named pipe to an SMB server and bind using schannel (bind type 68).
2590  Fetch the session key ourselves using a temporary netlogon pipe. This version
2591  uses an ntlmssp bind to get the session key.
2592  ****************************************************************************/
2593
2594 struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
2595                                                 int pipe_idx,
2596                                                 enum pipe_auth_level auth_level,
2597                                                 const char *domain,
2598                                                 const char *username,
2599                                                 const char *password,
2600                                                 NTSTATUS *perr)
2601 {
2602         struct rpc_pipe_client *netlogon_pipe = NULL;
2603         struct rpc_pipe_client *result = NULL;
2604
2605         netlogon_pipe = get_schannel_session_key_auth_ntlmssp(cli, domain, username, password, perr);
2606         if (!netlogon_pipe) {
2607                 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
2608                         "key from server %s for domain %s.\n",
2609                         cli->desthost, domain ));
2610                 return NULL;
2611         }
2612
2613         result = cli_rpc_pipe_open_schannel_with_key(cli, pipe_idx,
2614                                 auth_level,
2615                                 domain, netlogon_pipe->dc, perr);
2616
2617         /* Now we've bound using the session key we can close the netlog pipe. */
2618         cli_rpc_pipe_close(netlogon_pipe);
2619
2620         return result;
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.
2626  ****************************************************************************/
2627
2628 struct rpc_pipe_client *cli_rpc_pipe_open_schannel(struct cli_state *cli,
2629                                                 int pipe_idx,
2630                                                 enum pipe_auth_level auth_level,
2631                                                 const char *domain,
2632                                                 NTSTATUS *perr)
2633 {
2634         struct rpc_pipe_client *netlogon_pipe = NULL;
2635         struct rpc_pipe_client *result = NULL;
2636
2637         netlogon_pipe = get_schannel_session_key(cli, domain, perr);
2638         if (!netlogon_pipe) {
2639                 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
2640                         "key from server %s for domain %s.\n",
2641                         cli->desthost, domain ));
2642                 return NULL;
2643         }
2644
2645         result = cli_rpc_pipe_open_schannel_with_key(cli, pipe_idx,
2646                                 auth_level,
2647                                 domain, netlogon_pipe->dc, perr);
2648
2649         /* Now we've bound using the session key we can close the netlog pipe. */
2650         cli_rpc_pipe_close(netlogon_pipe);
2651
2652         return result;
2653 }
2654
2655 #ifdef HAVE_KRB5
2656
2657 /****************************************************************************
2658  Free function for the kerberos spcific data.
2659  ****************************************************************************/
2660
2661 static void kerberos_auth_struct_free(struct cli_pipe_auth_data *a)
2662 {
2663         data_blob_free(&a->a_u.kerberos_auth->session_key);
2664 }
2665
2666 #endif
2667
2668 /****************************************************************************
2669  Open a named pipe to an SMB server and bind using krb5 (bind type 16).
2670  The idea is this can be called with service_princ, username and password all
2671  NULL so long as the caller has a TGT.
2672  ****************************************************************************/
2673
2674 struct rpc_pipe_client *cli_rpc_pipe_open_krb5(struct cli_state *cli,
2675                                                 int pipe_idx,
2676                                                 enum pipe_auth_level auth_level,
2677                                                 const char *service_princ,
2678                                                 const char *username,
2679                                                 const char *password,
2680                                                 NTSTATUS *perr)
2681 {
2682 #ifdef HAVE_KRB5
2683         struct rpc_pipe_client *result;
2684
2685         result = cli_rpc_pipe_open(cli, pipe_idx, perr);
2686         if (result == NULL) {
2687                 return NULL;
2688         }
2689
2690         /* Default service principal is "host/server@realm" */
2691         if (!service_princ) {
2692                 service_princ = talloc_asprintf(result->mem_ctx, "host/%s@%s",
2693                         cli->desthost, lp_realm() );
2694                 if (!service_princ) {
2695                         cli_rpc_pipe_close(result);
2696                         return NULL;
2697                 }
2698         }
2699
2700         /* Only get a new TGT if username/password are given. */
2701         if (username && password) {
2702                 int ret = kerberos_kinit_password(username, password, 0, NULL, NULL, NULL, False, 0);
2703                 if (ret) {
2704                         cli_rpc_pipe_close(result);
2705                         return NULL;
2706                 }
2707         }
2708
2709         result->auth.a_u.kerberos_auth = TALLOC_ZERO_P(cli->mem_ctx, struct kerberos_auth_struct);
2710         if (!result->auth.a_u.kerberos_auth) {
2711                 cli_rpc_pipe_close(result);
2712                 *perr = NT_STATUS_NO_MEMORY;
2713                 return NULL;
2714         }
2715
2716         result->auth.a_u.kerberos_auth->service_principal = service_princ;
2717         result->auth.cli_auth_data_free_func = kerberos_auth_struct_free;
2718
2719         *perr = rpc_pipe_bind(result, PIPE_AUTH_TYPE_KRB5, auth_level);
2720         if (!NT_STATUS_IS_OK(*perr)) {
2721                 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed with error %s\n",
2722                         nt_errstr(*perr) ));
2723                 cli_rpc_pipe_close(result);
2724                 return NULL;
2725         }
2726
2727         return result;
2728 #else
2729         DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
2730         return NULL;
2731 #endif
2732 }
2733
2734 #if 0 /* Moved to libsmb/clientgen.c */
2735 /****************************************************************************
2736  External interface.
2737  Close an open named pipe over SMB. Free any authentication data.
2738  ****************************************************************************/
2739
2740  void cli_rpc_pipe_close(struct rpc_pipe_client *cli)
2741 {
2742         if (!cli_close(cli->cli, cli->fnum)) {
2743                 DEBUG(0,("cli_rpc_pipe_close: cli_close failed on pipe %s "
2744                          "to machine %s.  Error was %s\n",
2745                          cli->pipe_name),
2746                          cli->cli->desthost,
2747                          cli_errstr(cli->cli)));
2748         }
2749
2750         if (cli->auth.cli_auth_data_free_func) {
2751                 (*cli->auth.cli_auth_data_free_func)(&cli->auth);
2752         }
2753         DEBUG(10,("cli_rpc_pipe_close: closed pipe %s to machine %s\n",
2754                 cli->pipe_name, cli->cli->desthost ));
2755
2756         DLIST_REMOVE(cli->cli->pipe_list, cli);
2757         talloc_destroy(cli->mem_ctx);   
2758 }
2759 #endif