Move cli_api_pipe() to its only user cli_pipe.c
[ira/wip.git] / source3 / rpc_client / cli_pipe.c
1 /* 
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Largely rewritten by Jeremy Allison             2005.
5  *  
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 3 of the License, or
9  *  (at your option) any later version.
10  *  
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *  
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include "includes.h"
21 #include "librpc/gen_ndr/cli_epmapper.h"
22
23 #undef DBGC_CLASS
24 #define DBGC_CLASS DBGC_RPC_CLI
25
26 /*******************************************************************
27 interface/version dce/rpc pipe identification
28 ********************************************************************/
29
30 #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  Call a remote api on an arbitrary pipe.  takes param, data and setup buffers.
838 ****************************************************************************/
839
840 static bool cli_api_pipe(struct cli_state *cli, const char *pipe_name,
841                          uint16 *setup, uint32 setup_count,
842                          uint32 max_setup_count,
843                          char *params, uint32 param_count,
844                          uint32 max_param_count,
845                          char *data, uint32 data_count,
846                          uint32 max_data_count,
847                          char **rparam, uint32 *rparam_count,
848                          char **rdata, uint32 *rdata_count)
849 {
850         cli_send_trans(cli, SMBtrans,
851                  pipe_name,
852                  0,0,                         /* fid, flags */
853                  setup, setup_count, max_setup_count,
854                  params, param_count, max_param_count,
855                  data, data_count, max_data_count);
856
857         return (cli_receive_trans(cli, SMBtrans,
858                             rparam, (unsigned int *)rparam_count,
859                             rdata, (unsigned int *)rdata_count));
860 }
861
862 /****************************************************************************
863  Send data on an rpc pipe via trans. The prs_struct data must be the last
864  pdu fragment of an NDR data stream.
865
866  Receive response data from an rpc pipe, which may be large...
867
868  Read the first fragment: unfortunately have to use SMBtrans for the first
869  bit, then SMBreadX for subsequent bits.
870
871  If first fragment received also wasn't the last fragment, continue
872  getting fragments until we _do_ receive the last fragment.
873
874  Request/Response PDU's look like the following...
875
876  |<------------------PDU len----------------------------------------------->|
877  |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
878
879  +------------+-----------------+-------------+---------------+-------------+
880  | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR      | AUTH DATA   |
881  +------------+-----------------+-------------+---------------+-------------+
882
883  Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
884  signing & sealing being negotiated.
885
886  ****************************************************************************/
887
888 static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli,
889                         prs_struct *data, /* Outgoing pdu fragment, already formatted for send. */
890                         prs_struct *rbuf, /* Incoming reply - return as an NDR stream. */
891                         uint8 expected_pkt_type)
892 {
893         NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
894         char *rparam = NULL;
895         uint32 rparam_len = 0;
896         char *pdata = prs_data_p(data);
897         uint32 data_len = prs_offset(data);
898         char *prdata = NULL;
899         uint32 rdata_len = 0;
900         uint32 max_data = cli->max_xmit_frag ? cli->max_xmit_frag : RPC_MAX_PDU_FRAG_LEN;
901         uint32 current_rbuf_offset = 0;
902         prs_struct current_pdu;
903
904 #ifdef DEVELOPER
905         /* Ensure we're not sending too much. */
906         SMB_ASSERT(data_len <= max_data);
907 #endif
908
909         /* Set up the current pdu parse struct. */
910         prs_init_empty(&current_pdu, prs_get_mem_context(rbuf), UNMARSHALL);
911
912         DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(debug_ctx(), cli)));
913
914         switch (cli->transport_type) {
915         case NCACN_NP: {
916                 uint16 setup[2];
917                 /* Create setup parameters - must be in native byte order. */
918                 setup[0] = TRANSACT_DCERPCCMD;
919                 setup[1] = cli->trans.np.fnum; /* Pipe file handle. */
920
921                 /*
922                  * Send the last (or only) fragment of an RPC request. For
923                  * small amounts of data (about 1024 bytes or so) the RPC
924                  * request and response appears in a SMBtrans request and
925                  * response.
926                  */
927
928                 if (!cli_api_pipe(cli->trans.np.cli, "\\PIPE\\",
929                                   setup, 2, 0,     /* Setup, length, max */
930                                   NULL, 0, 0,      /* Params, length, max */
931                                   pdata, data_len, max_data, /* data, length,
932                                                               * max */
933                                   &rparam, &rparam_len, /* return params,
934                                                          * len */
935                                   &prdata, &rdata_len)) /* return data, len */
936                 {
937                         DEBUG(0, ("rpc_api_pipe: %s returned critical error. "
938                                   "Error was %s\n",
939                                   rpccli_pipe_txt(debug_ctx(), cli),
940                                   cli_errstr(cli->trans.np.cli)));
941                         ret = cli_get_nt_error(cli->trans.np.cli);
942                         SAFE_FREE(rparam);
943                         SAFE_FREE(prdata);
944                         goto err;
945                 }
946                 break;
947         }
948         case NCACN_IP_TCP:
949         case NCACN_UNIX_STREAM:
950         {
951                 ssize_t nwritten, nread;
952                 nwritten = write_data(cli->trans.sock.fd, pdata, data_len);
953                 if (nwritten == -1) {
954                         ret = map_nt_error_from_unix(errno);
955                         DEBUG(0, ("rpc_api_pipe: write_data returned %s\n",
956                                   strerror(errno)));
957                         goto err;
958                 }
959                 rparam = NULL;
960                 prdata = SMB_MALLOC_ARRAY(char, 1);
961                 if (prdata == NULL) {
962                         return NT_STATUS_NO_MEMORY;
963                 }
964                 nread = sys_read(cli->trans.sock.fd, prdata, 1);
965                 if (nread == 0) {
966                         SAFE_FREE(prdata);
967                 }
968                 if (nread == -1) {
969                         ret = NT_STATUS_END_OF_FILE;
970                         goto err;
971                 }
972                 rdata_len = nread;
973                 break;
974         }
975         default:
976                 DEBUG(0, ("unknown transport type %d\n",
977                           cli->transport_type));
978                 return NT_STATUS_INTERNAL_ERROR;
979         }
980
981         /* Throw away returned params - we know we won't use them. */
982
983         SAFE_FREE(rparam);
984
985         if (prdata == NULL) {
986                 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
987                          rpccli_pipe_txt(debug_ctx(), cli)));
988                 /* Yes - some calls can truely return no data... */
989                 prs_mem_free(&current_pdu);
990                 return NT_STATUS_OK;
991         }
992
993         /*
994          * Give this memory as dynamic to the current pdu.
995          */
996
997         prs_give_memory(&current_pdu, prdata, rdata_len, True);
998
999         /* Ensure we can mess with the return prs_struct. */
1000         SMB_ASSERT(UNMARSHALLING(rbuf));
1001         SMB_ASSERT(prs_data_size(rbuf) == 0);
1002
1003         /* Make rbuf dynamic with no memory. */
1004         prs_give_memory(rbuf, 0, 0, True);
1005
1006         while(1) {
1007                 RPC_HDR rhdr;
1008                 char *ret_data = NULL;
1009                 uint32 ret_data_len = 0;
1010
1011                 /* Ensure we have enough data for a pdu. */
1012                 ret = cli_pipe_get_current_pdu(cli, &rhdr, &current_pdu);
1013                 if (!NT_STATUS_IS_OK(ret)) {
1014                         goto err;
1015                 }
1016
1017                 /* We pass in rbuf here so if the alloc hint is set correctly 
1018                    we can set the output size and avoid reallocs. */
1019
1020                 ret = cli_pipe_validate_current_pdu(cli, &rhdr, &current_pdu, expected_pkt_type,
1021                                 &ret_data, &ret_data_len, rbuf);
1022
1023                 DEBUG(10,("rpc_api_pipe: got PDU len of %u at offset %u\n",
1024                         prs_data_size(&current_pdu), current_rbuf_offset ));
1025
1026                 if (!NT_STATUS_IS_OK(ret)) {
1027                         goto err;
1028                 }
1029
1030                 if ((rhdr.flags & RPC_FLG_FIRST)) {
1031                         if (rhdr.pack_type[0] == 0) {
1032                                 /* Set the data type correctly for big-endian data on the first packet. */
1033                                 DEBUG(10,("rpc_api_pipe: On %s "
1034                                         "PDU data format is big-endian.\n",
1035                                         rpccli_pipe_txt(debug_ctx(), cli)));
1036
1037                                 prs_set_endian_data(rbuf, RPC_BIG_ENDIAN);
1038                         } else {
1039                                 /* Check endianness on subsequent packets. */
1040                                 if (current_pdu.bigendian_data != rbuf->bigendian_data) {
1041                                         DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to %s\n",
1042                                                 rbuf->bigendian_data ? "big" : "little",
1043                                                 current_pdu.bigendian_data ? "big" : "little" ));
1044                                         ret = NT_STATUS_INVALID_PARAMETER;
1045                                         goto err;
1046                                 }
1047                         }
1048                 }
1049
1050                 /* Now copy the data portion out of the pdu into rbuf. */
1051                 if (!prs_force_grow(rbuf, ret_data_len)) {
1052                         ret = NT_STATUS_NO_MEMORY;
1053                         goto err;
1054                 }
1055                 memcpy(prs_data_p(rbuf)+current_rbuf_offset, ret_data, (size_t)ret_data_len);
1056                 current_rbuf_offset += ret_data_len;
1057
1058                 /* See if we've finished with all the data in current_pdu yet ? */
1059                 ret = cli_pipe_reset_current_pdu(cli, &rhdr, &current_pdu);
1060                 if (!NT_STATUS_IS_OK(ret)) {
1061                         goto err;
1062                 }
1063
1064                 if (rhdr.flags & RPC_FLG_LAST) {
1065                         break; /* We're done. */
1066                 }
1067         }
1068
1069         DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1070                 rpccli_pipe_txt(debug_ctx(), cli),
1071                 (unsigned int)prs_data_size(rbuf) ));
1072
1073         prs_mem_free(&current_pdu);
1074         return NT_STATUS_OK;
1075
1076   err:
1077
1078         prs_mem_free(&current_pdu);
1079         prs_mem_free(rbuf);
1080         return ret;
1081 }
1082
1083 /*******************************************************************
1084  Creates krb5 auth bind.
1085  ********************************************************************/
1086
1087 static NTSTATUS create_krb5_auth_bind_req( struct rpc_pipe_client *cli,
1088                                                 enum pipe_auth_level auth_level,
1089                                                 RPC_HDR_AUTH *pauth_out,
1090                                                 prs_struct *auth_data)
1091 {
1092 #ifdef HAVE_KRB5
1093         int ret;
1094         struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth;
1095         DATA_BLOB tkt = data_blob_null;
1096         DATA_BLOB tkt_wrapped = data_blob_null;
1097
1098         /* We may change the pad length before marshalling. */
1099         init_rpc_hdr_auth(pauth_out, RPC_KRB5_AUTH_TYPE, (int)auth_level, 0, 1);
1100
1101         DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
1102                 a->service_principal ));
1103
1104         /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
1105
1106         ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
1107                         &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL);
1108
1109         if (ret) {
1110                 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
1111                         "failed with %s\n",
1112                         a->service_principal,
1113                         error_message(ret) ));
1114
1115                 data_blob_free(&tkt);
1116                 prs_mem_free(auth_data);
1117                 return NT_STATUS_INVALID_PARAMETER;
1118         }
1119
1120         /* wrap that up in a nice GSS-API wrapping */
1121         tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
1122
1123         data_blob_free(&tkt);
1124
1125         /* Auth len in the rpc header doesn't include auth_header. */
1126         if (!prs_copy_data_in(auth_data, (char *)tkt_wrapped.data, tkt_wrapped.length)) {
1127                 data_blob_free(&tkt_wrapped);
1128                 prs_mem_free(auth_data);
1129                 return NT_STATUS_NO_MEMORY;
1130         }
1131
1132         DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1133         dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
1134
1135         data_blob_free(&tkt_wrapped);
1136         return NT_STATUS_OK;
1137 #else
1138         return NT_STATUS_INVALID_PARAMETER;
1139 #endif
1140 }
1141
1142 /*******************************************************************
1143  Creates SPNEGO NTLMSSP auth bind.
1144  ********************************************************************/
1145
1146 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1147                                                 enum pipe_auth_level auth_level,
1148                                                 RPC_HDR_AUTH *pauth_out,
1149                                                 prs_struct *auth_data)
1150 {
1151         NTSTATUS nt_status;
1152         DATA_BLOB null_blob = data_blob_null;
1153         DATA_BLOB request = data_blob_null;
1154         DATA_BLOB spnego_msg = data_blob_null;
1155
1156         /* We may change the pad length before marshalling. */
1157         init_rpc_hdr_auth(pauth_out, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
1158
1159         DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1160         nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1161                                         null_blob,
1162                                         &request);
1163
1164         if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1165                 data_blob_free(&request);
1166                 prs_mem_free(auth_data);
1167                 return nt_status;
1168         }
1169
1170         /* Wrap this in SPNEGO. */
1171         spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
1172
1173         data_blob_free(&request);
1174
1175         /* Auth len in the rpc header doesn't include auth_header. */
1176         if (!prs_copy_data_in(auth_data, (char *)spnego_msg.data, spnego_msg.length)) {
1177                 data_blob_free(&spnego_msg);
1178                 prs_mem_free(auth_data);
1179                 return NT_STATUS_NO_MEMORY;
1180         }
1181
1182         DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1183         dump_data(5, spnego_msg.data, spnego_msg.length);
1184
1185         data_blob_free(&spnego_msg);
1186         return NT_STATUS_OK;
1187 }
1188
1189 /*******************************************************************
1190  Creates NTLMSSP auth bind.
1191  ********************************************************************/
1192
1193 static NTSTATUS create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1194                                                 enum pipe_auth_level auth_level,
1195                                                 RPC_HDR_AUTH *pauth_out,
1196                                                 prs_struct *auth_data)
1197 {
1198         NTSTATUS nt_status;
1199         DATA_BLOB null_blob = data_blob_null;
1200         DATA_BLOB request = data_blob_null;
1201
1202         /* We may change the pad length before marshalling. */
1203         init_rpc_hdr_auth(pauth_out, RPC_NTLMSSP_AUTH_TYPE, (int)auth_level, 0, 1);
1204
1205         DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1206         nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1207                                         null_blob,
1208                                         &request);
1209
1210         if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1211                 data_blob_free(&request);
1212                 prs_mem_free(auth_data);
1213                 return nt_status;
1214         }
1215
1216         /* Auth len in the rpc header doesn't include auth_header. */
1217         if (!prs_copy_data_in(auth_data, (char *)request.data, request.length)) {
1218                 data_blob_free(&request);
1219                 prs_mem_free(auth_data);
1220                 return NT_STATUS_NO_MEMORY;
1221         }
1222
1223         DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1224         dump_data(5, request.data, request.length);
1225
1226         data_blob_free(&request);
1227         return NT_STATUS_OK;
1228 }
1229
1230 /*******************************************************************
1231  Creates schannel auth bind.
1232  ********************************************************************/
1233
1234 static NTSTATUS create_schannel_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1235                                                 enum pipe_auth_level auth_level,
1236                                                 RPC_HDR_AUTH *pauth_out,
1237                                                 prs_struct *auth_data)
1238 {
1239         RPC_AUTH_SCHANNEL_NEG schannel_neg;
1240
1241         /* We may change the pad length before marshalling. */
1242         init_rpc_hdr_auth(pauth_out, RPC_SCHANNEL_AUTH_TYPE, (int)auth_level, 0, 1);
1243
1244         /* Use lp_workgroup() if domain not specified */
1245
1246         if (!cli->auth->domain || !cli->auth->domain[0]) {
1247                 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1248                 if (cli->auth->domain == NULL) {
1249                         return NT_STATUS_NO_MEMORY;
1250                 }
1251         }
1252
1253         init_rpc_auth_schannel_neg(&schannel_neg, cli->auth->domain,
1254                                    global_myname());
1255
1256         /*
1257          * Now marshall the data into the auth parse_struct.
1258          */
1259
1260         if(!smb_io_rpc_auth_schannel_neg("schannel_neg",
1261                                        &schannel_neg, auth_data, 0)) {
1262                 DEBUG(0,("Failed to marshall RPC_AUTH_SCHANNEL_NEG.\n"));
1263                 prs_mem_free(auth_data);
1264                 return NT_STATUS_NO_MEMORY;
1265         }
1266
1267         return NT_STATUS_OK;
1268 }
1269
1270 /*******************************************************************
1271  Creates the internals of a DCE/RPC bind request or alter context PDU.
1272  ********************************************************************/
1273
1274 static NTSTATUS create_bind_or_alt_ctx_internal(enum RPC_PKT_TYPE pkt_type,
1275                                                 prs_struct *rpc_out, 
1276                                                 uint32 rpc_call_id,
1277                                                 const RPC_IFACE *abstract,
1278                                                 const RPC_IFACE *transfer,
1279                                                 RPC_HDR_AUTH *phdr_auth,
1280                                                 prs_struct *pauth_info)
1281 {
1282         RPC_HDR hdr;
1283         RPC_HDR_RB hdr_rb;
1284         RPC_CONTEXT rpc_ctx;
1285         uint16 auth_len = prs_offset(pauth_info);
1286         uint8 ss_padding_len = 0;
1287         uint16 frag_len = 0;
1288
1289         /* create the RPC context. */
1290         init_rpc_context(&rpc_ctx, 0 /* context id */, abstract, transfer);
1291
1292         /* create the bind request RPC_HDR_RB */
1293         init_rpc_hdr_rb(&hdr_rb, RPC_MAX_PDU_FRAG_LEN, RPC_MAX_PDU_FRAG_LEN, 0x0, &rpc_ctx);
1294
1295         /* Start building the frag length. */
1296         frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1297
1298         /* Do we need to pad ? */
1299         if (auth_len) {
1300                 uint16 data_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1301                 if (data_len % 8) {
1302                         ss_padding_len = 8 - (data_len % 8);
1303                         phdr_auth->auth_pad_len = ss_padding_len;
1304                 }
1305                 frag_len += RPC_HDR_AUTH_LEN + auth_len + ss_padding_len;
1306         }
1307
1308         /* Create the request RPC_HDR */
1309         init_rpc_hdr(&hdr, pkt_type, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id, frag_len, auth_len);
1310
1311         /* Marshall the RPC header */
1312         if(!smb_io_rpc_hdr("hdr"   , &hdr, rpc_out, 0)) {
1313                 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR.\n"));
1314                 return NT_STATUS_NO_MEMORY;
1315         }
1316
1317         /* Marshall the bind request data */
1318         if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_out, 0)) {
1319                 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1320                 return NT_STATUS_NO_MEMORY;
1321         }
1322
1323         /*
1324          * Grow the outgoing buffer to store any auth info.
1325          */
1326
1327         if(auth_len != 0) {
1328                 if (ss_padding_len) {
1329                         char pad[8];
1330                         memset(pad, '\0', 8);
1331                         if (!prs_copy_data_in(rpc_out, pad, ss_padding_len)) {
1332                                 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n"));
1333                                 return NT_STATUS_NO_MEMORY;
1334                         }
1335                 }
1336
1337                 if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth, rpc_out, 0)) {
1338                         DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n"));
1339                         return NT_STATUS_NO_MEMORY;
1340                 }
1341
1342
1343                 if(!prs_append_prs_data( rpc_out, pauth_info)) {
1344                         DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n"));
1345                         return NT_STATUS_NO_MEMORY;
1346                 }
1347         }
1348
1349         return NT_STATUS_OK;
1350 }
1351
1352 /*******************************************************************
1353  Creates a DCE/RPC bind request.
1354  ********************************************************************/
1355
1356 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
1357                                 prs_struct *rpc_out, 
1358                                 uint32 rpc_call_id,
1359                                 const RPC_IFACE *abstract,
1360                                 const RPC_IFACE *transfer,
1361                                 enum pipe_auth_type auth_type,
1362                                 enum pipe_auth_level auth_level)
1363 {
1364         RPC_HDR_AUTH hdr_auth;
1365         prs_struct auth_info;
1366         NTSTATUS ret = NT_STATUS_OK;
1367
1368         ZERO_STRUCT(hdr_auth);
1369         if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
1370                 return NT_STATUS_NO_MEMORY;
1371
1372         switch (auth_type) {
1373                 case PIPE_AUTH_TYPE_SCHANNEL:
1374                         ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1375                         if (!NT_STATUS_IS_OK(ret)) {
1376                                 prs_mem_free(&auth_info);
1377                                 return ret;
1378                         }
1379                         break;
1380
1381                 case PIPE_AUTH_TYPE_NTLMSSP:
1382                         ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1383                         if (!NT_STATUS_IS_OK(ret)) {
1384                                 prs_mem_free(&auth_info);
1385                                 return ret;
1386                         }
1387                         break;
1388
1389                 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1390                         ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1391                         if (!NT_STATUS_IS_OK(ret)) {
1392                                 prs_mem_free(&auth_info);
1393                                 return ret;
1394                         }
1395                         break;
1396
1397                 case PIPE_AUTH_TYPE_KRB5:
1398                         ret = create_krb5_auth_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1399                         if (!NT_STATUS_IS_OK(ret)) {
1400                                 prs_mem_free(&auth_info);
1401                                 return ret;
1402                         }
1403                         break;
1404
1405                 case PIPE_AUTH_TYPE_NONE:
1406                         break;
1407
1408                 default:
1409                         /* "Can't" happen. */
1410                         return NT_STATUS_INVALID_INFO_CLASS;
1411         }
1412
1413         ret = create_bind_or_alt_ctx_internal(RPC_BIND,
1414                                                 rpc_out, 
1415                                                 rpc_call_id,
1416                                                 abstract,
1417                                                 transfer,
1418                                                 &hdr_auth,
1419                                                 &auth_info);
1420
1421         prs_mem_free(&auth_info);
1422         return ret;
1423 }
1424
1425 /*******************************************************************
1426  Create and add the NTLMSSP sign/seal auth header and data.
1427  ********************************************************************/
1428
1429 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
1430                                         RPC_HDR *phdr,
1431                                         uint32 ss_padding_len,
1432                                         prs_struct *outgoing_pdu)
1433 {
1434         RPC_HDR_AUTH auth_info;
1435         NTSTATUS status;
1436         DATA_BLOB auth_blob = data_blob_null;
1437         uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1438
1439         if (!cli->auth->a_u.ntlmssp_state) {
1440                 return NT_STATUS_INVALID_PARAMETER;
1441         }
1442
1443         /* Init and marshall the auth header. */
1444         init_rpc_hdr_auth(&auth_info,
1445                         map_pipe_auth_type_to_rpc_auth_type(
1446                                 cli->auth->auth_type),
1447                         cli->auth->auth_level,
1448                         ss_padding_len,
1449                         1 /* context id. */);
1450
1451         if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1452                 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1453                 data_blob_free(&auth_blob);
1454                 return NT_STATUS_NO_MEMORY;
1455         }
1456
1457         switch (cli->auth->auth_level) {
1458                 case PIPE_AUTH_LEVEL_PRIVACY:
1459                         /* Data portion is encrypted. */
1460                         status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state,
1461                                         (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1462                                         data_and_pad_len,
1463                                         (unsigned char *)prs_data_p(outgoing_pdu),
1464                                         (size_t)prs_offset(outgoing_pdu),
1465                                         &auth_blob);
1466                         if (!NT_STATUS_IS_OK(status)) {
1467                                 data_blob_free(&auth_blob);
1468                                 return status;
1469                         }
1470                         break;
1471
1472                 case PIPE_AUTH_LEVEL_INTEGRITY:
1473                         /* Data is signed. */
1474                         status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state,
1475                                         (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1476                                         data_and_pad_len,
1477                                         (unsigned char *)prs_data_p(outgoing_pdu),
1478                                         (size_t)prs_offset(outgoing_pdu),
1479                                         &auth_blob);
1480                         if (!NT_STATUS_IS_OK(status)) {
1481                                 data_blob_free(&auth_blob);
1482                                 return status;
1483                         }
1484                         break;
1485
1486                 default:
1487                         /* Can't happen. */
1488                         smb_panic("bad auth level");
1489                         /* Notreached. */
1490                         return NT_STATUS_INVALID_PARAMETER;
1491         }
1492
1493         /* Finally marshall the blob. */
1494
1495         if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {
1496                 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
1497                         (unsigned int)NTLMSSP_SIG_SIZE));
1498                 data_blob_free(&auth_blob);
1499                 return NT_STATUS_NO_MEMORY;
1500         }
1501
1502         data_blob_free(&auth_blob);
1503         return NT_STATUS_OK;
1504 }
1505
1506 /*******************************************************************
1507  Create and add the schannel sign/seal auth header and data.
1508  ********************************************************************/
1509
1510 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
1511                                         RPC_HDR *phdr,
1512                                         uint32 ss_padding_len,
1513                                         prs_struct *outgoing_pdu)
1514 {
1515         RPC_HDR_AUTH auth_info;
1516         RPC_AUTH_SCHANNEL_CHK verf;
1517         struct schannel_auth_struct *sas = cli->auth->a_u.schannel_auth;
1518         char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
1519         size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1520
1521         if (!sas) {
1522                 return NT_STATUS_INVALID_PARAMETER;
1523         }
1524
1525         /* Init and marshall the auth header. */
1526         init_rpc_hdr_auth(&auth_info,
1527                         map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
1528                         cli->auth->auth_level,
1529                         ss_padding_len,
1530                         1 /* context id. */);
1531
1532         if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1533                 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1534                 return NT_STATUS_NO_MEMORY;
1535         }
1536
1537         switch (cli->auth->auth_level) {
1538                 case PIPE_AUTH_LEVEL_PRIVACY:
1539                 case PIPE_AUTH_LEVEL_INTEGRITY:
1540                         DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
1541                                 sas->seq_num));
1542
1543                         schannel_encode(sas,
1544                                         cli->auth->auth_level,
1545                                         SENDER_IS_INITIATOR,
1546                                         &verf,
1547                                         data_p,
1548                                         data_and_pad_len);
1549
1550                         sas->seq_num++;
1551                         break;
1552
1553                 default:
1554                         /* Can't happen. */
1555                         smb_panic("bad auth level");
1556                         /* Notreached. */
1557                         return NT_STATUS_INVALID_PARAMETER;
1558         }
1559
1560         /* Finally marshall the blob. */
1561         smb_io_rpc_auth_schannel_chk("",
1562                         RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN,
1563                         &verf,
1564                         outgoing_pdu,
1565                         0);
1566
1567         return NT_STATUS_OK;
1568 }
1569
1570 /*******************************************************************
1571  Calculate how much data we're going to send in this packet, also
1572  work out any sign/seal padding length.
1573  ********************************************************************/
1574
1575 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
1576                                         uint32 data_left,
1577                                         uint16 *p_frag_len,
1578                                         uint16 *p_auth_len,
1579                                         uint32 *p_ss_padding)
1580 {
1581         uint32 data_space, data_len;
1582
1583         switch (cli->auth->auth_level) {
1584                 case PIPE_AUTH_LEVEL_NONE:
1585                 case PIPE_AUTH_LEVEL_CONNECT:
1586                         data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
1587                         data_len = MIN(data_space, data_left);
1588                         *p_ss_padding = 0;
1589                         *p_auth_len = 0;
1590                         *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
1591                         return data_len;
1592
1593                 case PIPE_AUTH_LEVEL_INTEGRITY:
1594                 case PIPE_AUTH_LEVEL_PRIVACY:
1595                         /* Treat the same for all authenticated rpc requests. */
1596                         switch(cli->auth->auth_type) {
1597                                 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1598                                 case PIPE_AUTH_TYPE_NTLMSSP:
1599                                         *p_auth_len = NTLMSSP_SIG_SIZE;
1600                                         break;
1601                                 case PIPE_AUTH_TYPE_SCHANNEL:
1602                                         *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
1603                                         break;
1604                                 default:
1605                                         smb_panic("bad auth type");
1606                                         break;
1607                         }
1608
1609                         data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
1610                                                 RPC_HDR_AUTH_LEN - *p_auth_len;
1611
1612                         data_len = MIN(data_space, data_left);
1613                         if (data_len % 8) {
1614                                 *p_ss_padding = 8 - (data_len % 8);
1615                         }
1616                         *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN +                /* Normal headers. */
1617                                         data_len + *p_ss_padding +              /* data plus padding. */
1618                                         RPC_HDR_AUTH_LEN + *p_auth_len;         /* Auth header and auth data. */
1619                         return data_len;
1620
1621                 default:
1622                         smb_panic("bad auth level");
1623                         /* Notreached. */
1624                         return 0;
1625         }
1626 }
1627
1628 /*******************************************************************
1629  External interface.
1630  Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1631  Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1632  and deals with signing/sealing details.
1633  ********************************************************************/
1634
1635 NTSTATUS rpc_api_pipe_req(struct rpc_pipe_client *cli,
1636                         uint8 op_num,
1637                         prs_struct *in_data,
1638                         prs_struct *out_data)
1639 {
1640         NTSTATUS ret;
1641         uint32 data_left = prs_offset(in_data);
1642         uint32 alloc_hint = prs_offset(in_data);
1643         uint32 data_sent_thistime = 0;
1644         uint32 current_data_offset = 0;
1645         uint32 call_id = get_rpc_call_id();
1646         char pad[8];
1647         prs_struct outgoing_pdu;
1648
1649         memset(pad, '\0', 8);
1650
1651         if (cli->max_xmit_frag < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
1652                 /* Server is screwed up ! */
1653                 return NT_STATUS_INVALID_PARAMETER;
1654         }
1655
1656         if (!prs_init(&outgoing_pdu, cli->max_xmit_frag, prs_get_mem_context(in_data), MARSHALL))
1657                 return NT_STATUS_NO_MEMORY;
1658
1659         while (1) {
1660                 RPC_HDR hdr;
1661                 RPC_HDR_REQ hdr_req;
1662                 uint16 auth_len = 0;
1663                 uint16 frag_len = 0;
1664                 uint8 flags = 0;
1665                 uint32 ss_padding = 0;
1666                 ssize_t num_written;
1667
1668                 data_sent_thistime = calculate_data_len_tosend(cli, data_left,
1669                                                 &frag_len, &auth_len, &ss_padding);
1670
1671                 if (current_data_offset == 0) {
1672                         flags = RPC_FLG_FIRST;
1673                 }
1674
1675                 if (data_sent_thistime == data_left) {
1676                         flags |= RPC_FLG_LAST;
1677                 }
1678
1679                 /* Create and marshall the header and request header. */
1680                 init_rpc_hdr(&hdr, RPC_REQUEST, flags, call_id, frag_len, auth_len);
1681
1682                 if(!smb_io_rpc_hdr("hdr    ", &hdr, &outgoing_pdu, 0)) {
1683                         prs_mem_free(&outgoing_pdu);
1684                         return NT_STATUS_NO_MEMORY;
1685                 }
1686
1687                 /* Create the rpc request RPC_HDR_REQ */
1688                 init_rpc_hdr_req(&hdr_req, alloc_hint, op_num);
1689
1690                 if(!smb_io_rpc_hdr_req("hdr_req", &hdr_req, &outgoing_pdu, 0)) {
1691                         prs_mem_free(&outgoing_pdu);
1692                         return NT_STATUS_NO_MEMORY;
1693                 }
1694
1695                 /* Copy in the data, plus any ss padding. */
1696                 if (!prs_append_some_prs_data(&outgoing_pdu, in_data, current_data_offset, data_sent_thistime)) {
1697                         prs_mem_free(&outgoing_pdu);
1698                         return NT_STATUS_NO_MEMORY;
1699                 }
1700
1701                 /* Copy the sign/seal padding data. */
1702                 if (ss_padding) {
1703                         if (!prs_copy_data_in(&outgoing_pdu, pad, ss_padding)) {
1704                                 prs_mem_free(&outgoing_pdu);
1705                                 return NT_STATUS_NO_MEMORY;
1706                         }
1707                 }
1708
1709                 /* Generate any auth sign/seal and add the auth footer. */
1710                 if (auth_len) {
1711                         switch (cli->auth->auth_type) {
1712                                 case PIPE_AUTH_TYPE_NONE:
1713                                         break;
1714                                 case PIPE_AUTH_TYPE_NTLMSSP:
1715                                 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1716                                         ret = add_ntlmssp_auth_footer(cli, &hdr, ss_padding, &outgoing_pdu);
1717                                         if (!NT_STATUS_IS_OK(ret)) {
1718                                                 prs_mem_free(&outgoing_pdu);
1719                                                 return ret;
1720                                         }
1721                                         break;
1722                                 case PIPE_AUTH_TYPE_SCHANNEL:
1723                                         ret = add_schannel_auth_footer(cli, &hdr, ss_padding, &outgoing_pdu);
1724                                         if (!NT_STATUS_IS_OK(ret)) {
1725                                                 prs_mem_free(&outgoing_pdu);
1726                                                 return ret;
1727                                         }
1728                                         break;
1729                                 default:
1730                                         smb_panic("bad auth type");
1731                                         break; /* notreached */
1732                         }
1733                 }
1734
1735                 /* Actually send the packet. */
1736                 if (flags & RPC_FLG_LAST) {
1737                         /* Last packet - send the data, get the reply and return. */
1738                         ret = rpc_api_pipe(cli, &outgoing_pdu, out_data, RPC_RESPONSE);
1739                         prs_mem_free(&outgoing_pdu);
1740
1741                         if ((DEBUGLEVEL >= 50)
1742                             && (cli->transport_type == NCACN_NP)) {
1743                                 char *dump_name = NULL;
1744                                 /* Also capture received data */
1745                                 if (asprintf(&dump_name, "%s/reply_%s_%d",
1746                                              get_dyn_LOGFILEBASE(),
1747                                              cli->trans.np.pipe_name, op_num) > 0) {
1748                                         prs_dump(dump_name, op_num, out_data);
1749                                         SAFE_FREE(dump_name);
1750                                 }
1751                         }
1752
1753                         return ret;
1754                 }
1755
1756                 switch (cli->transport_type) {
1757                 case NCACN_NP:
1758                         num_written = cli_write(cli->trans.np.cli,
1759                                                 cli->trans.np.fnum,
1760                                                 8, /* 8 means message mode. */
1761                                                 prs_data_p(&outgoing_pdu),
1762                                                 (off_t)0,
1763                                                 (size_t)hdr.frag_len);
1764
1765                         if (num_written != hdr.frag_len) {
1766                                 prs_mem_free(&outgoing_pdu);
1767                                 return cli_get_nt_error(cli->trans.np.cli);
1768                         }
1769                         break;
1770                 case NCACN_IP_TCP:
1771                 case NCACN_UNIX_STREAM:
1772                         num_written = write_data(
1773                                 cli->trans.sock.fd,
1774                                 prs_data_p(&outgoing_pdu),
1775                                 (size_t)hdr.frag_len);
1776                         if (num_written != hdr.frag_len) {
1777                                 NTSTATUS status;
1778                                 status = map_nt_error_from_unix(errno);
1779                                 prs_mem_free(&outgoing_pdu);
1780                                 return status;
1781                         }
1782                         break;
1783                 default:
1784                         DEBUG(0, ("unknown transport type %d\n",
1785                                   cli->transport_type));
1786                         return NT_STATUS_INTERNAL_ERROR;
1787                 }
1788
1789                 current_data_offset += data_sent_thistime;
1790                 data_left -= data_sent_thistime;
1791
1792                 /* Reset the marshalling position back to zero. */
1793                 if (!prs_set_offset(&outgoing_pdu, 0)) {
1794                         prs_mem_free(&outgoing_pdu);
1795                         return NT_STATUS_NO_MEMORY;
1796                 }
1797         }
1798 }
1799 #if 0
1800 /****************************************************************************
1801  Set the handle state.
1802 ****************************************************************************/
1803
1804 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
1805                                    const char *pipe_name, uint16 device_state)
1806 {
1807         bool state_set = False;
1808         char param[2];
1809         uint16 setup[2]; /* only need 2 uint16 setup parameters */
1810         char *rparam = NULL;
1811         char *rdata = NULL;
1812         uint32 rparam_len, rdata_len;
1813
1814         if (pipe_name == NULL)
1815                 return False;
1816
1817         DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
1818                  cli->fnum, pipe_name, device_state));
1819
1820         /* create parameters: device state */
1821         SSVAL(param, 0, device_state);
1822
1823         /* create setup parameters. */
1824         setup[0] = 0x0001; 
1825         setup[1] = cli->fnum; /* pipe file handle.  got this from an SMBOpenX. */
1826
1827         /* send the data on \PIPE\ */
1828         if (cli_api_pipe(cli->cli, "\\PIPE\\",
1829                     setup, 2, 0,                /* setup, length, max */
1830                     param, 2, 0,                /* param, length, max */
1831                     NULL, 0, 1024,              /* data, length, max */
1832                     &rparam, &rparam_len,        /* return param, length */
1833                     &rdata, &rdata_len))         /* return data, length */
1834         {
1835                 DEBUG(5, ("Set Handle state: return OK\n"));
1836                 state_set = True;
1837         }
1838
1839         SAFE_FREE(rparam);
1840         SAFE_FREE(rdata);
1841
1842         return state_set;
1843 }
1844 #endif
1845
1846 /****************************************************************************
1847  Check the rpc bind acknowledge response.
1848 ****************************************************************************/
1849
1850 static bool check_bind_response(RPC_HDR_BA *hdr_ba, const RPC_IFACE *transfer)
1851 {
1852         if ( hdr_ba->addr.len == 0) {
1853                 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1854         }
1855
1856         /* check the transfer syntax */
1857         if ((hdr_ba->transfer.if_version != transfer->if_version) ||
1858              (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
1859                 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1860                 return False;
1861         }
1862
1863         if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) {
1864                 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1865                           hdr_ba->res.num_results, hdr_ba->res.reason));
1866         }
1867
1868         DEBUG(5,("check_bind_response: accepted!\n"));
1869         return True;
1870 }
1871
1872 /*******************************************************************
1873  Creates a DCE/RPC bind authentication response.
1874  This is the packet that is sent back to the server once we
1875  have received a BIND-ACK, to finish the third leg of
1876  the authentication handshake.
1877  ********************************************************************/
1878
1879 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
1880                                 uint32 rpc_call_id,
1881                                 enum pipe_auth_type auth_type,
1882                                 enum pipe_auth_level auth_level,
1883                                 DATA_BLOB *pauth_blob,
1884                                 prs_struct *rpc_out)
1885 {
1886         RPC_HDR hdr;
1887         RPC_HDR_AUTH hdr_auth;
1888         uint32 pad = 0;
1889
1890         /* Create the request RPC_HDR */
1891         init_rpc_hdr(&hdr, RPC_AUTH3, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id,
1892                      RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + pauth_blob->length,
1893                      pauth_blob->length );
1894
1895         /* Marshall it. */
1896         if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
1897                 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
1898                 return NT_STATUS_NO_MEMORY;
1899         }
1900
1901         /*
1902                 I'm puzzled about this - seems to violate the DCE RPC auth rules,
1903                 about padding - shouldn't this pad to length 8 ? JRA.
1904         */
1905
1906         /* 4 bytes padding. */
1907         if (!prs_uint32("pad", rpc_out, 0, &pad)) {
1908                 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
1909                 return NT_STATUS_NO_MEMORY;
1910         }
1911
1912         /* Create the request RPC_HDR_AUTHA */
1913         init_rpc_hdr_auth(&hdr_auth,
1914                         map_pipe_auth_type_to_rpc_auth_type(auth_type),
1915                         auth_level, 0, 1);
1916
1917         if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rpc_out, 0)) {
1918                 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
1919                 return NT_STATUS_NO_MEMORY;
1920         }
1921
1922         /*
1923          * Append the auth data to the outgoing buffer.
1924          */
1925
1926         if(!prs_copy_data_in(rpc_out, (char *)pauth_blob->data, pauth_blob->length)) {
1927                 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
1928                 return NT_STATUS_NO_MEMORY;
1929         }
1930
1931         return NT_STATUS_OK;
1932 }
1933
1934 /****************************************************************************
1935  Create and send the third packet in an RPC auth.
1936 ****************************************************************************/
1937
1938 static NTSTATUS rpc_finish_auth3_bind(struct rpc_pipe_client *cli,
1939                                 RPC_HDR *phdr,
1940                                 prs_struct *rbuf,
1941                                 uint32 rpc_call_id,
1942                                 enum pipe_auth_type auth_type,
1943                                 enum pipe_auth_level auth_level)
1944 {
1945         DATA_BLOB server_response = data_blob_null;
1946         DATA_BLOB client_reply = data_blob_null;
1947         RPC_HDR_AUTH hdr_auth;
1948         NTSTATUS nt_status;
1949         prs_struct rpc_out;
1950         ssize_t ret;
1951
1952         if (!phdr->auth_len || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
1953                 return NT_STATUS_INVALID_PARAMETER;
1954         }
1955
1956         /* Process the returned NTLMSSP blob first. */
1957         if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
1958                 return NT_STATUS_INVALID_PARAMETER;
1959         }
1960
1961         if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
1962                 return NT_STATUS_INVALID_PARAMETER;
1963         }
1964
1965         /* TODO - check auth_type/auth_level match. */
1966
1967         server_response = data_blob(NULL, phdr->auth_len);
1968         prs_copy_data_out((char *)server_response.data, rbuf, phdr->auth_len);
1969
1970         nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1971                                    server_response,
1972                                    &client_reply);
1973
1974         if (!NT_STATUS_IS_OK(nt_status)) {
1975                 DEBUG(0,("rpc_finish_auth3_bind: NTLMSSP update using server blob failed.\n"));
1976                 data_blob_free(&server_response);
1977                 return nt_status;
1978         }
1979
1980         prs_init_empty(&rpc_out, prs_get_mem_context(rbuf), MARSHALL);
1981
1982         nt_status = create_rpc_bind_auth3(cli, rpc_call_id,
1983                                 auth_type, auth_level,
1984                                 &client_reply, &rpc_out);
1985
1986         if (!NT_STATUS_IS_OK(nt_status)) {
1987                 prs_mem_free(&rpc_out);
1988                 data_blob_free(&client_reply);
1989                 data_blob_free(&server_response);
1990                 return nt_status;
1991         }
1992
1993         switch (cli->transport_type) {
1994         case NCACN_NP:
1995                 /* 8 here is named pipe message mode. */
1996                 ret = cli_write(cli->trans.np.cli, cli->trans.np.fnum,
1997                                 0x8, prs_data_p(&rpc_out), 0,
1998                                 (size_t)prs_offset(&rpc_out));
1999                 break;
2000
2001                 if (ret != (ssize_t)prs_offset(&rpc_out)) {
2002                         nt_status = cli_get_nt_error(cli->trans.np.cli);
2003                 }
2004         case NCACN_IP_TCP:
2005         case NCACN_UNIX_STREAM:
2006                 ret = write_data(cli->trans.sock.fd, prs_data_p(&rpc_out),
2007                                  (size_t)prs_offset(&rpc_out));
2008                 if (ret != (ssize_t)prs_offset(&rpc_out)) {
2009                         nt_status = map_nt_error_from_unix(errno);
2010                 }
2011                 break;
2012         default:
2013                 DEBUG(0, ("unknown transport type %d\n", cli->transport_type));
2014                 return NT_STATUS_INTERNAL_ERROR;
2015         }
2016
2017         if (ret != (ssize_t)prs_offset(&rpc_out)) {
2018                 DEBUG(0,("rpc_send_auth_auth3: write failed. Return was %s\n",
2019                          nt_errstr(nt_status)));
2020                 prs_mem_free(&rpc_out);
2021                 data_blob_free(&client_reply);
2022                 data_blob_free(&server_response);
2023                 return nt_status;
2024         }
2025
2026         DEBUG(5,("rpc_send_auth_auth3: %s sent auth3 response ok.\n",
2027                  rpccli_pipe_txt(debug_ctx(), cli)));
2028
2029         prs_mem_free(&rpc_out);
2030         data_blob_free(&client_reply);
2031         data_blob_free(&server_response);
2032         return NT_STATUS_OK;
2033 }
2034
2035 /*******************************************************************
2036  Creates a DCE/RPC bind alter context authentication request which
2037  may contain a spnego auth blobl
2038  ********************************************************************/
2039
2040 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
2041                                         const RPC_IFACE *abstract,
2042                                         const RPC_IFACE *transfer,
2043                                         enum pipe_auth_level auth_level,
2044                                         const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
2045                                         prs_struct *rpc_out)
2046 {
2047         RPC_HDR_AUTH hdr_auth;
2048         prs_struct auth_info;
2049         NTSTATUS ret = NT_STATUS_OK;
2050
2051         ZERO_STRUCT(hdr_auth);
2052         if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
2053                 return NT_STATUS_NO_MEMORY;
2054
2055         /* We may change the pad length before marshalling. */
2056         init_rpc_hdr_auth(&hdr_auth, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
2057
2058         if (pauth_blob->length) {
2059                 if (!prs_copy_data_in(&auth_info, (const char *)pauth_blob->data, pauth_blob->length)) {
2060                         prs_mem_free(&auth_info);
2061                         return NT_STATUS_NO_MEMORY;
2062                 }
2063         }
2064
2065         ret = create_bind_or_alt_ctx_internal(RPC_ALTCONT,
2066                                                 rpc_out, 
2067                                                 rpc_call_id,
2068                                                 abstract,
2069                                                 transfer,
2070                                                 &hdr_auth,
2071                                                 &auth_info);
2072         prs_mem_free(&auth_info);
2073         return ret;
2074 }
2075
2076 /*******************************************************************
2077  Third leg of the SPNEGO bind mechanism - sends alter context PDU
2078  and gets a response.
2079  ********************************************************************/
2080
2081 static NTSTATUS rpc_finish_spnego_ntlmssp_bind(struct rpc_pipe_client *cli,
2082                                 RPC_HDR *phdr,
2083                                 prs_struct *rbuf,
2084                                 uint32 rpc_call_id,
2085                                 const RPC_IFACE *abstract,
2086                                 const RPC_IFACE *transfer,
2087                                 enum pipe_auth_type auth_type,
2088                                 enum pipe_auth_level auth_level)
2089 {
2090         DATA_BLOB server_spnego_response = data_blob_null;
2091         DATA_BLOB server_ntlm_response = data_blob_null;
2092         DATA_BLOB client_reply = data_blob_null;
2093         DATA_BLOB tmp_blob = data_blob_null;
2094         RPC_HDR_AUTH hdr_auth;
2095         NTSTATUS nt_status;
2096         prs_struct rpc_out;
2097
2098         if (!phdr->auth_len || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2099                 return NT_STATUS_INVALID_PARAMETER;
2100         }
2101
2102         /* Process the returned NTLMSSP blob first. */
2103         if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2104                 return NT_STATUS_INVALID_PARAMETER;
2105         }
2106
2107         if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
2108                 return NT_STATUS_INVALID_PARAMETER;
2109         }
2110
2111         server_spnego_response = data_blob(NULL, phdr->auth_len);
2112         prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len);
2113
2114         /* The server might give us back two challenges - tmp_blob is for the second. */
2115         if (!spnego_parse_challenge(server_spnego_response, &server_ntlm_response, &tmp_blob)) {
2116                 data_blob_free(&server_spnego_response);
2117                 data_blob_free(&server_ntlm_response);
2118                 data_blob_free(&tmp_blob);
2119                 return NT_STATUS_INVALID_PARAMETER;
2120         }
2121
2122         /* We're finished with the server spnego response and the tmp_blob. */
2123         data_blob_free(&server_spnego_response);
2124         data_blob_free(&tmp_blob);
2125
2126         nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
2127                                    server_ntlm_response,
2128                                    &client_reply);
2129
2130         /* Finished with the server_ntlm response */
2131         data_blob_free(&server_ntlm_response);
2132
2133         if (!NT_STATUS_IS_OK(nt_status)) {
2134                 DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update using server blob failed.\n"));
2135                 data_blob_free(&client_reply);
2136                 return nt_status;
2137         }
2138
2139         /* SPNEGO wrap the client reply. */
2140         tmp_blob = spnego_gen_auth(client_reply);
2141         data_blob_free(&client_reply);
2142         client_reply = tmp_blob;
2143         tmp_blob = data_blob_null; /* Ensure it's safe to free this just in case. */
2144
2145         /* Now prepare the alter context pdu. */
2146         prs_init_empty(&rpc_out, prs_get_mem_context(rbuf), MARSHALL);
2147
2148         nt_status = create_rpc_alter_context(rpc_call_id,
2149                                                 abstract,
2150                                                 transfer,
2151                                                 auth_level,
2152                                                 &client_reply,
2153                                                 &rpc_out);
2154
2155         data_blob_free(&client_reply);
2156
2157         if (!NT_STATUS_IS_OK(nt_status)) {
2158                 prs_mem_free(&rpc_out);
2159                 return nt_status;
2160         }
2161
2162         /* Initialize the returning data struct. */
2163         prs_mem_free(rbuf);
2164         prs_init_empty(rbuf, talloc_tos(), UNMARSHALL);
2165
2166         nt_status = rpc_api_pipe(cli, &rpc_out, rbuf, RPC_ALTCONTRESP);
2167         if (!NT_STATUS_IS_OK(nt_status)) {
2168                 prs_mem_free(&rpc_out);
2169                 return nt_status;
2170         }
2171
2172         prs_mem_free(&rpc_out);
2173
2174         /* Get the auth blob from the reply. */
2175         if(!smb_io_rpc_hdr("rpc_hdr   ", phdr, rbuf, 0)) {
2176                 DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: Failed to unmarshall RPC_HDR.\n"));
2177                 return NT_STATUS_BUFFER_TOO_SMALL;
2178         }
2179
2180         if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2181                 return NT_STATUS_INVALID_PARAMETER;
2182         }
2183
2184         if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
2185                 return NT_STATUS_INVALID_PARAMETER;
2186         }
2187
2188         server_spnego_response = data_blob(NULL, phdr->auth_len);
2189         prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len);
2190
2191         /* Check we got a valid auth response. */
2192         if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK, OID_NTLMSSP, &tmp_blob)) {
2193                 data_blob_free(&server_spnego_response);
2194                 data_blob_free(&tmp_blob);
2195                 return NT_STATUS_INVALID_PARAMETER;
2196         }
2197
2198         data_blob_free(&server_spnego_response);
2199         data_blob_free(&tmp_blob);
2200
2201         DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
2202                  "%s.\n", rpccli_pipe_txt(debug_ctx(), cli)));
2203
2204         return NT_STATUS_OK;
2205 }
2206
2207 /****************************************************************************
2208  Do an rpc bind.
2209 ****************************************************************************/
2210
2211 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
2212                        struct cli_pipe_auth_data *auth)
2213 {
2214         RPC_HDR hdr;
2215         RPC_HDR_BA hdr_ba;
2216         prs_struct rpc_out;
2217         prs_struct rbuf;
2218         uint32 rpc_call_id;
2219         NTSTATUS status;
2220
2221         DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2222                 rpccli_pipe_txt(debug_ctx(), cli),
2223                 (unsigned int)auth->auth_type,
2224                 (unsigned int)auth->auth_level ));
2225
2226         cli->auth = talloc_move(cli, &auth);
2227
2228         prs_init_empty(&rpc_out, talloc_tos(), MARSHALL);
2229
2230         rpc_call_id = get_rpc_call_id();
2231
2232         /* Marshall the outgoing data. */
2233         status = create_rpc_bind_req(cli, &rpc_out, rpc_call_id,
2234                                 &cli->abstract_syntax,
2235                                 &cli->transfer_syntax,
2236                                 cli->auth->auth_type,
2237                                 cli->auth->auth_level);
2238
2239         if (!NT_STATUS_IS_OK(status)) {
2240                 prs_mem_free(&rpc_out);
2241                 return status;
2242         }
2243
2244         /* Initialize the incoming data struct. */
2245         prs_init_empty(&rbuf, talloc_tos(), UNMARSHALL);
2246
2247         /* send data on \PIPE\.  receive a response */
2248         status = rpc_api_pipe(cli, &rpc_out, &rbuf, RPC_BINDACK);
2249         if (!NT_STATUS_IS_OK(status)) {
2250                 prs_mem_free(&rpc_out);
2251                 return status;
2252         }
2253
2254         prs_mem_free(&rpc_out);
2255
2256         DEBUG(3,("rpc_pipe_bind: %s bind request returned ok.\n",
2257                  rpccli_pipe_txt(debug_ctx(), cli)));
2258
2259         /* Unmarshall the RPC header */
2260         if(!smb_io_rpc_hdr("hdr"   , &hdr, &rbuf, 0)) {
2261                 DEBUG(0,("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2262                 prs_mem_free(&rbuf);
2263                 return NT_STATUS_BUFFER_TOO_SMALL;
2264         }
2265
2266         if(!smb_io_rpc_hdr_ba("", &hdr_ba, &rbuf, 0)) {
2267                 DEBUG(0,("rpc_pipe_bind: Failed to unmarshall RPC_HDR_BA.\n"));
2268                 prs_mem_free(&rbuf);
2269                 return NT_STATUS_BUFFER_TOO_SMALL;
2270         }
2271
2272         if(!check_bind_response(&hdr_ba, &cli->transfer_syntax)) {
2273                 DEBUG(2,("rpc_pipe_bind: check_bind_response failed.\n"));
2274                 prs_mem_free(&rbuf);
2275                 return NT_STATUS_BUFFER_TOO_SMALL;
2276         }
2277
2278         cli->max_xmit_frag = hdr_ba.bba.max_tsize;
2279         cli->max_recv_frag = hdr_ba.bba.max_rsize;
2280
2281         /* For authenticated binds we may need to do 3 or 4 leg binds. */
2282         switch(cli->auth->auth_type) {
2283
2284                 case PIPE_AUTH_TYPE_NONE:
2285                 case PIPE_AUTH_TYPE_SCHANNEL:
2286                         /* Bind complete. */
2287                         break;
2288
2289                 case PIPE_AUTH_TYPE_NTLMSSP:
2290                         /* Need to send AUTH3 packet - no reply. */
2291                         status = rpc_finish_auth3_bind(
2292                                 cli, &hdr, &rbuf, rpc_call_id,
2293                                 cli->auth->auth_type,
2294                                 cli->auth->auth_level);
2295                         if (!NT_STATUS_IS_OK(status)) {
2296                                 prs_mem_free(&rbuf);
2297                                 return status;
2298                         }
2299                         break;
2300
2301                 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2302                         /* Need to send alter context request and reply. */
2303                         status = rpc_finish_spnego_ntlmssp_bind(
2304                                 cli, &hdr, &rbuf, rpc_call_id,
2305                                 &cli->abstract_syntax, &cli->transfer_syntax,
2306                                 cli->auth->auth_type, cli->auth->auth_level);
2307                         if (!NT_STATUS_IS_OK(status)) {
2308                                 prs_mem_free(&rbuf);
2309                                 return status;
2310                         }
2311                         break;
2312
2313                 case PIPE_AUTH_TYPE_KRB5:
2314                         /* */
2315
2316                 default:
2317                         DEBUG(0,("cli_finish_bind_auth: unknown auth type "
2318                                  "%u\n", (unsigned int)cli->auth->auth_type));
2319                         prs_mem_free(&rbuf);
2320                         return NT_STATUS_INVALID_INFO_CLASS;
2321         }
2322
2323         /* For NTLMSSP ensure the server gave us the auth_level we wanted. */
2324         if (cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP
2325             || cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2326                 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2327                         if (!(cli->auth->a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN)) {
2328                                 DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP signing and server refused.\n"));
2329                                 prs_mem_free(&rbuf);
2330                                 return NT_STATUS_INVALID_PARAMETER;
2331                         }
2332                 }
2333                 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2334                         if (!(cli->auth->a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL)) {
2335                                 DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP sealing and server refused.\n"));
2336                                 prs_mem_free(&rbuf);
2337                                 return NT_STATUS_INVALID_PARAMETER;
2338                         }
2339                 }
2340         }
2341
2342         prs_mem_free(&rbuf);
2343         return NT_STATUS_OK;
2344 }
2345
2346 unsigned int rpccli_set_timeout(struct rpc_pipe_client *cli,
2347                                 unsigned int timeout)
2348 {
2349         return cli_set_timeout(cli->trans.np.cli, timeout);
2350 }
2351
2352 bool rpccli_get_pwd_hash(struct rpc_pipe_client *cli, uint8_t nt_hash[16])
2353 {
2354         if ((cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
2355             || (cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) {
2356                 memcpy(nt_hash, cli->auth->a_u.ntlmssp_state->nt_hash, 16);
2357                 return true;
2358         }
2359
2360         if (cli->transport_type == NCACN_NP) {
2361                 E_md4hash(cli->trans.np.cli->pwd.password, nt_hash);
2362                 return true;
2363         }
2364
2365         return false;
2366 }
2367
2368 struct cli_state *rpc_pipe_np_smb_conn(struct rpc_pipe_client *p)
2369 {
2370         if (p->transport_type == NCACN_NP) {
2371                 return p->trans.np.cli;
2372         }
2373         return NULL;
2374 }
2375
2376 static int rpc_pipe_destructor(struct rpc_pipe_client *p)
2377 {
2378         if (p->transport_type == NCACN_NP) {
2379                 bool ret;
2380                 ret = cli_close(p->trans.np.cli, p->trans.np.fnum);
2381                 if (!ret) {
2382                         DEBUG(1, ("rpc_pipe_destructor: cli_close failed on "
2383                                   "pipe %s. Error was %s\n",
2384                                   rpccli_pipe_txt(debug_ctx(), p),
2385                                   cli_errstr(p->trans.np.cli)));
2386                 }
2387
2388                 DEBUG(10, ("rpc_pipe_destructor: closed %s\n",
2389                            rpccli_pipe_txt(debug_ctx(), p)));
2390
2391                 DLIST_REMOVE(p->trans.np.cli->pipe_list, p);
2392                 return ret ? -1 : 0;
2393         }
2394
2395         return -1;
2396 }
2397
2398 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2399                                struct cli_pipe_auth_data **presult)
2400 {
2401         struct cli_pipe_auth_data *result;
2402
2403         result = talloc(mem_ctx, struct cli_pipe_auth_data);
2404         if (result == NULL) {
2405                 return NT_STATUS_NO_MEMORY;
2406         }
2407
2408         result->auth_type = PIPE_AUTH_TYPE_NONE;
2409         result->auth_level = PIPE_AUTH_LEVEL_NONE;
2410
2411         result->user_name = talloc_strdup(result, "");
2412         result->domain = talloc_strdup(result, "");
2413         if ((result->user_name == NULL) || (result->domain == NULL)) {
2414                 TALLOC_FREE(result);
2415                 return NT_STATUS_NO_MEMORY;
2416         }
2417
2418         *presult = result;
2419         return NT_STATUS_OK;
2420 }
2421
2422 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth)
2423 {
2424         ntlmssp_end(&auth->a_u.ntlmssp_state);
2425         return 0;
2426 }
2427
2428 NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
2429                                   enum pipe_auth_type auth_type,
2430                                   enum pipe_auth_level auth_level,
2431                                   const char *domain,
2432                                   const char *username,
2433                                   const char *password,
2434                                   struct cli_pipe_auth_data **presult)
2435 {
2436         struct cli_pipe_auth_data *result;
2437         NTSTATUS status;
2438
2439         result = talloc(mem_ctx, struct cli_pipe_auth_data);
2440         if (result == NULL) {
2441                 return NT_STATUS_NO_MEMORY;
2442         }
2443
2444         result->auth_type = auth_type;
2445         result->auth_level = auth_level;
2446
2447         result->user_name = talloc_strdup(result, username);
2448         result->domain = talloc_strdup(result, domain);
2449         if ((result->user_name == NULL) || (result->domain == NULL)) {
2450                 status = NT_STATUS_NO_MEMORY;
2451                 goto fail;
2452         }
2453
2454         status = ntlmssp_client_start(&result->a_u.ntlmssp_state);
2455         if (!NT_STATUS_IS_OK(status)) {
2456                 goto fail;
2457         }
2458
2459         talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
2460
2461         status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);
2462         if (!NT_STATUS_IS_OK(status)) {
2463                 goto fail;
2464         }
2465
2466         status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);
2467         if (!NT_STATUS_IS_OK(status)) {
2468                 goto fail;
2469         }
2470
2471         status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);
2472         if (!NT_STATUS_IS_OK(status)) {
2473                 goto fail;
2474         }
2475
2476         /*
2477          * Turn off sign+seal to allow selected auth level to turn it back on.
2478          */
2479         result->a_u.ntlmssp_state->neg_flags &=
2480                 ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);
2481
2482         if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2483                 result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
2484         } else if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) {
2485                 result->a_u.ntlmssp_state->neg_flags
2486                         |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
2487         }
2488
2489         *presult = result;
2490         return NT_STATUS_OK;
2491
2492  fail:
2493         TALLOC_FREE(result);
2494         return status;
2495 }
2496
2497 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
2498                                    enum pipe_auth_level auth_level,
2499                                    const uint8_t sess_key[16],
2500                                    struct cli_pipe_auth_data **presult)
2501 {
2502         struct cli_pipe_auth_data *result;
2503
2504         result = talloc(mem_ctx, struct cli_pipe_auth_data);
2505         if (result == NULL) {
2506                 return NT_STATUS_NO_MEMORY;
2507         }
2508
2509         result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
2510         result->auth_level = auth_level;
2511
2512         result->user_name = talloc_strdup(result, "");
2513         result->domain = talloc_strdup(result, domain);
2514         if ((result->user_name == NULL) || (result->domain == NULL)) {
2515                 goto fail;
2516         }
2517
2518         result->a_u.schannel_auth = talloc(result,
2519                                            struct schannel_auth_struct);
2520         if (result->a_u.schannel_auth == NULL) {
2521                 goto fail;
2522         }
2523
2524         memcpy(result->a_u.schannel_auth->sess_key, sess_key,
2525                sizeof(result->a_u.schannel_auth->sess_key));
2526         result->a_u.schannel_auth->seq_num = 0;
2527
2528         *presult = result;
2529         return NT_STATUS_OK;
2530
2531  fail:
2532         TALLOC_FREE(result);
2533         return NT_STATUS_NO_MEMORY;
2534 }
2535
2536 #ifdef HAVE_KRB5
2537 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
2538 {
2539         data_blob_free(&auth->session_key);
2540         return 0;
2541 }
2542 #endif
2543
2544 NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
2545                                    enum pipe_auth_level auth_level,
2546                                    const char *service_princ,
2547                                    const char *username,
2548                                    const char *password,
2549                                    struct cli_pipe_auth_data **presult)
2550 {
2551 #ifdef HAVE_KRB5
2552         struct cli_pipe_auth_data *result;
2553
2554         if ((username != NULL) && (password != NULL)) {
2555                 int ret = kerberos_kinit_password(username, password, 0, NULL);
2556                 if (ret != 0) {
2557                         return NT_STATUS_ACCESS_DENIED;
2558                 }
2559         }
2560
2561         result = talloc(mem_ctx, struct cli_pipe_auth_data);
2562         if (result == NULL) {
2563                 return NT_STATUS_NO_MEMORY;
2564         }
2565
2566         result->auth_type = PIPE_AUTH_TYPE_KRB5;
2567         result->auth_level = auth_level;
2568
2569         /*
2570          * Username / domain need fixing!
2571          */
2572         result->user_name = talloc_strdup(result, "");
2573         result->domain = talloc_strdup(result, "");
2574         if ((result->user_name == NULL) || (result->domain == NULL)) {
2575                 goto fail;
2576         }
2577
2578         result->a_u.kerberos_auth = TALLOC_ZERO_P(
2579                 result, struct kerberos_auth_struct);
2580         if (result->a_u.kerberos_auth == NULL) {
2581                 goto fail;
2582         }
2583         talloc_set_destructor(result->a_u.kerberos_auth,
2584                               cli_auth_kerberos_data_destructor);
2585
2586         result->a_u.kerberos_auth->service_principal = talloc_strdup(
2587                 result, service_princ);
2588         if (result->a_u.kerberos_auth->service_principal == NULL) {
2589                 goto fail;
2590         }
2591
2592         *presult = result;
2593         return NT_STATUS_OK;
2594
2595  fail:
2596         TALLOC_FREE(result);
2597         return NT_STATUS_NO_MEMORY;
2598 #else
2599         return NT_STATUS_NOT_SUPPORTED;
2600 #endif
2601 }
2602
2603 static int rpc_pipe_sock_destructor(struct rpc_pipe_client *p)
2604 {
2605         close(p->trans.sock.fd);
2606         return 0;
2607 }
2608
2609 /**
2610  * Create an rpc pipe client struct, connecting to a tcp port.
2611  */
2612 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
2613                                        uint16_t port,
2614                                        const struct ndr_syntax_id *abstract_syntax,
2615                                        struct rpc_pipe_client **presult)
2616 {
2617         struct rpc_pipe_client *result;
2618         struct sockaddr_storage addr;
2619         NTSTATUS status;
2620
2621         result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
2622         if (result == NULL) {
2623                 return NT_STATUS_NO_MEMORY;
2624         }
2625
2626         result->transport_type = NCACN_IP_TCP;
2627
2628         result->abstract_syntax = *abstract_syntax;
2629         result->transfer_syntax = ndr_transfer_syntax;
2630
2631         result->desthost = talloc_strdup(result, host);
2632         result->srv_name_slash = talloc_asprintf_strupper_m(
2633                 result, "\\\\%s", result->desthost);
2634         if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2635                 status = NT_STATUS_NO_MEMORY;
2636                 goto fail;
2637         }
2638
2639         result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2640         result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2641
2642         if (!resolve_name(host, &addr, 0)) {
2643                 status = NT_STATUS_NOT_FOUND;
2644                 goto fail;
2645         }
2646
2647         status = open_socket_out(&addr, port, 60, &result->trans.sock.fd);
2648         if (!NT_STATUS_IS_OK(status)) {
2649                 goto fail;
2650         }
2651
2652         talloc_set_destructor(result, rpc_pipe_sock_destructor);
2653
2654         *presult = result;
2655         return NT_STATUS_OK;
2656
2657  fail:
2658         TALLOC_FREE(result);
2659         return status;
2660 }
2661
2662 /**
2663  * Determine the tcp port on which a dcerpc interface is listening
2664  * for the ncacn_ip_tcp transport via the endpoint mapper of the
2665  * target host.
2666  */
2667 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
2668                                       const struct ndr_syntax_id *abstract_syntax,
2669                                       uint16_t *pport)
2670 {
2671         NTSTATUS status;
2672         struct rpc_pipe_client *epm_pipe = NULL;
2673         struct cli_pipe_auth_data *auth = NULL;
2674         struct dcerpc_binding *map_binding = NULL;
2675         struct dcerpc_binding *res_binding = NULL;
2676         struct epm_twr_t *map_tower = NULL;
2677         struct epm_twr_t *res_towers = NULL;
2678         struct policy_handle *entry_handle = NULL;
2679         uint32_t num_towers = 0;
2680         uint32_t max_towers = 1;
2681         struct epm_twr_p_t towers;
2682         TALLOC_CTX *tmp_ctx = talloc_stackframe();
2683
2684         if (pport == NULL) {
2685                 status = NT_STATUS_INVALID_PARAMETER;
2686                 goto done;
2687         }
2688
2689         /* open the connection to the endpoint mapper */
2690         status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
2691                                         &ndr_table_epmapper.syntax_id,
2692                                         &epm_pipe);
2693
2694         if (!NT_STATUS_IS_OK(status)) {
2695                 goto done;
2696         }
2697
2698         status = rpccli_anon_bind_data(tmp_ctx, &auth);
2699         if (!NT_STATUS_IS_OK(status)) {
2700                 goto done;
2701         }
2702
2703         status = rpc_pipe_bind(epm_pipe, auth);
2704         if (!NT_STATUS_IS_OK(status)) {
2705                 goto done;
2706         }
2707
2708         /* create tower for asking the epmapper */
2709
2710         map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
2711         if (map_binding == NULL) {
2712                 status = NT_STATUS_NO_MEMORY;
2713                 goto done;
2714         }
2715
2716         map_binding->transport = NCACN_IP_TCP;
2717         map_binding->object = *abstract_syntax;
2718         map_binding->host = host; /* needed? */
2719         map_binding->endpoint = "0"; /* correct? needed? */
2720
2721         map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
2722         if (map_tower == NULL) {
2723                 status = NT_STATUS_NO_MEMORY;
2724                 goto done;
2725         }
2726
2727         status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
2728                                             &(map_tower->tower));
2729         if (!NT_STATUS_IS_OK(status)) {
2730                 goto done;
2731         }
2732
2733         /* allocate further parameters for the epm_Map call */
2734
2735         res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
2736         if (res_towers == NULL) {
2737                 status = NT_STATUS_NO_MEMORY;
2738                 goto done;
2739         }
2740         towers.twr = res_towers;
2741
2742         entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
2743         if (entry_handle == NULL) {
2744                 status = NT_STATUS_NO_MEMORY;
2745                 goto done;
2746         }
2747
2748         /* ask the endpoint mapper for the port */
2749
2750         status = rpccli_epm_Map(epm_pipe,
2751                                 tmp_ctx,
2752                                 CONST_DISCARD(struct GUID *,
2753                                               &(abstract_syntax->uuid)),
2754                                 map_tower,
2755                                 entry_handle,
2756                                 max_towers,
2757                                 &num_towers,
2758                                 &towers);
2759
2760         if (!NT_STATUS_IS_OK(status)) {
2761                 goto done;
2762         }
2763
2764         if (num_towers != 1) {
2765                 status = NT_STATUS_UNSUCCESSFUL;
2766                 goto done;
2767         }
2768
2769         /* extract the port from the answer */
2770
2771         status = dcerpc_binding_from_tower(tmp_ctx,
2772                                            &(towers.twr->tower),
2773                                            &res_binding);
2774         if (!NT_STATUS_IS_OK(status)) {
2775                 goto done;
2776         }
2777
2778         /* are further checks here necessary? */
2779         if (res_binding->transport != NCACN_IP_TCP) {
2780                 status = NT_STATUS_UNSUCCESSFUL;
2781                 goto done;
2782         }
2783
2784         *pport = (uint16_t)atoi(res_binding->endpoint);
2785
2786 done:
2787         TALLOC_FREE(tmp_ctx);
2788         return status;
2789 }
2790
2791 /**
2792  * Create a rpc pipe client struct, connecting to a host via tcp.
2793  * The port is determined by asking the endpoint mapper on the given
2794  * host.
2795  */
2796 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
2797                            const struct ndr_syntax_id *abstract_syntax,
2798                            struct rpc_pipe_client **presult)
2799 {
2800         NTSTATUS status;
2801         uint16_t port = 0;
2802
2803         *presult = NULL;
2804
2805         status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
2806         if (!NT_STATUS_IS_OK(status)) {
2807                 goto done;
2808         }
2809
2810         status = rpc_pipe_open_tcp_port(mem_ctx, host, port,
2811                                         abstract_syntax, presult);
2812
2813 done:
2814         return status;
2815 }
2816
2817 /********************************************************************
2818  Create a rpc pipe client struct, connecting to a unix domain socket
2819  ********************************************************************/
2820 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
2821                                const struct ndr_syntax_id *abstract_syntax,
2822                                struct rpc_pipe_client **presult)
2823 {
2824         struct rpc_pipe_client *result;
2825         struct sockaddr_un addr;
2826         NTSTATUS status;
2827
2828         result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2829         if (result == NULL) {
2830                 return NT_STATUS_NO_MEMORY;
2831         }
2832
2833         result->transport_type = NCACN_UNIX_STREAM;
2834
2835         result->abstract_syntax = *abstract_syntax;
2836         result->transfer_syntax = ndr_transfer_syntax;
2837
2838         result->desthost = talloc_get_myname(result);
2839         result->srv_name_slash = talloc_asprintf_strupper_m(
2840                 result, "\\\\%s", result->desthost);
2841         if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2842                 status = NT_STATUS_NO_MEMORY;
2843                 goto fail;
2844         }
2845
2846         result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2847         result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2848
2849         result->trans.sock.fd = socket(AF_UNIX, SOCK_STREAM, 0);
2850         if (result->trans.sock.fd == -1) {
2851                 status = map_nt_error_from_unix(errno);
2852                 goto fail;
2853         }
2854
2855         talloc_set_destructor(result, rpc_pipe_sock_destructor);
2856
2857         ZERO_STRUCT(addr);
2858         addr.sun_family = AF_UNIX;
2859         strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
2860
2861         if (sys_connect(result->trans.sock.fd,
2862                         (struct sockaddr *)&addr) == -1) {
2863                 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
2864                           strerror(errno)));
2865                 close(result->trans.sock.fd);
2866                 return map_nt_error_from_unix(errno);
2867         }
2868
2869         *presult = result;
2870         return NT_STATUS_OK;
2871
2872  fail:
2873         TALLOC_FREE(result);
2874         return status;
2875 }
2876
2877
2878 /****************************************************************************
2879  Open a named pipe over SMB to a remote server.
2880  *
2881  * CAVEAT CALLER OF THIS FUNCTION:
2882  *    The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2883  *    so be sure that this function is called AFTER any structure (vs pointer)
2884  *    assignment of the cli.  In particular, libsmbclient does structure
2885  *    assignments of cli, which invalidates the data in the returned
2886  *    rpc_pipe_client if this function is called before the structure assignment
2887  *    of cli.
2888  * 
2889  ****************************************************************************/
2890
2891 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
2892                                  const struct ndr_syntax_id *abstract_syntax,
2893                                  struct rpc_pipe_client **presult)
2894 {
2895         struct rpc_pipe_client *result;
2896         int fnum;
2897
2898         /* sanity check to protect against crashes */
2899
2900         if ( !cli ) {
2901                 return NT_STATUS_INVALID_HANDLE;
2902         }
2903
2904         result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
2905         if (result == NULL) {
2906                 return NT_STATUS_NO_MEMORY;
2907         }
2908
2909         result->transport_type = NCACN_NP;
2910
2911         result->trans.np.pipe_name = cli_get_pipe_name_from_iface(
2912                 result, cli, abstract_syntax);
2913         if (result->trans.np.pipe_name == NULL) {
2914                 DEBUG(1, ("Could not find pipe for interface\n"));
2915                 TALLOC_FREE(result);
2916                 return NT_STATUS_INVALID_PARAMETER;
2917         }
2918
2919         result->trans.np.cli = cli;
2920         result->abstract_syntax = *abstract_syntax;
2921         result->transfer_syntax = ndr_transfer_syntax;
2922         result->desthost = talloc_strdup(result, cli->desthost);
2923         result->srv_name_slash = talloc_asprintf_strupper_m(
2924                 result, "\\\\%s", result->desthost);
2925
2926         if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2927                 TALLOC_FREE(result);
2928                 return NT_STATUS_NO_MEMORY;
2929         }
2930
2931         fnum = cli_nt_create(cli, result->trans.np.pipe_name,
2932                              DESIRED_ACCESS_PIPE);
2933         if (fnum == -1) {
2934                 DEBUG(3,("rpc_pipe_open_np: cli_nt_create failed on pipe %s "
2935                          "to machine %s.  Error was %s\n",
2936                          result->trans.np.pipe_name, cli->desthost,
2937                          cli_errstr(cli)));
2938                 TALLOC_FREE(result);
2939                 return cli_get_nt_error(cli);
2940         }
2941
2942         result->trans.np.fnum = fnum;
2943
2944         DLIST_ADD(cli->pipe_list, result);
2945         talloc_set_destructor(result, rpc_pipe_destructor);
2946
2947         *presult = result;
2948         return NT_STATUS_OK;
2949 }
2950
2951 /****************************************************************************
2952  Open a pipe to a remote server.
2953  ****************************************************************************/
2954
2955 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
2956                                   const struct ndr_syntax_id *interface,
2957                                   struct rpc_pipe_client **presult)
2958 {
2959         if (ndr_syntax_id_equal(interface, &ndr_table_drsuapi.syntax_id)) {
2960                 /*
2961                  * We should have a better way to figure out this drsuapi
2962                  * speciality...
2963                  */
2964                 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
2965                                          presult);
2966         }
2967
2968         return rpc_pipe_open_np(cli, interface, presult);
2969 }
2970
2971 /****************************************************************************
2972  Open a named pipe to an SMB server and bind anonymously.
2973  ****************************************************************************/
2974
2975 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
2976                                   const struct ndr_syntax_id *interface,
2977                                   struct rpc_pipe_client **presult)
2978 {
2979         struct rpc_pipe_client *result;
2980         struct cli_pipe_auth_data *auth;
2981         NTSTATUS status;
2982
2983         status = cli_rpc_pipe_open(cli, interface, &result);
2984         if (!NT_STATUS_IS_OK(status)) {
2985                 return status;
2986         }
2987
2988         status = rpccli_anon_bind_data(result, &auth);
2989         if (!NT_STATUS_IS_OK(status)) {
2990                 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
2991                           nt_errstr(status)));
2992                 TALLOC_FREE(result);
2993                 return status;
2994         }
2995
2996         /*
2997          * This is a bit of an abstraction violation due to the fact that an
2998          * anonymous bind on an authenticated SMB inherits the user/domain
2999          * from the enclosing SMB creds
3000          */
3001
3002         TALLOC_FREE(auth->user_name);
3003         TALLOC_FREE(auth->domain);
3004
3005         auth->user_name = talloc_strdup(auth, cli->user_name);
3006         auth->domain = talloc_strdup(auth, cli->domain);
3007         auth->user_session_key = data_blob_talloc(auth,
3008                 cli->user_session_key.data,
3009                 cli->user_session_key.length);
3010
3011         if ((auth->user_name == NULL) || (auth->domain == NULL)) {
3012                 TALLOC_FREE(result);
3013                 return NT_STATUS_NO_MEMORY;
3014         }
3015
3016         status = rpc_pipe_bind(result, auth);
3017         if (!NT_STATUS_IS_OK(status)) {
3018                 int lvl = 0;
3019                 if (ndr_syntax_id_equal(interface,
3020                                         &ndr_table_dssetup.syntax_id)) {
3021                         /* non AD domains just don't have this pipe, avoid
3022                          * level 0 statement in that case - gd */
3023                         lvl = 3;
3024                 }
3025                 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3026                             "%s failed with error %s\n",
3027                             cli_get_pipe_name_from_iface(debug_ctx(), cli,
3028                                                          interface),
3029                             nt_errstr(status) ));
3030                 TALLOC_FREE(result);
3031                 return status;
3032         }
3033
3034         DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3035                   "%s and bound anonymously.\n", result->trans.np.pipe_name,
3036                   cli->desthost ));
3037
3038         *presult = result;
3039         return NT_STATUS_OK;
3040 }
3041
3042 /****************************************************************************
3043  Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
3044  ****************************************************************************/
3045
3046 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
3047                                                    const struct ndr_syntax_id *interface,
3048                                                    enum pipe_auth_type auth_type,
3049                                                    enum pipe_auth_level auth_level,
3050                                                    const char *domain,
3051                                                    const char *username,
3052                                                    const char *password,
3053                                                    struct rpc_pipe_client **presult)
3054 {
3055         struct rpc_pipe_client *result;
3056         struct cli_pipe_auth_data *auth;
3057         NTSTATUS status;
3058
3059         status = cli_rpc_pipe_open(cli, interface, &result);
3060         if (!NT_STATUS_IS_OK(status)) {
3061                 return status;
3062         }
3063
3064         status = rpccli_ntlmssp_bind_data(
3065                 result, auth_type, auth_level, domain, username,
3066                 cli->pwd.null_pwd ? NULL : password, &auth);
3067         if (!NT_STATUS_IS_OK(status)) {
3068                 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
3069                           nt_errstr(status)));
3070                 goto err;
3071         }
3072
3073         status = rpc_pipe_bind(result, auth);
3074         if (!NT_STATUS_IS_OK(status)) {
3075                 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
3076                         nt_errstr(status) ));
3077                 goto err;
3078         }
3079
3080         DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
3081                 "machine %s and bound NTLMSSP as user %s\\%s.\n",
3082                 result->trans.np.pipe_name, cli->desthost,
3083                 domain, username ));
3084
3085         *presult = result;
3086         return NT_STATUS_OK;
3087
3088   err:
3089
3090         TALLOC_FREE(result);
3091         return status;
3092 }
3093
3094 /****************************************************************************
3095  External interface.
3096  Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
3097  ****************************************************************************/
3098
3099 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
3100                                    const struct ndr_syntax_id *interface,
3101                                    enum pipe_auth_level auth_level,
3102                                    const char *domain,
3103                                    const char *username,
3104                                    const char *password,
3105                                    struct rpc_pipe_client **presult)
3106 {
3107         return cli_rpc_pipe_open_ntlmssp_internal(cli,
3108                                                 interface,
3109                                                 PIPE_AUTH_TYPE_NTLMSSP,
3110                                                 auth_level,
3111                                                 domain,
3112                                                 username,
3113                                                 password,
3114                                                 presult);
3115 }
3116
3117 /****************************************************************************
3118  External interface.
3119  Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
3120  ****************************************************************************/
3121
3122 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3123                                           const struct ndr_syntax_id *interface,
3124                                           enum pipe_auth_level auth_level,
3125                                           const char *domain,
3126                                           const char *username,
3127                                           const char *password,
3128                                           struct rpc_pipe_client **presult)
3129 {
3130         return cli_rpc_pipe_open_ntlmssp_internal(cli,
3131                                                 interface,
3132                                                 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
3133                                                 auth_level,
3134                                                 domain,
3135                                                 username,
3136                                                 password,
3137                                                 presult);
3138 }
3139
3140 /****************************************************************************
3141   Get a the schannel session key out of an already opened netlogon pipe.
3142  ****************************************************************************/
3143 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
3144                                                 struct cli_state *cli,
3145                                                 const char *domain,
3146                                                 uint32 *pneg_flags)
3147 {
3148         uint32 sec_chan_type = 0;
3149         unsigned char machine_pwd[16];
3150         const char *machine_account;
3151         NTSTATUS status;
3152
3153         /* Get the machine account credentials from secrets.tdb. */
3154         if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
3155                                &sec_chan_type))
3156         {
3157                 DEBUG(0, ("get_schannel_session_key: could not fetch "
3158                         "trust account password for domain '%s'\n",
3159                         domain));
3160                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3161         }
3162
3163         status = rpccli_netlogon_setup_creds(netlogon_pipe,
3164                                         cli->desthost, /* server name */
3165                                         domain,        /* domain */
3166                                         global_myname(), /* client name */
3167                                         machine_account, /* machine account name */
3168                                         machine_pwd,
3169                                         sec_chan_type,
3170                                         pneg_flags);
3171
3172         if (!NT_STATUS_IS_OK(status)) {
3173                 DEBUG(3, ("get_schannel_session_key_common: "
3174                           "rpccli_netlogon_setup_creds failed with result %s "
3175                           "to server %s, domain %s, machine account %s.\n",
3176                           nt_errstr(status), cli->desthost, domain,
3177                           machine_account ));
3178                 return status;
3179         }
3180
3181         if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
3182                 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
3183                         cli->desthost));
3184                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3185         }
3186
3187         return NT_STATUS_OK;;
3188 }
3189
3190 /****************************************************************************
3191  Open a netlogon pipe and get the schannel session key.
3192  Now exposed to external callers.
3193  ****************************************************************************/
3194
3195
3196 NTSTATUS get_schannel_session_key(struct cli_state *cli,
3197                                   const char *domain,
3198                                   uint32 *pneg_flags,
3199                                   struct rpc_pipe_client **presult)
3200 {
3201         struct rpc_pipe_client *netlogon_pipe = NULL;
3202         NTSTATUS status;
3203
3204         status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
3205                                           &netlogon_pipe);
3206         if (!NT_STATUS_IS_OK(status)) {
3207                 return status;
3208         }
3209
3210         status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3211                                                  pneg_flags);
3212         if (!NT_STATUS_IS_OK(status)) {
3213                 TALLOC_FREE(netlogon_pipe);
3214                 return status;
3215         }
3216
3217         *presult = netlogon_pipe;
3218         return NT_STATUS_OK;
3219 }
3220
3221 /****************************************************************************
3222  External interface.
3223  Open a named pipe to an SMB server and bind using schannel (bind type 68)
3224  using session_key. sign and seal.
3225  ****************************************************************************/
3226
3227 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
3228                                              const struct ndr_syntax_id *interface,
3229                                              enum pipe_auth_level auth_level,
3230                                              const char *domain,
3231                                              const struct dcinfo *pdc,
3232                                              struct rpc_pipe_client **presult)
3233 {
3234         struct rpc_pipe_client *result;
3235         struct cli_pipe_auth_data *auth;
3236         NTSTATUS status;
3237
3238         status = cli_rpc_pipe_open(cli, interface, &result);
3239         if (!NT_STATUS_IS_OK(status)) {
3240                 return status;
3241         }
3242
3243         status = rpccli_schannel_bind_data(result, domain, auth_level,
3244                                            pdc->sess_key, &auth);
3245         if (!NT_STATUS_IS_OK(status)) {
3246                 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
3247                           nt_errstr(status)));
3248                 TALLOC_FREE(result);
3249                 return status;
3250         }
3251
3252         status = rpc_pipe_bind(result, auth);
3253         if (!NT_STATUS_IS_OK(status)) {
3254                 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
3255                           "cli_rpc_pipe_bind failed with error %s\n",
3256                           nt_errstr(status) ));
3257                 TALLOC_FREE(result);
3258                 return status;
3259         }
3260
3261         /*
3262          * The credentials on a new netlogon pipe are the ones we are passed
3263          * in - copy them over.
3264          */
3265         result->dc = (struct dcinfo *)talloc_memdup(result, pdc, sizeof(*pdc));
3266         if (result->dc == NULL) {
3267                 DEBUG(0, ("talloc failed\n"));
3268                 TALLOC_FREE(result);
3269                 return NT_STATUS_NO_MEMORY;
3270         }
3271
3272         DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
3273                 "for domain %s "
3274                 "and bound using schannel.\n",
3275                 result->trans.np.pipe_name, cli->desthost, domain ));
3276
3277         *presult = result;
3278         return NT_STATUS_OK;
3279 }
3280
3281 /****************************************************************************
3282  Open a named pipe to an SMB server and bind using schannel (bind type 68).
3283  Fetch the session key ourselves using a temporary netlogon pipe. This
3284  version uses an ntlmssp auth bound netlogon pipe to get the key.
3285  ****************************************************************************/
3286
3287 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
3288                                                       const char *domain,
3289                                                       const char *username,
3290                                                       const char *password,
3291                                                       uint32 *pneg_flags,
3292                                                       struct rpc_pipe_client **presult)
3293 {
3294         struct rpc_pipe_client *netlogon_pipe = NULL;
3295         NTSTATUS status;
3296
3297         status = cli_rpc_pipe_open_spnego_ntlmssp(
3298                 cli, &ndr_table_netlogon.syntax_id, PIPE_AUTH_LEVEL_PRIVACY,
3299                 domain, username, password, &netlogon_pipe);
3300         if (!NT_STATUS_IS_OK(status)) {
3301                 return status;
3302         }
3303
3304         status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3305                                                  pneg_flags);
3306         if (!NT_STATUS_IS_OK(status)) {
3307                 TALLOC_FREE(netlogon_pipe);
3308                 return status;
3309         }
3310
3311         *presult = netlogon_pipe;
3312         return NT_STATUS_OK;
3313 }
3314
3315 /****************************************************************************
3316  Open a named pipe to an SMB server and bind using schannel (bind type 68).
3317  Fetch the session key ourselves using a temporary netlogon pipe. This version
3318  uses an ntlmssp bind to get the session key.
3319  ****************************************************************************/
3320
3321 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
3322                                                  const struct ndr_syntax_id *interface,
3323                                                  enum pipe_auth_level auth_level,
3324                                                  const char *domain,
3325                                                  const char *username,
3326                                                  const char *password,
3327                                                  struct rpc_pipe_client **presult)
3328 {
3329         uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3330         struct rpc_pipe_client *netlogon_pipe = NULL;
3331         struct rpc_pipe_client *result = NULL;
3332         NTSTATUS status;
3333
3334         status = get_schannel_session_key_auth_ntlmssp(
3335                 cli, domain, username, password, &neg_flags, &netlogon_pipe);
3336         if (!NT_STATUS_IS_OK(status)) {
3337                 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
3338                         "key from server %s for domain %s.\n",
3339                         cli->desthost, domain ));
3340                 return status;
3341         }
3342
3343         status = cli_rpc_pipe_open_schannel_with_key(
3344                 cli, interface, auth_level, domain, netlogon_pipe->dc,
3345                 &result);
3346
3347         /* Now we've bound using the session key we can close the netlog pipe. */
3348         TALLOC_FREE(netlogon_pipe);
3349
3350         if (NT_STATUS_IS_OK(status)) {
3351                 *presult = result;
3352         }
3353         return status;
3354 }
3355
3356 /****************************************************************************
3357  Open a named pipe to an SMB server and bind using schannel (bind type 68).
3358  Fetch the session key ourselves using a temporary netlogon pipe.
3359  ****************************************************************************/
3360
3361 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
3362                                     const struct ndr_syntax_id *interface,
3363                                     enum pipe_auth_level auth_level,
3364                                     const char *domain,
3365                                     struct rpc_pipe_client **presult)
3366 {
3367         uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3368         struct rpc_pipe_client *netlogon_pipe = NULL;
3369         struct rpc_pipe_client *result = NULL;
3370         NTSTATUS status;
3371
3372         status = get_schannel_session_key(cli, domain, &neg_flags,
3373                                           &netlogon_pipe);
3374         if (!NT_STATUS_IS_OK(status)) {
3375                 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
3376                         "key from server %s for domain %s.\n",
3377                         cli->desthost, domain ));
3378                 return status;
3379         }
3380
3381         status = cli_rpc_pipe_open_schannel_with_key(
3382                 cli, interface, auth_level, domain, netlogon_pipe->dc,
3383                 &result);
3384
3385         /* Now we've bound using the session key we can close the netlog pipe. */
3386         TALLOC_FREE(netlogon_pipe);
3387
3388         if (NT_STATUS_IS_OK(status)) {
3389                 *presult = result;
3390         }
3391
3392         return NT_STATUS_OK;
3393 }
3394
3395 /****************************************************************************
3396  Open a named pipe to an SMB server and bind using krb5 (bind type 16).
3397  The idea is this can be called with service_princ, username and password all
3398  NULL so long as the caller has a TGT.
3399  ****************************************************************************/
3400
3401 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
3402                                 const struct ndr_syntax_id *interface,
3403                                 enum pipe_auth_level auth_level,
3404                                 const char *service_princ,
3405                                 const char *username,
3406                                 const char *password,
3407                                 struct rpc_pipe_client **presult)
3408 {
3409 #ifdef HAVE_KRB5
3410         struct rpc_pipe_client *result;
3411         struct cli_pipe_auth_data *auth;
3412         NTSTATUS status;
3413
3414         status = cli_rpc_pipe_open(cli, interface, &result);
3415         if (!NT_STATUS_IS_OK(status)) {
3416                 return status;
3417         }
3418
3419         status = rpccli_kerberos_bind_data(result, auth_level, service_princ,
3420                                            username, password, &auth);
3421         if (!NT_STATUS_IS_OK(status)) {
3422                 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
3423                           nt_errstr(status)));
3424                 TALLOC_FREE(result);
3425                 return status;
3426         }
3427
3428         status = rpc_pipe_bind(result, auth);
3429         if (!NT_STATUS_IS_OK(status)) {
3430                 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
3431                           "with error %s\n", nt_errstr(status)));
3432                 TALLOC_FREE(result);
3433                 return status;
3434         }
3435
3436         *presult = result;
3437         return NT_STATUS_OK;
3438 #else
3439         DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
3440         return NT_STATUS_NOT_IMPLEMENTED;
3441 #endif
3442 }
3443
3444 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
3445                              struct rpc_pipe_client *cli,
3446                              DATA_BLOB *session_key)
3447 {
3448         if (!session_key || !cli) {
3449                 return NT_STATUS_INVALID_PARAMETER;
3450         }
3451
3452         if (!cli->auth) {
3453                 return NT_STATUS_INVALID_PARAMETER;
3454         }
3455
3456         switch (cli->auth->auth_type) {
3457                 case PIPE_AUTH_TYPE_SCHANNEL:
3458                         *session_key = data_blob_talloc(mem_ctx,
3459                                 cli->auth->a_u.schannel_auth->sess_key, 16);
3460                         break;
3461                 case PIPE_AUTH_TYPE_NTLMSSP:
3462                 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
3463                         *session_key = data_blob_talloc(mem_ctx,
3464                                 cli->auth->a_u.ntlmssp_state->session_key.data,
3465                                 cli->auth->a_u.ntlmssp_state->session_key.length);
3466                         break;
3467                 case PIPE_AUTH_TYPE_KRB5:
3468                 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
3469                         *session_key = data_blob_talloc(mem_ctx,
3470                                 cli->auth->a_u.kerberos_auth->session_key.data,
3471                                 cli->auth->a_u.kerberos_auth->session_key.length);
3472                         break;
3473                 case PIPE_AUTH_TYPE_NONE:
3474                         *session_key = data_blob_talloc(mem_ctx,
3475                                 cli->auth->user_session_key.data,
3476                                 cli->auth->user_session_key.length);
3477                         break;
3478                 default:
3479                         return NT_STATUS_NO_USER_SESSION_KEY;
3480         }
3481
3482         return NT_STATUS_OK;
3483 }