Create rpccli_xxx_bind_data functions
[ira/wip.git] / source3 / rpc_client / cli_pipe.c
1 /* 
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Largely rewritten by Jeremy Allison             2005.
5  *  
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 3 of the License, or
9  *  (at your option) any later version.
10  *  
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *  
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include "includes.h"
21
22 #undef DBGC_CLASS
23 #define DBGC_CLASS DBGC_RPC_CLI
24
25 extern struct pipe_id_info pipe_names[];
26
27 /********************************************************************
28  Map internal value to wire value.
29  ********************************************************************/
30
31 static int map_pipe_auth_type_to_rpc_auth_type(enum pipe_auth_type auth_type)
32 {
33         switch (auth_type) {
34
35         case PIPE_AUTH_TYPE_NONE:
36                 return RPC_ANONYMOUS_AUTH_TYPE;
37
38         case PIPE_AUTH_TYPE_NTLMSSP:
39                 return RPC_NTLMSSP_AUTH_TYPE;
40
41         case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
42         case PIPE_AUTH_TYPE_SPNEGO_KRB5:
43                 return RPC_SPNEGO_AUTH_TYPE;
44
45         case PIPE_AUTH_TYPE_SCHANNEL:
46                 return RPC_SCHANNEL_AUTH_TYPE;
47
48         case PIPE_AUTH_TYPE_KRB5:
49                 return RPC_KRB5_AUTH_TYPE;
50
51         default:
52                 DEBUG(0,("map_pipe_auth_type_to_rpc_type: unknown pipe "
53                         "auth type %u\n",
54                         (unsigned int)auth_type ));
55                 break;
56         }
57         return -1;
58 }
59
60 /********************************************************************
61  Rpc pipe call id.
62  ********************************************************************/
63
64 static uint32 get_rpc_call_id(void)
65 {
66         static uint32 call_id = 0;
67         return ++call_id;
68 }
69
70 /*******************************************************************
71  Use SMBreadX to get rest of one fragment's worth of rpc data.
72  Will expand the current_pdu struct to the correct size.
73  ********************************************************************/
74
75 static NTSTATUS rpc_read(struct rpc_pipe_client *cli,
76                         prs_struct *current_pdu,
77                         uint32 data_to_read,
78                         uint32 *current_pdu_offset)
79 {
80         size_t size = (size_t)cli->max_recv_frag;
81         uint32 stream_offset = 0;
82         ssize_t num_read;
83         char *pdata;
84         ssize_t extra_data_size = ((ssize_t)*current_pdu_offset) + ((ssize_t)data_to_read) - (ssize_t)prs_data_size(current_pdu);
85
86         DEBUG(5,("rpc_read: data_to_read: %u current_pdu offset: %u extra_data_size: %d\n",
87                 (unsigned int)data_to_read, (unsigned int)*current_pdu_offset, (int)extra_data_size ));
88
89         /*
90          * Grow the buffer if needed to accommodate the data to be read.
91          */
92
93         if (extra_data_size > 0) {
94                 if(!prs_force_grow(current_pdu, (uint32)extra_data_size)) {
95                         DEBUG(0,("rpc_read: Failed to grow parse struct by %d bytes.\n", (int)extra_data_size ));
96                         return NT_STATUS_NO_MEMORY;
97                 }
98                 DEBUG(5,("rpc_read: grew buffer by %d bytes to %u\n", (int)extra_data_size, prs_data_size(current_pdu) ));
99         }
100
101         pdata = prs_data_p(current_pdu) + *current_pdu_offset;
102
103         do {
104                 /* read data using SMBreadX */
105                 if (size > (size_t)data_to_read) {
106                         size = (size_t)data_to_read;
107                 }
108
109                 num_read = cli_read(cli->cli, cli->fnum, pdata,
110                                          (off_t)stream_offset, size);
111
112                 DEBUG(5,("rpc_read: num_read = %d, read offset: %u, to read: %u\n",
113                         (int)num_read, (unsigned int)stream_offset, (unsigned int)data_to_read));
114
115                 /*
116                  * A dos error of ERRDOS/ERRmoredata is not an error.
117                  */
118                 if (cli_is_dos_error(cli->cli)) {
119                         uint32 ecode;
120                         uint8 eclass;
121                         cli_dos_error(cli->cli, &eclass, &ecode);
122                         if (eclass != ERRDOS && ecode != ERRmoredata) {
123                                 DEBUG(0,("rpc_read: DOS Error %d/%u (%s) in cli_read on pipe %s\n",
124                                         eclass, (unsigned int)ecode,
125                                         cli_errstr(cli->cli),
126                                         cli->pipe_name ));
127                                 return dos_to_ntstatus(eclass, ecode);
128                         }
129                 }
130
131                 /*
132                  * Likewise for NT_STATUS_BUFFER_TOO_SMALL
133                  */
134                 if (cli_is_nt_error(cli->cli)) {
135                         if (!NT_STATUS_EQUAL(cli_nt_error(cli->cli), NT_STATUS_BUFFER_TOO_SMALL)) {
136                                 DEBUG(0,("rpc_read: Error (%s) in cli_read on pipe %s\n",
137                                         nt_errstr(cli_nt_error(cli->cli)),
138                                         cli->pipe_name ));
139                                 return cli_nt_error(cli->cli);
140                         }
141                 }
142
143                 if (num_read == -1) {
144                         DEBUG(0,("rpc_read: Error - cli_read on pipe %s returned -1\n",
145                                 cli->pipe_name ));
146                         return cli_get_nt_error(cli->cli);
147                 }
148
149                 data_to_read -= num_read;
150                 stream_offset += num_read;
151                 pdata += num_read;
152
153         } while (num_read > 0 && data_to_read > 0);
154         /* && err == (0x80000000 | STATUS_BUFFER_OVERFLOW)); */
155
156         /*
157          * Update the current offset into current_pdu by the amount read.
158          */
159         *current_pdu_offset += stream_offset;
160         return NT_STATUS_OK;
161 }
162
163 /****************************************************************************
164  Try and get a PDU's worth of data from current_pdu. If not, then read more
165  from the wire.
166  ****************************************************************************/
167
168 static NTSTATUS cli_pipe_get_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
169 {
170         NTSTATUS ret = NT_STATUS_OK;
171         uint32 current_pdu_len = prs_data_size(current_pdu);
172
173         /* Ensure we have at least RPC_HEADER_LEN worth of data to parse. */
174         if (current_pdu_len < RPC_HEADER_LEN) {
175                 /* rpc_read expands the current_pdu struct as neccessary. */
176                 ret = rpc_read(cli, current_pdu, RPC_HEADER_LEN - current_pdu_len, &current_pdu_len);
177                 if (!NT_STATUS_IS_OK(ret)) {
178                         return ret;
179                 }
180         }
181
182         /* This next call sets the endian bit correctly in current_pdu. */
183         /* We will propagate this to rbuf later. */
184         if(!smb_io_rpc_hdr("rpc_hdr   ", prhdr, current_pdu, 0)) {
185                 DEBUG(0,("cli_pipe_get_current_pdu: Failed to unmarshall RPC_HDR.\n"));
186                 return NT_STATUS_BUFFER_TOO_SMALL;
187         }
188
189         /* Ensure we have frag_len bytes of data. */
190         if (current_pdu_len < prhdr->frag_len) {
191                 /* rpc_read expands the current_pdu struct as neccessary. */
192                 ret = rpc_read(cli, current_pdu, (uint32)prhdr->frag_len - current_pdu_len, &current_pdu_len);
193                 if (!NT_STATUS_IS_OK(ret)) {
194                         return ret;
195                 }
196         }
197
198         if (current_pdu_len < prhdr->frag_len) {
199                 return NT_STATUS_BUFFER_TOO_SMALL;
200         }
201
202         return NT_STATUS_OK;
203 }
204
205 /****************************************************************************
206  NTLMSSP specific sign/seal.
207  Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.
208  In fact I should probably abstract these into identical pieces of code... JRA.
209  ****************************************************************************/
210
211 static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
212                                 prs_struct *current_pdu,
213                                 uint8 *p_ss_padding_len)
214 {
215         RPC_HDR_AUTH auth_info;
216         uint32 save_offset = prs_offset(current_pdu);
217         uint32 auth_len = prhdr->auth_len;
218         NTLMSSP_STATE *ntlmssp_state = cli->auth->a_u.ntlmssp_state;
219         unsigned char *data = NULL;
220         size_t data_len;
221         unsigned char *full_packet_data = NULL;
222         size_t full_packet_data_len;
223         DATA_BLOB auth_blob;
224         NTSTATUS status;
225
226         if (cli->auth->auth_level == PIPE_AUTH_LEVEL_NONE
227             || cli->auth->auth_level == PIPE_AUTH_LEVEL_CONNECT) {
228                 return NT_STATUS_OK;
229         }
230
231         if (!ntlmssp_state) {
232                 return NT_STATUS_INVALID_PARAMETER;
233         }
234
235         /* Ensure there's enough data for an authenticated response. */
236         if ((auth_len > RPC_MAX_SIGN_SIZE) ||
237                         (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
238                 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
239                         (unsigned int)auth_len ));
240                 return NT_STATUS_BUFFER_TOO_SMALL;
241         }
242
243         /*
244          * We need the full packet data + length (minus auth stuff) as well as the packet data + length
245          * after the RPC header.
246          * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
247          * functions as NTLMv2 checks the rpc headers also.
248          */
249
250         data = (unsigned char *)(prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN);
251         data_len = (size_t)(prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len);
252
253         full_packet_data = (unsigned char *)prs_data_p(current_pdu);
254         full_packet_data_len = prhdr->frag_len - auth_len;
255
256         /* Pull the auth header and the following data into a blob. */
257         if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
258                 DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n",
259                         (unsigned int)RPC_HEADER_LEN + (unsigned int)RPC_HDR_RESP_LEN + (unsigned int)data_len ));
260                 return NT_STATUS_BUFFER_TOO_SMALL;
261         }
262
263         if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
264                 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall RPC_HDR_AUTH.\n"));
265                 return NT_STATUS_BUFFER_TOO_SMALL;
266         }
267
268         auth_blob.data = (unsigned char *)prs_data_p(current_pdu) + prs_offset(current_pdu);
269         auth_blob.length = auth_len;
270
271         switch (cli->auth->auth_level) {
272                 case PIPE_AUTH_LEVEL_PRIVACY:
273                         /* Data is encrypted. */
274                         status = ntlmssp_unseal_packet(ntlmssp_state,
275                                                         data, data_len,
276                                                         full_packet_data,
277                                                         full_packet_data_len,
278                                                         &auth_blob);
279                         if (!NT_STATUS_IS_OK(status)) {
280                                 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal "
281                                         "packet from remote machine %s on pipe %s "
282                                         "fnum 0x%x. Error was %s.\n",
283                                         cli->desthost,
284                                         cli->pipe_name,
285                                         (unsigned int)cli->fnum,
286                                         nt_errstr(status) ));
287                                 return status;
288                         }
289                         break;
290                 case PIPE_AUTH_LEVEL_INTEGRITY:
291                         /* Data is signed. */
292                         status = ntlmssp_check_packet(ntlmssp_state,
293                                                         data, data_len,
294                                                         full_packet_data,
295                                                         full_packet_data_len,
296                                                         &auth_blob);
297                         if (!NT_STATUS_IS_OK(status)) {
298                                 DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on "
299                                         "packet from remote machine %s on pipe %s "
300                                         "fnum 0x%x. Error was %s.\n",
301                                         cli->desthost,
302                                         cli->pipe_name,
303                                         (unsigned int)cli->fnum,
304                                         nt_errstr(status) ));
305                                 return status;
306                         }
307                         break;
308                 default:
309                         DEBUG(0, ("cli_pipe_verify_ntlmssp: unknown internal "
310                                   "auth level %d\n", cli->auth->auth_level));
311                         return NT_STATUS_INVALID_INFO_CLASS;
312         }
313
314         /*
315          * Return the current pointer to the data offset.
316          */
317
318         if(!prs_set_offset(current_pdu, save_offset)) {
319                 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
320                         (unsigned int)save_offset ));
321                 return NT_STATUS_BUFFER_TOO_SMALL;
322         }
323
324         /*
325          * Remember the padding length. We must remove it from the real data
326          * stream once the sign/seal is done.
327          */
328
329         *p_ss_padding_len = auth_info.auth_pad_len;
330
331         return NT_STATUS_OK;
332 }
333
334 /****************************************************************************
335  schannel specific sign/seal.
336  ****************************************************************************/
337
338 static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
339                                 prs_struct *current_pdu,
340                                 uint8 *p_ss_padding_len)
341 {
342         RPC_HDR_AUTH auth_info;
343         RPC_AUTH_SCHANNEL_CHK schannel_chk;
344         uint32 auth_len = prhdr->auth_len;
345         uint32 save_offset = prs_offset(current_pdu);
346         struct schannel_auth_struct *schannel_auth =
347                 cli->auth->a_u.schannel_auth;
348         uint32 data_len;
349
350         if (cli->auth->auth_level == PIPE_AUTH_LEVEL_NONE
351             || cli->auth->auth_level == PIPE_AUTH_LEVEL_CONNECT) {
352                 return NT_STATUS_OK;
353         }
354
355         if (auth_len != RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) {
356                 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u.\n", (unsigned int)auth_len ));
357                 return NT_STATUS_INVALID_PARAMETER;
358         }
359
360         if (!schannel_auth) {
361                 return NT_STATUS_INVALID_PARAMETER;
362         }
363
364         /* Ensure there's enough data for an authenticated response. */
365         if ((auth_len > RPC_MAX_SIGN_SIZE) ||
366                         (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
367                 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u is too large.\n",
368                         (unsigned int)auth_len ));
369                 return NT_STATUS_INVALID_PARAMETER;
370         }
371
372         data_len = prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len;
373
374         if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
375                 DEBUG(0,("cli_pipe_verify_schannel: cannot move offset to %u.\n",
376                         (unsigned int)RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len ));
377                 return NT_STATUS_BUFFER_TOO_SMALL;
378         }
379
380         if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
381                 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshall RPC_HDR_AUTH.\n"));
382                 return NT_STATUS_BUFFER_TOO_SMALL;
383         }
384
385         if (auth_info.auth_type != RPC_SCHANNEL_AUTH_TYPE) {
386                 DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n",
387                         auth_info.auth_type));
388                 return NT_STATUS_BUFFER_TOO_SMALL;
389         }
390
391         if(!smb_io_rpc_auth_schannel_chk("", RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN,
392                                 &schannel_chk, current_pdu, 0)) {
393                 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshal RPC_AUTH_SCHANNEL_CHK.\n"));
394                 return NT_STATUS_BUFFER_TOO_SMALL;
395         }
396
397         if (!schannel_decode(schannel_auth,
398                         cli->auth->auth_level,
399                         SENDER_IS_ACCEPTOR,
400                         &schannel_chk,
401                         prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN,
402                         data_len)) {
403                 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
404                                 "Connection to remote machine %s "
405                                 "pipe %s fnum 0x%x.\n",
406                                 cli->desthost,
407                                 cli->pipe_name,
408                                 (unsigned int)cli->fnum ));
409                 return NT_STATUS_INVALID_PARAMETER;
410         }
411
412         /* The sequence number gets incremented on both send and receive. */
413         schannel_auth->seq_num++;
414
415         /*
416          * Return the current pointer to the data offset.
417          */
418
419         if(!prs_set_offset(current_pdu, save_offset)) {
420                 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
421                         (unsigned int)save_offset ));
422                 return NT_STATUS_BUFFER_TOO_SMALL;
423         }
424
425         /*
426          * Remember the padding length. We must remove it from the real data
427          * stream once the sign/seal is done.
428          */
429
430         *p_ss_padding_len = auth_info.auth_pad_len;
431
432         return NT_STATUS_OK;
433 }
434
435 /****************************************************************************
436  Do the authentication checks on an incoming pdu. Check sign and unseal etc.
437  ****************************************************************************/
438
439 static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
440                                 prs_struct *current_pdu,
441                                 uint8 *p_ss_padding_len)
442 {
443         NTSTATUS ret = NT_STATUS_OK;
444
445         /* Paranioa checks for auth_len. */
446         if (prhdr->auth_len) {
447                 if (prhdr->auth_len > prhdr->frag_len) {
448                         return NT_STATUS_INVALID_PARAMETER;
449                 }
450
451                 if (prhdr->auth_len + RPC_HDR_AUTH_LEN < prhdr->auth_len ||
452                                 prhdr->auth_len + RPC_HDR_AUTH_LEN < RPC_HDR_AUTH_LEN) {
453                         /* Integer wrap attempt. */
454                         return NT_STATUS_INVALID_PARAMETER;
455                 }
456         }
457
458         /*
459          * Now we have a complete RPC request PDU fragment, try and verify any auth data.
460          */
461
462         switch(cli->auth->auth_type) {
463                 case PIPE_AUTH_TYPE_NONE:
464                         if (prhdr->auth_len) {
465                                 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection to remote machine %s "
466                                         "pipe %s fnum 0x%x - got non-zero auth len %u.\n",
467                                         cli->desthost,
468                                         cli->pipe_name,
469                                         (unsigned int)cli->fnum,
470                                         (unsigned int)prhdr->auth_len ));
471                                 return NT_STATUS_INVALID_PARAMETER;
472                         }
473                         break;
474
475                 case PIPE_AUTH_TYPE_NTLMSSP:
476                 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
477                         ret = cli_pipe_verify_ntlmssp(cli, prhdr, current_pdu, p_ss_padding_len);
478                         if (!NT_STATUS_IS_OK(ret)) {
479                                 return ret;
480                         }
481                         break;
482
483                 case PIPE_AUTH_TYPE_SCHANNEL:
484                         ret = cli_pipe_verify_schannel(cli, prhdr, current_pdu, p_ss_padding_len);
485                         if (!NT_STATUS_IS_OK(ret)) {
486                                 return ret;
487                         }
488                         break;
489
490                 case PIPE_AUTH_TYPE_KRB5:
491                 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
492                 default:
493                         DEBUG(3, ("cli_pipe_validate_rpc_response: Connection "
494                                   "to remote machine %s pipe %s fnum %x - "
495                                   "unknown internal auth type %u.\n",
496                                   cli->desthost, cli->pipe_name,
497                                   (unsigned int)cli->fnum,
498                                   cli->auth->auth_type ));
499                         return NT_STATUS_INVALID_INFO_CLASS;
500         }
501
502         return NT_STATUS_OK;
503 }
504
505 /****************************************************************************
506  Do basic authentication checks on an incoming pdu.
507  ****************************************************************************/
508
509 static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
510                         prs_struct *current_pdu,
511                         uint8 expected_pkt_type,
512                         char **ppdata,
513                         uint32 *pdata_len,
514                         prs_struct *return_data)
515 {
516
517         NTSTATUS ret = NT_STATUS_OK;
518         uint32 current_pdu_len = prs_data_size(current_pdu);
519
520         if (current_pdu_len != prhdr->frag_len) {
521                 DEBUG(5,("cli_pipe_validate_current_pdu: incorrect pdu length %u, expected %u\n",
522                         (unsigned int)current_pdu_len, (unsigned int)prhdr->frag_len ));
523                 return NT_STATUS_INVALID_PARAMETER;
524         }
525
526         /*
527          * Point the return values at the real data including the RPC
528          * header. Just in case the caller wants it.
529          */
530         *ppdata = prs_data_p(current_pdu);
531         *pdata_len = current_pdu_len;
532
533         /* Ensure we have the correct type. */
534         switch (prhdr->pkt_type) {
535                 case RPC_ALTCONTRESP:
536                 case RPC_BINDACK:
537
538                         /* Alter context and bind ack share the same packet definitions. */
539                         break;
540
541
542                 case RPC_RESPONSE:
543                 {
544                         RPC_HDR_RESP rhdr_resp;
545                         uint8 ss_padding_len = 0;
546
547                         if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
548                                 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
549                                 return NT_STATUS_BUFFER_TOO_SMALL;
550                         }
551
552                         /* Here's where we deal with incoming sign/seal. */
553                         ret = cli_pipe_validate_rpc_response(cli, prhdr,
554                                         current_pdu, &ss_padding_len);
555                         if (!NT_STATUS_IS_OK(ret)) {
556                                 return ret;
557                         }
558
559                         /* Point the return values at the NDR data. Remember to remove any ss padding. */
560                         *ppdata = prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
561
562                         if (current_pdu_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN + ss_padding_len) {
563                                 return NT_STATUS_BUFFER_TOO_SMALL;
564                         }
565
566                         *pdata_len = current_pdu_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - ss_padding_len;
567
568                         /* Remember to remove the auth footer. */
569                         if (prhdr->auth_len) {
570                                 /* We've already done integer wrap tests on auth_len in
571                                         cli_pipe_validate_rpc_response(). */
572                                 if (*pdata_len < RPC_HDR_AUTH_LEN + prhdr->auth_len) {
573                                         return NT_STATUS_BUFFER_TOO_SMALL;
574                                 }
575                                 *pdata_len -= (RPC_HDR_AUTH_LEN + prhdr->auth_len);
576                         }
577
578                         DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n",
579                                 current_pdu_len, *pdata_len, ss_padding_len ));
580
581                         /*
582                          * If this is the first reply, and the allocation hint is reasonably, try and
583                          * set up the return_data parse_struct to the correct size.
584                          */
585
586                         if ((prs_data_size(return_data) == 0) && rhdr_resp.alloc_hint && (rhdr_resp.alloc_hint < 15*1024*1024)) {
587                                 if (!prs_set_buffer_size(return_data, rhdr_resp.alloc_hint)) {
588                                         DEBUG(0,("cli_pipe_validate_current_pdu: reply alloc hint %u "
589                                                 "too large to allocate\n",
590                                                 (unsigned int)rhdr_resp.alloc_hint ));
591                                         return NT_STATUS_NO_MEMORY;
592                                 }
593                         }
594
595                         break;
596                 }
597
598                 case RPC_BINDNACK:
599                         DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK received from remote machine %s "
600                                 "pipe %s fnum 0x%x!\n",
601                                 cli->desthost,
602                                 cli->pipe_name,
603                                 (unsigned int)cli->fnum));
604                         /* Use this for now... */
605                         return NT_STATUS_NETWORK_ACCESS_DENIED;
606
607                 case RPC_FAULT:
608                 {
609                         RPC_HDR_RESP rhdr_resp;
610                         RPC_HDR_FAULT fault_resp;
611
612                         if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
613                                 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
614                                 return NT_STATUS_BUFFER_TOO_SMALL;
615                         }
616
617                         if(!smb_io_rpc_hdr_fault("fault", &fault_resp, current_pdu, 0)) {
618                                 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_FAULT.\n"));
619                                 return NT_STATUS_BUFFER_TOO_SMALL;
620                         }
621
622                         DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault code %s received from remote machine %s "
623                                 "pipe %s fnum 0x%x!\n",
624                                 dcerpc_errstr(NT_STATUS_V(fault_resp.status)),
625                                 cli->desthost,
626                                 cli->pipe_name,
627                                 (unsigned int)cli->fnum));
628                         if (NT_STATUS_IS_OK(fault_resp.status)) {
629                                 return NT_STATUS_UNSUCCESSFUL;
630                         } else {
631                                 return fault_resp.status;
632                         }
633                 }
634
635                 default:
636                         DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
637                                 "from remote machine %s pipe %s fnum 0x%x!\n",
638                                 (unsigned int)prhdr->pkt_type,
639                                 cli->desthost,
640                                 cli->pipe_name,
641                                 (unsigned int)cli->fnum));
642                         return NT_STATUS_INVALID_INFO_CLASS;
643         }
644
645         if (prhdr->pkt_type != expected_pkt_type) {
646                 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to remote machine %s "
647                         "pipe %s fnum %x got an unexpected RPC packet "
648                         "type - %u, not %u\n",
649                         cli->desthost,
650                         cli->pipe_name,
651                         (unsigned int)cli->fnum,
652                         prhdr->pkt_type,
653                         expected_pkt_type));
654                 return NT_STATUS_INVALID_INFO_CLASS;
655         }
656
657         /* Do this just before return - we don't want to modify any rpc header
658            data before now as we may have needed to do cryptographic actions on
659            it before. */
660
661         if ((prhdr->pkt_type == RPC_BINDACK) && !(prhdr->flags & RPC_FLG_LAST)) {
662                 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
663                         "setting fragment first/last ON.\n"));
664                 prhdr->flags |= RPC_FLG_FIRST|RPC_FLG_LAST;
665         }
666
667         return NT_STATUS_OK;
668 }
669
670 /****************************************************************************
671  Ensure we eat the just processed pdu from the current_pdu prs_struct.
672  Normally the frag_len and buffer size will match, but on the first trans
673  reply there is a theoretical chance that buffer size > frag_len, so we must
674  deal with that.
675  ****************************************************************************/
676
677 static NTSTATUS cli_pipe_reset_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
678 {
679         uint32 current_pdu_len = prs_data_size(current_pdu);
680
681         if (current_pdu_len < prhdr->frag_len) {
682                 return NT_STATUS_BUFFER_TOO_SMALL;
683         }
684
685         /* Common case. */
686         if (current_pdu_len == (uint32)prhdr->frag_len) {
687                 prs_mem_free(current_pdu);
688                 prs_init_empty(current_pdu, prs_get_mem_context(current_pdu), UNMARSHALL);
689                 /* Make current_pdu dynamic with no memory. */
690                 prs_give_memory(current_pdu, 0, 0, True);
691                 return NT_STATUS_OK;
692         }
693
694         /*
695          * Oh no ! More data in buffer than we processed in current pdu.
696          * Cheat. Move the data down and shrink the buffer.
697          */
698
699         memcpy(prs_data_p(current_pdu), prs_data_p(current_pdu) + prhdr->frag_len,
700                         current_pdu_len - prhdr->frag_len);
701
702         /* Remember to set the read offset back to zero. */
703         prs_set_offset(current_pdu, 0);
704
705         /* Shrink the buffer. */
706         if (!prs_set_buffer_size(current_pdu, current_pdu_len - prhdr->frag_len)) {
707                 return NT_STATUS_BUFFER_TOO_SMALL;
708         }
709
710         return NT_STATUS_OK;
711 }
712
713 /****************************************************************************
714  Send data on an rpc pipe via trans. The prs_struct data must be the last
715  pdu fragment of an NDR data stream.
716
717  Receive response data from an rpc pipe, which may be large...
718
719  Read the first fragment: unfortunately have to use SMBtrans for the first
720  bit, then SMBreadX for subsequent bits.
721
722  If first fragment received also wasn't the last fragment, continue
723  getting fragments until we _do_ receive the last fragment.
724
725  Request/Response PDU's look like the following...
726
727  |<------------------PDU len----------------------------------------------->|
728  |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
729
730  +------------+-----------------+-------------+---------------+-------------+
731  | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR      | AUTH DATA   |
732  +------------+-----------------+-------------+---------------+-------------+
733
734  Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
735  signing & sealing being negotiated.
736
737  ****************************************************************************/
738
739 static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli,
740                         prs_struct *data, /* Outgoing pdu fragment, already formatted for send. */
741                         prs_struct *rbuf, /* Incoming reply - return as an NDR stream. */
742                         uint8 expected_pkt_type)
743 {
744         NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
745         char *rparam = NULL;
746         uint32 rparam_len = 0;
747         uint16 setup[2];
748         char *pdata = prs_data_p(data);
749         uint32 data_len = prs_offset(data);
750         char *prdata = NULL;
751         uint32 rdata_len = 0;
752         uint32 max_data = cli->max_xmit_frag ? cli->max_xmit_frag : RPC_MAX_PDU_FRAG_LEN;
753         uint32 current_rbuf_offset = 0;
754         prs_struct current_pdu;
755
756 #ifdef DEVELOPER
757         /* Ensure we're not sending too much. */
758         SMB_ASSERT(data_len <= max_data);
759 #endif
760
761         /* Set up the current pdu parse struct. */
762         prs_init_empty(&current_pdu, prs_get_mem_context(rbuf), UNMARSHALL);
763
764         /* Create setup parameters - must be in native byte order. */
765         setup[0] = TRANSACT_DCERPCCMD; 
766         setup[1] = cli->fnum; /* Pipe file handle. */
767
768         DEBUG(5,("rpc_api_pipe: Remote machine %s pipe %s fnum 0x%x\n",
769                 cli->desthost,
770                 cli->pipe_name,
771                 (unsigned int)cli->fnum ));
772
773         /*
774          * Send the last (or only) fragment of an RPC request. For small
775          * amounts of data (about 1024 bytes or so) the RPC request and response
776          * appears in a SMBtrans request and response.
777          */
778
779         if (!cli_api_pipe(cli->cli, "\\PIPE\\",
780                   setup, 2, 0,                     /* Setup, length, max */
781                   NULL, 0, 0,                      /* Params, length, max */
782                   pdata, data_len, max_data,       /* data, length, max */
783                   &rparam, &rparam_len,            /* return params, len */
784                   &prdata, &rdata_len))            /* return data, len */
785         {
786                 DEBUG(0, ("rpc_api_pipe: Remote machine %s pipe %s fnum 0x%x "
787                         "returned critical error. Error was %s\n",
788                         cli->desthost,
789                         cli->pipe_name,
790                         (unsigned int)cli->fnum,
791                         cli_errstr(cli->cli)));
792                 ret = cli_get_nt_error(cli->cli);
793                 SAFE_FREE(rparam);
794                 SAFE_FREE(prdata);
795                 goto err;
796         }
797
798         /* Throw away returned params - we know we won't use them. */
799
800         SAFE_FREE(rparam);
801
802         if (prdata == NULL) {
803                 DEBUG(3,("rpc_api_pipe: Remote machine %s pipe %s "
804                         "fnum 0x%x failed to return data.\n",
805                         cli->desthost,
806                         cli->pipe_name,
807                         (unsigned int)cli->fnum));
808                 /* Yes - some calls can truely return no data... */
809                 prs_mem_free(&current_pdu);
810                 return NT_STATUS_OK;
811         }
812
813         /*
814          * Give this memory as dynamic to the current pdu.
815          */
816
817         prs_give_memory(&current_pdu, prdata, rdata_len, True);
818
819         /* Ensure we can mess with the return prs_struct. */
820         SMB_ASSERT(UNMARSHALLING(rbuf));
821         SMB_ASSERT(prs_data_size(rbuf) == 0);
822
823         /* Make rbuf dynamic with no memory. */
824         prs_give_memory(rbuf, 0, 0, True);
825
826         while(1) {
827                 RPC_HDR rhdr;
828                 char *ret_data;
829                 uint32 ret_data_len;
830
831                 /* Ensure we have enough data for a pdu. */
832                 ret = cli_pipe_get_current_pdu(cli, &rhdr, &current_pdu);
833                 if (!NT_STATUS_IS_OK(ret)) {
834                         goto err;
835                 }
836
837                 /* We pass in rbuf here so if the alloc hint is set correctly 
838                    we can set the output size and avoid reallocs. */
839
840                 ret = cli_pipe_validate_current_pdu(cli, &rhdr, &current_pdu, expected_pkt_type,
841                                 &ret_data, &ret_data_len, rbuf);
842
843                 DEBUG(10,("rpc_api_pipe: got PDU len of %u at offset %u\n",
844                         prs_data_size(&current_pdu), current_rbuf_offset ));
845
846                 if (!NT_STATUS_IS_OK(ret)) {
847                         goto err;
848                 }
849
850                 if ((rhdr.flags & RPC_FLG_FIRST)) {
851                         if (rhdr.pack_type[0] == 0) {
852                                 /* Set the data type correctly for big-endian data on the first packet. */
853                                 DEBUG(10,("rpc_api_pipe: On machine %s pipe %s fnum 0x%x "
854                                         "PDU data format is big-endian.\n",
855                                         cli->desthost,
856                                         cli->pipe_name,
857                                         (unsigned int)cli->fnum));
858
859                                 prs_set_endian_data(rbuf, RPC_BIG_ENDIAN);
860                         } else {
861                                 /* Check endianness on subsequent packets. */
862                                 if (current_pdu.bigendian_data != rbuf->bigendian_data) {
863                                         DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to %s\n",
864                                                 rbuf->bigendian_data ? "big" : "little",
865                                                 current_pdu.bigendian_data ? "big" : "little" ));
866                                         ret = NT_STATUS_INVALID_PARAMETER;
867                                         goto err;
868                                 }
869                         }
870                 }
871
872                 /* Now copy the data portion out of the pdu into rbuf. */
873                 if (!prs_force_grow(rbuf, ret_data_len)) {
874                         ret = NT_STATUS_NO_MEMORY;
875                         goto err;
876                 }
877                 memcpy(prs_data_p(rbuf)+current_rbuf_offset, ret_data, (size_t)ret_data_len);
878                 current_rbuf_offset += ret_data_len;
879
880                 /* See if we've finished with all the data in current_pdu yet ? */
881                 ret = cli_pipe_reset_current_pdu(cli, &rhdr, &current_pdu);
882                 if (!NT_STATUS_IS_OK(ret)) {
883                         goto err;
884                 }
885
886                 if (rhdr.flags & RPC_FLG_LAST) {
887                         break; /* We're done. */
888                 }
889         }
890
891         DEBUG(10,("rpc_api_pipe: Remote machine %s pipe %s fnum 0x%x returned %u bytes.\n",
892                 cli->desthost,
893                 cli->pipe_name,
894                 (unsigned int)cli->fnum,
895                 (unsigned int)prs_data_size(rbuf) ));
896
897         prs_mem_free(&current_pdu);
898         return NT_STATUS_OK;
899
900   err:
901
902         prs_mem_free(&current_pdu);
903         prs_mem_free(rbuf);
904         return ret;
905 }
906
907 /*******************************************************************
908  Creates krb5 auth bind.
909  ********************************************************************/
910
911 static NTSTATUS create_krb5_auth_bind_req( struct rpc_pipe_client *cli,
912                                                 enum pipe_auth_level auth_level,
913                                                 RPC_HDR_AUTH *pauth_out,
914                                                 prs_struct *auth_data)
915 {
916 #ifdef HAVE_KRB5
917         int ret;
918         struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth;
919         DATA_BLOB tkt = data_blob_null;
920         DATA_BLOB tkt_wrapped = data_blob_null;
921
922         /* We may change the pad length before marshalling. */
923         init_rpc_hdr_auth(pauth_out, RPC_KRB5_AUTH_TYPE, (int)auth_level, 0, 1);
924
925         DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
926                 a->service_principal ));
927
928         /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
929
930         ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
931                         &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL);
932
933         if (ret) {
934                 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
935                         "failed with %s\n",
936                         a->service_principal,
937                         error_message(ret) ));
938
939                 data_blob_free(&tkt);
940                 prs_mem_free(auth_data);
941                 return NT_STATUS_INVALID_PARAMETER;
942         }
943
944         /* wrap that up in a nice GSS-API wrapping */
945         tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
946
947         data_blob_free(&tkt);
948
949         /* Auth len in the rpc header doesn't include auth_header. */
950         if (!prs_copy_data_in(auth_data, (char *)tkt_wrapped.data, tkt_wrapped.length)) {
951                 data_blob_free(&tkt_wrapped);
952                 prs_mem_free(auth_data);
953                 return NT_STATUS_NO_MEMORY;
954         }
955
956         DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
957         dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
958
959         data_blob_free(&tkt_wrapped);
960         return NT_STATUS_OK;
961 #else
962         return NT_STATUS_INVALID_PARAMETER;
963 #endif
964 }
965
966 /*******************************************************************
967  Creates SPNEGO NTLMSSP auth bind.
968  ********************************************************************/
969
970 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
971                                                 enum pipe_auth_level auth_level,
972                                                 RPC_HDR_AUTH *pauth_out,
973                                                 prs_struct *auth_data)
974 {
975         NTSTATUS nt_status;
976         DATA_BLOB null_blob = data_blob_null;
977         DATA_BLOB request = data_blob_null;
978         DATA_BLOB spnego_msg = data_blob_null;
979
980         /* We may change the pad length before marshalling. */
981         init_rpc_hdr_auth(pauth_out, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
982
983         DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
984         nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
985                                         null_blob,
986                                         &request);
987
988         if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
989                 data_blob_free(&request);
990                 prs_mem_free(auth_data);
991                 return nt_status;
992         }
993
994         /* Wrap this in SPNEGO. */
995         spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
996
997         data_blob_free(&request);
998
999         /* Auth len in the rpc header doesn't include auth_header. */
1000         if (!prs_copy_data_in(auth_data, (char *)spnego_msg.data, spnego_msg.length)) {
1001                 data_blob_free(&spnego_msg);
1002                 prs_mem_free(auth_data);
1003                 return NT_STATUS_NO_MEMORY;
1004         }
1005
1006         DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1007         dump_data(5, spnego_msg.data, spnego_msg.length);
1008
1009         data_blob_free(&spnego_msg);
1010         return NT_STATUS_OK;
1011 }
1012
1013 /*******************************************************************
1014  Creates NTLMSSP auth bind.
1015  ********************************************************************/
1016
1017 static NTSTATUS create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1018                                                 enum pipe_auth_level auth_level,
1019                                                 RPC_HDR_AUTH *pauth_out,
1020                                                 prs_struct *auth_data)
1021 {
1022         NTSTATUS nt_status;
1023         DATA_BLOB null_blob = data_blob_null;
1024         DATA_BLOB request = data_blob_null;
1025
1026         /* We may change the pad length before marshalling. */
1027         init_rpc_hdr_auth(pauth_out, RPC_NTLMSSP_AUTH_TYPE, (int)auth_level, 0, 1);
1028
1029         DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1030         nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1031                                         null_blob,
1032                                         &request);
1033
1034         if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1035                 data_blob_free(&request);
1036                 prs_mem_free(auth_data);
1037                 return nt_status;
1038         }
1039
1040         /* Auth len in the rpc header doesn't include auth_header. */
1041         if (!prs_copy_data_in(auth_data, (char *)request.data, request.length)) {
1042                 data_blob_free(&request);
1043                 prs_mem_free(auth_data);
1044                 return NT_STATUS_NO_MEMORY;
1045         }
1046
1047         DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1048         dump_data(5, request.data, request.length);
1049
1050         data_blob_free(&request);
1051         return NT_STATUS_OK;
1052 }
1053
1054 /*******************************************************************
1055  Creates schannel auth bind.
1056  ********************************************************************/
1057
1058 static NTSTATUS create_schannel_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1059                                                 enum pipe_auth_level auth_level,
1060                                                 RPC_HDR_AUTH *pauth_out,
1061                                                 prs_struct *auth_data)
1062 {
1063         RPC_AUTH_SCHANNEL_NEG schannel_neg;
1064
1065         /* We may change the pad length before marshalling. */
1066         init_rpc_hdr_auth(pauth_out, RPC_SCHANNEL_AUTH_TYPE, (int)auth_level, 0, 1);
1067
1068         /* Use lp_workgroup() if domain not specified */
1069
1070         if (!cli->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 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2189                                struct cli_pipe_auth_data **presult)
2190 {
2191         struct cli_pipe_auth_data *result;
2192
2193         result = talloc(mem_ctx, struct cli_pipe_auth_data);
2194         if (result == NULL) {
2195                 return NT_STATUS_NO_MEMORY;
2196         }
2197
2198         result->auth_type = PIPE_AUTH_TYPE_NONE;
2199         result->auth_level = PIPE_AUTH_LEVEL_NONE;
2200
2201         result->user_name = talloc_strdup(result, "");
2202         result->domain = talloc_strdup(result, "");
2203         if ((result->user_name == NULL) || (result->domain == NULL)) {
2204                 TALLOC_FREE(result);
2205                 return NT_STATUS_NO_MEMORY;
2206         }
2207
2208         *presult = result;
2209         return NT_STATUS_OK;
2210 }
2211
2212 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth)
2213 {
2214         ntlmssp_end(&auth->a_u.ntlmssp_state);
2215         return 0;
2216 }
2217
2218 NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
2219                                   enum pipe_auth_type auth_type,
2220                                   enum pipe_auth_level auth_level,
2221                                   const char *domain,
2222                                   const char *username,
2223                                   const char *password,
2224                                   struct cli_pipe_auth_data **presult)
2225 {
2226         struct cli_pipe_auth_data *result;
2227         NTSTATUS status;
2228
2229         result = talloc(mem_ctx, struct cli_pipe_auth_data);
2230         if (result == NULL) {
2231                 return NT_STATUS_NO_MEMORY;
2232         }
2233
2234         result->auth_type = auth_type;
2235         result->auth_level = auth_level;
2236
2237         result->user_name = talloc_strdup(result, username);
2238         result->domain = talloc_strdup(result, domain);
2239         if ((result->user_name == NULL) || (result->domain == NULL)) {
2240                 status = NT_STATUS_NO_MEMORY;
2241                 goto fail;
2242         }
2243
2244         status = ntlmssp_client_start(&result->a_u.ntlmssp_state);
2245         if (!NT_STATUS_IS_OK(status)) {
2246                 goto fail;
2247         }
2248
2249         talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
2250
2251         status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);
2252         if (!NT_STATUS_IS_OK(status)) {
2253                 goto fail;
2254         }
2255
2256         status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);
2257         if (!NT_STATUS_IS_OK(status)) {
2258                 goto fail;
2259         }
2260
2261         status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);
2262         if (!NT_STATUS_IS_OK(status)) {
2263                 goto fail;
2264         }
2265
2266         /*
2267          * Turn off sign+seal to allow selected auth level to turn it back on.
2268          */
2269         result->a_u.ntlmssp_state->neg_flags &=
2270                 ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);
2271
2272         if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2273                 result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
2274         } else if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) {
2275                 result->a_u.ntlmssp_state->neg_flags
2276                         |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
2277         }
2278
2279         *presult = result;
2280         return NT_STATUS_OK;
2281
2282  fail:
2283         TALLOC_FREE(result);
2284         return status;
2285 }
2286
2287 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
2288                                    enum pipe_auth_level auth_level,
2289                                    const struct dcinfo *pdc,
2290                                    struct cli_pipe_auth_data **presult)
2291 {
2292         struct cli_pipe_auth_data *result;
2293
2294         result = talloc(mem_ctx, struct cli_pipe_auth_data);
2295         if (result == NULL) {
2296                 return NT_STATUS_NO_MEMORY;
2297         }
2298
2299         result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
2300         result->auth_level = auth_level;
2301
2302         result->user_name = talloc_strdup(result, "");
2303         result->domain = talloc_strdup(result, domain);
2304         if ((result->user_name == NULL) || (result->domain == NULL)) {
2305                 goto fail;
2306         }
2307
2308         result->a_u.schannel_auth = talloc(result,
2309                                            struct schannel_auth_struct);
2310         if (result->a_u.schannel_auth == NULL) {
2311                 goto fail;
2312         }
2313
2314         memcpy(result->a_u.schannel_auth->sess_key, pdc->sess_key, 16);
2315         result->a_u.schannel_auth->seq_num = 0;
2316
2317         *presult = result;
2318         return NT_STATUS_OK;
2319
2320  fail:
2321         TALLOC_FREE(result);
2322         return NT_STATUS_NO_MEMORY;
2323 }
2324
2325 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
2326 {
2327         data_blob_free(&auth->session_key);
2328         return 0;
2329 }
2330
2331 NTSTATUS rpccli_krb5_bind_data(TALLOC_CTX *mem_ctx,
2332                                enum pipe_auth_level auth_level,
2333                                const char *service_princ,
2334                                const char *username,
2335                                const char *password,
2336                                struct cli_pipe_auth_data **presult)
2337 {
2338         struct cli_pipe_auth_data *result;
2339
2340         if ((username != NULL) && (password != NULL)) {
2341                 int ret = kerberos_kinit_password(username, password, 0, NULL);
2342                 if (ret != 0) {
2343                         return NT_STATUS_ACCESS_DENIED;
2344                 }
2345         }
2346
2347         result = talloc(mem_ctx, struct cli_pipe_auth_data);
2348         if (result == NULL) {
2349                 return NT_STATUS_NO_MEMORY;
2350         }
2351
2352         result->auth_type = PIPE_AUTH_TYPE_KRB5;
2353         result->auth_level = auth_level;
2354
2355         /*
2356          * Username / domain need fixing!
2357          */
2358         result->user_name = talloc_strdup(result, "");
2359         result->domain = talloc_strdup(result, "");
2360         if ((result->user_name == NULL) || (result->domain == NULL)) {
2361                 goto fail;
2362         }
2363
2364         result->a_u.kerberos_auth = TALLOC_ZERO_P(
2365                 result, struct kerberos_auth_struct);
2366         if (result->a_u.kerberos_auth == NULL) {
2367                 goto fail;
2368         }
2369         talloc_set_destructor(result->a_u.kerberos_auth,
2370                               cli_auth_kerberos_data_destructor);
2371
2372         result->a_u.kerberos_auth->service_principal = talloc_strdup(
2373                 result, service_princ);
2374         if (result->a_u.kerberos_auth->service_principal == NULL) {
2375                 goto fail;
2376         }
2377
2378         *presult = result;
2379         return NT_STATUS_OK;
2380
2381  fail:
2382         TALLOC_FREE(result);
2383         return NT_STATUS_NO_MEMORY;
2384 }
2385
2386 /****************************************************************************
2387  Open a named pipe over SMB to a remote server.
2388  *
2389  * CAVEAT CALLER OF THIS FUNCTION:
2390  *    The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2391  *    so be sure that this function is called AFTER any structure (vs pointer)
2392  *    assignment of the cli.  In particular, libsmbclient does structure
2393  *    assignments of cli, which invalidates the data in the returned
2394  *    rpc_pipe_client if this function is called before the structure assignment
2395  *    of cli.
2396  * 
2397  ****************************************************************************/
2398
2399 static struct rpc_pipe_client *cli_rpc_pipe_open(struct cli_state *cli, int pipe_idx, NTSTATUS *perr)
2400 {
2401         struct rpc_pipe_client *result;
2402         int fnum;
2403
2404         *perr = NT_STATUS_NO_MEMORY;
2405
2406         /* sanity check to protect against crashes */
2407
2408         if ( !cli ) {
2409                 *perr = NT_STATUS_INVALID_HANDLE;
2410                 return NULL;
2411         }
2412
2413         /* The pipe name index must fall within our array */
2414         SMB_ASSERT((pipe_idx >= 0) && (pipe_idx < PI_MAX_PIPES));
2415
2416         result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
2417         if (result == NULL) {
2418                 *perr = NT_STATUS_NO_MEMORY;
2419                 return NULL;
2420         }
2421
2422         result->auth = TALLOC_ZERO_P(result, struct cli_pipe_auth_data);
2423         if (result->auth == NULL) {
2424                 *perr = NT_STATUS_NO_MEMORY;
2425                 TALLOC_FREE(result);
2426                 return NULL;
2427         }
2428
2429         result->pipe_name = cli_get_pipe_name(pipe_idx);
2430
2431         result->cli = cli;
2432         result->abstract_syntax = pipe_names[pipe_idx].abstr_syntax;
2433         result->transfer_syntax = pipe_names[pipe_idx].trans_syntax;
2434         result->auth->auth_type = PIPE_AUTH_TYPE_NONE;
2435         result->auth->auth_level = PIPE_AUTH_LEVEL_NONE;
2436
2437         result->auth->domain = talloc_strdup(result, cli->domain);
2438         result->auth->user_name = talloc_strdup(result, cli->user_name);
2439         result->desthost = talloc_strdup(result, cli->desthost);
2440         result->srv_name_slash = talloc_asprintf_strupper_m(
2441                 result, "\\\\%s", result->desthost);
2442
2443         if ((result->auth->domain == NULL)
2444             || (result->auth->user_name == NULL)
2445             || (result->desthost == NULL)
2446             || (result->srv_name_slash == NULL)) {
2447                 *perr = NT_STATUS_NO_MEMORY;
2448                 TALLOC_FREE(result);
2449                 return NULL;
2450         }
2451
2452         if (pipe_idx == PI_NETLOGON) {
2453                 /* Set up a netlogon credential chain for a netlogon pipe. */
2454                 result->dc = TALLOC_ZERO_P(result, struct dcinfo);
2455                 if (result->dc == NULL) {
2456                         *perr = NT_STATUS_NO_MEMORY;
2457                         TALLOC_FREE(result);
2458                         return NULL;
2459                 }
2460         }
2461
2462         fnum = cli_nt_create(cli, result->pipe_name, DESIRED_ACCESS_PIPE);
2463         if (fnum == -1) {
2464                 DEBUG(1,("cli_rpc_pipe_open: cli_nt_create failed on pipe %s "
2465                          "to machine %s.  Error was %s\n",
2466                          result->pipe_name, cli->desthost,
2467                          cli_errstr(cli)));
2468                 *perr = cli_get_nt_error(cli);
2469                 talloc_destroy(result);
2470                 return NULL;
2471         }
2472
2473         result->fnum = fnum;
2474
2475         DLIST_ADD(cli->pipe_list, result);
2476         talloc_set_destructor(result, rpc_pipe_destructor);
2477
2478         *perr = NT_STATUS_OK;
2479
2480         return result;
2481 }
2482
2483 /****************************************************************************
2484  Open a named pipe to an SMB server and bind anonymously.
2485  ****************************************************************************/
2486
2487 struct rpc_pipe_client *cli_rpc_pipe_open_noauth(struct cli_state *cli, int pipe_idx, NTSTATUS *perr)
2488 {
2489         struct rpc_pipe_client *result;
2490
2491         result = cli_rpc_pipe_open(cli, pipe_idx, perr);
2492         if (result == NULL) {
2493                 return NULL;
2494         }
2495
2496         *perr = rpc_pipe_bind(result, PIPE_AUTH_TYPE_NONE, PIPE_AUTH_LEVEL_NONE);
2497         if (!NT_STATUS_IS_OK(*perr)) {
2498                 int lvl = 0;
2499                 if (rpccli_is_pipe_idx(result, PI_DSSETUP)) {
2500                         /* non AD domains just don't have this pipe, avoid
2501                          * level 0 statement in that case - gd */
2502                         lvl = 3;
2503                 }
2504                 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe %s failed with error %s\n",
2505                         cli_get_pipe_name(pipe_idx), nt_errstr(*perr) ));
2506                 TALLOC_FREE(result);
2507                 return NULL;
2508         }
2509
2510         DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine %s and bound anonymously.\n",
2511                         result->pipe_name, cli->desthost ));
2512
2513         return result;
2514 }
2515
2516 /****************************************************************************
2517  Free function for NTLMSSP auth.
2518  ****************************************************************************/
2519
2520 static void cli_ntlmssp_auth_free(struct cli_pipe_auth_data *auth)
2521 {
2522         if (auth->a_u.ntlmssp_state) {
2523                 ntlmssp_end(&auth->a_u.ntlmssp_state);
2524                 auth->a_u.ntlmssp_state = NULL;
2525         }
2526 }
2527
2528 /****************************************************************************
2529  Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
2530  ****************************************************************************/
2531
2532 static struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
2533                                                 int pipe_idx,
2534                                                 enum pipe_auth_type auth_type,
2535                                                 enum pipe_auth_level auth_level,
2536                                                 const char *domain,
2537                                                 const char *username,
2538                                                 const char *password,
2539                                                 NTSTATUS *perr)
2540 {
2541         struct rpc_pipe_client *result;
2542         NTLMSSP_STATE *ntlmssp_state = NULL;
2543
2544         result = cli_rpc_pipe_open(cli, pipe_idx, perr);
2545         if (result == NULL) {
2546                 return NULL;
2547         }
2548
2549         result->auth->cli_auth_data_free_func = cli_ntlmssp_auth_free;
2550
2551         TALLOC_FREE(result->auth->domain);
2552         TALLOC_FREE(result->auth->user_name);
2553
2554         result->auth->domain = talloc_strdup(result, domain);
2555         result->auth->user_name = talloc_strdup(result, username);
2556
2557         if ((result->auth->domain == NULL)
2558             || (result->auth->user_name == NULL)) {
2559                 *perr = NT_STATUS_NO_MEMORY;
2560                 goto err;
2561         }
2562
2563         *perr = ntlmssp_client_start(&ntlmssp_state);
2564         if (!NT_STATUS_IS_OK(*perr)) {
2565                 goto err;
2566         }
2567
2568         result->auth->a_u.ntlmssp_state = ntlmssp_state;
2569
2570         *perr = ntlmssp_set_username(ntlmssp_state, username);
2571         if (!NT_STATUS_IS_OK(*perr)) {
2572                 goto err;
2573         }
2574
2575         *perr = ntlmssp_set_domain(ntlmssp_state, domain);
2576         if (!NT_STATUS_IS_OK(*perr)) {
2577                 goto err;
2578         }
2579
2580         if (cli->pwd.null_pwd) {
2581                 *perr = ntlmssp_set_password(ntlmssp_state, NULL);
2582                 if (!NT_STATUS_IS_OK(*perr)) {
2583                         goto err;
2584                 }
2585         } else {
2586                 *perr = ntlmssp_set_password(ntlmssp_state, password);
2587                 if (!NT_STATUS_IS_OK(*perr)) {
2588                         goto err;
2589                 }
2590         }
2591
2592         /* Turn off sign+seal to allow selected auth level to turn it back on. */
2593         ntlmssp_state->neg_flags &= ~(NTLMSSP_NEGOTIATE_SIGN|NTLMSSP_NEGOTIATE_SEAL);
2594
2595         if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2596                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
2597         } else if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) {
2598                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
2599         }
2600
2601         *perr = rpc_pipe_bind(result, auth_type, auth_level);
2602         if (!NT_STATUS_IS_OK(*perr)) {
2603                 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
2604                         nt_errstr(*perr) ));
2605                 goto err;
2606         }
2607
2608         DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
2609                 "machine %s and bound NTLMSSP as user %s\\%s.\n",
2610                 result->pipe_name, cli->desthost,
2611                 domain, username ));
2612
2613         return result;
2614
2615   err:
2616
2617         TALLOC_FREE(result);
2618         return NULL;
2619 }
2620
2621 /****************************************************************************
2622  External interface.
2623  Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
2624  ****************************************************************************/
2625
2626 struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
2627                                                 int pipe_idx,
2628                                                 enum pipe_auth_level auth_level,
2629                                                 const char *domain,
2630                                                 const char *username,
2631                                                 const char *password,
2632                                                 NTSTATUS *perr)
2633 {
2634         return cli_rpc_pipe_open_ntlmssp_internal(cli,
2635                                                 pipe_idx,
2636                                                 PIPE_AUTH_TYPE_NTLMSSP,
2637                                                 auth_level,
2638                                                 domain,
2639                                                 username,
2640                                                 password,
2641                                                 perr);
2642 }
2643
2644 /****************************************************************************
2645  External interface.
2646  Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
2647  ****************************************************************************/
2648
2649 struct rpc_pipe_client *cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
2650                                                 int pipe_idx,
2651                                                 enum pipe_auth_level auth_level,
2652                                                 const char *domain,
2653                                                 const char *username,
2654                                                 const char *password,
2655                                                 NTSTATUS *perr)
2656 {
2657         return cli_rpc_pipe_open_ntlmssp_internal(cli,
2658                                                 pipe_idx,
2659                                                 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
2660                                                 auth_level,
2661                                                 domain,
2662                                                 username,
2663                                                 password,
2664                                                 perr);
2665 }
2666
2667 /****************************************************************************
2668   Get a the schannel session key out of an already opened netlogon pipe.
2669  ****************************************************************************/
2670 static bool get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
2671                                             struct cli_state *cli,
2672                                             const char *domain,
2673                                             uint32 *pneg_flags,
2674                                             NTSTATUS *perr)
2675 {
2676         uint32 sec_chan_type = 0;
2677         unsigned char machine_pwd[16];
2678         const char *machine_account;
2679
2680         /* Get the machine account credentials from secrets.tdb. */
2681         if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
2682                                &sec_chan_type))
2683         {
2684                 DEBUG(0, ("get_schannel_session_key: could not fetch "
2685                         "trust account password for domain '%s'\n",
2686                         domain));
2687                 *perr = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2688                 return false;
2689         }
2690
2691         *perr = rpccli_netlogon_setup_creds(netlogon_pipe,
2692                                         cli->desthost, /* server name */
2693                                         domain,        /* domain */
2694                                         global_myname(), /* client name */
2695                                         machine_account, /* machine account name */
2696                                         machine_pwd,
2697                                         sec_chan_type,
2698                                         pneg_flags);
2699
2700         if (!NT_STATUS_IS_OK(*perr)) {
2701                 DEBUG(3,("get_schannel_session_key_common: rpccli_netlogon_setup_creds "
2702                         "failed with result %s to server %s, domain %s, machine account %s.\n",
2703                         nt_errstr(*perr), cli->desthost, domain, machine_account ));
2704                 return false;
2705         }
2706
2707         if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
2708                 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
2709                         cli->desthost));
2710                 *perr = NT_STATUS_INVALID_NETWORK_RESPONSE;
2711                 return false;
2712         }
2713
2714         return true;
2715 }
2716
2717 /****************************************************************************
2718  Open a netlogon pipe and get the schannel session key.
2719  Now exposed to external callers.
2720  ****************************************************************************/
2721
2722
2723 struct rpc_pipe_client *get_schannel_session_key(struct cli_state *cli,
2724                                                         const char *domain,
2725                                                         uint32 *pneg_flags,
2726                                                         NTSTATUS *perr)
2727 {
2728         struct rpc_pipe_client *netlogon_pipe = NULL;
2729
2730         netlogon_pipe = cli_rpc_pipe_open_noauth(cli, PI_NETLOGON, perr);
2731         if (!netlogon_pipe) {
2732                 return NULL;
2733         }
2734
2735         if (!get_schannel_session_key_common(netlogon_pipe, cli, domain,
2736                                              pneg_flags, perr))
2737         {
2738                 TALLOC_FREE(netlogon_pipe);
2739                 return NULL;
2740         }
2741
2742         return netlogon_pipe;
2743 }
2744
2745 /****************************************************************************
2746  External interface.
2747  Open a named pipe to an SMB server and bind using schannel (bind type 68)
2748  using session_key. sign and seal.
2749  ****************************************************************************/
2750
2751 struct rpc_pipe_client *cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
2752                                         int pipe_idx,
2753                                         enum pipe_auth_level auth_level,
2754                                         const char *domain,
2755                                         const struct dcinfo *pdc,
2756                                         NTSTATUS *perr)
2757 {
2758         struct rpc_pipe_client *result;
2759
2760         result = cli_rpc_pipe_open(cli, pipe_idx, perr);
2761         if (result == NULL) {
2762                 return NULL;
2763         }
2764
2765         result->auth->a_u.schannel_auth = TALLOC_ZERO_P(
2766                 result, struct schannel_auth_struct);
2767         if (!result->auth->a_u.schannel_auth) {
2768                 TALLOC_FREE(result);
2769                 *perr = NT_STATUS_NO_MEMORY;
2770                 return NULL;
2771         }
2772
2773         TALLOC_FREE(result->auth->domain);
2774         result->auth->domain = talloc_strdup(result, domain);
2775         if (result->auth->domain == NULL) {
2776                 TALLOC_FREE(result);
2777                 *perr = NT_STATUS_NO_MEMORY;
2778                 return NULL;
2779         }
2780
2781         memcpy(result->auth->a_u.schannel_auth->sess_key, pdc->sess_key, 16);
2782
2783         *perr = rpc_pipe_bind(result, PIPE_AUTH_TYPE_SCHANNEL, auth_level);
2784         if (!NT_STATUS_IS_OK(*perr)) {
2785                 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: cli_rpc_pipe_bind failed with error %s\n",
2786                         nt_errstr(*perr) ));
2787                 TALLOC_FREE(result);
2788                 return NULL;
2789         }
2790
2791         /* The credentials on a new netlogon pipe are the ones we are passed in - copy them over. */
2792         if (result->dc) {
2793                 *result->dc = *pdc;
2794         }
2795
2796         DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
2797                 "for domain %s "
2798                 "and bound using schannel.\n",
2799                 result->pipe_name, cli->desthost, domain ));
2800
2801         return result;
2802 }
2803
2804 /****************************************************************************
2805  Open a named pipe to an SMB server and bind using schannel (bind type 68).
2806  Fetch the session key ourselves using a temporary netlogon pipe. This
2807  version uses an ntlmssp auth bound netlogon pipe to get the key.
2808  ****************************************************************************/
2809
2810 static struct rpc_pipe_client *get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
2811                                                         const char *domain,
2812                                                         const char *username,
2813                                                         const char *password,
2814                                                         uint32 *pneg_flags,
2815                                                         NTSTATUS *perr)
2816 {
2817         struct rpc_pipe_client *netlogon_pipe = NULL;
2818
2819         netlogon_pipe = cli_rpc_pipe_open_spnego_ntlmssp(cli, PI_NETLOGON, PIPE_AUTH_LEVEL_PRIVACY, domain, username, password, perr);
2820         if (!netlogon_pipe) {
2821                 return NULL;
2822         }
2823
2824         if (!get_schannel_session_key_common(netlogon_pipe, cli, domain,
2825                                              pneg_flags, perr))
2826         {
2827                 TALLOC_FREE(netlogon_pipe);
2828                 return NULL;
2829         }
2830
2831         return netlogon_pipe;
2832 }
2833
2834 /****************************************************************************
2835  Open a named pipe to an SMB server and bind using schannel (bind type 68).
2836  Fetch the session key ourselves using a temporary netlogon pipe. This version
2837  uses an ntlmssp bind to get the session key.
2838  ****************************************************************************/
2839
2840 struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
2841                                                 int pipe_idx,
2842                                                 enum pipe_auth_level auth_level,
2843                                                 const char *domain,
2844                                                 const char *username,
2845                                                 const char *password,
2846                                                 NTSTATUS *perr)
2847 {
2848         uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
2849         struct rpc_pipe_client *netlogon_pipe = NULL;
2850         struct rpc_pipe_client *result = NULL;
2851
2852         netlogon_pipe = get_schannel_session_key_auth_ntlmssp(cli, domain, username,
2853                                                         password, &neg_flags, perr);
2854         if (!netlogon_pipe) {
2855                 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
2856                         "key from server %s for domain %s.\n",
2857                         cli->desthost, domain ));
2858                 return NULL;
2859         }
2860
2861         result = cli_rpc_pipe_open_schannel_with_key(cli, pipe_idx,
2862                                 auth_level,
2863                                 domain, netlogon_pipe->dc, perr);
2864
2865         /* Now we've bound using the session key we can close the netlog pipe. */
2866         TALLOC_FREE(netlogon_pipe);
2867
2868         return result;
2869 }
2870
2871 /****************************************************************************
2872  Open a named pipe to an SMB server and bind using schannel (bind type 68).
2873  Fetch the session key ourselves using a temporary netlogon pipe.
2874  ****************************************************************************/
2875
2876 struct rpc_pipe_client *cli_rpc_pipe_open_schannel(struct cli_state *cli,
2877                                                 int pipe_idx,
2878                                                 enum pipe_auth_level auth_level,
2879                                                 const char *domain,
2880                                                 NTSTATUS *perr)
2881 {
2882         uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
2883         struct rpc_pipe_client *netlogon_pipe = NULL;
2884         struct rpc_pipe_client *result = NULL;
2885
2886         netlogon_pipe = get_schannel_session_key(cli, domain, &neg_flags, perr);
2887         if (!netlogon_pipe) {
2888                 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
2889                         "key from server %s for domain %s.\n",
2890                         cli->desthost, domain ));
2891                 return NULL;
2892         }
2893
2894         result = cli_rpc_pipe_open_schannel_with_key(cli, pipe_idx,
2895                                 auth_level,
2896                                 domain, netlogon_pipe->dc, perr);
2897
2898         /* Now we've bound using the session key we can close the netlog pipe. */
2899         TALLOC_FREE(netlogon_pipe);
2900
2901         return result;
2902 }
2903
2904 #ifdef HAVE_KRB5
2905
2906 /****************************************************************************
2907  Free function for the kerberos spcific data.
2908  ****************************************************************************/
2909
2910 static void kerberos_auth_struct_free(struct cli_pipe_auth_data *a)
2911 {
2912         data_blob_free(&a->a_u.kerberos_auth->session_key);
2913 }
2914
2915 #endif
2916
2917 /****************************************************************************
2918  Open a named pipe to an SMB server and bind using krb5 (bind type 16).
2919  The idea is this can be called with service_princ, username and password all
2920  NULL so long as the caller has a TGT.
2921  ****************************************************************************/
2922
2923 struct rpc_pipe_client *cli_rpc_pipe_open_krb5(struct cli_state *cli,
2924                                                 int pipe_idx,
2925                                                 enum pipe_auth_level auth_level,
2926                                                 const char *service_princ,
2927                                                 const char *username,
2928                                                 const char *password,
2929                                                 NTSTATUS *perr)
2930 {
2931 #ifdef HAVE_KRB5
2932         struct rpc_pipe_client *result;
2933
2934         result = cli_rpc_pipe_open(cli, pipe_idx, perr);
2935         if (result == NULL) {
2936                 return NULL;
2937         }
2938
2939         /* Default service principal is "desthost$@realm" */
2940         if (!service_princ) {
2941                 service_princ = talloc_asprintf(result, "%s$@%s",
2942                                                 cli->desthost, lp_realm() );
2943                 if (!service_princ) {
2944                         TALLOC_FREE(result);
2945                         return NULL;
2946                 }
2947         }
2948
2949         /* Only get a new TGT if username/password are given. */
2950         if (username && password) {
2951                 int ret = kerberos_kinit_password(username, password, 0, NULL);
2952                 if (ret) {
2953                         TALLOC_FREE(result);
2954                         return NULL;
2955                 }
2956         }
2957
2958         result->auth->a_u.kerberos_auth = TALLOC_ZERO_P(
2959                 result, struct kerberos_auth_struct);
2960         if (!result->auth->a_u.kerberos_auth) {
2961                 TALLOC_FREE(result);
2962                 *perr = NT_STATUS_NO_MEMORY;
2963                 return NULL;
2964         }
2965
2966         result->auth->a_u.kerberos_auth->service_principal = service_princ;
2967         result->auth->cli_auth_data_free_func = kerberos_auth_struct_free;
2968
2969         *perr = rpc_pipe_bind(result, PIPE_AUTH_TYPE_KRB5, auth_level);
2970         if (!NT_STATUS_IS_OK(*perr)) {
2971                 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed with error %s\n",
2972                         nt_errstr(*perr) ));
2973                 TALLOC_FREE(result);
2974                 return NULL;
2975         }
2976
2977         return result;
2978 #else
2979         DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
2980         return NULL;
2981 #endif
2982 }