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