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