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