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