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