Slightly simplify the paths after rpc_api_pipe()
[metze/samba/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                          char *pdata, size_t size)
259 {
260         ssize_t num_read = 0;
261
262         DEBUG(5, ("rpc_read: data_to_read: %u\n", (unsigned int)size));
263
264         while (num_read < size) {
265                 ssize_t thistime = 0;
266                 NTSTATUS status;
267
268                 switch (cli->transport_type) {
269                 case NCACN_NP:
270                         status = rpc_read_np(cli->trans.np.cli,
271                                              cli->trans.np.pipe_name,
272                                              cli->trans.np.fnum,
273                                              pdata + num_read,
274                                              size - num_read, &thistime);
275                         break;
276                 case NCACN_IP_TCP:
277                 case NCACN_UNIX_STREAM:
278                         status = NT_STATUS_OK;
279                         thistime = sys_read(cli->trans.sock.fd,
280                                             pdata + num_read,
281                                             size - num_read);
282                         if (thistime == -1) {
283                                 status = map_nt_error_from_unix(errno);
284                         }
285                         break;
286                 default:
287                         DEBUG(0, ("unknown transport type %d\n",
288                                   cli->transport_type));
289                         return NT_STATUS_INTERNAL_ERROR;
290                 }
291
292                 if (!NT_STATUS_IS_OK(status)) {
293                         return status;
294                 }
295                 if (thistime == 0) {
296                         return NT_STATUS_END_OF_FILE;
297                 }
298
299                 num_read += thistime;
300
301         }
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,
322                                prs_data_p(current_pdu) + current_pdu_len,
323                                RPC_HEADER_LEN - 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,
350                                prs_data_p(current_pdu) + current_pdu_len,
351                                prhdr->frag_len - 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         prs_mem_free(&rpc_out);
2179         if (!NT_STATUS_IS_OK(nt_status)) {
2180                 return nt_status;
2181         }
2182
2183         /* Get the auth blob from the reply. */
2184         if(!smb_io_rpc_hdr("rpc_hdr   ", phdr, rbuf, 0)) {
2185                 DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: Failed to unmarshall RPC_HDR.\n"));
2186                 return NT_STATUS_BUFFER_TOO_SMALL;
2187         }
2188
2189         if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2190                 return NT_STATUS_INVALID_PARAMETER;
2191         }
2192
2193         if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
2194                 return NT_STATUS_INVALID_PARAMETER;
2195         }
2196
2197         server_spnego_response = data_blob(NULL, phdr->auth_len);
2198         prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len);
2199
2200         /* Check we got a valid auth response. */
2201         if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK, OID_NTLMSSP, &tmp_blob)) {
2202                 data_blob_free(&server_spnego_response);
2203                 data_blob_free(&tmp_blob);
2204                 return NT_STATUS_INVALID_PARAMETER;
2205         }
2206
2207         data_blob_free(&server_spnego_response);
2208         data_blob_free(&tmp_blob);
2209
2210         DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
2211                  "%s.\n", rpccli_pipe_txt(debug_ctx(), cli)));
2212
2213         return NT_STATUS_OK;
2214 }
2215
2216 /****************************************************************************
2217  Do an rpc bind.
2218 ****************************************************************************/
2219
2220 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
2221                        struct cli_pipe_auth_data *auth)
2222 {
2223         RPC_HDR hdr;
2224         RPC_HDR_BA hdr_ba;
2225         prs_struct rpc_out;
2226         prs_struct rbuf;
2227         uint32 rpc_call_id;
2228         NTSTATUS status;
2229
2230         DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2231                 rpccli_pipe_txt(debug_ctx(), cli),
2232                 (unsigned int)auth->auth_type,
2233                 (unsigned int)auth->auth_level ));
2234
2235         cli->auth = talloc_move(cli, &auth);
2236
2237         prs_init_empty(&rpc_out, talloc_tos(), MARSHALL);
2238
2239         rpc_call_id = get_rpc_call_id();
2240
2241         /* Marshall the outgoing data. */
2242         status = create_rpc_bind_req(cli, &rpc_out, rpc_call_id,
2243                                 &cli->abstract_syntax,
2244                                 &cli->transfer_syntax,
2245                                 cli->auth->auth_type,
2246                                 cli->auth->auth_level);
2247
2248         if (!NT_STATUS_IS_OK(status)) {
2249                 prs_mem_free(&rpc_out);
2250                 return status;
2251         }
2252
2253         /* Initialize the incoming data struct. */
2254         prs_init_empty(&rbuf, talloc_tos(), UNMARSHALL);
2255
2256         /* send data on \PIPE\.  receive a response */
2257         status = rpc_api_pipe(cli, &rpc_out, &rbuf, RPC_BINDACK);
2258         prs_mem_free(&rpc_out);
2259         if (!NT_STATUS_IS_OK(status)) {
2260                 return status;
2261         }
2262
2263         DEBUG(3,("rpc_pipe_bind: %s bind request returned ok.\n",
2264                  rpccli_pipe_txt(debug_ctx(), cli)));
2265
2266         /* Unmarshall the RPC header */
2267         if(!smb_io_rpc_hdr("hdr"   , &hdr, &rbuf, 0)) {
2268                 DEBUG(0,("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2269                 prs_mem_free(&rbuf);
2270                 return NT_STATUS_BUFFER_TOO_SMALL;
2271         }
2272
2273         if(!smb_io_rpc_hdr_ba("", &hdr_ba, &rbuf, 0)) {
2274                 DEBUG(0,("rpc_pipe_bind: Failed to unmarshall RPC_HDR_BA.\n"));
2275                 prs_mem_free(&rbuf);
2276                 return NT_STATUS_BUFFER_TOO_SMALL;
2277         }
2278
2279         if(!check_bind_response(&hdr_ba, &cli->transfer_syntax)) {
2280                 DEBUG(2,("rpc_pipe_bind: check_bind_response failed.\n"));
2281                 prs_mem_free(&rbuf);
2282                 return NT_STATUS_BUFFER_TOO_SMALL;
2283         }
2284
2285         cli->max_xmit_frag = hdr_ba.bba.max_tsize;
2286         cli->max_recv_frag = hdr_ba.bba.max_rsize;
2287
2288         /* For authenticated binds we may need to do 3 or 4 leg binds. */
2289         switch(cli->auth->auth_type) {
2290
2291                 case PIPE_AUTH_TYPE_NONE:
2292                 case PIPE_AUTH_TYPE_SCHANNEL:
2293                         /* Bind complete. */
2294                         break;
2295
2296                 case PIPE_AUTH_TYPE_NTLMSSP:
2297                         /* Need to send AUTH3 packet - no reply. */
2298                         status = rpc_finish_auth3_bind(
2299                                 cli, &hdr, &rbuf, rpc_call_id,
2300                                 cli->auth->auth_type,
2301                                 cli->auth->auth_level);
2302                         if (!NT_STATUS_IS_OK(status)) {
2303                                 prs_mem_free(&rbuf);
2304                                 return status;
2305                         }
2306                         break;
2307
2308                 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2309                         /* Need to send alter context request and reply. */
2310                         status = rpc_finish_spnego_ntlmssp_bind(
2311                                 cli, &hdr, &rbuf, rpc_call_id,
2312                                 &cli->abstract_syntax, &cli->transfer_syntax,
2313                                 cli->auth->auth_type, cli->auth->auth_level);
2314                         if (!NT_STATUS_IS_OK(status)) {
2315                                 prs_mem_free(&rbuf);
2316                                 return status;
2317                         }
2318                         break;
2319
2320                 case PIPE_AUTH_TYPE_KRB5:
2321                         /* */
2322
2323                 default:
2324                         DEBUG(0,("cli_finish_bind_auth: unknown auth type "
2325                                  "%u\n", (unsigned int)cli->auth->auth_type));
2326                         prs_mem_free(&rbuf);
2327                         return NT_STATUS_INVALID_INFO_CLASS;
2328         }
2329
2330         /* For NTLMSSP ensure the server gave us the auth_level we wanted. */
2331         if (cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP
2332             || cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
2333                 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2334                         if (!(cli->auth->a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN)) {
2335                                 DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP signing and server refused.\n"));
2336                                 prs_mem_free(&rbuf);
2337                                 return NT_STATUS_INVALID_PARAMETER;
2338                         }
2339                 }
2340                 if (cli->auth->auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2341                         if (!(cli->auth->a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL)) {
2342                                 DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP sealing and server refused.\n"));
2343                                 prs_mem_free(&rbuf);
2344                                 return NT_STATUS_INVALID_PARAMETER;
2345                         }
2346                 }
2347         }
2348
2349         prs_mem_free(&rbuf);
2350         return NT_STATUS_OK;
2351 }
2352
2353 unsigned int rpccli_set_timeout(struct rpc_pipe_client *cli,
2354                                 unsigned int timeout)
2355 {
2356         return cli_set_timeout(cli->trans.np.cli, timeout);
2357 }
2358
2359 bool rpccli_get_pwd_hash(struct rpc_pipe_client *cli, uint8_t nt_hash[16])
2360 {
2361         if ((cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
2362             || (cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) {
2363                 memcpy(nt_hash, cli->auth->a_u.ntlmssp_state->nt_hash, 16);
2364                 return true;
2365         }
2366
2367         if (cli->transport_type == NCACN_NP) {
2368                 E_md4hash(cli->trans.np.cli->pwd.password, nt_hash);
2369                 return true;
2370         }
2371
2372         return false;
2373 }
2374
2375 struct cli_state *rpc_pipe_np_smb_conn(struct rpc_pipe_client *p)
2376 {
2377         if (p->transport_type == NCACN_NP) {
2378                 return p->trans.np.cli;
2379         }
2380         return NULL;
2381 }
2382
2383 static int rpc_pipe_destructor(struct rpc_pipe_client *p)
2384 {
2385         if (p->transport_type == NCACN_NP) {
2386                 bool ret;
2387                 ret = cli_close(p->trans.np.cli, p->trans.np.fnum);
2388                 if (!ret) {
2389                         DEBUG(1, ("rpc_pipe_destructor: cli_close failed on "
2390                                   "pipe %s. Error was %s\n",
2391                                   rpccli_pipe_txt(debug_ctx(), p),
2392                                   cli_errstr(p->trans.np.cli)));
2393                 }
2394
2395                 DEBUG(10, ("rpc_pipe_destructor: closed %s\n",
2396                            rpccli_pipe_txt(debug_ctx(), p)));
2397
2398                 DLIST_REMOVE(p->trans.np.cli->pipe_list, p);
2399                 return ret ? -1 : 0;
2400         }
2401
2402         return -1;
2403 }
2404
2405 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2406                                struct cli_pipe_auth_data **presult)
2407 {
2408         struct cli_pipe_auth_data *result;
2409
2410         result = talloc(mem_ctx, struct cli_pipe_auth_data);
2411         if (result == NULL) {
2412                 return NT_STATUS_NO_MEMORY;
2413         }
2414
2415         result->auth_type = PIPE_AUTH_TYPE_NONE;
2416         result->auth_level = PIPE_AUTH_LEVEL_NONE;
2417
2418         result->user_name = talloc_strdup(result, "");
2419         result->domain = talloc_strdup(result, "");
2420         if ((result->user_name == NULL) || (result->domain == NULL)) {
2421                 TALLOC_FREE(result);
2422                 return NT_STATUS_NO_MEMORY;
2423         }
2424
2425         *presult = result;
2426         return NT_STATUS_OK;
2427 }
2428
2429 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth)
2430 {
2431         ntlmssp_end(&auth->a_u.ntlmssp_state);
2432         return 0;
2433 }
2434
2435 NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
2436                                   enum pipe_auth_type auth_type,
2437                                   enum pipe_auth_level auth_level,
2438                                   const char *domain,
2439                                   const char *username,
2440                                   const char *password,
2441                                   struct cli_pipe_auth_data **presult)
2442 {
2443         struct cli_pipe_auth_data *result;
2444         NTSTATUS status;
2445
2446         result = talloc(mem_ctx, struct cli_pipe_auth_data);
2447         if (result == NULL) {
2448                 return NT_STATUS_NO_MEMORY;
2449         }
2450
2451         result->auth_type = auth_type;
2452         result->auth_level = auth_level;
2453
2454         result->user_name = talloc_strdup(result, username);
2455         result->domain = talloc_strdup(result, domain);
2456         if ((result->user_name == NULL) || (result->domain == NULL)) {
2457                 status = NT_STATUS_NO_MEMORY;
2458                 goto fail;
2459         }
2460
2461         status = ntlmssp_client_start(&result->a_u.ntlmssp_state);
2462         if (!NT_STATUS_IS_OK(status)) {
2463                 goto fail;
2464         }
2465
2466         talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
2467
2468         status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);
2469         if (!NT_STATUS_IS_OK(status)) {
2470                 goto fail;
2471         }
2472
2473         status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);
2474         if (!NT_STATUS_IS_OK(status)) {
2475                 goto fail;
2476         }
2477
2478         status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);
2479         if (!NT_STATUS_IS_OK(status)) {
2480                 goto fail;
2481         }
2482
2483         /*
2484          * Turn off sign+seal to allow selected auth level to turn it back on.
2485          */
2486         result->a_u.ntlmssp_state->neg_flags &=
2487                 ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);
2488
2489         if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
2490                 result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
2491         } else if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) {
2492                 result->a_u.ntlmssp_state->neg_flags
2493                         |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
2494         }
2495
2496         *presult = result;
2497         return NT_STATUS_OK;
2498
2499  fail:
2500         TALLOC_FREE(result);
2501         return status;
2502 }
2503
2504 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
2505                                    enum pipe_auth_level auth_level,
2506                                    const uint8_t sess_key[16],
2507                                    struct cli_pipe_auth_data **presult)
2508 {
2509         struct cli_pipe_auth_data *result;
2510
2511         result = talloc(mem_ctx, struct cli_pipe_auth_data);
2512         if (result == NULL) {
2513                 return NT_STATUS_NO_MEMORY;
2514         }
2515
2516         result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
2517         result->auth_level = auth_level;
2518
2519         result->user_name = talloc_strdup(result, "");
2520         result->domain = talloc_strdup(result, domain);
2521         if ((result->user_name == NULL) || (result->domain == NULL)) {
2522                 goto fail;
2523         }
2524
2525         result->a_u.schannel_auth = talloc(result,
2526                                            struct schannel_auth_struct);
2527         if (result->a_u.schannel_auth == NULL) {
2528                 goto fail;
2529         }
2530
2531         memcpy(result->a_u.schannel_auth->sess_key, sess_key,
2532                sizeof(result->a_u.schannel_auth->sess_key));
2533         result->a_u.schannel_auth->seq_num = 0;
2534
2535         *presult = result;
2536         return NT_STATUS_OK;
2537
2538  fail:
2539         TALLOC_FREE(result);
2540         return NT_STATUS_NO_MEMORY;
2541 }
2542
2543 #ifdef HAVE_KRB5
2544 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
2545 {
2546         data_blob_free(&auth->session_key);
2547         return 0;
2548 }
2549 #endif
2550
2551 NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
2552                                    enum pipe_auth_level auth_level,
2553                                    const char *service_princ,
2554                                    const char *username,
2555                                    const char *password,
2556                                    struct cli_pipe_auth_data **presult)
2557 {
2558 #ifdef HAVE_KRB5
2559         struct cli_pipe_auth_data *result;
2560
2561         if ((username != NULL) && (password != NULL)) {
2562                 int ret = kerberos_kinit_password(username, password, 0, NULL);
2563                 if (ret != 0) {
2564                         return NT_STATUS_ACCESS_DENIED;
2565                 }
2566         }
2567
2568         result = talloc(mem_ctx, struct cli_pipe_auth_data);
2569         if (result == NULL) {
2570                 return NT_STATUS_NO_MEMORY;
2571         }
2572
2573         result->auth_type = PIPE_AUTH_TYPE_KRB5;
2574         result->auth_level = auth_level;
2575
2576         /*
2577          * Username / domain need fixing!
2578          */
2579         result->user_name = talloc_strdup(result, "");
2580         result->domain = talloc_strdup(result, "");
2581         if ((result->user_name == NULL) || (result->domain == NULL)) {
2582                 goto fail;
2583         }
2584
2585         result->a_u.kerberos_auth = TALLOC_ZERO_P(
2586                 result, struct kerberos_auth_struct);
2587         if (result->a_u.kerberos_auth == NULL) {
2588                 goto fail;
2589         }
2590         talloc_set_destructor(result->a_u.kerberos_auth,
2591                               cli_auth_kerberos_data_destructor);
2592
2593         result->a_u.kerberos_auth->service_principal = talloc_strdup(
2594                 result, service_princ);
2595         if (result->a_u.kerberos_auth->service_principal == NULL) {
2596                 goto fail;
2597         }
2598
2599         *presult = result;
2600         return NT_STATUS_OK;
2601
2602  fail:
2603         TALLOC_FREE(result);
2604         return NT_STATUS_NO_MEMORY;
2605 #else
2606         return NT_STATUS_NOT_SUPPORTED;
2607 #endif
2608 }
2609
2610 static int rpc_pipe_sock_destructor(struct rpc_pipe_client *p)
2611 {
2612         close(p->trans.sock.fd);
2613         return 0;
2614 }
2615
2616 /**
2617  * Create an rpc pipe client struct, connecting to a tcp port.
2618  */
2619 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
2620                                        uint16_t port,
2621                                        const struct ndr_syntax_id *abstract_syntax,
2622                                        struct rpc_pipe_client **presult)
2623 {
2624         struct rpc_pipe_client *result;
2625         struct sockaddr_storage addr;
2626         NTSTATUS status;
2627
2628         result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
2629         if (result == NULL) {
2630                 return NT_STATUS_NO_MEMORY;
2631         }
2632
2633         result->transport_type = NCACN_IP_TCP;
2634
2635         result->abstract_syntax = *abstract_syntax;
2636         result->transfer_syntax = ndr_transfer_syntax;
2637
2638         result->desthost = talloc_strdup(result, host);
2639         result->srv_name_slash = talloc_asprintf_strupper_m(
2640                 result, "\\\\%s", result->desthost);
2641         if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2642                 status = NT_STATUS_NO_MEMORY;
2643                 goto fail;
2644         }
2645
2646         result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2647         result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2648
2649         if (!resolve_name(host, &addr, 0)) {
2650                 status = NT_STATUS_NOT_FOUND;
2651                 goto fail;
2652         }
2653
2654         status = open_socket_out(&addr, port, 60, &result->trans.sock.fd);
2655         if (!NT_STATUS_IS_OK(status)) {
2656                 goto fail;
2657         }
2658
2659         talloc_set_destructor(result, rpc_pipe_sock_destructor);
2660
2661         *presult = result;
2662         return NT_STATUS_OK;
2663
2664  fail:
2665         TALLOC_FREE(result);
2666         return status;
2667 }
2668
2669 /**
2670  * Determine the tcp port on which a dcerpc interface is listening
2671  * for the ncacn_ip_tcp transport via the endpoint mapper of the
2672  * target host.
2673  */
2674 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
2675                                       const struct ndr_syntax_id *abstract_syntax,
2676                                       uint16_t *pport)
2677 {
2678         NTSTATUS status;
2679         struct rpc_pipe_client *epm_pipe = NULL;
2680         struct cli_pipe_auth_data *auth = NULL;
2681         struct dcerpc_binding *map_binding = NULL;
2682         struct dcerpc_binding *res_binding = NULL;
2683         struct epm_twr_t *map_tower = NULL;
2684         struct epm_twr_t *res_towers = NULL;
2685         struct policy_handle *entry_handle = NULL;
2686         uint32_t num_towers = 0;
2687         uint32_t max_towers = 1;
2688         struct epm_twr_p_t towers;
2689         TALLOC_CTX *tmp_ctx = talloc_stackframe();
2690
2691         if (pport == NULL) {
2692                 status = NT_STATUS_INVALID_PARAMETER;
2693                 goto done;
2694         }
2695
2696         /* open the connection to the endpoint mapper */
2697         status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
2698                                         &ndr_table_epmapper.syntax_id,
2699                                         &epm_pipe);
2700
2701         if (!NT_STATUS_IS_OK(status)) {
2702                 goto done;
2703         }
2704
2705         status = rpccli_anon_bind_data(tmp_ctx, &auth);
2706         if (!NT_STATUS_IS_OK(status)) {
2707                 goto done;
2708         }
2709
2710         status = rpc_pipe_bind(epm_pipe, auth);
2711         if (!NT_STATUS_IS_OK(status)) {
2712                 goto done;
2713         }
2714
2715         /* create tower for asking the epmapper */
2716
2717         map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
2718         if (map_binding == NULL) {
2719                 status = NT_STATUS_NO_MEMORY;
2720                 goto done;
2721         }
2722
2723         map_binding->transport = NCACN_IP_TCP;
2724         map_binding->object = *abstract_syntax;
2725         map_binding->host = host; /* needed? */
2726         map_binding->endpoint = "0"; /* correct? needed? */
2727
2728         map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
2729         if (map_tower == NULL) {
2730                 status = NT_STATUS_NO_MEMORY;
2731                 goto done;
2732         }
2733
2734         status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
2735                                             &(map_tower->tower));
2736         if (!NT_STATUS_IS_OK(status)) {
2737                 goto done;
2738         }
2739
2740         /* allocate further parameters for the epm_Map call */
2741
2742         res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
2743         if (res_towers == NULL) {
2744                 status = NT_STATUS_NO_MEMORY;
2745                 goto done;
2746         }
2747         towers.twr = res_towers;
2748
2749         entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
2750         if (entry_handle == NULL) {
2751                 status = NT_STATUS_NO_MEMORY;
2752                 goto done;
2753         }
2754
2755         /* ask the endpoint mapper for the port */
2756
2757         status = rpccli_epm_Map(epm_pipe,
2758                                 tmp_ctx,
2759                                 CONST_DISCARD(struct GUID *,
2760                                               &(abstract_syntax->uuid)),
2761                                 map_tower,
2762                                 entry_handle,
2763                                 max_towers,
2764                                 &num_towers,
2765                                 &towers);
2766
2767         if (!NT_STATUS_IS_OK(status)) {
2768                 goto done;
2769         }
2770
2771         if (num_towers != 1) {
2772                 status = NT_STATUS_UNSUCCESSFUL;
2773                 goto done;
2774         }
2775
2776         /* extract the port from the answer */
2777
2778         status = dcerpc_binding_from_tower(tmp_ctx,
2779                                            &(towers.twr->tower),
2780                                            &res_binding);
2781         if (!NT_STATUS_IS_OK(status)) {
2782                 goto done;
2783         }
2784
2785         /* are further checks here necessary? */
2786         if (res_binding->transport != NCACN_IP_TCP) {
2787                 status = NT_STATUS_UNSUCCESSFUL;
2788                 goto done;
2789         }
2790
2791         *pport = (uint16_t)atoi(res_binding->endpoint);
2792
2793 done:
2794         TALLOC_FREE(tmp_ctx);
2795         return status;
2796 }
2797
2798 /**
2799  * Create a rpc pipe client struct, connecting to a host via tcp.
2800  * The port is determined by asking the endpoint mapper on the given
2801  * host.
2802  */
2803 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
2804                            const struct ndr_syntax_id *abstract_syntax,
2805                            struct rpc_pipe_client **presult)
2806 {
2807         NTSTATUS status;
2808         uint16_t port = 0;
2809
2810         *presult = NULL;
2811
2812         status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
2813         if (!NT_STATUS_IS_OK(status)) {
2814                 goto done;
2815         }
2816
2817         status = rpc_pipe_open_tcp_port(mem_ctx, host, port,
2818                                         abstract_syntax, presult);
2819
2820 done:
2821         return status;
2822 }
2823
2824 /********************************************************************
2825  Create a rpc pipe client struct, connecting to a unix domain socket
2826  ********************************************************************/
2827 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
2828                                const struct ndr_syntax_id *abstract_syntax,
2829                                struct rpc_pipe_client **presult)
2830 {
2831         struct rpc_pipe_client *result;
2832         struct sockaddr_un addr;
2833         NTSTATUS status;
2834
2835         result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2836         if (result == NULL) {
2837                 return NT_STATUS_NO_MEMORY;
2838         }
2839
2840         result->transport_type = NCACN_UNIX_STREAM;
2841
2842         result->abstract_syntax = *abstract_syntax;
2843         result->transfer_syntax = ndr_transfer_syntax;
2844
2845         result->desthost = talloc_get_myname(result);
2846         result->srv_name_slash = talloc_asprintf_strupper_m(
2847                 result, "\\\\%s", result->desthost);
2848         if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2849                 status = NT_STATUS_NO_MEMORY;
2850                 goto fail;
2851         }
2852
2853         result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2854         result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2855
2856         result->trans.sock.fd = socket(AF_UNIX, SOCK_STREAM, 0);
2857         if (result->trans.sock.fd == -1) {
2858                 status = map_nt_error_from_unix(errno);
2859                 goto fail;
2860         }
2861
2862         talloc_set_destructor(result, rpc_pipe_sock_destructor);
2863
2864         ZERO_STRUCT(addr);
2865         addr.sun_family = AF_UNIX;
2866         strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
2867
2868         if (sys_connect(result->trans.sock.fd,
2869                         (struct sockaddr *)&addr) == -1) {
2870                 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
2871                           strerror(errno)));
2872                 close(result->trans.sock.fd);
2873                 return map_nt_error_from_unix(errno);
2874         }
2875
2876         *presult = result;
2877         return NT_STATUS_OK;
2878
2879  fail:
2880         TALLOC_FREE(result);
2881         return status;
2882 }
2883
2884
2885 /****************************************************************************
2886  Open a named pipe over SMB to a remote server.
2887  *
2888  * CAVEAT CALLER OF THIS FUNCTION:
2889  *    The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2890  *    so be sure that this function is called AFTER any structure (vs pointer)
2891  *    assignment of the cli.  In particular, libsmbclient does structure
2892  *    assignments of cli, which invalidates the data in the returned
2893  *    rpc_pipe_client if this function is called before the structure assignment
2894  *    of cli.
2895  * 
2896  ****************************************************************************/
2897
2898 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
2899                                  const struct ndr_syntax_id *abstract_syntax,
2900                                  struct rpc_pipe_client **presult)
2901 {
2902         struct rpc_pipe_client *result;
2903         int fnum;
2904
2905         /* sanity check to protect against crashes */
2906
2907         if ( !cli ) {
2908                 return NT_STATUS_INVALID_HANDLE;
2909         }
2910
2911         result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
2912         if (result == NULL) {
2913                 return NT_STATUS_NO_MEMORY;
2914         }
2915
2916         result->transport_type = NCACN_NP;
2917
2918         result->trans.np.pipe_name = cli_get_pipe_name_from_iface(
2919                 result, cli, abstract_syntax);
2920         if (result->trans.np.pipe_name == NULL) {
2921                 DEBUG(1, ("Could not find pipe for interface\n"));
2922                 TALLOC_FREE(result);
2923                 return NT_STATUS_INVALID_PARAMETER;
2924         }
2925
2926         result->trans.np.cli = cli;
2927         result->abstract_syntax = *abstract_syntax;
2928         result->transfer_syntax = ndr_transfer_syntax;
2929         result->desthost = talloc_strdup(result, cli->desthost);
2930         result->srv_name_slash = talloc_asprintf_strupper_m(
2931                 result, "\\\\%s", result->desthost);
2932
2933         result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2934         result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2935
2936         if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2937                 TALLOC_FREE(result);
2938                 return NT_STATUS_NO_MEMORY;
2939         }
2940
2941         fnum = cli_nt_create(cli, result->trans.np.pipe_name,
2942                              DESIRED_ACCESS_PIPE);
2943         if (fnum == -1) {
2944                 DEBUG(3,("rpc_pipe_open_np: cli_nt_create failed on pipe %s "
2945                          "to machine %s.  Error was %s\n",
2946                          result->trans.np.pipe_name, cli->desthost,
2947                          cli_errstr(cli)));
2948                 TALLOC_FREE(result);
2949                 return cli_get_nt_error(cli);
2950         }
2951
2952         result->trans.np.fnum = fnum;
2953
2954         DLIST_ADD(cli->pipe_list, result);
2955         talloc_set_destructor(result, rpc_pipe_destructor);
2956
2957         *presult = result;
2958         return NT_STATUS_OK;
2959 }
2960
2961 /****************************************************************************
2962  Open a pipe to a remote server.
2963  ****************************************************************************/
2964
2965 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
2966                                   const struct ndr_syntax_id *interface,
2967                                   struct rpc_pipe_client **presult)
2968 {
2969         if (ndr_syntax_id_equal(interface, &ndr_table_drsuapi.syntax_id)) {
2970                 /*
2971                  * We should have a better way to figure out this drsuapi
2972                  * speciality...
2973                  */
2974                 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
2975                                          presult);
2976         }
2977
2978         return rpc_pipe_open_np(cli, interface, presult);
2979 }
2980
2981 /****************************************************************************
2982  Open a named pipe to an SMB server and bind anonymously.
2983  ****************************************************************************/
2984
2985 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
2986                                   const struct ndr_syntax_id *interface,
2987                                   struct rpc_pipe_client **presult)
2988 {
2989         struct rpc_pipe_client *result;
2990         struct cli_pipe_auth_data *auth;
2991         NTSTATUS status;
2992
2993         status = cli_rpc_pipe_open(cli, interface, &result);
2994         if (!NT_STATUS_IS_OK(status)) {
2995                 return status;
2996         }
2997
2998         status = rpccli_anon_bind_data(result, &auth);
2999         if (!NT_STATUS_IS_OK(status)) {
3000                 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3001                           nt_errstr(status)));
3002                 TALLOC_FREE(result);
3003                 return status;
3004         }
3005
3006         /*
3007          * This is a bit of an abstraction violation due to the fact that an
3008          * anonymous bind on an authenticated SMB inherits the user/domain
3009          * from the enclosing SMB creds
3010          */
3011
3012         TALLOC_FREE(auth->user_name);
3013         TALLOC_FREE(auth->domain);
3014
3015         auth->user_name = talloc_strdup(auth, cli->user_name);
3016         auth->domain = talloc_strdup(auth, cli->domain);
3017         auth->user_session_key = data_blob_talloc(auth,
3018                 cli->user_session_key.data,
3019                 cli->user_session_key.length);
3020
3021         if ((auth->user_name == NULL) || (auth->domain == NULL)) {
3022                 TALLOC_FREE(result);
3023                 return NT_STATUS_NO_MEMORY;
3024         }
3025
3026         status = rpc_pipe_bind(result, auth);
3027         if (!NT_STATUS_IS_OK(status)) {
3028                 int lvl = 0;
3029                 if (ndr_syntax_id_equal(interface,
3030                                         &ndr_table_dssetup.syntax_id)) {
3031                         /* non AD domains just don't have this pipe, avoid
3032                          * level 0 statement in that case - gd */
3033                         lvl = 3;
3034                 }
3035                 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3036                             "%s failed with error %s\n",
3037                             cli_get_pipe_name_from_iface(debug_ctx(), cli,
3038                                                          interface),
3039                             nt_errstr(status) ));
3040                 TALLOC_FREE(result);
3041                 return status;
3042         }
3043
3044         DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3045                   "%s and bound anonymously.\n", result->trans.np.pipe_name,
3046                   cli->desthost ));
3047
3048         *presult = result;
3049         return NT_STATUS_OK;
3050 }
3051
3052 /****************************************************************************
3053  Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
3054  ****************************************************************************/
3055
3056 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
3057                                                    const struct ndr_syntax_id *interface,
3058                                                    enum pipe_auth_type auth_type,
3059                                                    enum pipe_auth_level auth_level,
3060                                                    const char *domain,
3061                                                    const char *username,
3062                                                    const char *password,
3063                                                    struct rpc_pipe_client **presult)
3064 {
3065         struct rpc_pipe_client *result;
3066         struct cli_pipe_auth_data *auth;
3067         NTSTATUS status;
3068
3069         status = cli_rpc_pipe_open(cli, interface, &result);
3070         if (!NT_STATUS_IS_OK(status)) {
3071                 return status;
3072         }
3073
3074         status = rpccli_ntlmssp_bind_data(
3075                 result, auth_type, auth_level, domain, username,
3076                 cli->pwd.null_pwd ? NULL : password, &auth);
3077         if (!NT_STATUS_IS_OK(status)) {
3078                 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
3079                           nt_errstr(status)));
3080                 goto err;
3081         }
3082
3083         status = rpc_pipe_bind(result, auth);
3084         if (!NT_STATUS_IS_OK(status)) {
3085                 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
3086                         nt_errstr(status) ));
3087                 goto err;
3088         }
3089
3090         DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
3091                 "machine %s and bound NTLMSSP as user %s\\%s.\n",
3092                 result->trans.np.pipe_name, cli->desthost,
3093                 domain, username ));
3094
3095         *presult = result;
3096         return NT_STATUS_OK;
3097
3098   err:
3099
3100         TALLOC_FREE(result);
3101         return status;
3102 }
3103
3104 /****************************************************************************
3105  External interface.
3106  Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
3107  ****************************************************************************/
3108
3109 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
3110                                    const struct ndr_syntax_id *interface,
3111                                    enum pipe_auth_level auth_level,
3112                                    const char *domain,
3113                                    const char *username,
3114                                    const char *password,
3115                                    struct rpc_pipe_client **presult)
3116 {
3117         return cli_rpc_pipe_open_ntlmssp_internal(cli,
3118                                                 interface,
3119                                                 PIPE_AUTH_TYPE_NTLMSSP,
3120                                                 auth_level,
3121                                                 domain,
3122                                                 username,
3123                                                 password,
3124                                                 presult);
3125 }
3126
3127 /****************************************************************************
3128  External interface.
3129  Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
3130  ****************************************************************************/
3131
3132 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3133                                           const struct ndr_syntax_id *interface,
3134                                           enum pipe_auth_level auth_level,
3135                                           const char *domain,
3136                                           const char *username,
3137                                           const char *password,
3138                                           struct rpc_pipe_client **presult)
3139 {
3140         return cli_rpc_pipe_open_ntlmssp_internal(cli,
3141                                                 interface,
3142                                                 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
3143                                                 auth_level,
3144                                                 domain,
3145                                                 username,
3146                                                 password,
3147                                                 presult);
3148 }
3149
3150 /****************************************************************************
3151   Get a the schannel session key out of an already opened netlogon pipe.
3152  ****************************************************************************/
3153 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
3154                                                 struct cli_state *cli,
3155                                                 const char *domain,
3156                                                 uint32 *pneg_flags)
3157 {
3158         uint32 sec_chan_type = 0;
3159         unsigned char machine_pwd[16];
3160         const char *machine_account;
3161         NTSTATUS status;
3162
3163         /* Get the machine account credentials from secrets.tdb. */
3164         if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
3165                                &sec_chan_type))
3166         {
3167                 DEBUG(0, ("get_schannel_session_key: could not fetch "
3168                         "trust account password for domain '%s'\n",
3169                         domain));
3170                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3171         }
3172
3173         status = rpccli_netlogon_setup_creds(netlogon_pipe,
3174                                         cli->desthost, /* server name */
3175                                         domain,        /* domain */
3176                                         global_myname(), /* client name */
3177                                         machine_account, /* machine account name */
3178                                         machine_pwd,
3179                                         sec_chan_type,
3180                                         pneg_flags);
3181
3182         if (!NT_STATUS_IS_OK(status)) {
3183                 DEBUG(3, ("get_schannel_session_key_common: "
3184                           "rpccli_netlogon_setup_creds failed with result %s "
3185                           "to server %s, domain %s, machine account %s.\n",
3186                           nt_errstr(status), cli->desthost, domain,
3187                           machine_account ));
3188                 return status;
3189         }
3190
3191         if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
3192                 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
3193                         cli->desthost));
3194                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3195         }
3196
3197         return NT_STATUS_OK;;
3198 }
3199
3200 /****************************************************************************
3201  Open a netlogon pipe and get the schannel session key.
3202  Now exposed to external callers.
3203  ****************************************************************************/
3204
3205
3206 NTSTATUS get_schannel_session_key(struct cli_state *cli,
3207                                   const char *domain,
3208                                   uint32 *pneg_flags,
3209                                   struct rpc_pipe_client **presult)
3210 {
3211         struct rpc_pipe_client *netlogon_pipe = NULL;
3212         NTSTATUS status;
3213
3214         status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
3215                                           &netlogon_pipe);
3216         if (!NT_STATUS_IS_OK(status)) {
3217                 return status;
3218         }
3219
3220         status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3221                                                  pneg_flags);
3222         if (!NT_STATUS_IS_OK(status)) {
3223                 TALLOC_FREE(netlogon_pipe);
3224                 return status;
3225         }
3226
3227         *presult = netlogon_pipe;
3228         return NT_STATUS_OK;
3229 }
3230
3231 /****************************************************************************
3232  External interface.
3233  Open a named pipe to an SMB server and bind using schannel (bind type 68)
3234  using session_key. sign and seal.
3235  ****************************************************************************/
3236
3237 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
3238                                              const struct ndr_syntax_id *interface,
3239                                              enum pipe_auth_level auth_level,
3240                                              const char *domain,
3241                                              const struct dcinfo *pdc,
3242                                              struct rpc_pipe_client **presult)
3243 {
3244         struct rpc_pipe_client *result;
3245         struct cli_pipe_auth_data *auth;
3246         NTSTATUS status;
3247
3248         status = cli_rpc_pipe_open(cli, interface, &result);
3249         if (!NT_STATUS_IS_OK(status)) {
3250                 return status;
3251         }
3252
3253         status = rpccli_schannel_bind_data(result, domain, auth_level,
3254                                            pdc->sess_key, &auth);
3255         if (!NT_STATUS_IS_OK(status)) {
3256                 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
3257                           nt_errstr(status)));
3258                 TALLOC_FREE(result);
3259                 return status;
3260         }
3261
3262         status = rpc_pipe_bind(result, auth);
3263         if (!NT_STATUS_IS_OK(status)) {
3264                 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
3265                           "cli_rpc_pipe_bind failed with error %s\n",
3266                           nt_errstr(status) ));
3267                 TALLOC_FREE(result);
3268                 return status;
3269         }
3270
3271         /*
3272          * The credentials on a new netlogon pipe are the ones we are passed
3273          * in - copy them over.
3274          */
3275         result->dc = (struct dcinfo *)talloc_memdup(result, pdc, sizeof(*pdc));
3276         if (result->dc == NULL) {
3277                 DEBUG(0, ("talloc failed\n"));
3278                 TALLOC_FREE(result);
3279                 return NT_STATUS_NO_MEMORY;
3280         }
3281
3282         DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
3283                 "for domain %s "
3284                 "and bound using schannel.\n",
3285                 result->trans.np.pipe_name, cli->desthost, domain ));
3286
3287         *presult = result;
3288         return NT_STATUS_OK;
3289 }
3290
3291 /****************************************************************************
3292  Open a named pipe to an SMB server and bind using schannel (bind type 68).
3293  Fetch the session key ourselves using a temporary netlogon pipe. This
3294  version uses an ntlmssp auth bound netlogon pipe to get the key.
3295  ****************************************************************************/
3296
3297 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
3298                                                       const char *domain,
3299                                                       const char *username,
3300                                                       const char *password,
3301                                                       uint32 *pneg_flags,
3302                                                       struct rpc_pipe_client **presult)
3303 {
3304         struct rpc_pipe_client *netlogon_pipe = NULL;
3305         NTSTATUS status;
3306
3307         status = cli_rpc_pipe_open_spnego_ntlmssp(
3308                 cli, &ndr_table_netlogon.syntax_id, PIPE_AUTH_LEVEL_PRIVACY,
3309                 domain, username, password, &netlogon_pipe);
3310         if (!NT_STATUS_IS_OK(status)) {
3311                 return status;
3312         }
3313
3314         status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3315                                                  pneg_flags);
3316         if (!NT_STATUS_IS_OK(status)) {
3317                 TALLOC_FREE(netlogon_pipe);
3318                 return status;
3319         }
3320
3321         *presult = netlogon_pipe;
3322         return NT_STATUS_OK;
3323 }
3324
3325 /****************************************************************************
3326  Open a named pipe to an SMB server and bind using schannel (bind type 68).
3327  Fetch the session key ourselves using a temporary netlogon pipe. This version
3328  uses an ntlmssp bind to get the session key.
3329  ****************************************************************************/
3330
3331 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
3332                                                  const struct ndr_syntax_id *interface,
3333                                                  enum pipe_auth_level auth_level,
3334                                                  const char *domain,
3335                                                  const char *username,
3336                                                  const char *password,
3337                                                  struct rpc_pipe_client **presult)
3338 {
3339         uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3340         struct rpc_pipe_client *netlogon_pipe = NULL;
3341         struct rpc_pipe_client *result = NULL;
3342         NTSTATUS status;
3343
3344         status = get_schannel_session_key_auth_ntlmssp(
3345                 cli, domain, username, password, &neg_flags, &netlogon_pipe);
3346         if (!NT_STATUS_IS_OK(status)) {
3347                 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
3348                         "key from server %s for domain %s.\n",
3349                         cli->desthost, domain ));
3350                 return status;
3351         }
3352
3353         status = cli_rpc_pipe_open_schannel_with_key(
3354                 cli, interface, auth_level, domain, netlogon_pipe->dc,
3355                 &result);
3356
3357         /* Now we've bound using the session key we can close the netlog pipe. */
3358         TALLOC_FREE(netlogon_pipe);
3359
3360         if (NT_STATUS_IS_OK(status)) {
3361                 *presult = result;
3362         }
3363         return status;
3364 }
3365
3366 /****************************************************************************
3367  Open a named pipe to an SMB server and bind using schannel (bind type 68).
3368  Fetch the session key ourselves using a temporary netlogon pipe.
3369  ****************************************************************************/
3370
3371 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
3372                                     const struct ndr_syntax_id *interface,
3373                                     enum pipe_auth_level auth_level,
3374                                     const char *domain,
3375                                     struct rpc_pipe_client **presult)
3376 {
3377         uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3378         struct rpc_pipe_client *netlogon_pipe = NULL;
3379         struct rpc_pipe_client *result = NULL;
3380         NTSTATUS status;
3381
3382         status = get_schannel_session_key(cli, domain, &neg_flags,
3383                                           &netlogon_pipe);
3384         if (!NT_STATUS_IS_OK(status)) {
3385                 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
3386                         "key from server %s for domain %s.\n",
3387                         cli->desthost, domain ));
3388                 return status;
3389         }
3390
3391         status = cli_rpc_pipe_open_schannel_with_key(
3392                 cli, interface, auth_level, domain, netlogon_pipe->dc,
3393                 &result);
3394
3395         /* Now we've bound using the session key we can close the netlog pipe. */
3396         TALLOC_FREE(netlogon_pipe);
3397
3398         if (NT_STATUS_IS_OK(status)) {
3399                 *presult = result;
3400         }
3401
3402         return NT_STATUS_OK;
3403 }
3404
3405 /****************************************************************************
3406  Open a named pipe to an SMB server and bind using krb5 (bind type 16).
3407  The idea is this can be called with service_princ, username and password all
3408  NULL so long as the caller has a TGT.
3409  ****************************************************************************/
3410
3411 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
3412                                 const struct ndr_syntax_id *interface,
3413                                 enum pipe_auth_level auth_level,
3414                                 const char *service_princ,
3415                                 const char *username,
3416                                 const char *password,
3417                                 struct rpc_pipe_client **presult)
3418 {
3419 #ifdef HAVE_KRB5
3420         struct rpc_pipe_client *result;
3421         struct cli_pipe_auth_data *auth;
3422         NTSTATUS status;
3423
3424         status = cli_rpc_pipe_open(cli, interface, &result);
3425         if (!NT_STATUS_IS_OK(status)) {
3426                 return status;
3427         }
3428
3429         status = rpccli_kerberos_bind_data(result, auth_level, service_princ,
3430                                            username, password, &auth);
3431         if (!NT_STATUS_IS_OK(status)) {
3432                 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
3433                           nt_errstr(status)));
3434                 TALLOC_FREE(result);
3435                 return status;
3436         }
3437
3438         status = rpc_pipe_bind(result, auth);
3439         if (!NT_STATUS_IS_OK(status)) {
3440                 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
3441                           "with error %s\n", nt_errstr(status)));
3442                 TALLOC_FREE(result);
3443                 return status;
3444         }
3445
3446         *presult = result;
3447         return NT_STATUS_OK;
3448 #else
3449         DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
3450         return NT_STATUS_NOT_IMPLEMENTED;
3451 #endif
3452 }
3453
3454 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
3455                              struct rpc_pipe_client *cli,
3456                              DATA_BLOB *session_key)
3457 {
3458         if (!session_key || !cli) {
3459                 return NT_STATUS_INVALID_PARAMETER;
3460         }
3461
3462         if (!cli->auth) {
3463                 return NT_STATUS_INVALID_PARAMETER;
3464         }
3465
3466         switch (cli->auth->auth_type) {
3467                 case PIPE_AUTH_TYPE_SCHANNEL:
3468                         *session_key = data_blob_talloc(mem_ctx,
3469                                 cli->auth->a_u.schannel_auth->sess_key, 16);
3470                         break;
3471                 case PIPE_AUTH_TYPE_NTLMSSP:
3472                 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
3473                         *session_key = data_blob_talloc(mem_ctx,
3474                                 cli->auth->a_u.ntlmssp_state->session_key.data,
3475                                 cli->auth->a_u.ntlmssp_state->session_key.length);
3476                         break;
3477                 case PIPE_AUTH_TYPE_KRB5:
3478                 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
3479                         *session_key = data_blob_talloc(mem_ctx,
3480                                 cli->auth->a_u.kerberos_auth->session_key.data,
3481                                 cli->auth->a_u.kerberos_auth->session_key.length);
3482                         break;
3483                 case PIPE_AUTH_TYPE_NONE:
3484                         *session_key = data_blob_talloc(mem_ctx,
3485                                 cli->auth->user_session_key.data,
3486                                 cli->auth->user_session_key.length);
3487                         break;
3488                 default:
3489                         return NT_STATUS_NO_USER_SESSION_KEY;
3490         }
3491
3492         return NT_STATUS_OK;
3493 }