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