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