e02bb889cc5378d9bd9716a0b25a798f9c4523e1
[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 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 True;
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                 cli->ntlmssp_seq_num++;
204         }
205         return True;
206 }
207
208
209 /****************************************************************************
210  send data on an rpc pipe, which *must* be in one fragment.
211  receive response data from an rpc pipe, which may be large...
212
213  read the first fragment: unfortunately have to use SMBtrans for the first
214  bit, then SMBreadX for subsequent bits.
215
216  if first fragment received also wasn't the last fragment, continue
217  getting fragments until we _do_ receive the last fragment.
218
219  [note: from a data abstraction viewpoint, this function is marginally
220         complicated by the return side of cli_api_pipe getting in the way
221         (i.e, the SMB header stuff).  the proper way to do this is to split
222         cli_api_pipe down into receive / transmit.  oh, and split cli_readx
223         down.  in other words, state-based (kernel) techniques...]
224
225  ****************************************************************************/
226
227 static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, 
228                   prs_struct *param , prs_struct *data,
229                   prs_struct *rparam, prs_struct *rdata)
230 {
231         int len;
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         }
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                         {
926                                 unsigned char j = 0;
927                                 int ind;
928                                 unsigned char k2[8];
929
930                                 memcpy(k2, p24, 5);
931                                 k2[5] = 0xe5;
932                                 k2[6] = 0x38;
933                                 k2[7] = 0xb0;
934
935                                 for (ind = 0; ind < 256; ind++)
936                                 {
937                                         cli->ntlmssp_hash[ind] = (unsigned char)ind;
938                                 }
939
940                                 for( ind = 0; ind < 256; ind++)
941                                 {
942                                         unsigned char tc;
943
944                                         j += (cli->ntlmssp_hash[ind] + k2[ind%8]);
945
946                                         tc = cli->ntlmssp_hash[ind];
947                                         cli->ntlmssp_hash[ind] = cli->ntlmssp_hash[j];
948                                         cli->ntlmssp_hash[j] = tc;
949                                 }
950
951                                 cli->ntlmssp_hash[256] = 0;
952                                 cli->ntlmssp_hash[257] = 0;
953                         }
954 /*                      NTLMSSPhash(cli->ntlmssp_hash, p24); */
955                         bzero(lm_hash, sizeof(lm_hash));
956
957                         /* this is a hack due to limitations in rpc_api_pipe */
958                         prs_init(&dataa, mem_buf_len(hdra.data), 4, 0x0, False);
959                         mem_buf_copy(dataa.data->data, hdra.data, 0, mem_buf_len(hdra.data));
960
961                         if (cli_write(cli, cli->nt_pipe_fnum, 0x0008,
962                                   dataa.data->data, 0,
963                                   dataa.data->data_used) < 0)
964                         {
965                                 valid_ack = False;
966                         }
967
968                         if (valid_ack)
969                         {
970                                 cli->ntlmssp_srv_flgs = rhdr_chal.neg_flags;
971                         }
972
973                         prs_mem_free(&hdra);
974                         prs_mem_free(&dataa);
975                         prs_mem_free(&hdr_autha);
976                         prs_mem_free(&auth_resp);
977                 }
978         }
979
980         prs_mem_free(&data     );
981         prs_mem_free(&hdr      );
982         prs_mem_free(&hdr_rb   );
983         prs_mem_free(&hdr_auth );
984         prs_mem_free(&auth_req );
985         prs_mem_free(&auth_ntlm);
986         prs_mem_free(&rdata    );
987         prs_mem_free(&rparam   );
988
989         return valid_ack;
990 }
991
992 /****************************************************************************
993  set ntlmssp negotiation flags
994  ****************************************************************************/
995
996 void cli_nt_set_ntlmssp_flgs(struct cli_state *cli, uint32 ntlmssp_flgs)
997 {
998         cli->ntlmssp_cli_flgs = ntlmssp_flgs;
999 }
1000
1001
1002 /****************************************************************************
1003  open a session
1004  ****************************************************************************/
1005
1006 BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name)
1007 {
1008         RPC_IFACE abstract;
1009         RPC_IFACE transfer;
1010         int fnum;
1011
1012         /******************* open the pipe *****************/
1013         if (IS_BITS_SET_ALL(cli->capabilities, CAP_NT_SMBS))
1014         {
1015                 if ((fnum = cli_nt_create(cli, &(pipe_name[5]))) == -1)
1016                 {
1017                         DEBUG(0,("cli_nt_session_open: cli_nt_create failed on pipe %s to machine %s.  Error was %s\n",
1018                                  &(pipe_name[5]), cli->desthost, cli_errstr(cli)));
1019                         return False;
1020                 }
1021
1022                 cli->nt_pipe_fnum = (uint16)fnum;
1023         }
1024         else
1025         {
1026                 if ((fnum = cli_open(cli, pipe_name, O_CREAT|O_RDWR, DENY_NONE)) == -1)
1027                 {
1028                         DEBUG(0,("cli_nt_session_open: cli_open failed on pipe %s to machine %s.  Error was %s\n",
1029                                  pipe_name, cli->desthost, cli_errstr(cli)));
1030                         return False;
1031                 }
1032
1033                 cli->nt_pipe_fnum = (uint16)fnum;
1034
1035                 /**************** Set Named Pipe State ***************/
1036                 if (!rpc_pipe_set_hnd_state(cli, pipe_name, 0x4300))
1037                 {
1038                         DEBUG(0,("cli_nt_session_open: pipe hnd state failed.  Error was %s\n",
1039                                   cli_errstr(cli)));
1040                         cli_close(cli, cli->nt_pipe_fnum);
1041                         return False;
1042                 }
1043
1044         }
1045
1046         /******************* bind request on pipe *****************/
1047
1048         if (!rpc_pipe_bind(cli, pipe_name,
1049                            &abstract, &transfer,
1050                            global_myname))
1051         {
1052                 DEBUG(0,("cli_nt_session_open: rpc bind failed. Error was %s\n",
1053                           cli_errstr(cli)));
1054                 cli_close(cli, cli->nt_pipe_fnum);
1055                 return False;
1056         }
1057
1058         /* 
1059          * Setup the remote server name prefixed by \ and the machine account name.
1060          */
1061
1062         fstrcpy(cli->srv_name_slash, "\\\\");
1063         fstrcat(cli->srv_name_slash, cli->desthost);
1064         strupper(cli->srv_name_slash);
1065
1066         fstrcpy(cli->clnt_name_slash, "\\\\");
1067         fstrcat(cli->clnt_name_slash, global_myname);
1068         strupper(cli->clnt_name_slash);
1069
1070         fstrcpy(cli->mach_acct, global_myname);
1071         fstrcat(cli->mach_acct, "$");
1072         strupper(cli->mach_acct);
1073
1074         return True;
1075 }
1076
1077 /****************************************************************************
1078 close the session
1079 ****************************************************************************/
1080
1081 void cli_nt_session_close(struct cli_state *cli)
1082 {
1083         cli_close(cli, cli->nt_pipe_fnum);
1084 }