dce/rpc
[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 *rhdr_auth,
293                                 prs_struct *auth_req,
294                                 prs_struct *auth_ntlm,
295                                 RPC_IFACE *abstract, RPC_IFACE *transfer,
296                                 char *my_name, char *domain)
297 {
298         RPC_HDR_RB           hdr_rb;
299         RPC_HDR              hdr;
300         RPC_HDR_AUTH         hdr_auth;
301         RPC_AUTH_VERIFIER    auth_verifier;
302         RPC_AUTH_NTLMSSP_NEG ntlmssp_neg;
303
304         /* create the bind request RPC_HDR_RB */
305         make_rpc_hdr_rb(&hdr_rb, 0x1630, 0x1630, 0x0,
306         0x1, 0x0, 0x1, abstract, transfer);
307
308         /* stream the bind request data */
309         smb_io_rpc_hdr_rb("", &hdr_rb,  rhdr_rb, 0);
310         mem_realloc_data(rhdr_rb->data, rhdr_rb->offset);
311
312         if (auth_req != NULL && rhdr_auth != NULL && auth_ntlm != NULL)
313         {
314                 make_rpc_hdr_auth(&hdr_auth, 0x0a, 0x06, 0x00);
315                 smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rhdr_auth, 0);
316                 mem_realloc_data(rhdr_auth->data, rhdr_auth->offset);
317
318                 make_rpc_auth_verifier(&auth_verifier,
319                                        "NTLMSSP", NTLMSSP_NEGOTIATE);
320
321                 smb_io_rpc_auth_verifier("auth_verifier", &auth_verifier, auth_req, 0);
322                 mem_realloc_data(auth_req->data, auth_req->offset);
323
324                 make_rpc_auth_ntlmssp_neg(&ntlmssp_neg,
325                                        0x0000b2b3, my_name, domain);
326
327                 smb_io_rpc_auth_ntlmssp_neg("ntlmssp_neg", &ntlmssp_neg, auth_req, 0);
328                 mem_realloc_data(auth_req->data, auth_req->offset);
329         }
330
331         /* create the request RPC_HDR */
332         make_rpc_hdr(&hdr, RPC_BIND, 0x0, get_rpc_call_id(),
333                      rhdr_rb->offset + 0x10,
334                      auth_req  != NULL ? auth_req ->offset : 0 +
335                      auth_ntlm != NULL ? auth_ntlm->offset : 0);
336
337         smb_io_rpc_hdr("hdr"   , &hdr   , rhdr, 0);
338         mem_realloc_data(rhdr->data, rhdr->offset);
339
340         if (rhdr->data == NULL || rhdr_rb->data == NULL) return False;
341
342         /***/
343         /*** link rpc header, bind acknowledgment and authentication responses ***/
344         /***/
345
346         if (auth_req != NULL)
347         {
348                 prs_link(NULL     , rhdr      , rhdr_rb  );
349                 prs_link(rhdr     , rhdr_rb   , rhdr_auth);
350                 prs_link(rhdr_rb  , rhdr_auth , auth_req );
351                 prs_link(rhdr_auth, auth_req  , auth_ntlm);
352                 prs_link(auth_req , auth_ntlm , NULL     );
353         }
354         else
355         {
356                 prs_link(NULL, rhdr   , rhdr_rb);
357                 prs_link(rhdr, rhdr_rb, 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 hdr_auth;
582         prs_struct auth_req;
583         prs_struct auth_ntlm;
584         prs_struct data;
585         prs_struct rdata;
586         prs_struct rparam;
587
588         BOOL valid_ack = False;
589
590         if (pipe_name == NULL || abstract == NULL || transfer == NULL)
591         return False;
592
593         DEBUG(5,("Bind RPC Pipe[%x]: %s\n", cli->nt_pipe_fnum, pipe_name));
594
595         if (!valid_pipe_name(pipe_name, abstract, transfer)) return False;
596
597         prs_init(&hdr      , 0x10                   , 4, 0x0          , False);
598         prs_init(&hdr_rb   , 1024                   , 4, SAFETY_MARGIN, False);
599         prs_init(&hdr_auth , ntlmssp_auth ?    8 : 0, 4, SAFETY_MARGIN, False);
600         prs_init(&auth_req , ntlmssp_auth ? 1024 : 0, 4, SAFETY_MARGIN, False);
601         prs_init(&auth_ntlm, ntlmssp_auth ? 1024 : 0, 4, SAFETY_MARGIN, False);
602
603         prs_init(&rdata , 0   , 4, SAFETY_MARGIN, True );
604         prs_init(&rparam, 0   , 4, SAFETY_MARGIN, True );
605
606         create_rpc_bind_req(&hdr, &hdr_rb,
607                             ntlmssp_auth ? &hdr_auth : NULL,
608                             ntlmssp_auth ? &auth_req : NULL,
609                             ntlmssp_auth ? &auth_ntlm : NULL,
610                             abstract, transfer, global_myname, global_myworkgroup);
611
612         /* this is a hack due to limitations in rpc_api_pipe */
613         prs_init(&data, mem_buf_len(hdr.data), 4, 0x0, False);
614         mem_buf_copy(data.data->data, hdr.data, 0, mem_buf_len(hdr.data));
615
616         /* send data on \PIPE\.  receive a response */
617         if (rpc_api_pipe(cli, 0x0026, NULL, &data, &rparam, &rdata))
618         {
619                 RPC_HDR_BA   hdr_ba;
620                 RPC_HDR_AUTH rhdr_auth;
621                 RPC_AUTH_VERIFIER rhdr_verf;
622                 RPC_AUTH_NTLMSSP_CHAL rhdr_chal;
623
624                 DEBUG(5, ("rpc_api_pipe: return OK\n"));
625
626                 smb_io_rpc_hdr_ba("", &hdr_ba, &rdata, 0);
627
628                 if (rdata.offset != 0)
629                 {
630                         valid_ack = check_bind_response(&hdr_ba, pipe_name, transfer);
631                 }
632
633                 if (valid_ack && ntlmssp_auth)
634                 {
635                         smb_io_rpc_hdr_auth("", &rhdr_auth, &rdata, 0);
636                         if (rdata.offset == 0) valid_ack = False;
637                 }
638
639                 if (valid_ack && ntlmssp_auth)
640                 {
641                         smb_io_rpc_auth_verifier("", &rhdr_verf, &rdata, 0);
642                         if (rdata.offset == 0) valid_ack = False;
643                 }
644                 if (valid_ack && ntlmssp_auth)
645                 {
646                         smb_io_rpc_auth_ntlmssp_chal("", &rhdr_chal, &rdata, 0);
647                         if (rdata.offset == 0) valid_ack = False;
648                 }
649         }
650
651         prs_mem_free(&data     );
652         prs_mem_free(&hdr      );
653         prs_mem_free(&hdr_rb   );
654         prs_mem_free(&hdr_auth );
655         prs_mem_free(&auth_req );
656         prs_mem_free(&auth_ntlm);
657         prs_mem_free(&rdata    );
658         prs_mem_free(&rparam   );
659
660         return valid_ack;
661 }
662
663 /****************************************************************************
664  open a session
665  ****************************************************************************/
666
667 BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name, BOOL encrypted)
668 {
669         RPC_IFACE abstract;
670         RPC_IFACE transfer;
671         int fnum;
672
673         /******************* open the pipe *****************/
674         if ((fnum = cli_open(cli, pipe_name, O_CREAT|O_RDWR, DENY_NONE)) == -1)
675         {
676                 DEBUG(0,("cli_nt_session_open: cli_open failed on pipe %s to machine %s.  Error was %s\n",
677                          pipe_name, cli->desthost, cli_errstr(cli)));
678                 return False;
679         }
680
681         cli->nt_pipe_fnum = (uint16)fnum;
682
683         /**************** Set Named Pipe State ***************/
684         if (!rpc_pipe_set_hnd_state(cli, pipe_name, 0x4300))
685         {
686                 DEBUG(0,("cli_nt_session_open: pipe hnd state failed.  Error was %s\n",
687                           cli_errstr(cli)));
688                 cli_close(cli, cli->nt_pipe_fnum);
689                 return False;
690         }
691
692         /******************* bind request on pipe *****************/
693         if (!rpc_pipe_bind(cli, pipe_name, &abstract, &transfer, encrypted))
694         {
695                 DEBUG(0,("cli_nt_session_open: rpc bind failed. Error was %s\n",
696                           cli_errstr(cli)));
697                 cli_close(cli, cli->nt_pipe_fnum);
698                 return False;
699         }
700
701         /* 
702         * Setup the remote server name prefixed by \ and the machine account name.
703         */
704
705         fstrcpy(cli->srv_name_slash, "\\\\");
706         fstrcat(cli->srv_name_slash, cli->desthost);
707         strupper(cli->srv_name_slash);
708
709         fstrcpy(cli->clnt_name_slash, "\\\\");
710         fstrcat(cli->clnt_name_slash, global_myname);
711         strupper(cli->clnt_name_slash);
712
713         fstrcpy(cli->mach_acct, global_myname);
714         fstrcat(cli->mach_acct, "$");
715         strupper(cli->mach_acct);
716
717         return True;
718 }
719
720 /****************************************************************************
721 close the session
722 ****************************************************************************/
723
724 void cli_nt_session_close(struct cli_state *cli)
725 {
726         cli_close(cli, cli->nt_pipe_fnum);
727 }