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