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