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