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