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