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