a8debd87fdb1166bdd65f98ef3c068826427ca70
[mimir/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 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         DEBUG(100,("data_len: %x data_calc_len: %x\n",
699                 data_len, mem_buf_len(data->data)));
700
701         /* this is a hack due to limitations in rpc_api_pipe */
702         prs_init(&dataa, data_len, 4, 0x0, False);
703         mem_buf_copy(dataa.data->data, hdr.data, 0, mem_buf_len(hdr.data));
704
705         ret = rpc_api_pipe(cli, fnum, False, 0x0026, NULL, &dataa, &rparam, rdata);
706
707         prs_mem_free(&hdr_auth );
708         prs_mem_free(&auth_verf);
709         prs_mem_free(&rparam   );
710         prs_mem_free(&hdr      );
711         prs_mem_free(&dataa    );
712
713         return ret;
714 }
715
716 /****************************************************************************
717 do an rpc bind
718 ****************************************************************************/
719
720 static BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, uint16 fnum,
721                                 const char *pipe_name, uint16 device_state)
722 {
723         BOOL state_set = False;
724         char param[2];
725         uint16 setup[2]; /* only need 2 uint16 setup parameters */
726         char *rparam = NULL;
727         char *rdata = NULL;
728         uint32 rparam_len, rdata_len;
729
730         if (pipe_name == NULL) return False;
731
732         DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
733                   fnum, pipe_name, device_state));
734
735         /* create parameters: device state */
736         SSVAL(param, 0, device_state);
737
738         /* create setup parameters. */
739         setup[0] = 0x0001; 
740         setup[1] = fnum; /* pipe file handle.  got this from an SMBOpenX. */
741
742         /* send the data on \PIPE\ */
743         if (cli_api_pipe(cli, "\\PIPE\\\0\0\0", 8,
744                     setup, 2, 0,                /* setup, length, max */
745                     param, 2, 0,                /* param, length, max */
746                     NULL, 0, 1024,              /* data, length, max */
747                     &rparam, &rparam_len,        /* return param, length */
748                     &rdata, &rdata_len))         /* return data, length */
749         {
750                 DEBUG(5, ("Set Handle state: return OK\n"));
751                 state_set = True;
752         }
753
754         if (rparam) free(rparam);
755         if (rdata ) free(rdata );
756
757         return state_set;
758 }
759
760 /****************************************************************************
761  check the rpc bind acknowledge response
762 ****************************************************************************/
763
764 static BOOL valid_pipe_name(const char *pipe_name,
765                                 RPC_IFACE *abstract, RPC_IFACE *transfer)
766 {
767         int pipe_idx = 0;
768
769         while (pipe_names[pipe_idx].client_pipe != NULL)
770         {
771                 if (strequal(pipe_name, pipe_names[pipe_idx].client_pipe ))
772                 {
773                         DEBUG(5,("Bind Abstract Syntax:\n"));   
774                         dump_data(5, (char*)&(pipe_names[pipe_idx].abstr_syntax), 
775                                   sizeof(pipe_names[pipe_idx].abstr_syntax));
776                         DEBUG(5,("Bind Transfer Syntax:\n"));
777                         dump_data(5, (char*)&(pipe_names[pipe_idx].trans_syntax),
778                                   sizeof(pipe_names[pipe_idx].trans_syntax));
779
780                         /* copy the required syntaxes out so we can do the right bind */
781                         memcpy(transfer, &(pipe_names[pipe_idx].trans_syntax),
782                                sizeof(pipe_names[pipe_idx].trans_syntax));
783                         memcpy(abstract, &(pipe_names[pipe_idx].abstr_syntax),
784                                sizeof(pipe_names[pipe_idx].abstr_syntax));
785
786                         return True;
787                 }
788                 pipe_idx++;
789         };
790
791         DEBUG(5,("Bind RPC Pipe[%s] unsupported\n", pipe_name));
792         return False;
793 }
794
795 /****************************************************************************
796  check the rpc bind acknowledge response
797 ****************************************************************************/
798
799 static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, const char *pipe_name,
800                                 RPC_IFACE *transfer)
801 {
802         int i = 0;
803
804         while ((pipe_names[i].client_pipe != NULL) && hdr_ba->addr.len > 0)
805         {
806                 DEBUG(6,("bind_rpc_pipe: searching pipe name: client:%s server:%s\n",
807                 pipe_names[i].client_pipe , pipe_names[i].server_pipe ));
808
809                 if ((strequal(pipe_name, pipe_names[i].client_pipe )))
810                 {
811                         if (strequal(hdr_ba->addr.str, pipe_names[i].server_pipe ))
812                         {
813                                 DEBUG(5,("bind_rpc_pipe: server pipe_name found: %s\n",
814                                          pipe_names[i].server_pipe ));
815                                 break;
816                         }
817                         else
818                         {
819                                 DEBUG(4,("bind_rpc_pipe: pipe_name %s != expected pipe %s.  oh well!\n",
820                                          pipe_names[i].server_pipe ,
821                                          hdr_ba->addr.str));
822                                 break;
823                         }
824                 }
825                 else
826                 {
827                         i++;
828                 }
829         }
830
831         if (pipe_names[i].server_pipe == NULL)
832         {
833                 DEBUG(2,("bind_rpc_pipe: pipe name %s unsupported\n", hdr_ba->addr.str));
834                 return False;
835         }
836
837         /* check the transfer syntax */
838         if (!((hdr_ba->transfer.version == transfer->version) &&
839              (memcmp(hdr_ba->transfer.data, transfer->data,
840                      sizeof(transfer->version)) ==0)))
841         {
842                 DEBUG(0,("bind_rpc_pipe: transfer syntax differs\n"));
843                 return False;
844         }
845
846         /* lkclXXXX only accept one result: check the result(s) */
847         if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0)
848         {
849                 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
850                           hdr_ba->res.num_results, hdr_ba->res.reason));
851         }
852
853         DEBUG(5,("bind_rpc_pipe: accepted!\n"));
854         return True;
855 }
856
857 /****************************************************************************
858 do an rpc bind
859 ****************************************************************************/
860
861 static BOOL rpc_pipe_bind(struct cli_state *cli, uint16 fnum,
862                                 const char *pipe_name,
863                                 RPC_IFACE *abstract, RPC_IFACE *transfer, 
864                                 char *my_name)
865 {
866         prs_struct hdr;
867         prs_struct hdr_rb;
868         prs_struct hdr_auth;
869         prs_struct auth_req;
870         prs_struct auth_ntlm;
871         prs_struct data;
872         prs_struct rdata;
873         prs_struct rparam;
874
875         BOOL valid_ack = False;
876         BOOL ntlmssp_auth = cli->ntlmssp_cli_flgs != 0;
877         uint32 rpc_call_id;
878
879         if (pipe_name == NULL || abstract == NULL || transfer == NULL)
880         {
881                 return False;
882         }
883
884         DEBUG(5,("Bind RPC Pipe[%x]: %s\n", fnum, pipe_name));
885
886         if (!valid_pipe_name(pipe_name, abstract, transfer)) return False;
887
888         prs_init(&hdr      , 0x10                     , 4, 0x0          , False);
889         prs_init(&hdr_rb   , 1024                     , 4, SAFETY_MARGIN, False);
890         prs_init(&hdr_auth , (ntlmssp_auth ?    8 : 0), 4, SAFETY_MARGIN, False);
891         prs_init(&auth_req , (ntlmssp_auth ? 1024 : 0), 4, SAFETY_MARGIN, False);
892         prs_init(&auth_ntlm, (ntlmssp_auth ? 1024 : 0), 4, SAFETY_MARGIN, False);
893
894         prs_init(&rdata    , 0   , 4, SAFETY_MARGIN, True);
895         prs_init(&rparam   , 0   , 4, SAFETY_MARGIN, True);
896
897         rpc_call_id = get_rpc_call_id();
898         create_rpc_bind_req(&hdr, &hdr_rb,
899                             ntlmssp_auth ? &hdr_auth : NULL,
900                             ntlmssp_auth ? &auth_req : NULL,
901                             ntlmssp_auth ? &auth_ntlm : NULL,
902                             rpc_call_id,
903                             abstract, transfer,
904                             global_myname, cli->usr.domain, cli->usr.ntlmssp_flags);
905
906         /* this is a hack due to limitations in rpc_api_pipe */
907         prs_init(&data, mem_buf_len(hdr.data), 4, 0x0, False);
908         mem_buf_copy(data.data->data, hdr.data, 0, mem_buf_len(hdr.data));
909
910         cli->max_recv_frag = 0x1000;
911
912         /* send data on \PIPE\.  receive a response */
913         if (rpc_api_pipe(cli, fnum, True, 0x0026, NULL, &data, &rparam, &rdata))
914         {
915                 RPC_HDR_BA                hdr_ba;
916                 RPC_HDR_AUTH              rhdr_auth;
917                 RPC_AUTH_NTLMSSP_VERIFIER rhdr_verf;
918                 RPC_AUTH_NTLMSSP_CHAL     rhdr_chal;
919
920                 DEBUG(5, ("rpc_api_pipe: return OK\n"));
921
922                 smb_io_rpc_hdr_ba("", &hdr_ba, &rdata, 0);
923
924                 if (rdata.offset != 0)
925                 {
926                         valid_ack = check_bind_response(&hdr_ba, pipe_name, transfer);
927                 }
928
929                 if (valid_ack)
930                 {
931                         cli->max_xmit_frag = hdr_ba.bba.max_tsize;
932                         cli->max_recv_frag = hdr_ba.bba.max_rsize;
933                 }
934
935                 if (valid_ack && ntlmssp_auth)
936                 {
937                         smb_io_rpc_hdr_auth("", &rhdr_auth, &rdata, 0);
938                         if (rdata.offset == 0) valid_ack = False;
939                 }
940
941                 if (valid_ack && ntlmssp_auth)
942                 {
943                         smb_io_rpc_auth_ntlmssp_verifier("", &rhdr_verf, &rdata, 0);
944                         if (rdata.offset == 0) valid_ack = False;
945                 }
946                 if (valid_ack && ntlmssp_auth)
947                 {
948                         smb_io_rpc_auth_ntlmssp_chal("", &rhdr_chal, &rdata, 0);
949                         if (rdata.offset == 0) valid_ack = False;
950                 }
951                 if (valid_ack && ntlmssp_auth)
952                 {
953                         unsigned char p24[24];
954                         unsigned char lm_owf[24];
955                         unsigned char lm_hash[16];
956
957                         prs_struct hdra;
958                         prs_struct hdr_autha;
959                         prs_struct auth_resp;
960                         prs_struct dataa;
961
962                         cli->ntlmssp_cli_flgs = rhdr_chal.neg_flags;
963
964                         prs_init(&hdra     , 0x10, 4, 0x0          , False);
965                         prs_init(&hdr_autha, 1024, 4, SAFETY_MARGIN, False);
966                         prs_init(&auth_resp, 1024, 4, SAFETY_MARGIN, False);
967
968                         pwd_make_lm_nt_owf(&cli->usr.pwd, rhdr_chal.challenge);
969
970                         create_rpc_bind_resp(&cli->usr.pwd, cli->usr.domain,
971                                              cli->usr.user_name, global_myname, 
972                                              cli->ntlmssp_cli_flgs,
973                                              rpc_call_id,
974                                              &hdra, &hdr_autha, &auth_resp);
975                                             
976                         pwd_get_lm_nt_owf(&cli->usr.pwd, lm_owf, NULL, NULL, NULL);
977                         pwd_get_lm_nt_16(&cli->usr.pwd, lm_hash, NULL);
978                         NTLMSSPOWFencrypt(lm_hash, lm_owf, p24);
979                         {
980                                 unsigned char j = 0;
981                                 int ind;
982                                 unsigned char k2[8];
983
984                                 memcpy(k2, p24, 5);
985                                 k2[5] = 0xe5;
986                                 k2[6] = 0x38;
987                                 k2[7] = 0xb0;
988
989                                 for (ind = 0; ind < 256; ind++)
990                                 {
991                                         cli->ntlmssp_hash[ind] = (unsigned char)ind;
992                                 }
993
994                                 for( ind = 0; ind < 256; ind++)
995                                 {
996                                         unsigned char tc;
997
998                                         j += (cli->ntlmssp_hash[ind] + k2[ind%8]);
999
1000                                         tc = cli->ntlmssp_hash[ind];
1001                                         cli->ntlmssp_hash[ind] = cli->ntlmssp_hash[j];
1002                                         cli->ntlmssp_hash[j] = tc;
1003                                 }
1004
1005                                 cli->ntlmssp_hash[256] = 0;
1006                                 cli->ntlmssp_hash[257] = 0;
1007                         }
1008 /*                      NTLMSSPhash(cli->ntlmssp_hash, p24); */
1009                         bzero(lm_hash, sizeof(lm_hash));
1010
1011                         /* this is a hack due to limitations in rpc_api_pipe */
1012                         prs_init(&dataa, mem_buf_len(hdra.data), 4, 0x0, False);
1013                         mem_buf_copy(dataa.data->data, hdra.data, 0, mem_buf_len(hdra.data));
1014
1015                         if (cli_write(cli, fnum, 0x0008,
1016                                   dataa.data->data, 0,
1017                                   dataa.data->data_used) < 0)
1018                         {
1019                                 valid_ack = False;
1020                         }
1021
1022                         if (valid_ack)
1023                         {
1024                                 cli->ntlmssp_srv_flgs = rhdr_chal.neg_flags;
1025                         }
1026
1027                         prs_mem_free(&hdra);
1028                         prs_mem_free(&dataa);
1029                         prs_mem_free(&hdr_autha);
1030                         prs_mem_free(&auth_resp);
1031                 }
1032         }
1033
1034         prs_mem_free(&data     );
1035         prs_mem_free(&hdr      );
1036         prs_mem_free(&hdr_rb   );
1037         prs_mem_free(&hdr_auth );
1038         prs_mem_free(&auth_req );
1039         prs_mem_free(&auth_ntlm);
1040         prs_mem_free(&rdata    );
1041         prs_mem_free(&rparam   );
1042
1043         return valid_ack;
1044 }
1045
1046 /****************************************************************************
1047  set ntlmssp negotiation flags
1048  ****************************************************************************/
1049
1050 void cli_nt_set_ntlmssp_flgs(struct cli_state *cli, uint32 ntlmssp_flgs)
1051 {
1052         cli->ntlmssp_cli_flgs = ntlmssp_flgs;
1053 }
1054
1055
1056 /****************************************************************************
1057  open a session
1058  ****************************************************************************/
1059
1060 BOOL cli_nt_session_open(struct cli_state *cli, const char *pipe_name,
1061                 uint16* fnum)
1062 {
1063         RPC_IFACE abstract;
1064         RPC_IFACE transfer;
1065
1066         /******************* open the pipe *****************/
1067         if (IS_BITS_SET_ALL(cli->capabilities, CAP_NT_SMBS))
1068         {
1069                 int f;
1070                 f = cli_nt_create(cli, &(pipe_name[5]));
1071                 if (f == -1)
1072                 {
1073                         fstring errstr;
1074                         cli_safe_errstr(cli, errstr, sizeof(errstr)-1);
1075                         DEBUG(0,("cli_nt_session_open: cli_nt_create failed on pipe %s to machine %s.  Error was %s\n",
1076                                  &(pipe_name[5]), cli->desthost, errstr));
1077                         return False;
1078                 }
1079                 *fnum = (uint16)f;
1080         }
1081         else
1082         {
1083                 int f;
1084                 f = cli_open(cli, pipe_name, O_CREAT|O_RDWR, DENY_NONE);
1085                 if (f == -1)
1086                 {
1087                         fstring errstr;
1088                         cli_safe_errstr(cli, errstr, sizeof(errstr)-1);
1089                         DEBUG(0,("cli_nt_session_open: cli_open failed on pipe %s to machine %s.  Error was %s\n",
1090                                  pipe_name, cli->desthost, errstr));
1091                         return False;
1092                 }
1093                 *fnum = (uint16)f;
1094
1095                 /**************** Set Named Pipe State ***************/
1096                 if (!rpc_pipe_set_hnd_state(cli, *fnum, pipe_name, 0x4300))
1097                 {
1098                         fstring errstr;
1099                         cli_safe_errstr(cli, errstr, sizeof(errstr)-1);
1100                         DEBUG(0,("cli_nt_session_open: pipe hnd state failed.  Error was %s\n",
1101                                   errstr));
1102                         cli_close(cli, *fnum);
1103                         return False;
1104                 }
1105
1106         }
1107
1108         /******************* bind request on pipe *****************/
1109
1110         if (!rpc_pipe_bind(cli, *fnum, pipe_name,
1111                            &abstract, &transfer,
1112                            global_myname))
1113         {
1114                 fstring errstr;
1115                 cli_safe_errstr(cli, errstr, sizeof(errstr)-1);
1116                 DEBUG(0,("cli_nt_session_open: rpc bind failed. Error was %s\n",
1117                           errstr));
1118                 cli_close(cli, *fnum);
1119                 return False;
1120         }
1121
1122         /* 
1123          * Setup the remote server name prefixed by \ and the machine account name.
1124          */
1125
1126         return True;
1127 }
1128
1129 /****************************************************************************
1130 close the session
1131 ****************************************************************************/
1132
1133 void cli_nt_session_close(struct cli_state *cli, uint16 fnum)
1134 {
1135         if (fnum != 0xffff)
1136         {
1137                 cli_close(cli, fnum);
1138         }
1139 }