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