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