dce/rpc
[samba.git] / source / rpc_client / cli_pipe.c
1
2 /* 
3  *  Unix SMB/Netbios implementation.
4  *  Version 1.9.
5  *  RPC Pipe client / server routines
6  *  Copyright (C) Andrew Tridgell              1992-1998,
7  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
8  *  Copyright (C) Paul Ashton                       1998.
9  *  
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; either version 2 of the License, or
13  *  (at your option) any later version.
14  *  
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *  
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program; if not, write to the Free Software
22  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23  */
24
25
26 #ifdef SYSLOG
27 #undef SYSLOG
28 #endif
29
30 #include "includes.h"
31
32 extern int DEBUGLEVEL;
33 extern struct pipe_id_info pipe_names[];
34 extern fstring global_myworkgroup;
35 extern pstring global_myname;
36
37 /********************************************************************
38  rpc pipe call id 
39  ********************************************************************/
40 static uint32 get_rpc_call_id(void)
41 {
42   static uint32 call_id = 1;
43   return ++call_id;
44 }
45
46 /*******************************************************************
47  uses SMBreadX to get rest of rpc data
48  ********************************************************************/
49
50 static BOOL rpc_read(struct cli_state *cli, 
51                      prs_struct *rdata, uint32 data_to_read,
52                      uint32 rdata_offset)
53 {
54         int size = 0x1630;
55         int file_offset = rdata_offset;
56         int num_read;
57         char *data = rdata->data->data;
58         uint32 err;
59         uint32 new_data_size = rdata->data->data_used + data_to_read;
60
61         data += rdata_offset;
62
63         file_offset -= rdata_offset;
64
65         DEBUG(5,("rpc_read: data_to_read: %d data offset: %d file offset: %d\n",
66         data_to_read, rdata_offset, file_offset));
67
68         if (new_data_size > rdata->data->data_size)
69         {
70                 mem_grow_data(&rdata->data, True, new_data_size, True);
71                 DEBUG(5,("rpc_read: grow buffer to %d\n", rdata->data->data_used));
72         }
73
74         do /* read data using SMBreadX */
75         {
76                 if (size > data_to_read)
77                 size = data_to_read;
78
79                 new_data_size = rdata->data->data_used + size;
80
81                 if (new_data_size > rdata->data->data_size)
82                 {
83                         mem_grow_data(&rdata->data, True, new_data_size, True);
84                         DEBUG(5,("rpc_read: grow buffer to %d\n", rdata->data->data_used));
85                 }
86
87                 num_read = cli_read(cli, cli->nt_pipe_fnum, data, file_offset + 0x100000, size);
88
89                 DEBUG(5,("rpc_read: read offset: %d read: %d to read: %d\n",
90                           file_offset, num_read, data_to_read));
91
92                 data_to_read -= num_read;
93                 file_offset  += num_read;
94                 data         += num_read;
95
96                 if (cli_error(cli, NULL, &err)) return False;
97
98         } while (num_read > 0 && data_to_read > 0);
99         /* && err == (0x80000000 | STATUS_BUFFER_OVERFLOW)); */
100
101         mem_realloc_data(rdata->data, file_offset + rdata_offset);
102         rdata->data->offset.end = file_offset + rdata_offset;
103
104         DEBUG(5,("rpc_read: data supposedly left to read:0x%x\n", data_to_read));
105
106         return data_to_read == 0;
107 }
108
109 /****************************************************************************
110  checks the header
111  ****************************************************************************/
112 static BOOL rpc_check_hdr(prs_struct *rdata, uint8 *pkt_type,
113                           BOOL *first, BOOL *last, int *len)
114 {
115         RPC_HDR    rhdr;
116
117         DEBUG(5,("rpc_check_hdr: rdata->data->data_used: %d\n", rdata->data->data_used));
118
119         smb_io_rpc_hdr   ("rpc_hdr   ", &rhdr   , rdata, 0);
120
121         if (!rdata->offset || rdata->offset != 0x10)
122         {
123                 DEBUG(0,("cli_pipe: error in rpc header\n"));
124                 return False;
125         }
126
127         DEBUG(5,("rpc_check_hdr: (after smb_io_rpc_hdr call) rdata->data->data_used: %d\n",
128                   rdata->data->data_used));
129
130         (*first   ) = IS_BITS_SET_ALL(rhdr.flags, RPC_FLG_FIRST);
131         (*last    ) = IS_BITS_SET_ALL(rhdr.flags, RPC_FLG_LAST );
132         (*len     ) = rhdr.frag_len - rdata->data->data_used;
133         (*pkt_type) = rhdr.pkt_type;
134
135         return True;
136 }
137
138 /****************************************************************************
139  send data on an rpc pipe, which *must* be in one fragment.
140  receive response data from an rpc pipe, which may be large...
141
142  read the first fragment: unfortunately have to use SMBtrans for the first
143  bit, then SMBreadX for subsequent bits.
144
145  if first fragment received also wasn't the last fragment, continue
146  getting fragments until we _do_ receive the last fragment.
147
148  [note: from a data abstraction viewpoint, this function is marginally
149         complicated by the return side of cli_api_pipe getting in the way
150         (i.e, the SMB header stuff).  the proper way to do this is to split
151         cli_api_pipe down into receive / transmit.  oh, and split cli_readx
152         down.  in other words, state-based (kernel) techniques...]
153
154  ****************************************************************************/
155
156 static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, 
157                   prs_struct *param , prs_struct *data,
158                   prs_struct *rparam, prs_struct *rdata)
159 {
160         int len;
161
162         uint16 setup[2]; /* only need 2 uint16 setup parameters */
163         uint32 err;
164         uint8 pkt_type = 0xff;
165         BOOL first = True;
166         BOOL last  = True;
167
168         /*
169         * Setup the pointers from the incoming.
170         */
171         char *pparams = param ? param->data->data : NULL;
172         int params_len = param ? param->data->data_used : 0;
173         char *pdata = data ? data->data->data : NULL;
174         int data_len = data ? data->data->data_used : 0;
175
176         /*
177         * Setup the pointers to the outgoing.
178         */
179         char **pp_ret_params = rparam ? &rparam->data->data : NULL;
180         uint32 *p_ret_params_len = rparam ? &rparam->data->data_used : NULL;
181
182         char **pp_ret_data = rdata ? &rdata->data->data : NULL;
183         uint32 *p_ret_data_len = rdata ? &rdata->data->data_used : NULL;
184
185         /* create setup parameters. */
186         setup[0] = cmd; 
187         setup[1] = cli->nt_pipe_fnum; /* pipe file handle.  got this from an SMBOpenX. */
188
189         /* send the data: receive a response. */
190         if (!cli_api_pipe(cli, "\\PIPE\\\0\0\0", 8,
191                   setup, 2, 0,                     /* Setup, length, max */
192                   pparams, params_len, 0,          /* Params, length, max */
193                   pdata, data_len, 1024,           /* data, length, max */                  
194                   pp_ret_params, p_ret_params_len, /* return params, len */
195                   pp_ret_data, p_ret_data_len))    /* return data, len */
196         {
197                 DEBUG(0, ("cli_pipe: return critical error. Error was %s\n", cli_errstr(cli)));
198                 return False;
199         }
200
201         if (rdata->data->data == NULL) return False;
202
203         /**** parse the header: check it's a response record */
204
205         rdata->data->offset.start = 0;
206         rdata->data->offset.end   = rdata->data->data_used;
207         rdata->offset = 0;
208
209         /* cli_api_pipe does an ordinary Realloc - we have no margins now. */
210         rdata->data->margin = 0;
211         if (rparam) rparam->data->margin = 0;
212
213         if (!rpc_check_hdr(rdata, &pkt_type, &first, &last, &len)) return False;
214
215         if (pkt_type == RPC_RESPONSE)
216         {
217                 RPC_HDR_RESP rhdr_resp;
218                 smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, rdata, 0);
219         }
220
221         DEBUG(5,("rpc_api_pipe: len left: %d smbtrans read: %d\n",
222                   len, rdata->data->data_used));
223
224         /* check if data to be sent back was too large for one SMB. */
225         /* err status is only informational: the _real_ check is on the length */
226         if (len > 0) /* || err == (0x80000000 | STATUS_BUFFER_OVERFLOW)) */
227         {
228                 if (!rpc_read(cli, rdata, len, rdata->data->data_used))
229                 {
230                         return False;
231                 }
232         }
233
234         /* only one rpc fragment, and it has been read */
235         if (first && last)
236         {
237                 DEBUG(6,("rpc_api_pipe: fragment first and last both set\n"));
238                 return True;
239         }
240
241         while (!last) /* read more fragments until we get the last one */
242         {
243                 RPC_HDR      rhdr;
244                 RPC_HDR_RESP rhdr_resp;
245                 int num_read;
246                 prs_struct hps;
247
248                 prs_init(&hps, 0x18, 4, 0, True);
249
250                 num_read = cli_read(cli, cli->nt_pipe_fnum, hps.data->data, 0, 0x18);
251                 DEBUG(5,("rpc_api_pipe: read header (size:%d)\n", num_read));
252
253                 if (num_read != 0x18) return False;
254
255                 smb_io_rpc_hdr     ("rpc_hdr     ", &rhdr     , &hps, 0);
256                 smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, &hps, 0);
257
258                 prs_mem_free(&hps);
259
260                 if (cli_error(cli, NULL, &err)) return False;
261
262                 first = IS_BITS_SET_ALL(rhdr.flags, RPC_FLG_FIRST);
263                 last  = IS_BITS_SET_ALL(rhdr.flags, RPC_FLG_LAST );
264
265                 if (first)
266                 {
267                         DEBUG(0,("rpc_api_pipe: wierd rpc header received\n"));
268                         return False;
269                 }
270
271                 len = rhdr.frag_len - hps.offset;
272                 if (!rpc_read(cli, rdata, len, rdata->data->data_used))
273                 {
274                         return False;
275                 }
276         }
277
278         return True;
279 }
280
281 /*******************************************************************
282  creates a DCE/RPC bind request
283
284  - initialises the parse structure.
285  - dynamically allocates the header data structure
286  - caller is expected to free the header data structure once used.
287
288  ********************************************************************/
289 static BOOL create_rpc_bind_req(prs_struct *rhdr,
290                                 prs_struct *rhdr_rb,
291                                 prs_struct *rhdr_auth,
292                                 prs_struct *auth_req,
293                                 prs_struct *auth_ntlm,
294                                 uint32 call_id,
295                                 RPC_IFACE *abstract, RPC_IFACE *transfer,
296                                 char *my_name, char *domain)
297 {
298         RPC_HDR_RB           hdr_rb;
299         RPC_HDR              hdr;
300         RPC_HDR_AUTH         hdr_auth;
301         RPC_AUTH_VERIFIER    auth_verifier;
302         RPC_AUTH_NTLMSSP_NEG ntlmssp_neg;
303
304         /* create the bind request RPC_HDR_RB */
305         make_rpc_hdr_rb(&hdr_rb, 0x1630, 0x1630, 0x0,
306                         0x1, 0x0, 0x1, abstract, transfer);
307
308         /* stream the bind request data */
309         smb_io_rpc_hdr_rb("", &hdr_rb,  rhdr_rb, 0);
310         mem_realloc_data(rhdr_rb->data, rhdr_rb->offset);
311
312         if (auth_req != NULL && rhdr_auth != NULL && auth_ntlm != NULL)
313         {
314                 make_rpc_hdr_auth(&hdr_auth, 0x0a, 0x06, 0x00);
315                 smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rhdr_auth, 0);
316                 mem_realloc_data(rhdr_auth->data, rhdr_auth->offset);
317
318                 make_rpc_auth_verifier(&auth_verifier,
319                                        "NTLMSSP", NTLMSSP_NEGOTIATE);
320
321                 smb_io_rpc_auth_verifier("auth_verifier", &auth_verifier, auth_req, 0);
322                 mem_realloc_data(auth_req->data, auth_req->offset);
323
324                 make_rpc_auth_ntlmssp_neg(&ntlmssp_neg,
325                                        0x0000b2b3, my_name, domain);
326
327                 smb_io_rpc_auth_ntlmssp_neg("ntlmssp_neg", &ntlmssp_neg, auth_req, 0);
328                 mem_realloc_data(auth_req->data, auth_req->offset);
329         }
330
331         /* create the request RPC_HDR */
332         make_rpc_hdr(&hdr, RPC_BIND, 0x0, call_id,
333                      rhdr_rb->offset + 0x10,
334                      auth_req  != NULL ? auth_req ->offset : 0 +
335                      auth_ntlm != NULL ? auth_ntlm->offset : 0);
336
337         smb_io_rpc_hdr("hdr"   , &hdr   , rhdr, 0);
338         mem_realloc_data(rhdr->data, rhdr->offset);
339
340         if (rhdr->data == NULL || rhdr_rb->data == NULL) return False;
341
342         /***/
343         /*** link rpc header, bind acknowledgment and authentication responses ***/
344         /***/
345
346         if (auth_req != NULL)
347         {
348                 prs_link(NULL     , rhdr      , rhdr_rb  );
349                 prs_link(rhdr     , rhdr_rb   , rhdr_auth);
350                 prs_link(rhdr_rb  , rhdr_auth , auth_req );
351                 prs_link(rhdr_auth, auth_req  , auth_ntlm);
352                 prs_link(auth_req , auth_ntlm , NULL     );
353         }
354         else
355         {
356                 prs_link(NULL, rhdr   , rhdr_rb);
357                 prs_link(rhdr, rhdr_rb, NULL   );
358         }
359
360         return True;
361 }
362
363
364 /*******************************************************************
365  creates a DCE/RPC bind authentication response
366
367  - initialises the parse structure.
368  - dynamically allocates the header data structure
369  - caller is expected to free the header data structure once used.
370
371  ********************************************************************/
372 static BOOL create_rpc_bind_resp(struct pwd_info *pwd,
373                                 char *domain, char *user_name, char *my_name,
374                                 uint32 ntlmssp_cli_flgs,
375                                 uint32 call_id,
376                                 prs_struct *rhdr,
377                                 prs_struct *rhdr_autha,
378                                 prs_struct *auth_resp)
379 {
380         unsigned char lm_owf[24];
381         unsigned char nt_owf[24];
382         RPC_HDR               hdr;
383         RPC_HDR_AUTHA         hdr_autha;
384         RPC_AUTH_VERIFIER     auth_verifier;
385         RPC_AUTH_NTLMSSP_RESP ntlmssp_resp;
386
387         make_rpc_hdr_autha(&hdr_autha, 0x1630, 0x1630, 0x0a, 0x06, 0x00);
388         smb_io_rpc_hdr_autha("hdr_autha", &hdr_autha, rhdr_autha, 0);
389         mem_realloc_data(rhdr_autha->data, rhdr_autha->offset);
390
391         make_rpc_auth_verifier(&auth_verifier,
392                                "NTLMSSP", NTLMSSP_AUTH);
393
394         smb_io_rpc_auth_verifier("auth_verifier", &auth_verifier, auth_resp, 0);
395         mem_realloc_data(auth_resp->data, auth_resp->offset);
396
397         pwd_get_lm_nt_owf(pwd, lm_owf, nt_owf);
398                         
399         make_rpc_auth_ntlmssp_resp(&ntlmssp_resp,
400                                  lm_owf, nt_owf,
401                                  domain, user_name, my_name,
402                                  ntlmssp_cli_flgs);
403
404         smb_io_rpc_auth_ntlmssp_resp("ntlmssp_resp", &ntlmssp_resp, auth_resp, 0);
405         mem_realloc_data(auth_resp->data, auth_resp->offset);
406
407         /* create the request RPC_HDR */
408         make_rpc_hdr(&hdr, RPC_BINDRESP, 0x0, call_id,
409                      auth_resp->offset + rhdr_autha->offset + 0x10,
410                      auth_resp->offset);
411
412         smb_io_rpc_hdr("hdr"   , &hdr   , rhdr, 0);
413         mem_realloc_data(rhdr->data, rhdr->offset);
414
415         if (rhdr->data == NULL || rhdr_autha->data == NULL) return False;
416
417         /***/
418         /*** link rpc header and authentication responses ***/
419         /***/
420
421         prs_link(NULL      , rhdr       , rhdr_autha);
422         prs_link(rhdr      , rhdr_autha , auth_resp );
423         prs_link(rhdr_autha, auth_resp  , NULL );
424
425         return True;
426 }
427
428
429 /*******************************************************************
430  creates a DCE/RPC bind request
431
432  - initialises the parse structure.
433  - dynamically allocates the header data structure
434  - caller is expected to free the header data structure once used.
435
436  ********************************************************************/
437
438 static BOOL create_rpc_request(prs_struct *rhdr, uint8 op_num, int data_len,
439                                 int auth_len)
440 {
441         uint32 alloc_hint;
442         RPC_HDR_REQ hdr_req;
443         RPC_HDR     hdr;
444
445         DEBUG(5,("create_rpc_request: opnum: 0x%x data_len: 0x%x\n",
446         op_num, data_len));
447
448         /* create the rpc header RPC_HDR */
449         make_rpc_hdr(&hdr   , RPC_REQUEST, RPC_FLG_FIRST | RPC_FLG_LAST,
450                      get_rpc_call_id(), data_len, auth_len);
451
452         if (auth_len != 0)
453         {
454                 alloc_hint = data_len - 0x18 - auth_len - 12;
455         }
456         else
457         {
458                 alloc_hint = data_len - 0x18;
459         }
460
461         DEBUG(10,("create_rpc_request: data_len: %x auth_len: %x alloc_hint: %x\n",
462                    data_len, auth_len, alloc_hint));
463
464         /* create the rpc request RPC_HDR_REQ */
465         make_rpc_hdr_req(&hdr_req, alloc_hint, op_num);
466
467         /* stream-time... */
468         smb_io_rpc_hdr    ("hdr    ", &hdr    , rhdr, 0);
469         smb_io_rpc_hdr_req("hdr_req", &hdr_req, rhdr, 0);
470
471         if (rhdr->data == NULL || rhdr->offset != 0x18) return False;
472
473         rhdr->data->offset.start = 0;
474         rhdr->data->offset.end   = rhdr->offset;
475
476         return True;
477 }
478
479
480 /****************************************************************************
481  send a request on an rpc pipe.
482  ****************************************************************************/
483 BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num,
484                       prs_struct *data, prs_struct *rdata)
485 {
486         /* fudge this, at the moment: create the header; memcpy the data.  oops. */
487         prs_struct dataa;
488         prs_struct rparam;
489         prs_struct hdr;
490         prs_struct hdr_auth;
491         prs_struct auth_verf;
492         int data_len;
493         int auth_len;
494         BOOL ret;
495         BOOL auth_verify;
496         BOOL auth_seal;
497         uint32 crc32;
498
499         auth_verify = IS_BITS_SET_ALL(cli->ntlmssp_srv_flgs, NTLMSSP_NEGOTIATE_SIGN);
500         auth_seal   = IS_BITS_SET_ALL(cli->ntlmssp_srv_flgs, NTLMSSP_NEGOTIATE_SEAL);
501
502         /* happen to know that NTLMSSP authentication verifier is 16 bytes */
503         auth_len               = auth_verify ? 16 : 0;
504         data_len               = data->offset + auth_len + (auth_verify ? 8 : 0) + 0x18;
505         data->data->offset.end = data->offset;
506
507         prs_init(&hdr      , data_len, 4, SAFETY_MARGIN, False);
508         prs_init(&hdr_auth , 8       , 4, SAFETY_MARGIN, False);
509         prs_init(&auth_verf, auth_len, 4, SAFETY_MARGIN, False);
510         prs_init(&rparam   , 0       , 4, 0            , True );
511
512         create_rpc_request(&hdr, op_num, data_len, auth_len);
513
514         if (auth_seal)
515         {
516                 crc32 = crc32_calc_buffer(data->offset, mem_data(&data->data, 0));
517                 NTLMSSPcalc(cli->ntlmssp_hash, mem_data(&data->data, 0), data->offset);
518         }
519
520         if (auth_verify)
521         {
522                 RPC_AUTH_NTLMSSP_CHK chk;
523                 RPC_HDR_AUTH         rhdr_auth;
524
525                 make_rpc_hdr_auth(&rhdr_auth, 0x0a, 0x06, 0x02);
526                 smb_io_rpc_hdr_auth("hdr_auth", &rhdr_auth, &hdr_auth, 0);
527
528                 make_rpc_auth_ntlmssp_chk(&chk, NTLMSSP_SIGN_VERSION, crc32, 0);
529                 smb_io_rpc_auth_ntlmssp_chk("auth_sign", &chk, &auth_verf, 0);
530                 NTLMSSPcalc(cli->ntlmssp_hash, mem_data(&auth_verf.data, 4), 12);
531         }
532
533         if (auth_seal || auth_verify)
534         {
535                 prs_link(NULL     , &hdr      , data      );
536                 prs_link(&hdr     , data      , &hdr_auth );
537                 prs_link(data     , &hdr_auth , &auth_verf);
538                 prs_link(&hdr_auth, &auth_verf, NULL      );
539         }
540         else
541         {
542                 prs_link(NULL, &hdr, data);
543                 prs_link(&hdr, data, NULL);
544         }
545
546         mem_realloc_data(hdr.data, data_len);
547
548         DEBUG(100,("data_len: %x data_calc_len: %x\n",
549                 data_len, mem_buf_len(data->data)));
550
551         /* this is a hack due to limitations in rpc_api_pipe */
552         prs_init(&dataa, mem_buf_len(hdr.data), 4, 0x0, False);
553         mem_buf_copy(dataa.data->data, hdr.data, 0, mem_buf_len(hdr.data));
554
555         ret = rpc_api_pipe(cli, 0x0026, NULL, &dataa, &rparam, rdata);
556
557         prs_mem_free(&hdr_auth );
558         prs_mem_free(&auth_verf);
559         prs_mem_free(&rparam   );
560         prs_mem_free(&hdr      );
561         prs_mem_free(&dataa    );
562
563         return ret;
564 }
565
566 /****************************************************************************
567 do an rpc bind
568 ****************************************************************************/
569
570 static BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, char *pipe_name, uint16 device_state)
571 {
572         BOOL state_set = False;
573         char param[2];
574         uint16 setup[2]; /* only need 2 uint16 setup parameters */
575         char *rparam = NULL;
576         char *rdata = NULL;
577         uint32 rparam_len, rdata_len;
578
579         if (pipe_name == NULL) return False;
580
581         DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
582         cli->nt_pipe_fnum, pipe_name, device_state));
583
584         /* create parameters: device state */
585         SSVAL(param, 0, device_state);
586
587         /* create setup parameters. */
588         setup[0] = 0x0001; 
589         setup[1] = cli->nt_pipe_fnum; /* pipe file handle.  got this from an SMBOpenX. */
590
591         /* send the data on \PIPE\ */
592         if (cli_api_pipe(cli, "\\PIPE\\\0\0\0", 8,
593                     setup, 2, 0,                /* setup, length, max */
594                     param, 2, 0,                /* param, length, max */
595                     NULL, 0, 1024,              /* data, length, max */
596                     &rparam, &rparam_len,        /* return param, length */
597                     &rdata, &rdata_len))         /* return data, length */
598         {
599                 DEBUG(5, ("Set Handle state: return OK\n"));
600                 state_set = True;
601         }
602
603         if (rparam) free(rparam);
604         if (rdata ) free(rdata );
605
606         return state_set;
607 }
608
609 /****************************************************************************
610  check the rpc bind acknowledge response
611 ****************************************************************************/
612
613 static BOOL valid_pipe_name(char *pipe_name, RPC_IFACE *abstract, RPC_IFACE *transfer)
614 {
615         int pipe_idx = 0;
616
617         while (pipe_names[pipe_idx].client_pipe != NULL)
618         {
619                 if (strequal(pipe_name, pipe_names[pipe_idx].client_pipe ))
620                 {
621                         DEBUG(5,("Bind Abstract Syntax: "));    
622                         dump_data(5, (char*)&(pipe_names[pipe_idx].abstr_syntax), 
623                                   sizeof(pipe_names[pipe_idx].abstr_syntax));
624                         DEBUG(5,("Bind Transfer Syntax: "));
625                         dump_data(5, (char*)&(pipe_names[pipe_idx].trans_syntax),
626                                   sizeof(pipe_names[pipe_idx].trans_syntax));
627
628                         /* copy the required syntaxes out so we can do the right bind */
629                         memcpy(transfer, &(pipe_names[pipe_idx].trans_syntax),
630                                sizeof(pipe_names[pipe_idx].trans_syntax));
631                         memcpy(abstract, &(pipe_names[pipe_idx].abstr_syntax),
632                                sizeof(pipe_names[pipe_idx].abstr_syntax));
633
634                         return True;
635                 }
636                 pipe_idx++;
637         };
638
639         DEBUG(5,("Bind RPC Pipe[%s] unsupported\n", pipe_name));
640         return False;
641 }
642
643 /****************************************************************************
644  check the rpc bind acknowledge response
645 ****************************************************************************/
646
647 static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, char *pipe_name, RPC_IFACE *transfer)
648 {
649         int i = 0;
650
651         while ((pipe_names[i].client_pipe != NULL))
652         {
653                 DEBUG(6,("bind_rpc_pipe: searching pipe name: client:%s server:%s\n",
654                 pipe_names[i].client_pipe , pipe_names[i].server_pipe ));
655
656                 if ((strequal(pipe_name, pipe_names[i].client_pipe )))
657                 {
658                         if (strequal(hdr_ba->addr.str, pipe_names[i].server_pipe ))
659                         {
660                                 DEBUG(5,("bind_rpc_pipe: server pipe_name found: %s\n",
661                                          pipe_names[i].server_pipe ));
662                                 break;
663                         }
664                         else
665                         {
666                                 DEBUG(2,("bind_rpc_pipe: pipe_name %s != expected pipe %s\n",
667                                          pipe_names[i].server_pipe ,
668                                          hdr_ba->addr.str));
669                                 return False;
670                         }
671                 }
672                 else
673                 {
674                         i++;
675                 }
676         }
677
678         if (pipe_names[i].server_pipe == NULL)
679         {
680                 DEBUG(2,("bind_rpc_pipe: pipe name %s unsupported\n", hdr_ba->addr.str));
681                 return False;
682         }
683
684         /* check the transfer syntax */
685         if (!((hdr_ba->transfer.version == transfer->version) &&
686              (memcmp(hdr_ba->transfer.data, transfer->data,
687                      sizeof(transfer->version)) ==0)))
688         {
689                 DEBUG(0,("bind_rpc_pipe: transfer syntax differs\n"));
690                 return False;
691         }
692
693         /* lkclXXXX only accept one result: check the result(s) */
694         if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0)
695         {
696                 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
697                           hdr_ba->res.num_results, hdr_ba->res.reason));
698         }
699
700         DEBUG(5,("bind_rpc_pipe: accepted!\n"));
701         return True;
702 }
703
704 /****************************************************************************
705 do an rpc bind
706 ****************************************************************************/
707
708 static BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name,
709                                 RPC_IFACE *abstract, RPC_IFACE *transfer, 
710                                 char *my_name)
711 {
712         prs_struct hdr;
713         prs_struct hdr_rb;
714         prs_struct hdr_auth;
715         prs_struct hdr_autha;
716         prs_struct auth_req;
717         prs_struct auth_ntlm;
718         prs_struct data;
719         prs_struct rdata;
720         prs_struct rparam;
721
722         BOOL valid_ack = False;
723         BOOL ntlmssp_auth = cli->ntlmssp_cli_flgs != 0;
724         uint32 call_id;
725
726         if (pipe_name == NULL || abstract == NULL || transfer == NULL)
727         {
728                 return False;
729         }
730
731         DEBUG(5,("Bind RPC Pipe[%x]: %s\n", cli->nt_pipe_fnum, pipe_name));
732
733         if (!valid_pipe_name(pipe_name, abstract, transfer)) return False;
734
735         prs_init(&hdr      , 0x10                   , 4, 0x0          , False);
736         prs_init(&hdr_rb   , 1024                   , 4, SAFETY_MARGIN, False);
737         prs_init(&hdr_auth , ntlmssp_auth ?    8 : 0, 4, SAFETY_MARGIN, False);
738         prs_init(&auth_req , ntlmssp_auth ? 1024 : 0, 4, SAFETY_MARGIN, False);
739         prs_init(&auth_ntlm, ntlmssp_auth ? 1024 : 0, 4, SAFETY_MARGIN, False);
740
741         prs_init(&rdata    , 0   , 4, SAFETY_MARGIN, True);
742         prs_init(&rparam   , 0   , 4, SAFETY_MARGIN, True);
743
744         call_id = get_rpc_call_id();
745         create_rpc_bind_req(&hdr, &hdr_rb,
746                             ntlmssp_auth ? &hdr_auth : NULL,
747                             ntlmssp_auth ? &auth_req : NULL,
748                             ntlmssp_auth ? &auth_ntlm : NULL,
749                             call_id,
750                             abstract, transfer, global_myname, cli->domain);
751
752         /* this is a hack due to limitations in rpc_api_pipe */
753         prs_init(&data, mem_buf_len(hdr.data), 4, 0x0, False);
754         mem_buf_copy(data.data->data, hdr.data, 0, mem_buf_len(hdr.data));
755
756         /* send data on \PIPE\.  receive a response */
757         if (rpc_api_pipe(cli, 0x0026, NULL, &data, &rparam, &rdata))
758         {
759                 RPC_HDR_BA   hdr_ba;
760                 RPC_HDR_AUTH rhdr_auth;
761                 RPC_AUTH_VERIFIER rhdr_verf;
762                 RPC_AUTH_NTLMSSP_CHAL rhdr_chal;
763
764                 DEBUG(5, ("rpc_api_pipe: return OK\n"));
765
766                 smb_io_rpc_hdr_ba("", &hdr_ba, &rdata, 0);
767
768                 if (rdata.offset != 0)
769                 {
770                         valid_ack = check_bind_response(&hdr_ba, pipe_name, transfer);
771                 }
772
773                 if (valid_ack && ntlmssp_auth)
774                 {
775                         smb_io_rpc_hdr_auth("", &rhdr_auth, &rdata, 0);
776                         if (rdata.offset == 0) valid_ack = False;
777                 }
778
779                 if (valid_ack && ntlmssp_auth)
780                 {
781                         smb_io_rpc_auth_verifier("", &rhdr_verf, &rdata, 0);
782                         if (rdata.offset == 0) valid_ack = False;
783                 }
784                 if (valid_ack && ntlmssp_auth)
785                 {
786                         smb_io_rpc_auth_ntlmssp_chal("", &rhdr_chal, &rdata, 0);
787                         if (rdata.offset == 0) valid_ack = False;
788                 }
789                 if (valid_ack && ntlmssp_auth)
790                 {
791                         unsigned char p24[24];
792                         unsigned char lm_owf[24];
793                         unsigned char lm_hash[16];
794
795                         prs_struct hdra;
796                         prs_struct hdr_autha;
797                         prs_struct auth_resp;
798                         prs_struct dataa;
799
800                         cli->ntlmssp_cli_flgs = rhdr_chal.neg_flags;
801
802                         prs_init(&hdra     , 0x10, 4, 0x0          , False);
803                         prs_init(&hdr_autha, 1024, 4, SAFETY_MARGIN, False);
804                         prs_init(&auth_resp, 1024, 4, SAFETY_MARGIN, False);
805
806                         pwd_make_lm_nt_owf(&cli->pwd, rhdr_chal.challenge);
807                         pwd_get_lm_nt_owf(&cli->pwd, lm_owf, NULL);
808                         pwd_get_lm_nt_16(&cli->pwd, lm_hash, NULL);
809                         NTLMSSPOWFencrypt(lm_hash, lm_owf, p24);
810                         bzero(lm_hash, sizeof(lm_hash));
811                         NTLMSSPhash(cli->ntlmssp_hash, p24);
812
813                         create_rpc_bind_resp(&cli->pwd, cli->domain,
814                                              cli->user_name, global_myname, 
815                                              cli->ntlmssp_cli_flgs,
816                                              call_id,
817                                              &hdra, &hdr_autha, &auth_resp);
818                                             
819                         /* this is a hack due to limitations in rpc_api_pipe */
820                         prs_init(&dataa, mem_buf_len(hdra.data), 4, 0x0, False);
821                         mem_buf_copy(dataa.data->data, hdra.data, 0, mem_buf_len(hdra.data));
822
823                         if (cli_write(cli, cli->nt_pipe_fnum, 0x0008,
824                                   dataa.data->data, 0,
825                                   dataa.data->data_used) < 0)
826                         {
827                                 valid_ack = False;
828                         }
829
830                         if (valid_ack)
831                         {
832                                 cli->ntlmssp_srv_flgs = rhdr_chal.neg_flags;
833                         }
834
835                         prs_mem_free(&hdra);
836                         prs_mem_free(&dataa);
837                         prs_mem_free(&hdr_autha);
838                         prs_mem_free(&auth_resp);
839                 }
840         }
841
842         prs_mem_free(&data     );
843         prs_mem_free(&hdr      );
844         prs_mem_free(&hdr_rb   );
845         prs_mem_free(&hdr_auth );
846         prs_mem_free(&auth_req );
847         prs_mem_free(&auth_ntlm);
848         prs_mem_free(&rdata    );
849         prs_mem_free(&rparam   );
850
851         return valid_ack;
852 }
853
854 /****************************************************************************
855  open a session
856  ****************************************************************************/
857
858 BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name, BOOL encrypted)
859 {
860         RPC_IFACE abstract;
861         RPC_IFACE transfer;
862         int fnum;
863
864         /******************* open the pipe *****************/
865         if ((fnum = cli_open(cli, pipe_name, O_CREAT|O_RDWR, DENY_NONE)) == -1)
866         {
867                 DEBUG(0,("cli_nt_session_open: cli_open failed on pipe %s to machine %s.  Error was %s\n",
868                          pipe_name, cli->desthost, cli_errstr(cli)));
869                 return False;
870         }
871
872         cli->nt_pipe_fnum = (uint16)fnum;
873
874         /**************** Set Named Pipe State ***************/
875         if (!rpc_pipe_set_hnd_state(cli, pipe_name, 0x4300))
876         {
877                 DEBUG(0,("cli_nt_session_open: pipe hnd state failed.  Error was %s\n",
878                           cli_errstr(cli)));
879                 cli_close(cli, cli->nt_pipe_fnum);
880                 return False;
881         }
882
883         /******************* bind request on pipe *****************/
884
885         if (encrypted)
886         {
887                 cli->ntlmssp_cli_flgs =
888                                     NTLMSSP_NEGOTIATE_UNICODE |
889                                     NTLMSSP_NEGOTIATE_OEM |
890                                     NTLMSSP_NEGOTIATE_SIGN |
891                                     NTLMSSP_NEGOTIATE_SEAL |
892                                     NTLMSSP_NEGOTIATE_LM_KEY |
893                                     NTLMSSP_NEGOTIATE_NTLM |
894                                     NTLMSSP_NEGOTIATE_ALWAYS_SIGN |
895                                     NTLMSSP_NEGOTIATE_00001000 |
896                                     NTLMSSP_NEGOTIATE_00002000;
897                 DEBUG(5,("cli_nt_session_open: neg_flags: %lx\n",
898                          cli->ntlmssp_cli_flgs));
899         }
900
901         if (!rpc_pipe_bind(cli, pipe_name,
902                            &abstract, &transfer,
903                            global_myname))
904         {
905                 DEBUG(0,("cli_nt_session_open: rpc bind failed. Error was %s\n",
906                           cli_errstr(cli)));
907                 cli_close(cli, cli->nt_pipe_fnum);
908                 return False;
909         }
910
911         /* 
912          * Setup the remote server name prefixed by \ and the machine account name.
913          */
914
915         fstrcpy(cli->srv_name_slash, "\\\\");
916         fstrcat(cli->srv_name_slash, cli->desthost);
917         strupper(cli->srv_name_slash);
918
919         fstrcpy(cli->clnt_name_slash, "\\\\");
920         fstrcat(cli->clnt_name_slash, global_myname);
921         strupper(cli->clnt_name_slash);
922
923         fstrcpy(cli->mach_acct, global_myname);
924         fstrcat(cli->mach_acct, "$");
925         strupper(cli->mach_acct);
926
927         return True;
928 }
929
930 /****************************************************************************
931 close the session
932 ****************************************************************************/
933
934 void cli_nt_session_close(struct cli_state *cli)
935 {
936         cli_close(cli, cli->nt_pipe_fnum);
937 }