This is a security audit change of the main source.
[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
41 uint32 get_rpc_call_id(void)
42 {
43   static uint32 call_id = 1;
44   return ++call_id;
45 }
46
47 /*******************************************************************
48  uses SMBreadX to get rest of rpc data
49  ********************************************************************/
50
51 static BOOL rpc_read(struct cli_state *cli, 
52                      prs_struct *rdata, uint32 data_to_read,
53                      uint32 rdata_offset)
54 {
55   int size = 0x1630;
56   int file_offset = rdata_offset;
57   int num_read;
58   char *data = rdata->data->data;
59   uint32 err;
60   uint32 errclass;
61   uint32 new_data_size = rdata->data->data_used + data_to_read;
62
63   data += rdata_offset;
64
65   file_offset -= rdata_offset;
66
67   DEBUG(5,("rpc_read: data_to_read: %d data offset: %d file offset: %d\n",
68            data_to_read, rdata_offset, file_offset));
69
70   if (new_data_size > rdata->data->data_size)
71   {
72     mem_grow_data(&rdata->data, True, new_data_size, True);
73     DEBUG(5,("rpc_read: grow buffer to %d\n", rdata->data->data_used));
74   }
75
76   do /* read data using SMBreadX */
77   {
78     if (size > data_to_read)
79       size = data_to_read;
80
81     new_data_size = rdata->data->data_used + size;
82
83     if (new_data_size > rdata->data->data_size)
84     {
85       mem_grow_data(&rdata->data, True, new_data_size, True);
86       DEBUG(5,("rpc_read: grow buffer to %d\n", rdata->data->data_used));
87     }
88
89     num_read = cli_read(cli, cli->nt_pipe_fnum, data, file_offset + 0x100000, size);
90
91     DEBUG(5,("rpc_read: read offset: %d read: %d to read: %d\n",
92          file_offset, num_read, data_to_read));
93
94     data_to_read -= num_read;
95     file_offset  += num_read;
96     data         += num_read;
97
98     cli_error(cli, (int *)&errclass, (int *)&err);
99     if (errclass != 0)
100       return False;
101
102   } while (num_read > 0 && data_to_read > 0);
103             /* && err == (0x80000000 | STATUS_BUFFER_OVERFLOW)); */
104
105   mem_realloc_data(rdata->data, file_offset + rdata_offset);
106   rdata->data->offset.end = file_offset + rdata_offset;
107
108   DEBUG(5,("rpc_read: data supposedly left to read:0x%x\n", data_to_read));
109
110   return data_to_read == 0;
111 }
112
113 /****************************************************************************
114  checks the header
115  ****************************************************************************/
116 static BOOL rpc_check_hdr(prs_struct *rdata, uint8 *pkt_type,
117                           BOOL *first, BOOL *last, int *len)
118 {
119   RPC_HDR    rhdr;
120
121   DEBUG(5,("rpc_check_hdr: rdata->data->data_used: %d\n", rdata->data->data_used));
122
123   smb_io_rpc_hdr   ("rpc_hdr   ", &rhdr   , rdata, 0);
124
125   if (!rdata->offset || rdata->offset != 0x10)
126   {
127     DEBUG(0,("cli_pipe: error in rpc header\n"));
128     return False;
129   }
130
131   DEBUG(5,("rpc_check_hdr: (after smb_io_rpc_hdr call) rdata->data->data_used: %d\n",
132          rdata->data->data_used));
133
134   (*first   ) = IS_BITS_SET_ALL(rhdr.flags, RPC_FLG_FIRST);
135   (*last    ) = IS_BITS_SET_ALL(rhdr.flags, RPC_FLG_LAST );
136   (*len     ) = rhdr.frag_len - rdata->data->data_used;
137   (*pkt_type) = rhdr.pkt_type;
138
139   return True;
140 }
141
142 /****************************************************************************
143  send data on an rpc pipe, which *must* be in one fragment.
144  receive response data from an rpc pipe, which may be large...
145
146  read the first fragment: unfortunately have to use SMBtrans for the first
147  bit, then SMBreadX for subsequent bits.
148
149  if first fragment received also wasn't the last fragment, continue
150  getting fragments until we _do_ receive the last fragment.
151
152  [note: from a data abstraction viewpoint, this function is marginally
153         complicated by the return side of cli_api_pipe getting in the way
154         (i.e, the SMB header stuff).  the proper way to do this is to split
155         cli_api_pipe down into receive / transmit.  oh, and split cli_readx
156         down.  in other words, state-based (kernel) techniques...]
157
158  ****************************************************************************/
159
160 BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, 
161                   prs_struct *param , prs_struct *data,
162                   prs_struct *rparam, prs_struct *rdata)
163 {
164   int len;
165
166   uint16 setup[2]; /* only need 2 uint16 setup parameters */
167   uint32 err;
168   uint32 errclass;
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)
207     return False;
208
209   /**** parse the header: check it's a response record */
210
211   rdata->data->offset.start = 0;
212   rdata->data->offset.end   = rdata->data->data_used;
213   rdata->offset = 0;
214
215   /* cli_api_pipe does an ordinary Realloc - we have no margins now. */
216   rdata->data->margin = 0;
217   if(rparam)
218     rparam->data->margin = 0;
219
220   if (!rpc_check_hdr(rdata, &pkt_type, &first, &last, &len))
221     return False;
222         
223   if (pkt_type == RPC_RESPONSE)
224   {
225     RPC_HDR_RESP rhdr_resp;
226     smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, rdata, 0);
227   }
228
229   DEBUG(5,("rpc_api_pipe: len left: %d smbtrans read: %d\n",
230          len, rdata->data->data_used));
231
232   /* check if data to be sent back was too large for one SMB. */
233   /* err status is only informational: the _real_ check is on the length */
234   if (len > 0) /* || err == (0x80000000 | STATUS_BUFFER_OVERFLOW)) */
235   {
236     if (!rpc_read(cli, rdata, len, rdata->data->data_used))
237       return False;
238   }
239
240   /* only one rpc fragment, and it has been read */
241   if (first && last)
242   {
243     DEBUG(6,("rpc_api_pipe: fragment first and last both set\n"));
244     return True;
245   }
246
247   while (!last) /* read more fragments until we get the last one */
248   {
249     RPC_HDR      rhdr;
250     RPC_HDR_RESP rhdr_resp;
251     int num_read;
252     prs_struct hps;
253
254     prs_init(&hps, 0x18, 4, 0, True);
255         
256     num_read = cli_read(cli, cli->nt_pipe_fnum, hps.data->data, 0, 0x18);
257     DEBUG(5,("rpc_api_pipe: read header (size:%d)\n", num_read));
258
259     if (num_read != 0x18)
260       return False;
261
262     smb_io_rpc_hdr     ("rpc_hdr     ", &rhdr     , &hps, 0);
263     smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, &hps, 0);
264
265     prs_mem_free(&hps);
266
267     cli_error(cli, (int *)&errclass, (int *)&err);
268     if (errclass != 0)
269       return False;
270
271     first = IS_BITS_SET_ALL(rhdr.flags, RPC_FLG_FIRST);
272     last  = IS_BITS_SET_ALL(rhdr.flags, RPC_FLG_LAST );
273
274     if (first)
275     {
276       DEBUG(0,("rpc_api_pipe: wierd rpc header received\n"));
277       return False;
278     }
279
280     len = rhdr.frag_len - hps.offset;
281     if (!rpc_read(cli, rdata, len, rdata->data->data_used))
282       return False;
283   }
284
285   return True;
286 }
287
288 /*******************************************************************
289  creates a DCE/RPC bind request
290
291  - initialises the parse structure.
292  - dynamically allocates the header data structure
293  - caller is expected to free the header data structure once used.
294
295  ********************************************************************/
296
297 static BOOL create_rpc_bind_req(prs_struct *rhdr,
298                                 prs_struct *rhdr_rb,
299                                 prs_struct *auth_req,
300                                 RPC_IFACE *abstract, RPC_IFACE *transfer,
301                                 char *my_name, char *domain)
302 {
303   RPC_HDR_RB        hdr_rb;
304   RPC_HDR           hdr;
305   RPC_AUTH_NTLMSSP_REQ ntlmssp_req;
306
307   /* create the bind request RPC_HDR_RB */
308   make_rpc_hdr_rb(&hdr_rb, 0x1630, 0x1630, 0x0,
309                   0x1, 0x0, 0x1, abstract, transfer);
310
311   /* stream the bind request data */
312   smb_io_rpc_hdr_rb("", &hdr_rb,  rhdr_rb, 0);
313   mem_realloc_data(rhdr_rb->data, rhdr_rb->offset);
314
315   if (auth_req != NULL)
316   {
317     /*
318      * I have a feeling this is broken right now... JRA.
319      */
320     make_rpc_auth_ntlmssp_req(&ntlmssp_req, "NTLMSSP", 0x1,
321                               0x0000b2b3, my_name, domain);
322     smb_io_rpc_auth_ntlmssp_req("", &ntlmssp_req, auth_req, 0);
323     mem_realloc_data(auth_req->data, auth_req->offset);
324   }
325
326   /* create the request RPC_HDR */
327   make_rpc_hdr(&hdr, RPC_BIND, 0x0, get_rpc_call_id(),
328                rhdr_rb->offset, auth_req != NULL ? auth_req->offset : 0);
329
330   smb_io_rpc_hdr("hdr"   , &hdr   , rhdr, 0);
331   mem_realloc_data(rhdr->data, rhdr->offset);
332
333   if (rhdr->data == NULL || rhdr_rb->data == NULL)
334     return False;
335
336   /***/
337   /*** link rpc header, bind acknowledgment and authentication responses ***/
338   /***/
339
340   rhdr->data->offset.start = 0;
341   rhdr->data->offset.end   = rhdr->offset;
342   rhdr->data->next         = rhdr_rb->data;
343
344   if (auth_req != NULL)
345   {
346     rhdr_rb->data->offset.start = rhdr->offset;
347     rhdr_rb->data->offset.end   = rhdr->offset + rhdr_rb->offset;
348     rhdr_rb->data->next         = auth_req->data;
349
350     auth_req->data->offset.start = rhdr->offset + rhdr_rb->offset;
351     auth_req->data->offset.end   = rhdr->offset + auth_req->offset + rhdr_rb->offset;
352     auth_req->data->next         = NULL;
353   }
354   else
355   {
356     rhdr_rb->data->offset.start = rhdr->offset;
357     rhdr_rb->data->offset.end   = rhdr->offset + rhdr_rb->offset;
358     rhdr_rb->data->next         = NULL;
359   }
360
361   return True;
362 }
363
364
365 /*******************************************************************
366  creates a DCE/RPC bind request
367
368  - initialises the parse structure.
369  - dynamically allocates the header data structure
370  - caller is expected to free the header data structure once used.
371
372  ********************************************************************/
373
374 static BOOL create_rpc_request(prs_struct *rhdr, uint8 op_num, int data_len)
375 {
376   RPC_HDR_REQ hdr_req;
377   RPC_HDR     hdr;
378
379   DEBUG(5,("create_rpc_request: opnum: 0x%x data_len: 0x%x\n",
380        op_num, data_len));
381
382   /* create the rpc header RPC_HDR */
383   make_rpc_hdr(&hdr   , RPC_REQUEST, RPC_FLG_FIRST | RPC_FLG_LAST,
384                get_rpc_call_id(), data_len + 0x18, 0);
385
386   /* create the rpc request RPC_HDR_REQ */
387   make_rpc_hdr_req(&hdr_req, data_len, op_num);
388
389   /* stream-time... */
390   smb_io_rpc_hdr    ("hdr    ", &hdr    , rhdr, 0);
391   smb_io_rpc_hdr_req("hdr_req", &hdr_req, rhdr, 0);
392
393   if (rhdr->data == NULL || rhdr->offset != 0x18)
394     return False;
395
396   rhdr->data->offset.start = 0;
397   rhdr->data->offset.end   = rhdr->offset;
398
399   return True;
400 }
401
402
403 /****************************************************************************
404  send a request on an rpc pipe.
405  ****************************************************************************/
406 BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num,
407                       prs_struct *data, prs_struct *rdata)
408 {
409   /* fudge this, at the moment: create the header; memcpy the data.  oops. */
410   prs_struct rparam;
411   prs_struct hdr;
412   int data_len;
413   BOOL ret;
414
415   data_len               = data->offset + 0x18;
416   data->data->offset.end = data->offset;
417
418   prs_init(&hdr   , data_len, 4, SAFETY_MARGIN, False);
419   prs_init(&rparam, 0       , 4, 0            , True );
420
421   create_rpc_request(&hdr, op_num, data_len);
422
423   mem_realloc_data(hdr.data, data_len);
424   hdr.data->offset.end = data_len;
425   mem_buf_copy(mem_data(&(hdr.data), 0x18), data->data, 0, data->offset);
426
427   ret = rpc_api_pipe(cli, 0x0026, NULL, &hdr, &rparam, rdata);
428
429   prs_mem_free(&rparam);
430   prs_mem_free(&hdr);
431
432   return ret;
433 }
434
435
436 /****************************************************************************
437 do an rpc bind
438 ****************************************************************************/
439
440 BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, char *pipe_name, uint16 device_state)
441 {
442   BOOL state_set = False;
443   char param[2];
444   uint16 setup[2]; /* only need 2 uint16 setup parameters */
445   char *rparam = NULL;
446   char *rdata = NULL;
447   uint32 rparam_len, rdata_len;
448
449   if (pipe_name == NULL)
450     return False;
451
452   DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
453               cli->nt_pipe_fnum, pipe_name, device_state));
454
455   /* create parameters: device state */
456   SSVAL(param, 0, device_state);
457
458   /* create setup parameters. */
459   setup[0] = 0x0001; 
460   setup[1] = cli->nt_pipe_fnum; /* pipe file handle.  got this from an SMBOpenX. */
461
462   /* send the data on \PIPE\ */
463   if (cli_api_pipe(cli, "\\PIPE\\\0\0\0", 8,
464                    setup, 2, 0,                /* setup, length, max */
465                    param, 2, 0,                /* param, length, max */
466                    NULL, 0, 1024,              /* data, length, max */
467                    &rparam, &rparam_len,        /* return param, length */
468                    &rdata, &rdata_len))         /* return data, length */
469   {
470     DEBUG(5, ("Set Handle state: return OK\n"));
471     state_set = True;
472   }
473
474   if(rparam)
475     free(rparam);
476   if(rdata)
477     free(rdata);
478
479   return state_set;
480 }
481
482 /****************************************************************************
483  check the rpc bind acknowledge response
484 ****************************************************************************/
485
486 static BOOL valid_pipe_name(char *pipe_name, RPC_IFACE *abstract, RPC_IFACE *transfer)
487 {
488   int pipe_idx = 0;
489
490   while (pipe_names[pipe_idx].client_pipe != NULL)
491   {
492     if (strequal(pipe_name, pipe_names[pipe_idx].client_pipe ))
493     {
494       DEBUG(5,("Bind Abstract Syntax: "));      
495       dump_data(5, (char*)&(pipe_names[pipe_idx].abstr_syntax), 
496                  sizeof(pipe_names[pipe_idx].abstr_syntax));
497       DEBUG(5,("Bind Transfer Syntax: "));
498       dump_data(5, (char*)&(pipe_names[pipe_idx].trans_syntax),
499                  sizeof(pipe_names[pipe_idx].trans_syntax));
500
501       /* copy the required syntaxes out so we can do the right bind */
502       memcpy(transfer, &(pipe_names[pipe_idx].trans_syntax),
503              sizeof(pipe_names[pipe_idx].trans_syntax));
504       memcpy(abstract, &(pipe_names[pipe_idx].abstr_syntax),
505              sizeof(pipe_names[pipe_idx].abstr_syntax));
506
507       return True;
508     }
509     pipe_idx++;
510   };
511
512   DEBUG(5,("Bind RPC Pipe[%s] unsupported\n", pipe_name));
513   return False;
514 }
515
516 /****************************************************************************
517  check the rpc bind acknowledge response
518 ****************************************************************************/
519
520 static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, char *pipe_name, RPC_IFACE *transfer)
521 {
522   int i = 0;
523
524   while ((pipe_names[i].client_pipe != NULL))
525   {
526     DEBUG(6,("bind_rpc_pipe: searching pipe name: client:%s server:%s\n",
527            pipe_names[i].client_pipe , pipe_names[i].server_pipe ));
528
529     if ((strequal(pipe_name, pipe_names[i].client_pipe )))
530     {
531       if (strequal(hdr_ba->addr.str, pipe_names[i].server_pipe ))
532       {
533         DEBUG(5,("bind_rpc_pipe: server pipe_name found: %s\n",
534               pipe_names[i].server_pipe ));
535         break;
536       }
537       else
538       {
539         DEBUG(2,("bind_rpc_pipe: pipe_name %s != expected pipe %s\n",
540            pipe_names[i].server_pipe , hdr_ba->addr.str));
541         return False;
542       }
543     }
544     else
545     {
546       i++;
547     }
548   }
549
550   if (pipe_names[i].server_pipe == NULL)
551   {
552     DEBUG(2,("bind_rpc_pipe: pipe name %s unsupported\n", hdr_ba->addr.str));
553     return False;
554   }
555
556   /* check the transfer syntax */
557   if (!((hdr_ba->transfer.version == transfer->version) &&
558        (memcmp(hdr_ba->transfer.data, transfer->data,
559                sizeof(transfer->version)) ==0)))
560   {
561     DEBUG(0,("bind_rpc_pipe: transfer syntax differs\n"));
562     return False;
563   }
564         
565   /* lkclXXXX only accept one result: check the result(s) */
566   if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0)
567   {
568     DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
569             hdr_ba->res.num_results, hdr_ba->res.reason));
570   }
571         
572   DEBUG(5,("bind_rpc_pipe: accepted!\n"));
573   return True;
574 }
575
576 /****************************************************************************
577 do an rpc bind
578 ****************************************************************************/
579
580 BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name,
581                    RPC_IFACE *abstract, RPC_IFACE *transfer, BOOL ntlmssp_auth)
582 {
583   prs_struct hdr;
584   prs_struct hdr_rb;
585   prs_struct auth_req;
586   prs_struct data;
587   prs_struct rdata;
588   prs_struct rparam;
589
590   BOOL valid_ack = False;
591
592   if (pipe_name == NULL || abstract == NULL || transfer == NULL)
593     return False;
594
595   DEBUG(5,("Bind RPC Pipe[%x]: %s\n", cli->nt_pipe_fnum, pipe_name));
596
597   if (!valid_pipe_name(pipe_name, abstract, transfer))
598     return False;
599
600   prs_init(&hdr     , 0x10                   , 4, 0x0          , False);
601   prs_init(&hdr_rb  , 1024                   , 4, SAFETY_MARGIN, False);
602   prs_init(&auth_req, ntlmssp_auth ? 1024 : 0, 4, SAFETY_MARGIN, False);
603
604   prs_init(&rdata , 0   , 4, SAFETY_MARGIN, True );
605   prs_init(&rparam, 0   , 4, SAFETY_MARGIN, True );
606
607   create_rpc_bind_req(&hdr, &hdr_rb, ntlmssp_auth ? &auth_req : NULL,
608                       abstract, transfer, global_myname, global_myworkgroup);
609
610   /* this is a hack due to limitations in rpc_api_pipe */
611   prs_init(&data, mem_buf_len(hdr.data), 4, 0x0, False);
612   mem_buf_copy(data.data->data, hdr.data, 0, mem_buf_len(hdr.data));
613
614   /* send data on \PIPE\.  receive a response */
615   if (rpc_api_pipe(cli, 0x0026, NULL, &data, &rparam, &rdata))
616   {
617     RPC_HDR_BA hdr_ba;
618
619     DEBUG(5, ("rpc_api_pipe: return OK\n"));
620
621     smb_io_rpc_hdr_ba("", &hdr_ba, &rdata, 0);
622
623     if (rdata.offset != 0)
624       valid_ack = check_bind_response(&hdr_ba, pipe_name, transfer);
625   }
626
627   prs_mem_free(&data    );
628   prs_mem_free(&hdr     );
629   prs_mem_free(&hdr_rb  );
630   prs_mem_free(&auth_req);
631   prs_mem_free(&rdata   );
632   prs_mem_free(&rparam  );
633
634   return valid_ack;
635 }
636
637 /****************************************************************************
638  open a session
639  ****************************************************************************/
640
641 BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name, BOOL encrypted)
642 {
643   RPC_IFACE abstract;
644   RPC_IFACE transfer;
645   int fnum;
646
647   /******************* open the pipe *****************/
648   if ((fnum = cli_open(cli, pipe_name, O_CREAT|O_RDWR, DENY_NONE)) == -1)
649   {
650     DEBUG(0,("cli_nt_session_open: cli_open failed on pipe %s to machine %s. \
651 Error was %s\n", pipe_name, cli->desthost, cli_errstr(cli)));
652     return False;
653   }
654
655   cli->nt_pipe_fnum = (uint16)fnum;
656
657   /**************** Set Named Pipe State ***************/
658   if (!rpc_pipe_set_hnd_state(cli, pipe_name, 0x4300))
659   {
660     DEBUG(0,("cli_nt_session_open: pipe hnd state failed. Error was %s\n",
661              cli_errstr(cli)));
662     cli_close(cli, cli->nt_pipe_fnum);
663     return False;
664   }
665
666   /******************* bind request on pipe *****************/
667   if (!rpc_pipe_bind(cli, pipe_name, &abstract, &transfer, encrypted))
668   {
669     DEBUG(0,("cli_nt_session_open: rpc bind failed. Error was %s\n", cli_errstr(cli)));
670     cli_close(cli, cli->nt_pipe_fnum);
671     return False;
672   }
673
674   /* 
675    * Setup the remote server name prefixed by \ and the machine account name.
676    */
677
678   fstrcpy(cli->srv_name_slash, "\\\\");
679   fstrcat(cli->srv_name_slash, cli->desthost);
680   strupper(cli->srv_name_slash);
681
682   fstrcpy(cli->clnt_name_slash, "\\\\");
683   fstrcat(cli->clnt_name_slash, global_myname);
684   strupper(cli->clnt_name_slash);
685
686   fstrcpy(cli->mach_acct, global_myname);
687   fstrcat(cli->mach_acct, "$");
688   strupper(cli->mach_acct);
689
690   return True;
691 }
692
693 /****************************************************************************
694 close the session
695 ****************************************************************************/
696
697 void cli_nt_session_close(struct cli_state *cli)
698 {
699   cli_close(cli, cli->nt_pipe_fnum);
700 }