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