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