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