Fix up 'net ads join' to delete and rejoin if the account already exists.
[ira/wip.git] / source3 / libsmb / cliconnect.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 3.0
4    client connect/disconnect routines
5    Copyright (C) Andrew Tridgell 1994-1998
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #define NO_SYSLOG
23
24 #include "includes.h"
25
26
27 static const struct {
28     int prot;
29     const char *name;
30   }
31 prots[] = 
32     {
33       {PROTOCOL_CORE,"PC NETWORK PROGRAM 1.0"},
34       {PROTOCOL_COREPLUS,"MICROSOFT NETWORKS 1.03"},
35       {PROTOCOL_LANMAN1,"MICROSOFT NETWORKS 3.0"},
36       {PROTOCOL_LANMAN1,"LANMAN1.0"},
37       {PROTOCOL_LANMAN2,"LM1.2X002"},
38       {PROTOCOL_LANMAN2,"Samba"},
39       {PROTOCOL_NT1,"NT LANMAN 1.0"},
40       {PROTOCOL_NT1,"NT LM 0.12"},
41       {-1,NULL}
42     };
43
44
45 /****************************************************************************
46 do an old lanman2 style session setup
47 ****************************************************************************/
48 static BOOL cli_session_setup_lanman2(struct cli_state *cli, char *user, 
49                                       char *pass, int passlen)
50 {
51         fstring pword;
52         char *p;
53
54         if (passlen > sizeof(pword)-1) {
55                 return False;
56         }
57
58         /* if in share level security then don't send a password now */
59         if (!(cli->sec_mode & 1)) {
60                 passlen = 0;
61         }
62
63         if (passlen > 0 && (cli->sec_mode & 2) && passlen != 24) {
64                 /* Encrypted mode needed, and non encrypted password supplied. */
65                 passlen = 24;
66                 clistr_push(cli, pword, pass, -1, STR_TERMINATE);
67                 SMBencrypt((uchar *)pword,cli->secblob.data,(uchar *)pword);
68         } else if ((cli->sec_mode & 2) && passlen == 24) {
69                 /* Encrypted mode needed, and encrypted password supplied. */
70                 memcpy(pword, pass, passlen);
71         } else if (passlen > 0) {
72                 /* Plaintext mode needed, assume plaintext supplied. */
73                 passlen = clistr_push(cli, pword, pass, -1, STR_TERMINATE);
74         }
75
76         /* send a session setup command */
77         memset(cli->outbuf,'\0',smb_size);
78         set_message(cli->outbuf,10, 0, True);
79         CVAL(cli->outbuf,smb_com) = SMBsesssetupX;
80         cli_setup_packet(cli);
81         
82         CVAL(cli->outbuf,smb_vwv0) = 0xFF;
83         SSVAL(cli->outbuf,smb_vwv2,cli->max_xmit);
84         SSVAL(cli->outbuf,smb_vwv3,2);
85         SSVAL(cli->outbuf,smb_vwv4,1);
86         SIVAL(cli->outbuf,smb_vwv5,cli->sesskey);
87         SSVAL(cli->outbuf,smb_vwv7,passlen);
88
89         p = smb_buf(cli->outbuf);
90         memcpy(p,pword,passlen);
91         p += passlen;
92         p += clistr_push(cli, p, user, -1, STR_TERMINATE);
93         cli_setup_bcc(cli, p);
94
95         cli_send_smb(cli);
96         if (!cli_receive_smb(cli))
97                 return False;
98
99         show_msg(cli->inbuf);
100
101         if (cli_is_error(cli)) {
102                 return False;
103         }
104         
105         /* use the returned vuid from now on */
106         cli->vuid = SVAL(cli->inbuf,smb_uid);   
107         fstrcpy(cli->user_name, user);
108
109         return True;
110 }
111
112
113 /****************************************************************************
114 work out suitable capabilities to offer the server
115 ****************************************************************************/
116 static uint32 cli_session_setup_capabilities(struct cli_state *cli)
117 {
118         uint32 capabilities = CAP_NT_SMBS;
119
120         if (!cli->force_dos_errors) {
121                 capabilities |= CAP_STATUS32;
122         }
123
124         if (cli->use_level_II_oplocks) {
125                 capabilities |= CAP_LEVEL_II_OPLOCKS;
126         }
127
128         if (cli->capabilities & CAP_UNICODE) {
129                 capabilities |= CAP_UNICODE;
130         }
131
132         return capabilities;
133 }
134
135
136 /****************************************************************************
137 do a NT1 guest session setup
138 ****************************************************************************/
139 static BOOL cli_session_setup_guest(struct cli_state *cli)
140 {
141         char *p;
142         uint32 capabilities = cli_session_setup_capabilities(cli);
143
144         set_message(cli->outbuf,13,0,True);
145         CVAL(cli->outbuf,smb_com) = SMBsesssetupX;
146         cli_setup_packet(cli);
147                         
148         CVAL(cli->outbuf,smb_vwv0) = 0xFF;
149         SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE);
150         SSVAL(cli->outbuf,smb_vwv3,2);
151         SSVAL(cli->outbuf,smb_vwv4,cli->pid);
152         SIVAL(cli->outbuf,smb_vwv5,cli->sesskey);
153         SSVAL(cli->outbuf,smb_vwv7,0);
154         SSVAL(cli->outbuf,smb_vwv8,0);
155         SIVAL(cli->outbuf,smb_vwv11,capabilities); 
156         p = smb_buf(cli->outbuf);
157         p += clistr_push(cli, p, "", -1, STR_TERMINATE); /* username */
158         p += clistr_push(cli, p, "", -1, STR_TERMINATE); /* workgroup */
159         p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE);
160         p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE);
161         cli_setup_bcc(cli, p);
162
163         cli_send_smb(cli);
164         if (!cli_receive_smb(cli))
165               return False;
166         
167         show_msg(cli->inbuf);
168         
169         if (cli_is_error(cli)) {
170                 return False;
171         }
172
173         cli->vuid = SVAL(cli->inbuf,smb_uid);
174
175         p = smb_buf(cli->inbuf);
176         p += clistr_pull(cli, cli->server_os, p, sizeof(fstring), -1, STR_TERMINATE);
177         p += clistr_pull(cli, cli->server_type, p, sizeof(fstring), -1, STR_TERMINATE);
178         p += clistr_pull(cli, cli->server_domain, p, sizeof(fstring), -1, STR_TERMINATE);
179
180         fstrcpy(cli->user_name, "");
181
182         return True;
183 }
184
185
186 /****************************************************************************
187 do a NT1 plaintext session setup
188 ****************************************************************************/
189 static BOOL cli_session_setup_plaintext(struct cli_state *cli, char *user, 
190                                         char *pass, char *workgroup)
191 {
192         uint32 capabilities = cli_session_setup_capabilities(cli);
193         fstring pword;
194         int passlen;
195         char *p;
196
197         passlen = clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE|STR_ASCII);
198
199         set_message(cli->outbuf,13,0,True);
200         CVAL(cli->outbuf,smb_com) = SMBsesssetupX;
201         cli_setup_packet(cli);
202                         
203         CVAL(cli->outbuf,smb_vwv0) = 0xFF;
204         SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE);
205         SSVAL(cli->outbuf,smb_vwv3,2);
206         SSVAL(cli->outbuf,smb_vwv4,cli->pid);
207         SIVAL(cli->outbuf,smb_vwv5,cli->sesskey);
208         SSVAL(cli->outbuf,smb_vwv7,passlen);
209         SSVAL(cli->outbuf,smb_vwv8,0);
210         SIVAL(cli->outbuf,smb_vwv11,capabilities); 
211         p = smb_buf(cli->outbuf);
212         memcpy(p, pword, passlen);
213         p += passlen;
214         p += clistr_push(cli, p, user, -1, STR_TERMINATE); /* username */
215         p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE); /* workgroup */
216         p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE);
217         p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE);
218         cli_setup_bcc(cli, p);
219
220         cli_send_smb(cli);
221         if (!cli_receive_smb(cli))
222               return False;
223         
224         show_msg(cli->inbuf);
225         
226         if (cli_is_error(cli)) {
227                 return False;
228         }
229
230         cli->vuid = SVAL(cli->inbuf,smb_uid);
231         p = smb_buf(cli->inbuf);
232         p += clistr_pull(cli, cli->server_os, p, sizeof(fstring), -1, STR_TERMINATE);
233         p += clistr_pull(cli, cli->server_type, p, sizeof(fstring), -1, STR_TERMINATE);
234         p += clistr_pull(cli, cli->server_domain, p, sizeof(fstring), -1, STR_TERMINATE);
235         fstrcpy(cli->user_name, user);
236
237         return True;
238 }
239
240
241 /****************************************************************************
242 do a NT1 NTLM/LM encrypted session setup
243 ****************************************************************************/
244 static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, 
245                                   char *pass, int passlen,
246                                   char *ntpass, int ntpasslen,
247                                   char *workgroup)
248 {
249         uint32 capabilities = cli_session_setup_capabilities(cli);
250         fstring pword, ntpword;
251         char *p;
252
253         if (passlen > sizeof(pword)-1 || ntpasslen > sizeof(ntpword)-1) {
254                 return False;
255         }
256
257         if (passlen != 24) {
258                 /* non encrypted password supplied. Ignore ntpass. */
259                 passlen = 24;
260                 ntpasslen = 24;
261                 clistr_push(cli, pword, 
262                             pass?pass:"", sizeof(pword), STR_TERMINATE|STR_ASCII);
263                 clistr_push(cli, ntpword, 
264                             pass?pass:"", sizeof(ntpword), STR_TERMINATE|STR_ASCII);
265                 SMBencrypt((uchar *)pword,cli->secblob.data,(uchar *)pword);
266                 SMBNTencrypt((uchar *)ntpword,cli->secblob.data,(uchar *)ntpword);
267         } else {
268                 memcpy(pword, pass, passlen);
269                 memcpy(ntpword, ntpass, ntpasslen);
270         }
271
272         /* send a session setup command */
273         memset(cli->outbuf,'\0',smb_size);
274
275         set_message(cli->outbuf,13,0,True);
276         CVAL(cli->outbuf,smb_com) = SMBsesssetupX;
277         cli_setup_packet(cli);
278                         
279         CVAL(cli->outbuf,smb_vwv0) = 0xFF;
280         SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE);
281         SSVAL(cli->outbuf,smb_vwv3,2);
282         SSVAL(cli->outbuf,smb_vwv4,cli->pid);
283         SIVAL(cli->outbuf,smb_vwv5,cli->sesskey);
284         SSVAL(cli->outbuf,smb_vwv7,passlen);
285         SSVAL(cli->outbuf,smb_vwv8,ntpasslen);
286         SIVAL(cli->outbuf,smb_vwv11,capabilities); 
287         p = smb_buf(cli->outbuf);
288         memcpy(p,pword,passlen); p += passlen;
289         memcpy(p,ntpword,ntpasslen); p += ntpasslen;
290         p += clistr_push(cli, p, user, -1, STR_TERMINATE|STR_UPPER);
291         p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE|STR_UPPER);
292         p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE);
293         p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE);
294         cli_setup_bcc(cli, p);
295
296         cli_send_smb(cli);
297         if (!cli_receive_smb(cli))
298                 return False;
299
300         show_msg(cli->inbuf);
301
302         if (cli_is_error(cli)) {
303                 return False;
304         }
305         
306         /* use the returned vuid from now on */
307         cli->vuid = SVAL(cli->inbuf,smb_uid);
308         
309         p = smb_buf(cli->inbuf);
310         p += clistr_pull(cli, cli->server_os, p, sizeof(fstring), -1, STR_TERMINATE);
311         p += clistr_pull(cli, cli->server_type, p, sizeof(fstring), -1, STR_TERMINATE);
312         p += clistr_pull(cli, cli->server_domain, p, sizeof(fstring), -1, STR_TERMINATE);
313
314         fstrcpy(cli->user_name, user);
315
316         return True;
317 }
318
319
320 /****************************************************************************
321 send a extended security session setup blob, returning a reply blob
322 ****************************************************************************/
323 static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob)
324 {
325         uint32 capabilities = cli_session_setup_capabilities(cli);
326         char *p;
327         DATA_BLOB blob2;
328         uint32 len;
329
330         blob2 = data_blob(NULL, 0);
331
332         capabilities |= CAP_EXTENDED_SECURITY;
333
334         /* send a session setup command */
335         memset(cli->outbuf,'\0',smb_size);
336
337         set_message(cli->outbuf,12,0,True);
338         CVAL(cli->outbuf,smb_com) = SMBsesssetupX;
339         cli_setup_packet(cli);
340                         
341         CVAL(cli->outbuf,smb_vwv0) = 0xFF;
342         SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE);
343         SSVAL(cli->outbuf,smb_vwv3,2);
344         SSVAL(cli->outbuf,smb_vwv4,1);
345         SIVAL(cli->outbuf,smb_vwv5,0);
346         SSVAL(cli->outbuf,smb_vwv7,blob.length);
347         SIVAL(cli->outbuf,smb_vwv10,capabilities); 
348         p = smb_buf(cli->outbuf);
349         memcpy(p, blob.data, blob.length);
350         p += blob.length;
351         p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE);
352         p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE);
353         cli_setup_bcc(cli, p);
354
355         cli_send_smb(cli);
356         if (!cli_receive_smb(cli))
357                 return blob2;
358
359         show_msg(cli->inbuf);
360
361         if (cli_is_error(cli) && !NT_STATUS_EQUAL(cli_nt_error(cli),
362                                                   NT_STATUS_MORE_PROCESSING_REQUIRED)) {
363                 return blob2;
364         }
365         
366         /* use the returned vuid from now on */
367         cli->vuid = SVAL(cli->inbuf,smb_uid);
368         
369         p = smb_buf(cli->inbuf);
370
371         blob2 = data_blob(p, SVAL(cli->inbuf, smb_vwv3));
372
373         p += blob2.length;
374         p += clistr_pull(cli, cli->server_os, p, sizeof(fstring), -1, STR_TERMINATE);
375
376         /* w2k with kerberos doesn't properly null terminate this field */
377         len = smb_buflen(cli->inbuf) - PTR_DIFF(p, smb_buf(cli->inbuf));
378         p += clistr_pull(cli, cli->server_type, p, sizeof(fstring), len, 0);
379
380         return blob2;
381 }
382
383
384 #ifdef HAVE_KRB5
385 /****************************************************************************
386 do a spnego/kerberos encrypted session setup
387 ****************************************************************************/
388 static BOOL cli_session_setup_kerberos(struct cli_state *cli, char *principal, char *workgroup)
389 {
390         DATA_BLOB blob2, negTokenTarg;
391
392         DEBUG(2,("Doing kerberos session setup\n"));
393
394         /* generate the encapsulated kerberos5 ticket */
395         negTokenTarg = spnego_gen_negTokenTarg(cli, principal);
396
397         if (!negTokenTarg.data) return False;
398
399 #if 0
400         file_save("negTokenTarg.dat", negTokenTarg.data, negTokenTarg.length);
401 #endif
402
403         blob2 = cli_session_setup_blob(cli, negTokenTarg);
404
405         /* we don't need this blob for kerberos */
406         data_blob_free(&blob2);
407
408         data_blob_free(&negTokenTarg);
409
410         return !cli_is_error(cli);
411 }
412 #endif
413
414 /****************************************************************************
415 do a spnego/NTLMSSP encrypted session setup
416 ****************************************************************************/
417 static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user, 
418                                       char *pass, char *workgroup)
419 {
420         const char *mechs[] = {OID_NTLMSSP, NULL};
421         DATA_BLOB msg1;
422         DATA_BLOB blob, chal1, chal2, auth;
423         uint8 challenge[8];
424         uint8 nthash[24], lmhash[24], sess_key[16];
425         uint32 neg_flags;
426
427         neg_flags = NTLMSSP_NEGOTIATE_UNICODE | 
428                 NTLMSSP_NEGOTIATE_LM_KEY | 
429                 NTLMSSP_NEGOTIATE_NTLM;
430
431         memset(sess_key, 0, 16);
432
433         /* generate the ntlmssp negotiate packet */
434         msrpc_gen(&blob, "CddB",
435                   "NTLMSSP",
436                   NTLMSSP_NEGOTIATE,
437                   neg_flags,
438                   sess_key, 16);
439
440         /* and wrap it in a SPNEGO wrapper */
441         msg1 = gen_negTokenTarg(mechs, blob);
442         data_blob_free(&blob);
443
444         /* now send that blob on its way */
445         blob = cli_session_setup_blob(cli, msg1);
446
447         data_blob_free(&msg1);
448
449         if (!NT_STATUS_EQUAL(cli_nt_error(cli), NT_STATUS_MORE_PROCESSING_REQUIRED)) {
450                 return False;
451         }
452
453 #if 0
454         file_save("chal.dat", blob.data, blob.length);
455 #endif
456
457         /* the server gives us back two challenges */
458         if (!spnego_parse_challenge(blob, &chal1, &chal2)) {
459                 DEBUG(3,("Failed to parse challenges\n"));
460                 return False;
461         }
462
463         data_blob_free(&blob);
464
465         /* encrypt the password with the challenge */
466         memcpy(challenge, chal1.data + 24, 8);
467         SMBencrypt((unsigned char *)pass, challenge,lmhash);
468         SMBNTencrypt((unsigned char *)pass, challenge,nthash);
469
470 #if 0
471         file_save("nthash.dat", nthash, 24);
472         file_save("lmhash.dat", lmhash, 24);
473         file_save("chal1.dat", chal1.data, chal1.length);
474 #endif
475
476         data_blob_free(&chal1);
477         data_blob_free(&chal2);
478
479         /* this generates the actual auth packet */
480         msrpc_gen(&blob, "CdBBUUUBd", 
481                   "NTLMSSP", 
482                   NTLMSSP_AUTH, 
483                   lmhash, 24,
484                   nthash, 24,
485                   workgroup, 
486                   user, 
487                   cli->calling.name,
488                   sess_key, 16,
489                   neg_flags);
490
491         /* wrap it in SPNEGO */
492         auth = spnego_gen_auth(blob);
493
494         data_blob_free(&blob);
495
496         /* now send the auth packet and we should be done */
497         blob = cli_session_setup_blob(cli, auth);
498
499         data_blob_free(&auth);
500         data_blob_free(&blob);
501
502         return !cli_is_error(cli);
503 }
504
505
506 /****************************************************************************
507 do a spnego encrypted session setup
508 ****************************************************************************/
509 static BOOL cli_session_setup_spnego(struct cli_state *cli, char *user, 
510                                      char *pass, char *workgroup)
511 {
512         char *principal;
513         char *OIDs[ASN1_MAX_OIDS];
514         uint8 guid[16];
515         int i;
516         BOOL got_kerberos_mechanism = False;
517
518         DEBUG(2,("Doing spnego session setup (blob length=%d)\n", cli->secblob.length));
519
520         /* the server might not even do spnego */
521         if (cli->secblob.length == 16) {
522                 DEBUG(3,("server didn't supply a full spnego negprot\n"));
523                 goto ntlmssp;
524         }
525
526 #if 0
527         file_save("negprot.dat", cli->secblob.data, cli->secblob.length);
528 #endif
529
530         /* the server sent us the first part of the SPNEGO exchange in the negprot 
531            reply */
532         if (!spnego_parse_negTokenInit(cli->secblob, guid, OIDs, &principal)) {
533                 return False;
534         }
535
536         /* make sure the server understands kerberos */
537         for (i=0;OIDs[i];i++) {
538                 DEBUG(3,("got OID=%s\n", OIDs[i]));
539                 if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0 ||
540                     strcmp(OIDs[i], OID_KERBEROS5) == 0) {
541                         got_kerberos_mechanism = True;
542                 }
543                 free(OIDs[i]);
544         }
545         DEBUG(3,("got principal=%s\n", principal));
546
547         fstrcpy(cli->user_name, user);
548
549 #ifdef HAVE_KRB5
550         if (got_kerberos_mechanism && cli->use_kerberos) {
551                 return cli_session_setup_kerberos(cli, principal, workgroup);
552         }
553 #endif
554
555         free(principal);
556
557 ntlmssp:
558
559         return cli_session_setup_ntlmssp(cli, user, pass, workgroup);
560 }
561
562
563 /****************************************************************************
564  Send a session setup. The username and workgroup is in UNIX character
565  format and must be converted to DOS codepage format before sending. If the
566  password is in plaintext, the same should be done.
567 ****************************************************************************/
568 BOOL cli_session_setup(struct cli_state *cli, 
569                        char *user, 
570                        char *pass, int passlen,
571                        char *ntpass, int ntpasslen,
572                        char *workgroup)
573 {
574         char *p;
575         fstring user2;
576
577         /* allow for workgroups as part of the username */
578         fstrcpy(user2, user);
579         if ((p=strchr_m(user2,'\\')) || (p=strchr_m(user2,'/')) ||
580             (p=strchr_m(user2,*lp_winbind_separator()))) {
581                 *p = 0;
582                 user = p+1;
583                 workgroup = user2;
584         }
585
586         if (cli->protocol < PROTOCOL_LANMAN1)
587                 return True;
588
589         /* now work out what sort of session setup we are going to
590            do. I have split this into separate functions to make the
591            flow a bit easier to understand (tridge) */
592
593         /* if its an older server then we have to use the older request format */
594         if (cli->protocol < PROTOCOL_NT1) {
595                 return cli_session_setup_lanman2(cli, user, pass, passlen);
596         }
597
598         /* if no user is supplied then we have to do an anonymous connection.
599            passwords are ignored */
600         if (!user || !*user) {
601                 return cli_session_setup_guest(cli);
602         }
603
604         /* if the server is share level then send a plaintext null
605            password at this point. The password is sent in the tree
606            connect */
607         if ((cli->sec_mode & 1) == 0) {
608                 return cli_session_setup_plaintext(cli, user, "", workgroup);
609         }
610
611         /* if the server doesn't support encryption then we have to use plaintext. The 
612            second password is ignored */
613         if ((cli->sec_mode & 2) == 0) {
614                 return cli_session_setup_plaintext(cli, user, pass, workgroup);
615         }
616
617         /* if the server supports extended security then use SPNEGO */
618         if (cli->capabilities & CAP_EXTENDED_SECURITY) {
619                 return cli_session_setup_spnego(cli, user, pass, workgroup);
620         }
621
622         /* otherwise do a NT1 style session setup */
623         return cli_session_setup_nt1(cli, user, 
624                                      pass, passlen, ntpass, ntpasslen,
625                                      workgroup);        
626 }
627
628 /****************************************************************************
629  Send a uloggoff.
630 *****************************************************************************/
631
632 BOOL cli_ulogoff(struct cli_state *cli)
633 {
634         memset(cli->outbuf,'\0',smb_size);
635         set_message(cli->outbuf,2,0,True);
636         CVAL(cli->outbuf,smb_com) = SMBulogoffX;
637         cli_setup_packet(cli);
638         SSVAL(cli->outbuf,smb_vwv0,0xFF);
639         SSVAL(cli->outbuf,smb_vwv2,0);  /* no additional info */
640
641         cli_send_smb(cli);
642         if (!cli_receive_smb(cli))
643                 return False;
644
645         return !cli_is_error(cli);
646 }
647
648 /****************************************************************************
649 send a tconX
650 ****************************************************************************/
651 BOOL cli_send_tconX(struct cli_state *cli, 
652                     const char *share, const char *dev, const char *pass, int passlen)
653 {
654         fstring fullshare, pword, dos_pword;
655         char *p;
656         memset(cli->outbuf,'\0',smb_size);
657         memset(cli->inbuf,'\0',smb_size);
658
659         fstrcpy(cli->share, share);
660
661         /* in user level security don't send a password now */
662         if (cli->sec_mode & 1) {
663                 passlen = 1;
664                 pass = "";
665         }
666
667         if ((cli->sec_mode & 2) && *pass && passlen != 24) {
668                 /*
669                  * Non-encrypted passwords - convert to DOS codepage before encryption.
670                  */
671                 passlen = 24;
672                 clistr_push(cli, dos_pword, pass, -1, STR_TERMINATE);
673                 SMBencrypt((uchar *)dos_pword,cli->secblob.data,(uchar *)pword);
674         } else {
675                 if((cli->sec_mode & 3) == 0) {
676                         /*
677                          * Non-encrypted passwords - convert to DOS codepage before using.
678                          */
679                         passlen = clistr_push(cli, pword, pass, -1, STR_TERMINATE);
680                 } else {
681                         memcpy(pword, pass, passlen);
682                 }
683         }
684
685         if (cli->port == 445) {
686                 slprintf(fullshare, sizeof(fullshare)-1,
687                          "%s", share);
688         } else {
689                 slprintf(fullshare, sizeof(fullshare)-1,
690                          "\\\\%s\\%s", cli->desthost, share);
691         }
692
693         set_message(cli->outbuf,4, 0, True);
694         CVAL(cli->outbuf,smb_com) = SMBtconX;
695         cli_setup_packet(cli);
696
697         SSVAL(cli->outbuf,smb_vwv0,0xFF);
698         SSVAL(cli->outbuf,smb_vwv3,passlen);
699
700         p = smb_buf(cli->outbuf);
701         memcpy(p,pword,passlen);
702         p += passlen;
703         p += clistr_push(cli, p, fullshare, -1, STR_TERMINATE |STR_UPPER);
704         fstrcpy(p, dev); p += strlen(dev)+1;
705
706         cli_setup_bcc(cli, p);
707
708         cli_send_smb(cli);
709         if (!cli_receive_smb(cli))
710                 return False;
711
712         if (cli_is_error(cli)) {
713                 return False;
714         }
715
716         clistr_pull(cli, cli->dev, smb_buf(cli->inbuf), sizeof(fstring), -1, STR_TERMINATE|STR_ASCII);
717
718         if (strcasecmp(share,"IPC$")==0) {
719                 fstrcpy(cli->dev, "IPC");
720         }
721
722         if (cli->protocol >= PROTOCOL_NT1 &&
723             smb_buflen(cli->inbuf) == 3) {
724                 /* almost certainly win95 - enable bug fixes */
725                 cli->win95 = True;
726         }
727
728         cli->cnum = SVAL(cli->inbuf,smb_tid);
729         return True;
730 }
731
732
733 /****************************************************************************
734 send a tree disconnect
735 ****************************************************************************/
736 BOOL cli_tdis(struct cli_state *cli)
737 {
738         memset(cli->outbuf,'\0',smb_size);
739         set_message(cli->outbuf,0,0,True);
740         CVAL(cli->outbuf,smb_com) = SMBtdis;
741         SSVAL(cli->outbuf,smb_tid,cli->cnum);
742         cli_setup_packet(cli);
743         
744         cli_send_smb(cli);
745         if (!cli_receive_smb(cli))
746                 return False;
747         
748         return !cli_is_error(cli);
749 }
750
751
752 /****************************************************************************
753 send a negprot command
754 ****************************************************************************/
755 void cli_negprot_send(struct cli_state *cli)
756 {
757         char *p;
758         int numprots;
759
760         memset(cli->outbuf,'\0',smb_size);
761
762         /* setup the protocol strings */
763         set_message(cli->outbuf,0,0,True);
764
765         p = smb_buf(cli->outbuf);
766         for (numprots=0;
767              prots[numprots].name && prots[numprots].prot<=cli->protocol;
768              numprots++) {
769                 *p++ = 2;
770                 p += clistr_push(cli, p, prots[numprots].name, -1, STR_TERMINATE);
771         }
772
773         CVAL(cli->outbuf,smb_com) = SMBnegprot;
774         cli_setup_bcc(cli, p);
775         cli_setup_packet(cli);
776
777         CVAL(smb_buf(cli->outbuf),0) = 2;
778
779         cli_send_smb(cli);
780 }
781
782
783 /****************************************************************************
784 send a negprot command
785 ****************************************************************************/
786 BOOL cli_negprot(struct cli_state *cli)
787 {
788         char *p;
789         int numprots;
790         int plength;
791
792         memset(cli->outbuf,'\0',smb_size);
793
794         /* setup the protocol strings */
795         for (plength=0,numprots=0;
796              prots[numprots].name && prots[numprots].prot<=cli->protocol;
797              numprots++)
798                 plength += strlen(prots[numprots].name)+2;
799     
800         set_message(cli->outbuf,0,plength,True);
801
802         p = smb_buf(cli->outbuf);
803         for (numprots=0;
804              prots[numprots].name && prots[numprots].prot<=cli->protocol;
805              numprots++) {
806                 *p++ = 2;
807                 p += clistr_push(cli, p, prots[numprots].name, -1, STR_TERMINATE);
808         }
809
810         CVAL(cli->outbuf,smb_com) = SMBnegprot;
811         cli_setup_packet(cli);
812
813         CVAL(smb_buf(cli->outbuf),0) = 2;
814
815         cli_send_smb(cli);
816         if (!cli_receive_smb(cli))
817                 return False;
818
819         show_msg(cli->inbuf);
820
821         if (cli_is_error(cli) ||
822             ((int)SVAL(cli->inbuf,smb_vwv0) >= numprots)) {
823                 return(False);
824         }
825
826         cli->protocol = prots[SVAL(cli->inbuf,smb_vwv0)].prot;
827
828         if (cli->protocol >= PROTOCOL_NT1) {    
829                 /* NT protocol */
830                 cli->sec_mode = CVAL(cli->inbuf,smb_vwv1);
831                 cli->max_mux = SVAL(cli->inbuf, smb_vwv1+1);
832                 cli->max_xmit = IVAL(cli->inbuf,smb_vwv3+1);
833                 cli->sesskey = IVAL(cli->inbuf,smb_vwv7+1);
834                 cli->serverzone = SVALS(cli->inbuf,smb_vwv15+1);
835                 cli->serverzone *= 60;
836                 /* this time arrives in real GMT */
837                 cli->servertime = interpret_long_date(cli->inbuf+smb_vwv11+1);
838                 cli->secblob = data_blob(smb_buf(cli->inbuf),smb_buflen(cli->inbuf));
839                 cli->capabilities = IVAL(cli->inbuf,smb_vwv9+1);
840                 if (cli->capabilities & CAP_RAW_MODE) {
841                         cli->readbraw_supported = True;
842                         cli->writebraw_supported = True;      
843                 }
844                 /* work out if they sent us a workgroup */
845                 if (!(cli->capabilities & CAP_EXTENDED_SECURITY) &&
846                     smb_buflen(cli->inbuf) > 8) {
847                         clistr_pull(cli, cli->server_domain, 
848                                     smb_buf(cli->inbuf)+8, sizeof(cli->server_domain),
849                                     smb_buflen(cli->inbuf)-8, STR_UNICODE|STR_NOALIGN);
850                 }
851         } else if (cli->protocol >= PROTOCOL_LANMAN1) {
852                 cli->sec_mode = SVAL(cli->inbuf,smb_vwv1);
853                 cli->max_xmit = SVAL(cli->inbuf,smb_vwv2);
854                 cli->sesskey = IVAL(cli->inbuf,smb_vwv6);
855                 cli->serverzone = SVALS(cli->inbuf,smb_vwv10);
856                 cli->serverzone *= 60;
857                 /* this time is converted to GMT by make_unix_date */
858                 cli->servertime = make_unix_date(cli->inbuf+smb_vwv8);
859                 cli->readbraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x1) != 0);
860                 cli->writebraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x2) != 0);
861                 cli->secblob = data_blob(smb_buf(cli->inbuf),smb_buflen(cli->inbuf));
862         } else {
863                 /* the old core protocol */
864                 cli->sec_mode = 0;
865                 cli->serverzone = TimeDiff(time(NULL));
866         }
867
868         cli->max_xmit = MIN(cli->max_xmit, CLI_BUFFER_SIZE);
869
870         /* a way to force ascii SMB */
871         if (getenv("CLI_FORCE_ASCII")) {
872                 cli->capabilities &= ~CAP_UNICODE;
873         }
874
875         return True;
876 }
877
878
879 /****************************************************************************
880   send a session request.  see rfc1002.txt 4.3 and 4.3.2
881 ****************************************************************************/
882 BOOL cli_session_request(struct cli_state *cli,
883                          struct nmb_name *calling, struct nmb_name *called)
884 {
885         char *p;
886         int len = 4;
887         extern pstring user_socket_options;
888
889         /* 445 doesn't have session request */
890         if (cli->port == 445) return True;
891
892         /* send a session request (RFC 1002) */
893         memcpy(&(cli->calling), calling, sizeof(*calling));
894         memcpy(&(cli->called ), called , sizeof(*called ));
895   
896         /* put in the destination name */
897         p = cli->outbuf+len;
898         name_mangle(cli->called .name, p, cli->called .name_type);
899         len += name_len(p);
900
901         /* and my name */
902         p = cli->outbuf+len;
903         name_mangle(cli->calling.name, p, cli->calling.name_type);
904         len += name_len(p);
905
906         /* setup the packet length */
907         _smb_setlen(cli->outbuf,len);
908         CVAL(cli->outbuf,0) = 0x81;
909
910 #ifdef WITH_SSL
911 retry:
912 #endif /* WITH_SSL */
913
914         cli_send_smb(cli);
915         DEBUG(5,("Sent session request\n"));
916
917         if (!cli_receive_smb(cli))
918                 return False;
919
920         if (CVAL(cli->inbuf,0) == 0x84) {
921                 /* C. Hoch  9/14/95 Start */
922                 /* For information, here is the response structure.
923                  * We do the byte-twiddling to for portability.
924                 struct RetargetResponse{
925                 unsigned char type;
926                 unsigned char flags;
927                 int16 length;
928                 int32 ip_addr;
929                 int16 port;
930                 };
931                 */
932                 int port = (CVAL(cli->inbuf,8)<<8)+CVAL(cli->inbuf,9);
933                 /* SESSION RETARGET */
934                 putip((char *)&cli->dest_ip,cli->inbuf+4);
935
936                 cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, port, LONG_CONNECT_TIMEOUT);
937                 if (cli->fd == -1)
938                         return False;
939
940                 DEBUG(3,("Retargeted\n"));
941
942                 set_socket_options(cli->fd,user_socket_options);
943
944                 /* Try again */
945                 {
946                         static int depth;
947                         BOOL ret;
948                         if (depth > 4) {
949                                 DEBUG(0,("Retarget recursion - failing\n"));
950                                 return False;
951                         }
952                         depth++;
953                         ret = cli_session_request(cli, calling, called);
954                         depth--;
955                         return ret;
956                 }
957         } /* C. Hoch 9/14/95 End */
958
959 #ifdef WITH_SSL
960     if (CVAL(cli->inbuf,0) == 0x83 && CVAL(cli->inbuf,4) == 0x8e){ /* use ssl */
961         if (!sslutil_fd_is_ssl(cli->fd)){
962             if (sslutil_connect(cli->fd) == 0)
963                 goto retry;
964         }
965     }
966 #endif /* WITH_SSL */
967
968         if (CVAL(cli->inbuf,0) != 0x82) {
969                 /* This is the wrong place to put the error... JRA. */
970                 cli->rap_error = CVAL(cli->inbuf,4);
971                 return False;
972         }
973         return(True);
974 }
975
976 /****************************************************************************
977 open the client sockets
978 ****************************************************************************/
979 BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip)
980 {
981         extern pstring user_socket_options;
982         int name_type = 0x20;
983         char *p;
984
985         /* reasonable default hostname */
986         if (!host) host = "*SMBSERVER";
987
988         fstrcpy(cli->desthost, host);
989
990         /* allow hostnames of the form NAME#xx and do a netbios lookup */
991         if ((p = strchr(cli->desthost, '#'))) {
992                 name_type = strtol(p+1, NULL, 16);              
993                 *p = 0;
994         }
995         
996         if (!ip || is_zero_ip(*ip)) {
997                 if (!resolve_name(cli->desthost, &cli->dest_ip, name_type)) {
998                         return False;
999                 }
1000                 if (ip) *ip = cli->dest_ip;
1001         } else {
1002                 cli->dest_ip = *ip;
1003         }
1004
1005         if (getenv("LIBSMB_PROG")) {
1006                 cli->fd = sock_exec(getenv("LIBSMB_PROG"));
1007         } else {
1008                 /* try 445 first, then 139 */
1009                 int port = cli->port?cli->port:445;
1010                 cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, 
1011                                           port, cli->timeout);
1012                 if (cli->fd == -1 && cli->port == 0) {
1013                         port = 139;
1014                         cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, 
1015                                                   port, cli->timeout);
1016                 }
1017                 if (cli->fd != -1) cli->port = port;
1018         }
1019         if (cli->fd == -1) {
1020                 DEBUG(1,("Error connecting to %s (%s)\n",
1021                          inet_ntoa(*ip),strerror(errno)));
1022                 return False;
1023         }
1024
1025         set_socket_options(cli->fd,user_socket_options);
1026
1027         return True;
1028 }
1029
1030 /****************************************************************************
1031 establishes a connection right up to doing tconX, password in cache.
1032 ****************************************************************************/
1033 BOOL cli_establish_connection(struct cli_state *cli, 
1034                                 char *dest_host, struct in_addr *dest_ip,
1035                                 struct nmb_name *calling, struct nmb_name *called,
1036                                 char *service, char *service_type,
1037                                 BOOL do_shutdown, BOOL do_tcon)
1038 {
1039         DEBUG(5,("cli_establish_connection: %s connecting to %s (%s) - %s [%s]\n",
1040                           nmb_namestr(calling), nmb_namestr(called), inet_ntoa(*dest_ip),
1041                       cli->user_name, cli->domain));
1042
1043         /* establish connection */
1044
1045         if ((!cli->initialised))
1046         {
1047                 return False;
1048         }
1049
1050         /* cli_establish_connection() can't handle spnego yet. Once we get rid of
1051            pwd_cache and other horrors we can get rid of this */
1052         cli->use_spnego = False;
1053
1054         if (cli->fd == -1)
1055         {
1056                 if (!cli_connect(cli, dest_host, dest_ip))
1057                 {
1058                         DEBUG(1,("cli_establish_connection: failed to connect to %s (%s)\n",
1059                                           nmb_namestr(called), inet_ntoa(*dest_ip)));
1060                         return False;
1061                 }
1062         }
1063
1064         if (!cli_session_request(cli, calling, called))
1065         {
1066                 DEBUG(1,("failed session request\n"));
1067                 if (do_shutdown)
1068                         cli_shutdown(cli);
1069                 return False;
1070         }
1071
1072         if (!cli_negprot(cli))
1073         {
1074                 DEBUG(1,("failed negprot\n"));
1075                 if (do_shutdown)
1076                         cli_shutdown(cli);
1077                 return False;
1078         }
1079
1080         if (cli->pwd.cleartext || cli->pwd.null_pwd)
1081         {
1082                 fstring passwd;
1083                 int pass_len;
1084
1085                 if (cli->pwd.null_pwd)
1086                 {
1087                         /* attempt null session */
1088                         passwd[0] = 0;
1089                         pass_len = 1;
1090                 }
1091                 else
1092                 {
1093                         /* attempt clear-text session */
1094                         pwd_get_cleartext(&(cli->pwd), passwd);
1095                         pass_len = strlen(passwd);
1096                 }
1097
1098                 /* attempt clear-text session */
1099                 if (!cli_session_setup(cli, cli->user_name,
1100                                passwd, pass_len,
1101                                NULL, 0,
1102                                cli->domain))
1103                 {
1104                         DEBUG(1,("failed session setup\n"));
1105                         if (do_shutdown)
1106                         {
1107                                 cli_shutdown(cli);
1108                         }
1109                         return False;
1110                 }
1111                 if (do_tcon)
1112                 {
1113                         if (!cli_send_tconX(cli, service, service_type,
1114                                             (char*)passwd, strlen(passwd)))
1115                         {
1116                                 DEBUG(1,("failed tcon_X\n"));
1117                                 if (do_shutdown)
1118                                 {
1119                                         cli_shutdown(cli);
1120                                 }
1121                                 return False;
1122                         }
1123                 }
1124         }
1125         else
1126         {
1127                 /* attempt encrypted session */
1128                 unsigned char nt_sess_pwd[24];
1129                 unsigned char lm_sess_pwd[24];
1130
1131                 /* creates (storing a copy of) and then obtains a 24 byte password OWF */
1132                 pwd_make_lm_nt_owf(&(cli->pwd), cli->secblob.data);
1133                 pwd_get_lm_nt_owf(&(cli->pwd), lm_sess_pwd, nt_sess_pwd);
1134
1135                 /* attempt encrypted session */
1136                 if (!cli_session_setup(cli, cli->user_name,
1137                                (char*)lm_sess_pwd, sizeof(lm_sess_pwd),
1138                                (char*)nt_sess_pwd, sizeof(nt_sess_pwd),
1139                                cli->domain))
1140                 {
1141                         DEBUG(1,("failed session setup\n"));
1142                         if (do_shutdown)
1143                               cli_shutdown(cli);
1144                         return False;
1145                 }
1146
1147                 DEBUG(1,("session setup ok\n"));
1148     
1149                 if (*cli->server_domain || *cli->server_os || *cli->server_type)
1150                 {
1151                         DEBUG(1,("Domain=[%s] OS=[%s] Server=[%s]\n",
1152                                  cli->server_domain,
1153                                  cli->server_os,
1154                                  cli->server_type));
1155                 }
1156                 
1157                 if (do_tcon)
1158                 {
1159                         if (!cli_send_tconX(cli, service, service_type,
1160                                             (char*)nt_sess_pwd, sizeof(nt_sess_pwd)))
1161                         {
1162                                 DEBUG(1,("failed tcon_X\n"));
1163                                 if (do_shutdown)
1164                                         cli_shutdown(cli);
1165                                 return False;
1166                         }
1167                 }
1168         }
1169
1170         if (do_shutdown)
1171                 cli_shutdown(cli);
1172
1173         return True;
1174 }
1175
1176 /* Initialise client credentials for authenticated pipe access */
1177
1178 static void init_creds(struct ntuser_creds *creds, char* username,
1179                        char* domain, char* password, int pass_len)
1180 {
1181         ZERO_STRUCTP(creds);
1182
1183         pwd_set_cleartext(&creds->pwd, password);
1184
1185         fstrcpy(creds->user_name, username);
1186         fstrcpy(creds->domain, domain);
1187
1188         if (!*username) {
1189                 creds->pwd.null_pwd = True;
1190         }
1191 }
1192
1193 /****************************************************************************
1194 establishes a connection right up to doing tconX, password specified.
1195 ****************************************************************************/
1196 NTSTATUS cli_full_connection(struct cli_state **output_cli, 
1197                              const char *my_name, const char *dest_host, 
1198                              struct in_addr *dest_ip, int port,
1199                              char *service, char *service_type,
1200                              char *user, char *domain, 
1201                              char *password, int pass_len) 
1202 {
1203         struct ntuser_creds creds;
1204         NTSTATUS nt_status;
1205         struct nmb_name calling;
1206         struct nmb_name called;
1207         struct cli_state *cli;
1208         struct in_addr ip;
1209         
1210         if (!output_cli) {
1211                 DEBUG(0, ("output_cli is NULL!?!"));
1212         }
1213
1214         *output_cli = NULL;
1215         
1216         make_nmb_name(&calling, my_name, 0x0);
1217         make_nmb_name(&called , dest_host, 0x20);
1218
1219 again:
1220
1221         if (!(cli = cli_initialise(NULL))) {
1222                 return NT_STATUS_NO_MEMORY;
1223         }
1224         
1225         if (cli_set_port(cli, port) != port) {
1226                 return NT_STATUS_UNSUCCESSFUL;
1227         }
1228
1229         ip = *dest_ip;
1230         
1231         DEBUG(3,("Connecting to host=%s share=%s\n\n", 
1232                  dest_host, service));
1233         
1234         if (!cli_connect(cli, dest_host, &ip))
1235         {
1236                 DEBUG(1,("cli_establish_connection: failed to connect to %s (%s)\n",
1237                          nmb_namestr(&called), inet_ntoa(*dest_ip)));
1238                 return NT_STATUS_UNSUCCESSFUL;
1239         }
1240
1241         if (!cli_session_request(cli, &calling, &called)) {
1242                 char *p;
1243                 DEBUG(1,("session request to %s failed (%s)\n", 
1244                          called.name, cli_errstr(cli)));
1245                 cli_shutdown(cli);
1246                 if ((p=strchr(called.name, '.'))) {
1247                         *p = 0;
1248                         goto again;
1249                 }
1250                 if (strcmp(called.name, "*SMBSERVER")) {
1251                         make_nmb_name(&called , "*SMBSERVER", 0x20);
1252                         goto again;
1253                 }
1254                 return NT_STATUS_UNSUCCESSFUL;
1255         }
1256
1257         if (!cli_negprot(cli))
1258         {
1259                 DEBUG(1,("failed negprot\n"));
1260                 nt_status = NT_STATUS_UNSUCCESSFUL;
1261                 cli_shutdown(cli);
1262                 return nt_status;
1263         }
1264
1265         if (!cli_session_setup(cli, user,
1266                                password, pass_len,
1267                                NULL, 0,
1268                                domain))
1269         {
1270                 DEBUG(1,("failed session setup\n"));
1271                 nt_status = cli_nt_error(cli);
1272                 cli_shutdown(cli);
1273                 return nt_status;
1274         } 
1275
1276         if (service)
1277         {
1278                 if (!cli_send_tconX(cli, service, service_type,
1279                                     (char*)password, pass_len))
1280                 {
1281                         DEBUG(1,("failed tcon_X\n"));
1282                         nt_status = cli_nt_error(cli);
1283                         cli_shutdown(cli);
1284                         return nt_status;
1285                 }
1286         }
1287
1288         init_creds(&creds, user, domain, password, pass_len);
1289         cli_init_creds(cli, &creds);
1290
1291         *output_cli = cli;
1292         return NT_STATUS_OK;
1293 }
1294
1295 /****************************************************************************
1296  Attempt a NetBIOS session request, falling back to *SMBSERVER if needed.
1297 ****************************************************************************/
1298
1299 BOOL attempt_netbios_session_request(struct cli_state *cli, char *srchost, char *desthost,
1300                                      struct in_addr *pdest_ip)
1301 {
1302   struct nmb_name calling, called;
1303
1304   make_nmb_name(&calling, srchost, 0x0);
1305
1306   /*
1307    * If the called name is an IP address
1308    * then use *SMBSERVER immediately.
1309    */
1310
1311   if(is_ipaddress(desthost))
1312     make_nmb_name(&called, "*SMBSERVER", 0x20);
1313   else
1314     make_nmb_name(&called, desthost, 0x20);
1315
1316   if (!cli_session_request(cli, &calling, &called)) {
1317     struct nmb_name smbservername;
1318
1319     make_nmb_name(&smbservername , "*SMBSERVER", 0x20);
1320
1321     /*
1322      * If the name wasn't *SMBSERVER then
1323      * try with *SMBSERVER if the first name fails.
1324      */
1325
1326     if (nmb_name_equal(&called, &smbservername)) {
1327
1328         /*
1329          * The name used was *SMBSERVER, don't bother with another name.
1330          */
1331
1332         DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER \
1333 with error %s.\n", desthost, cli_errstr(cli) ));
1334         cli_shutdown(cli);
1335         return False;
1336     }
1337
1338     cli_shutdown(cli);
1339
1340     if (!cli_initialise(cli) ||
1341         !cli_connect(cli, desthost, pdest_ip) ||
1342         !cli_session_request(cli, &calling, &smbservername)) {
1343           DEBUG(0,("attempt_netbios_session_request: %s rejected the session for \
1344 name *SMBSERVER with error %s\n", desthost, cli_errstr(cli) ));
1345           cli_shutdown(cli);
1346           return False;
1347     }
1348   }
1349
1350   return True;
1351 }
1352
1353