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