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