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