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