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