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