b899c6e08e0a2f7f4a8707569ef9297a2ba3a601
[samba.git] / source3 / 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 = 0;
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 = cli->max_recv_frag;
55         int file_offset = rdata_offset;
56         int num_read;
57         char *data;
58         uint32 err;
59         uint32 new_data_size = rdata->data->data_used + data_to_read;
60
61         file_offset -= rdata_offset;
62
63         DEBUG(5,("rpc_read: data_to_read: %d data offset: %d file offset: %d\n",
64         data_to_read, rdata_offset, file_offset));
65
66         if (new_data_size > rdata->data->data_size)
67         {
68                 mem_grow_data(&rdata->data, True, new_data_size, True);
69                 DEBUG(5,("rpc_read: grow buffer to %d\n", rdata->data->data_used));
70         }
71
72         data = rdata->data->data + rdata_offset;
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, 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: offset end: 0x%x.  data left to read:0x%x\n",
105                   rdata->data->offset.end, data_to_read));
106
107         return True;
108 }
109
110 /****************************************************************************
111  checks the header
112  ****************************************************************************/
113 static BOOL rpc_check_hdr(prs_struct *rdata, RPC_HDR *rhdr, 
114                           BOOL *first, BOOL *last, int *len)
115 {
116         DEBUG(5,("rpc_check_hdr: rdata->data->data_used: %d\n", rdata->data->data_used));
117
118         smb_io_rpc_hdr   ("rpc_hdr   ", rhdr   , rdata, 0);
119
120         if (!rdata->offset || rdata->offset != 0x10)
121         {
122                 DEBUG(0,("cli_pipe: error in rpc header\n"));
123                 return False;
124         }
125
126         DEBUG(5,("rpc_check_hdr: (after smb_io_rpc_hdr call) rdata->data->data_used: %d\n",
127                   rdata->data->data_used));
128
129         (*first   ) = IS_BITS_SET_ALL(rhdr->flags, RPC_FLG_FIRST);
130         (*last    ) = IS_BITS_SET_ALL(rhdr->flags, RPC_FLG_LAST );
131         (*len     ) = rhdr->frag_len - rdata->data->data_used;
132
133         return True;
134 }
135
136 static void NTLMSSPcalc_ap( struct cli_state *cli, unsigned char *data, int len)
137 {
138         unsigned char *hash = cli->ntlmssp_hash;
139     unsigned char index_i = hash[256];
140     unsigned char index_j = hash[257];
141     int ind;
142
143     for( ind = 0; ind < len; ind++)
144     {
145         unsigned char tc;
146         unsigned char t;
147
148         index_i++;
149         index_j += hash[index_i];
150
151         tc = hash[index_i];
152         hash[index_i] = hash[index_j];
153         hash[index_j] = tc;
154
155         t = hash[index_i] + hash[index_j];
156         data[ind] = data[ind] ^ hash[t];
157     }
158
159     hash[256] = index_i;
160     hash[257] = index_j;
161 }
162
163 /****************************************************************************
164  decrypt data on an rpc pipe
165  ****************************************************************************/
166
167 static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata,
168                                 int len, int auth_len)
169 {
170         RPC_AUTH_NTLMSSP_CHK chk;
171         uint32 crc32;
172         int data_len = len - 0x18 - auth_len - 8;
173         char *reply_data = mem_data(&rdata->data, 0x18);
174
175         BOOL auth_verify = IS_BITS_SET_ALL(cli->ntlmssp_srv_flgs, NTLMSSP_NEGOTIATE_SIGN);
176         BOOL auth_seal   = IS_BITS_SET_ALL(cli->ntlmssp_srv_flgs, NTLMSSP_NEGOTIATE_SEAL);
177
178         DEBUG(5,("rpc_auth_pipe: len: %d auth_len: %d verify %s seal %s\n",
179                   len, auth_len, BOOLSTR(auth_verify), BOOLSTR(auth_seal)));
180
181         if (reply_data == NULL) return False;
182
183         if (auth_seal)
184         {
185                 DEBUG(10,("rpc_auth_pipe: seal\n"));
186                 dump_data(100, reply_data, data_len);
187                 NTLMSSPcalc_ap(cli, (uchar*)reply_data, data_len);
188                 dump_data(100, reply_data, data_len);
189         }
190
191         if (auth_verify || auth_seal)
192         {
193                 RPC_HDR_AUTH         rhdr_auth; 
194                 prs_struct auth_req;
195                 char *data = mem_data(&rdata->data, len - auth_len - 8);
196                 prs_init(&auth_req , 0x08, 4, 0, True);
197                 memcpy(auth_req.data->data, data, 8);
198                 smb_io_rpc_hdr_auth("hdr_auth", &rhdr_auth, &auth_req, 0);
199                 prs_mem_free(&auth_req);
200
201                 if (!rpc_hdr_auth_chk(&rhdr_auth))
202                 {
203                         return False;
204                 }
205         }
206
207         if (auth_verify)
208         {
209                 prs_struct auth_verf;
210                 char *data = mem_data(&rdata->data, len - auth_len);
211                 if (data == NULL) return False;
212
213                 DEBUG(10,("rpc_auth_pipe: verify\n"));
214                 dump_data(100, data, auth_len);
215                 NTLMSSPcalc_ap(cli, (uchar*)(data+4), auth_len - 4);
216                 prs_init(&auth_verf, 0x08, 4, 0, True);
217                 memcpy(auth_verf.data->data, data, 16);
218                 smb_io_rpc_auth_ntlmssp_chk("auth_sign", &chk, &auth_verf, 0);
219                 dump_data(100, data, auth_len);
220                 prs_mem_free(&auth_verf);
221         }
222
223         if (auth_verify)
224         {
225                 crc32 = crc32_calc_buffer(data_len, reply_data);
226                 if (!rpc_auth_ntlmssp_chk(&chk, crc32 , cli->ntlmssp_seq_num))
227                 {
228                         return False;
229                 }
230                 cli->ntlmssp_seq_num++;
231         }
232         return True;
233 }
234
235
236 /****************************************************************************
237  send data on an rpc pipe, which *must* be in one fragment.
238  receive response data from an rpc pipe, which may be large...
239
240  read the first fragment: unfortunately have to use SMBtrans for the first
241  bit, then SMBreadX for subsequent bits.
242
243  if first fragment received also wasn't the last fragment, continue
244  getting fragments until we _do_ receive the last fragment.
245
246  [note: from a data abstraction viewpoint, this function is marginally
247         complicated by the return side of cli_api_pipe getting in the way
248         (i.e, the SMB header stuff).  the proper way to do this is to split
249         cli_api_pipe down into receive / transmit.  oh, and split cli_readx
250         down.  in other words, state-based (kernel) techniques...]
251
252  ****************************************************************************/
253
254 static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, 
255                   prs_struct *param , prs_struct *data,
256                   prs_struct *rparam, prs_struct *rdata)
257 {
258         int len;
259
260         uint16 setup[2]; /* only need 2 uint16 setup parameters */
261         uint32 err;
262         BOOL first = True;
263         BOOL last  = True;
264         RPC_HDR    rhdr;
265
266         /*
267         * Setup the pointers from the incoming.
268         */
269         char *pparams = param ? param->data->data : NULL;
270         int params_len = param ? param->data->data_used : 0;
271         char *pdata = data ? data->data->data : NULL;
272         int data_len = data ? data->data->data_used : 0;
273
274         /*
275         * Setup the pointers to the outgoing.
276         */
277         char **pp_ret_params = rparam ? &rparam->data->data : NULL;
278         uint32 *p_ret_params_len = rparam ? &rparam->data->data_used : NULL;
279
280         char **pp_ret_data = rdata ? &rdata->data->data : NULL;
281         uint32 *p_ret_data_len = rdata ? &rdata->data->data_used : NULL;
282
283         /* create setup parameters. */
284         setup[0] = cmd; 
285         setup[1] = cli->nt_pipe_fnum; /* pipe file handle.  got this from an SMBOpenX. */
286
287         DEBUG(5,("rpc_api_pipe: cmd:%x fnum:%x\n", cmd, cli->nt_pipe_fnum));
288
289         /* send the data: receive a response. */
290         if (!cli_api_pipe(cli, "\\PIPE\\\0\0\0", 8,
291                   setup, 2, 0,                     /* Setup, length, max */
292                   pparams, params_len, 0,          /* Params, length, max */
293                   pdata, data_len, 1024,           /* data, length, max */                  
294                   pp_ret_params, p_ret_params_len, /* return params, len */
295                   pp_ret_data, p_ret_data_len))    /* return data, len */
296         {
297                 DEBUG(0, ("cli_pipe: return critical error. Error was %s\n", cli_errstr(cli)));
298                 return False;
299         }
300
301         if (rdata->data->data == NULL) return False;
302
303         /**** parse the header: check it's a response record */
304
305         rdata->data->offset.start = 0;
306         rdata->data->offset.end   = rdata->data->data_used;
307         rdata->offset = 0;
308
309         /* cli_api_pipe does an ordinary Realloc - we have no margins now. */
310         rdata->data->margin = 0;
311         if (rparam) rparam->data->margin = 0;
312
313         if (!rpc_check_hdr(rdata, &rhdr, &first, &last, &len))
314         {
315                 return False;
316         }
317
318         if (rhdr.pkt_type == RPC_BINDACK)
319         {
320                 if (!last && !first)
321                 {
322                         DEBUG(5,("rpc_api_pipe: bug in AS/U, setting fragment first/last ON\n"));
323                         first = True;
324                         last = True;
325                 }
326         }
327
328         if (rhdr.pkt_type == RPC_RESPONSE)
329         {
330                 RPC_HDR_RESP rhdr_resp;
331                 smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, rdata, 0);
332         }
333
334         DEBUG(5,("rpc_api_pipe: len left: %d smbtrans read: %d\n",
335                   len, rdata->data->data_used));
336
337         /* check if data to be sent back was too large for one SMB. */
338         /* err status is only informational: the _real_ check is on the length */
339         if (len > 0) /* || err == (0x80000000 | STATUS_BUFFER_OVERFLOW)) */
340         {
341                 if (!rpc_read(cli, rdata, len, rdata->data->data_used))
342                 {
343                         return False;
344                 }
345         }
346
347         if (rhdr.auth_len != 0 && !rpc_auth_pipe(cli, rdata, rhdr.frag_len, rhdr.auth_len))
348         {
349                 return False;
350         }
351
352         /* only one rpc fragment, and it has been read */
353         if (first && last)
354         {
355                 DEBUG(6,("rpc_api_pipe: fragment first and last both set\n"));
356                 return True;
357         }
358
359         while (!last) /* read more fragments until we get the last one */
360         {
361                 RPC_HDR_RESP rhdr_resp;
362                 int num_read;
363                 prs_struct hps;
364
365                 prs_init(&hps, 0x8, 4, 0, True);
366
367                 num_read = cli_read(cli, cli->nt_pipe_fnum, hps.data->data, 0, 0x18);
368                 DEBUG(5,("rpc_api_pipe: read header (size:%d)\n", num_read));
369
370                 if (num_read != 0x18) return False;
371
372                 if (!rpc_check_hdr(&hps, &rhdr, &first, &last, &len))
373                 {
374                         return False;
375                 }
376
377                 smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, &hps, 0);
378
379                 prs_mem_free(&hps);
380
381                 if (cli_error(cli, NULL, &err)) return False;
382
383                 if (first)
384                 {
385                         DEBUG(0,("rpc_api_pipe: wierd rpc header received\n"));
386                         return False;
387                 }
388
389                 if (!rpc_read(cli, rdata, len, rdata->data->data_used))
390                 {
391                         return False;
392                 }
393
394                 if (rhdr.auth_len != 0 && !rpc_auth_pipe(cli, rdata, rhdr.frag_len, rhdr.auth_len))
395                 {
396                         return False;
397                 }
398         }
399
400         return True;
401 }
402
403 /*******************************************************************
404  creates a DCE/RPC bind request
405
406  - initialises the parse structure.
407  - dynamically allocates the header data structure
408  - caller is expected to free the header data structure once used.
409
410  ********************************************************************/
411 static BOOL create_rpc_bind_req(prs_struct *rhdr,
412                                 prs_struct *rhdr_rb,
413                                 prs_struct *rhdr_auth,
414                                 prs_struct *auth_req,
415                                 prs_struct *auth_ntlm,
416                                 uint32 rpc_call_id,
417                                 RPC_IFACE *abstract, RPC_IFACE *transfer,
418                                 char *my_name, char *domain, uint32 neg_flags)
419 {
420         RPC_HDR_RB           hdr_rb;
421         RPC_HDR              hdr;
422         RPC_HDR_AUTH         hdr_auth;
423         RPC_AUTH_VERIFIER    auth_verifier;
424         RPC_AUTH_NTLMSSP_NEG ntlmssp_neg;
425
426         /* create the bind request RPC_HDR_RB */
427         make_rpc_hdr_rb(&hdr_rb, 0x1630, 0x1630, 0x0,
428                         0x1, 0x0, 0x1, abstract, transfer);
429
430         /* stream the bind request data */
431         smb_io_rpc_hdr_rb("", &hdr_rb,  rhdr_rb, 0);
432         mem_realloc_data(rhdr_rb->data, rhdr_rb->offset);
433
434         if (auth_req != NULL && rhdr_auth != NULL && auth_ntlm != NULL)
435         {
436                 make_rpc_hdr_auth(&hdr_auth, 0x0a, 0x06, 0x00, 1);
437                 smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rhdr_auth, 0);
438                 mem_realloc_data(rhdr_auth->data, rhdr_auth->offset);
439
440                 make_rpc_auth_verifier(&auth_verifier,
441                                        "NTLMSSP", NTLMSSP_NEGOTIATE);
442
443                 smb_io_rpc_auth_verifier("auth_verifier", &auth_verifier, auth_req, 0);
444                 mem_realloc_data(auth_req->data, auth_req->offset);
445
446                 make_rpc_auth_ntlmssp_neg(&ntlmssp_neg,
447                                        neg_flags, my_name, domain);
448
449                 smb_io_rpc_auth_ntlmssp_neg("ntlmssp_neg", &ntlmssp_neg, auth_req, 0);
450                 mem_realloc_data(auth_req->data, auth_req->offset);
451         }
452
453         /* create the request RPC_HDR */
454         make_rpc_hdr(&hdr, RPC_BIND, 0x0, rpc_call_id,
455                      (auth_req  != NULL ? auth_req ->offset : 0) +
456                      (auth_ntlm != NULL ? auth_ntlm->offset : 0) +
457                      (rhdr_auth != NULL ? rhdr_auth->offset : 0) +
458                      rhdr_rb->offset + 0x10,
459                      (auth_req  != NULL ? auth_req ->offset : 0) +
460                      (auth_ntlm != NULL ? auth_ntlm->offset : 0));
461
462         smb_io_rpc_hdr("hdr"   , &hdr   , rhdr, 0);
463         mem_realloc_data(rhdr->data, rhdr->offset);
464
465         if (rhdr->data == NULL || rhdr_rb->data == NULL) return False;
466
467         /***/
468         /*** link rpc header, bind acknowledgment and authentication responses ***/
469         /***/
470
471         if (auth_req != NULL)
472         {
473                 prs_link(NULL     , rhdr      , rhdr_rb  );
474                 prs_link(rhdr     , rhdr_rb   , rhdr_auth);
475                 prs_link(rhdr_rb  , rhdr_auth , auth_req );
476                 prs_link(rhdr_auth, auth_req  , auth_ntlm);
477                 prs_link(auth_req , auth_ntlm , NULL     );
478         }
479         else
480         {
481                 prs_link(NULL, rhdr   , rhdr_rb);
482                 prs_link(rhdr, rhdr_rb, NULL   );
483         }
484
485         return True;
486 }
487
488
489 /*******************************************************************
490  creates a DCE/RPC bind authentication response
491
492  - initialises the parse structure.
493  - dynamically allocates the header data structure
494  - caller is expected to free the header data structure once used.
495
496  ********************************************************************/
497 static BOOL create_rpc_bind_resp(struct pwd_info *pwd,
498                                 char *domain, char *user_name, char *my_name,
499                                 uint32 ntlmssp_cli_flgs,
500                                 uint32 rpc_call_id,
501                                 prs_struct *rhdr,
502                                 prs_struct *rhdr_autha,
503                                 prs_struct *auth_resp)
504 {
505         unsigned char lm_owf[24];
506         unsigned char nt_owf[24];
507         RPC_HDR               hdr;
508         RPC_HDR_AUTHA         hdr_autha;
509         RPC_AUTH_VERIFIER     auth_verifier;
510         RPC_AUTH_NTLMSSP_RESP ntlmssp_resp;
511
512         make_rpc_hdr_autha(&hdr_autha, 0x1630, 0x1630, 0x0a, 0x06, 0x00);
513         smb_io_rpc_hdr_autha("hdr_autha", &hdr_autha, rhdr_autha, 0);
514         mem_realloc_data(rhdr_autha->data, rhdr_autha->offset);
515
516         make_rpc_auth_verifier(&auth_verifier,
517                                "NTLMSSP", NTLMSSP_AUTH);
518
519         smb_io_rpc_auth_verifier("auth_verifier", &auth_verifier, auth_resp, 0);
520         mem_realloc_data(auth_resp->data, auth_resp->offset);
521
522         pwd_get_lm_nt_owf(pwd, lm_owf, nt_owf);
523                         
524         make_rpc_auth_ntlmssp_resp(&ntlmssp_resp,
525                                  lm_owf, nt_owf,
526                                  domain, user_name, my_name,
527                                  ntlmssp_cli_flgs);
528
529         smb_io_rpc_auth_ntlmssp_resp("ntlmssp_resp", &ntlmssp_resp, auth_resp, 0);
530         mem_realloc_data(auth_resp->data, auth_resp->offset);
531
532         /* create the request RPC_HDR */
533         make_rpc_hdr(&hdr, RPC_BINDRESP, 0x0, rpc_call_id,
534                      auth_resp->offset + rhdr_autha->offset + 0x10,
535                      auth_resp->offset);
536
537         smb_io_rpc_hdr("hdr"   , &hdr   , rhdr, 0);
538         mem_realloc_data(rhdr->data, rhdr->offset);
539
540         if (rhdr->data == NULL || rhdr_autha->data == NULL) return False;
541
542         /***/
543         /*** link rpc header and authentication responses ***/
544         /***/
545
546         prs_link(NULL      , rhdr       , rhdr_autha);
547         prs_link(rhdr      , rhdr_autha , auth_resp );
548         prs_link(rhdr_autha, auth_resp  , NULL );
549
550         return True;
551 }
552
553
554 /*******************************************************************
555  creates a DCE/RPC bind request
556
557  - initialises the parse structure.
558  - dynamically allocates the header data structure
559  - caller is expected to free the header data structure once used.
560
561  ********************************************************************/
562
563 static BOOL create_rpc_request(prs_struct *rhdr, uint8 op_num, int data_len,
564                                 int auth_len)
565 {
566         uint32 alloc_hint;
567         RPC_HDR_REQ hdr_req;
568         RPC_HDR     hdr;
569
570         DEBUG(5,("create_rpc_request: opnum: 0x%x data_len: 0x%x\n",
571         op_num, data_len));
572
573         /* create the rpc header RPC_HDR */
574         make_rpc_hdr(&hdr   , RPC_REQUEST, RPC_FLG_FIRST | RPC_FLG_LAST,
575                      get_rpc_call_id(), data_len, auth_len);
576
577         if (auth_len != 0)
578         {
579                 alloc_hint = data_len - 0x18 - auth_len - 16;
580         }
581         else
582         {
583                 alloc_hint = data_len - 0x18;
584         }
585
586         DEBUG(10,("create_rpc_request: data_len: %x auth_len: %x alloc_hint: %x\n",
587                    data_len, auth_len, alloc_hint));
588
589         /* create the rpc request RPC_HDR_REQ */
590         make_rpc_hdr_req(&hdr_req, alloc_hint, op_num);
591
592         /* stream-time... */
593         smb_io_rpc_hdr    ("hdr    ", &hdr    , rhdr, 0);
594         smb_io_rpc_hdr_req("hdr_req", &hdr_req, rhdr, 0);
595
596         if (rhdr->data == NULL || rhdr->offset != 0x18) return False;
597
598         rhdr->data->offset.start = 0;
599         rhdr->data->offset.end   = rhdr->offset;
600
601         return True;
602 }
603
604
605 /****************************************************************************
606  send a request on an rpc pipe.
607  ****************************************************************************/
608 BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num,
609                       prs_struct *data, prs_struct *rdata)
610 {
611         /* fudge this, at the moment: create the header; memcpy the data.  oops. */
612         prs_struct dataa;
613         prs_struct rparam;
614         prs_struct hdr;
615         prs_struct hdr_auth;
616         prs_struct auth_verf;
617         int data_len;
618         int auth_len;
619         BOOL ret;
620         BOOL auth_verify;
621         BOOL auth_seal;
622         uint32 crc32;
623
624         auth_verify = IS_BITS_SET_ALL(cli->ntlmssp_srv_flgs, NTLMSSP_NEGOTIATE_SIGN);
625         auth_seal   = IS_BITS_SET_ALL(cli->ntlmssp_srv_flgs, NTLMSSP_NEGOTIATE_SEAL);
626
627         /* happen to know that NTLMSSP authentication verifier is 16 bytes */
628         auth_len               = (auth_verify ? 16 : 0);
629         data_len               = data->offset + auth_len + (auth_verify ? 8 : 0) + 0x18;
630         data->data->offset.end = data->offset;
631
632         prs_init(&hdr      , data_len, 4, SAFETY_MARGIN, False);
633         prs_init(&hdr_auth , 8       , 4, SAFETY_MARGIN, False);
634         prs_init(&auth_verf, auth_len, 4, SAFETY_MARGIN, False);
635         prs_init(&rparam   , 0       , 4, 0            , True );
636
637         create_rpc_request(&hdr, op_num, data_len, auth_len);
638
639         if (auth_seal)
640         {
641                 crc32 = crc32_calc_buffer(data->offset, mem_data(&data->data, 0));
642                 NTLMSSPcalc_ap(cli, (uchar*)mem_data(&data->data, 0), data->offset);
643         }
644
645         if (auth_seal || auth_verify)
646         {
647                 RPC_HDR_AUTH         rhdr_auth;
648
649                 make_rpc_hdr_auth(&rhdr_auth, 0x0a, 0x06, 0x08, (auth_verify ? 1 : 0));
650                 smb_io_rpc_hdr_auth("hdr_auth", &rhdr_auth, &hdr_auth, 0);
651         }
652
653         if (auth_verify)
654         {
655                 RPC_AUTH_NTLMSSP_CHK chk;
656
657                 make_rpc_auth_ntlmssp_chk(&chk, NTLMSSP_SIGN_VERSION, crc32, cli->ntlmssp_seq_num++);
658                 smb_io_rpc_auth_ntlmssp_chk("auth_sign", &chk, &auth_verf, 0);
659                 NTLMSSPcalc_ap(cli, (uchar*)mem_data(&auth_verf.data, 4), 12);
660         }
661
662         if (auth_seal || auth_verify)
663         {
664                 prs_link(NULL     , &hdr      , data      );
665                 prs_link(&hdr     , data      , &hdr_auth );
666                 prs_link(data     , &hdr_auth , &auth_verf);
667                 prs_link(&hdr_auth, &auth_verf, NULL      );
668         }
669         else
670         {
671                 prs_link(NULL, &hdr, data);
672                 prs_link(&hdr, data, NULL);
673         }
674
675         mem_realloc_data(hdr.data, data_len);
676
677         DEBUG(100,("data_len: %x data_calc_len: %x\n",
678                 data_len, mem_buf_len(data->data)));
679
680         /* this is a hack due to limitations in rpc_api_pipe */
681         prs_init(&dataa, mem_buf_len(hdr.data), 4, 0x0, False);
682         mem_buf_copy(dataa.data->data, hdr.data, 0, mem_buf_len(hdr.data));
683
684         ret = rpc_api_pipe(cli, 0x0026, NULL, &dataa, &rparam, rdata);
685
686         prs_mem_free(&hdr_auth );
687         prs_mem_free(&auth_verf);
688         prs_mem_free(&rparam   );
689         prs_mem_free(&hdr      );
690         prs_mem_free(&dataa    );
691
692         return ret;
693 }
694
695 /****************************************************************************
696 do an rpc bind
697 ****************************************************************************/
698
699 static BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, char *pipe_name, uint16 device_state)
700 {
701         BOOL state_set = False;
702         char param[2];
703         uint16 setup[2]; /* only need 2 uint16 setup parameters */
704         char *rparam = NULL;
705         char *rdata = NULL;
706         uint32 rparam_len, rdata_len;
707
708         if (pipe_name == NULL) return False;
709
710         DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
711         cli->nt_pipe_fnum, pipe_name, device_state));
712
713         /* create parameters: device state */
714         SSVAL(param, 0, device_state);
715
716         /* create setup parameters. */
717         setup[0] = 0x0001; 
718         setup[1] = cli->nt_pipe_fnum; /* pipe file handle.  got this from an SMBOpenX. */
719
720         /* send the data on \PIPE\ */
721         if (cli_api_pipe(cli, "\\PIPE\\\0\0\0", 8,
722                     setup, 2, 0,                /* setup, length, max */
723                     param, 2, 0,                /* param, length, max */
724                     NULL, 0, 1024,              /* data, length, max */
725                     &rparam, &rparam_len,        /* return param, length */
726                     &rdata, &rdata_len))         /* return data, length */
727         {
728                 DEBUG(5, ("Set Handle state: return OK\n"));
729                 state_set = True;
730         }
731
732         if (rparam) free(rparam);
733         if (rdata ) free(rdata );
734
735         return state_set;
736 }
737
738 /****************************************************************************
739  check the rpc bind acknowledge response
740 ****************************************************************************/
741
742 static BOOL valid_pipe_name(char *pipe_name, RPC_IFACE *abstract, RPC_IFACE *transfer)
743 {
744         int pipe_idx = 0;
745
746         while (pipe_names[pipe_idx].client_pipe != NULL)
747         {
748                 if (strequal(pipe_name, pipe_names[pipe_idx].client_pipe ))
749                 {
750                         DEBUG(5,("Bind Abstract Syntax: "));    
751                         dump_data(5, (char*)&(pipe_names[pipe_idx].abstr_syntax), 
752                                   sizeof(pipe_names[pipe_idx].abstr_syntax));
753                         DEBUG(5,("Bind Transfer Syntax: "));
754                         dump_data(5, (char*)&(pipe_names[pipe_idx].trans_syntax),
755                                   sizeof(pipe_names[pipe_idx].trans_syntax));
756
757                         /* copy the required syntaxes out so we can do the right bind */
758                         memcpy(transfer, &(pipe_names[pipe_idx].trans_syntax),
759                                sizeof(pipe_names[pipe_idx].trans_syntax));
760                         memcpy(abstract, &(pipe_names[pipe_idx].abstr_syntax),
761                                sizeof(pipe_names[pipe_idx].abstr_syntax));
762
763                         return True;
764                 }
765                 pipe_idx++;
766         };
767
768         DEBUG(5,("Bind RPC Pipe[%s] unsupported\n", pipe_name));
769         return False;
770 }
771
772 /****************************************************************************
773  check the rpc bind acknowledge response
774 ****************************************************************************/
775
776 static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, char *pipe_name, RPC_IFACE *transfer)
777 {
778         int i = 0;
779
780         while ((pipe_names[i].client_pipe != NULL) && hdr_ba->addr.len > 0)
781         {
782                 DEBUG(6,("bind_rpc_pipe: searching pipe name: client:%s server:%s\n",
783                 pipe_names[i].client_pipe , pipe_names[i].server_pipe ));
784
785                 if ((strequal(pipe_name, pipe_names[i].client_pipe )))
786                 {
787                         if (strequal(hdr_ba->addr.str, pipe_names[i].server_pipe ))
788                         {
789                                 DEBUG(5,("bind_rpc_pipe: server pipe_name found: %s\n",
790                                          pipe_names[i].server_pipe ));
791                                 break;
792                         }
793                         else
794                         {
795                                 DEBUG(4,("bind_rpc_pipe: pipe_name %s != expected pipe %s.  oh well!\n",
796                                          pipe_names[i].server_pipe ,
797                                          hdr_ba->addr.str));
798                                 break;
799                         }
800                 }
801                 else
802                 {
803                         i++;
804                 }
805         }
806
807         if (pipe_names[i].server_pipe == NULL)
808         {
809                 DEBUG(2,("bind_rpc_pipe: pipe name %s unsupported\n", hdr_ba->addr.str));
810                 return False;
811         }
812
813         /* check the transfer syntax */
814         if (!((hdr_ba->transfer.version == transfer->version) &&
815              (memcmp(hdr_ba->transfer.data, transfer->data,
816                      sizeof(transfer->version)) ==0)))
817         {
818                 DEBUG(0,("bind_rpc_pipe: transfer syntax differs\n"));
819                 return False;
820         }
821
822         /* lkclXXXX only accept one result: check the result(s) */
823         if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0)
824         {
825                 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
826                           hdr_ba->res.num_results, hdr_ba->res.reason));
827         }
828
829         DEBUG(5,("bind_rpc_pipe: accepted!\n"));
830         return True;
831 }
832
833 /****************************************************************************
834 do an rpc bind
835 ****************************************************************************/
836
837 static BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name,
838                                 RPC_IFACE *abstract, RPC_IFACE *transfer, 
839                                 char *my_name)
840 {
841         prs_struct hdr;
842         prs_struct hdr_rb;
843         prs_struct hdr_auth;
844         prs_struct auth_req;
845         prs_struct auth_ntlm;
846         prs_struct data;
847         prs_struct rdata;
848         prs_struct rparam;
849
850         BOOL valid_ack = False;
851         BOOL ntlmssp_auth = cli->ntlmssp_cli_flgs != 0;
852         uint32 rpc_call_id;
853
854         if (pipe_name == NULL || abstract == NULL || transfer == NULL)
855         {
856                 return False;
857         }
858
859         DEBUG(5,("Bind RPC Pipe[%x]: %s\n", cli->nt_pipe_fnum, pipe_name));
860
861         if (!valid_pipe_name(pipe_name, abstract, transfer)) return False;
862
863         prs_init(&hdr      , 0x10                     , 4, 0x0          , False);
864         prs_init(&hdr_rb   , 1024                     , 4, SAFETY_MARGIN, False);
865         prs_init(&hdr_auth , (ntlmssp_auth ?    8 : 0), 4, SAFETY_MARGIN, False);
866         prs_init(&auth_req , (ntlmssp_auth ? 1024 : 0), 4, SAFETY_MARGIN, False);
867         prs_init(&auth_ntlm, (ntlmssp_auth ? 1024 : 0), 4, SAFETY_MARGIN, False);
868
869         prs_init(&rdata    , 0   , 4, SAFETY_MARGIN, True);
870         prs_init(&rparam   , 0   , 4, SAFETY_MARGIN, True);
871
872         rpc_call_id = get_rpc_call_id();
873         create_rpc_bind_req(&hdr, &hdr_rb,
874                             ntlmssp_auth ? &hdr_auth : NULL,
875                             ntlmssp_auth ? &auth_req : NULL,
876                             ntlmssp_auth ? &auth_ntlm : NULL,
877                             rpc_call_id,
878                             abstract, transfer,
879                             global_myname, cli->domain, cli->ntlmssp_cli_flgs);
880
881         /* this is a hack due to limitations in rpc_api_pipe */
882         prs_init(&data, mem_buf_len(hdr.data), 4, 0x0, False);
883         mem_buf_copy(data.data->data, hdr.data, 0, mem_buf_len(hdr.data));
884
885         /* send data on \PIPE\.  receive a response */
886         if (rpc_api_pipe(cli, 0x0026, NULL, &data, &rparam, &rdata))
887         {
888                 RPC_HDR_BA   hdr_ba;
889                 RPC_HDR_AUTH rhdr_auth;
890                 RPC_AUTH_VERIFIER rhdr_verf;
891                 RPC_AUTH_NTLMSSP_CHAL rhdr_chal;
892
893                 DEBUG(5, ("rpc_api_pipe: return OK\n"));
894
895                 smb_io_rpc_hdr_ba("", &hdr_ba, &rdata, 0);
896
897                 if (rdata.offset != 0)
898                 {
899                         valid_ack = check_bind_response(&hdr_ba, pipe_name, transfer);
900                 }
901
902                 if (valid_ack)
903                 {
904                         cli->max_xmit_frag = hdr_ba.bba.max_tsize;
905                         cli->max_recv_frag = hdr_ba.bba.max_rsize;
906                 }
907
908                 if (valid_ack && ntlmssp_auth)
909                 {
910                         smb_io_rpc_hdr_auth("", &rhdr_auth, &rdata, 0);
911                         if (rdata.offset == 0) valid_ack = False;
912                 }
913
914                 if (valid_ack && ntlmssp_auth)
915                 {
916                         smb_io_rpc_auth_verifier("", &rhdr_verf, &rdata, 0);
917                         if (rdata.offset == 0) valid_ack = False;
918                 }
919                 if (valid_ack && ntlmssp_auth)
920                 {
921                         smb_io_rpc_auth_ntlmssp_chal("", &rhdr_chal, &rdata, 0);
922                         if (rdata.offset == 0) valid_ack = False;
923                 }
924                 if (valid_ack && ntlmssp_auth)
925                 {
926                         unsigned char p24[24];
927                         unsigned char lm_owf[24];
928                         unsigned char lm_hash[16];
929
930                         prs_struct hdra;
931                         prs_struct hdr_autha;
932                         prs_struct auth_resp;
933                         prs_struct dataa;
934
935                         cli->ntlmssp_cli_flgs = rhdr_chal.neg_flags;
936
937                         prs_init(&hdra     , 0x10, 4, 0x0          , False);
938                         prs_init(&hdr_autha, 1024, 4, SAFETY_MARGIN, False);
939                         prs_init(&auth_resp, 1024, 4, SAFETY_MARGIN, False);
940
941                         pwd_make_lm_nt_owf(&cli->pwd, rhdr_chal.challenge);
942
943                         create_rpc_bind_resp(&cli->pwd, cli->domain,
944                                              cli->user_name, global_myname, 
945                                              cli->ntlmssp_cli_flgs,
946                                              rpc_call_id,
947                                              &hdra, &hdr_autha, &auth_resp);
948                                             
949                         pwd_get_lm_nt_owf(&cli->pwd, lm_owf, NULL);
950                         pwd_get_lm_nt_16(&cli->pwd, lm_hash, NULL);
951                         NTLMSSPOWFencrypt(lm_hash, lm_owf, p24);
952                         {
953                                 unsigned char j = 0;
954                                 int ind;
955                                 unsigned char k2[8];
956
957                                 memcpy(k2, p24, 5);
958                                 k2[5] = 0xe5;
959                                 k2[6] = 0x38;
960                                 k2[7] = 0xb0;
961
962                                 for (ind = 0; ind < 256; ind++)
963                                 {
964                                         cli->ntlmssp_hash[ind] = (unsigned char)ind;
965                                 }
966
967                                 for( ind = 0; ind < 256; ind++)
968                                 {
969                                         unsigned char tc;
970
971                                         j += (cli->ntlmssp_hash[ind] + k2[ind%8]);
972
973                                         tc = cli->ntlmssp_hash[ind];
974                                         cli->ntlmssp_hash[ind] = cli->ntlmssp_hash[j];
975                                         cli->ntlmssp_hash[j] = tc;
976                                 }
977
978                                 cli->ntlmssp_hash[256] = 0;
979                                 cli->ntlmssp_hash[257] = 0;
980                         }
981 /*                      NTLMSSPhash(cli->ntlmssp_hash, p24); */
982                         bzero(lm_hash, sizeof(lm_hash));
983
984                         /* this is a hack due to limitations in rpc_api_pipe */
985                         prs_init(&dataa, mem_buf_len(hdra.data), 4, 0x0, False);
986                         mem_buf_copy(dataa.data->data, hdra.data, 0, mem_buf_len(hdra.data));
987
988                         if (cli_write(cli, cli->nt_pipe_fnum, 0x0008,
989                                   dataa.data->data, 0,
990                                   dataa.data->data_used) < 0)
991                         {
992                                 valid_ack = False;
993                         }
994
995                         if (valid_ack)
996                         {
997                                 cli->ntlmssp_srv_flgs = rhdr_chal.neg_flags;
998                         }
999
1000                         prs_mem_free(&hdra);
1001                         prs_mem_free(&dataa);
1002                         prs_mem_free(&hdr_autha);
1003                         prs_mem_free(&auth_resp);
1004                 }
1005         }
1006
1007         prs_mem_free(&data     );
1008         prs_mem_free(&hdr      );
1009         prs_mem_free(&hdr_rb   );
1010         prs_mem_free(&hdr_auth );
1011         prs_mem_free(&auth_req );
1012         prs_mem_free(&auth_ntlm);
1013         prs_mem_free(&rdata    );
1014         prs_mem_free(&rparam   );
1015
1016         return valid_ack;
1017 }
1018
1019 /****************************************************************************
1020  set ntlmssp negotiation flags
1021  ****************************************************************************/
1022
1023 void cli_nt_set_ntlmssp_flgs(struct cli_state *cli, uint32 ntlmssp_flgs)
1024 {
1025         cli->ntlmssp_cli_flgs = ntlmssp_flgs;
1026 }
1027
1028
1029 /****************************************************************************
1030  open a session
1031  ****************************************************************************/
1032
1033 BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name)
1034 {
1035         RPC_IFACE abstract;
1036         RPC_IFACE transfer;
1037         int fnum;
1038
1039         /******************* open the pipe *****************/
1040         if (IS_BITS_SET_ALL(cli->capabilities, CAP_NT_SMBS))
1041         {
1042                 if ((fnum = cli_nt_create(cli, &(pipe_name[5]))) == -1)
1043                 {
1044                         DEBUG(0,("cli_nt_session_open: cli_nt_create failed on pipe %s to machine %s.  Error was %s\n",
1045                                  &(pipe_name[5]), cli->desthost, cli_errstr(cli)));
1046                         return False;
1047                 }
1048
1049                 cli->nt_pipe_fnum = (uint16)fnum;
1050         }
1051         else
1052         {
1053                 if ((fnum = cli_open(cli, pipe_name, O_CREAT|O_RDWR, DENY_NONE)) == -1)
1054                 {
1055                         DEBUG(0,("cli_nt_session_open: cli_open failed on pipe %s to machine %s.  Error was %s\n",
1056                                  pipe_name, cli->desthost, cli_errstr(cli)));
1057                         return False;
1058                 }
1059
1060                 cli->nt_pipe_fnum = (uint16)fnum;
1061
1062                 /**************** Set Named Pipe State ***************/
1063                 if (!rpc_pipe_set_hnd_state(cli, pipe_name, 0x4300))
1064                 {
1065                         DEBUG(0,("cli_nt_session_open: pipe hnd state failed.  Error was %s\n",
1066                                   cli_errstr(cli)));
1067                         cli_close(cli, cli->nt_pipe_fnum);
1068                         return False;
1069                 }
1070
1071         }
1072
1073         /******************* bind request on pipe *****************/
1074
1075         if (!rpc_pipe_bind(cli, pipe_name,
1076                            &abstract, &transfer,
1077                            global_myname))
1078         {
1079                 DEBUG(0,("cli_nt_session_open: rpc bind failed. Error was %s\n",
1080                           cli_errstr(cli)));
1081                 cli_close(cli, cli->nt_pipe_fnum);
1082                 return False;
1083         }
1084
1085         /* 
1086          * Setup the remote server name prefixed by \ and the machine account name.
1087          */
1088
1089         fstrcpy(cli->srv_name_slash, "\\\\");
1090         fstrcat(cli->srv_name_slash, cli->desthost);
1091         strupper(cli->srv_name_slash);
1092
1093         fstrcpy(cli->clnt_name_slash, "\\\\");
1094         fstrcat(cli->clnt_name_slash, global_myname);
1095         strupper(cli->clnt_name_slash);
1096
1097         fstrcpy(cli->mach_acct, global_myname);
1098         fstrcat(cli->mach_acct, "$");
1099         strupper(cli->mach_acct);
1100
1101         return True;
1102 }
1103
1104 /****************************************************************************
1105 close the session
1106 ****************************************************************************/
1107
1108 void cli_nt_session_close(struct cli_state *cli)
1109 {
1110         cli_close(cli, cli->nt_pipe_fnum);
1111 }