When doing a cli_ulogoff don't invalidate the cnum, invalidate the vuid.
[samba.git] / source / 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 Bartlett 2001-2003
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 3 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, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "includes.h"
22
23 static const struct {
24         int prot;
25         const char *name;
26 } prots[] = {
27         {PROTOCOL_CORE,"PC NETWORK PROGRAM 1.0"},
28         {PROTOCOL_COREPLUS,"MICROSOFT NETWORKS 1.03"},
29         {PROTOCOL_LANMAN1,"MICROSOFT NETWORKS 3.0"},
30         {PROTOCOL_LANMAN1,"LANMAN1.0"},
31         {PROTOCOL_LANMAN2,"LM1.2X002"},
32         {PROTOCOL_LANMAN2,"DOS LANMAN2.1"},
33         {PROTOCOL_LANMAN2,"LANMAN2.1"},
34         {PROTOCOL_LANMAN2,"Samba"},
35         {PROTOCOL_NT1,"NT LANMAN 1.0"},
36         {PROTOCOL_NT1,"NT LM 0.12"},
37         {-1,NULL}
38 };
39
40 static const char *star_smbserver_name = "*SMBSERVER";
41
42 /**
43  * Set the user session key for a connection
44  * @param cli The cli structure to add it too
45  * @param session_key The session key used.  (A copy of this is taken for the cli struct)
46  *
47  */
48
49 static void cli_set_session_key (struct cli_state *cli, const DATA_BLOB session_key) 
50 {
51         cli->user_session_key = data_blob(session_key.data, session_key.length);
52 }
53
54 /****************************************************************************
55  Do an old lanman2 style session setup.
56 ****************************************************************************/
57
58 static NTSTATUS cli_session_setup_lanman2(struct cli_state *cli,
59                                           const char *user, 
60                                           const char *pass, size_t passlen,
61                                           const char *workgroup)
62 {
63         DATA_BLOB session_key = data_blob_null;
64         DATA_BLOB lm_response = data_blob_null;
65         fstring pword;
66         char *p;
67
68         if (passlen > sizeof(pword)-1) {
69                 return NT_STATUS_INVALID_PARAMETER;
70         }
71
72         /* LANMAN servers predate NT status codes and Unicode and ignore those 
73            smb flags so we must disable the corresponding default capabilities  
74            that would otherwise cause the Unicode and NT Status flags to be
75            set (and even returned by the server) */
76
77         cli->capabilities &= ~(CAP_UNICODE | CAP_STATUS32);
78
79         /* if in share level security then don't send a password now */
80         if (!(cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL))
81                 passlen = 0;
82
83         if (passlen > 0 && (cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && passlen != 24) {
84                 /* Encrypted mode needed, and non encrypted password supplied. */
85                 lm_response = data_blob(NULL, 24);
86                 if (!SMBencrypt(pass, cli->secblob.data,(uchar *)lm_response.data)) {
87                         DEBUG(1, ("Password is > 14 chars in length, and is therefore incompatible with Lanman authentication\n"));
88                         return NT_STATUS_ACCESS_DENIED;
89                 }
90         } else if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && passlen == 24) {
91                 /* Encrypted mode needed, and encrypted password supplied. */
92                 lm_response = data_blob(pass, passlen);
93         } else if (passlen > 0) {
94                 /* Plaintext mode needed, assume plaintext supplied. */
95                 passlen = clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE);
96                 lm_response = data_blob(pass, passlen);
97         }
98
99         /* send a session setup command */
100         memset(cli->outbuf,'\0',smb_size);
101         cli_set_message(cli->outbuf,10, 0, True);
102         SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
103         cli_setup_packet(cli);
104         
105         SCVAL(cli->outbuf,smb_vwv0,0xFF);
106         SSVAL(cli->outbuf,smb_vwv2,cli->max_xmit);
107         SSVAL(cli->outbuf,smb_vwv3,2);
108         SSVAL(cli->outbuf,smb_vwv4,1);
109         SIVAL(cli->outbuf,smb_vwv5,cli->sesskey);
110         SSVAL(cli->outbuf,smb_vwv7,lm_response.length);
111
112         p = smb_buf(cli->outbuf);
113         memcpy(p,lm_response.data,lm_response.length);
114         p += lm_response.length;
115         p += clistr_push(cli, p, user, -1, STR_TERMINATE|STR_UPPER);
116         p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE|STR_UPPER);
117         p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE);
118         p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE);
119         cli_setup_bcc(cli, p);
120
121         if (!cli_send_smb(cli) || !cli_receive_smb(cli)) {
122                 return cli_nt_error(cli);
123         }
124
125         show_msg(cli->inbuf);
126
127         if (cli_is_error(cli)) {
128                 return cli_nt_error(cli);
129         }
130         
131         /* use the returned vuid from now on */
132         cli->vuid = SVAL(cli->inbuf,smb_uid);   
133         fstrcpy(cli->user_name, user);
134
135         if (session_key.data) {
136                 /* Have plaintext orginal */
137                 cli_set_session_key(cli, session_key);
138         }
139
140         return NT_STATUS_OK;
141 }
142
143 /****************************************************************************
144  Work out suitable capabilities to offer the server.
145 ****************************************************************************/
146
147 static uint32 cli_session_setup_capabilities(struct cli_state *cli)
148 {
149         uint32 capabilities = CAP_NT_SMBS;
150
151         if (!cli->force_dos_errors)
152                 capabilities |= CAP_STATUS32;
153
154         if (cli->use_level_II_oplocks)
155                 capabilities |= CAP_LEVEL_II_OPLOCKS;
156
157         capabilities |= (cli->capabilities & (CAP_UNICODE|CAP_LARGE_FILES|CAP_LARGE_READX|CAP_LARGE_WRITEX|CAP_DFS));
158         return capabilities;
159 }
160
161 /****************************************************************************
162  Do a NT1 guest session setup.
163 ****************************************************************************/
164
165 static NTSTATUS cli_session_setup_guest(struct cli_state *cli)
166 {
167         char *p;
168         uint32 capabilities = cli_session_setup_capabilities(cli);
169
170         memset(cli->outbuf, '\0', smb_size);
171         cli_set_message(cli->outbuf,13,0,True);
172         SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
173         cli_setup_packet(cli);
174                         
175         SCVAL(cli->outbuf,smb_vwv0,0xFF);
176         SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE);
177         SSVAL(cli->outbuf,smb_vwv3,2);
178         SSVAL(cli->outbuf,smb_vwv4,cli->pid);
179         SIVAL(cli->outbuf,smb_vwv5,cli->sesskey);
180         SSVAL(cli->outbuf,smb_vwv7,0);
181         SSVAL(cli->outbuf,smb_vwv8,0);
182         SIVAL(cli->outbuf,smb_vwv11,capabilities); 
183         p = smb_buf(cli->outbuf);
184         p += clistr_push(cli, p, "", -1, STR_TERMINATE); /* username */
185         p += clistr_push(cli, p, "", -1, STR_TERMINATE); /* workgroup */
186         p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE);
187         p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE);
188         cli_setup_bcc(cli, p);
189
190         if (!cli_send_smb(cli) || !cli_receive_smb(cli)) {
191                 return cli_nt_error(cli);
192         }
193         
194         show_msg(cli->inbuf);
195         
196         if (cli_is_error(cli)) {
197                 return cli_nt_error(cli);
198         }
199
200         cli->vuid = SVAL(cli->inbuf,smb_uid);
201
202         p = smb_buf(cli->inbuf);
203         p += clistr_pull(cli, cli->server_os, p, sizeof(fstring), -1, STR_TERMINATE);
204         p += clistr_pull(cli, cli->server_type, p, sizeof(fstring), -1, STR_TERMINATE);
205         p += clistr_pull(cli, cli->server_domain, p, sizeof(fstring), -1, STR_TERMINATE);
206
207         if (strstr(cli->server_type, "Samba")) {
208                 cli->is_samba = True;
209         }
210
211         fstrcpy(cli->user_name, "");
212
213         return NT_STATUS_OK;
214 }
215
216 /****************************************************************************
217  Do a NT1 plaintext session setup.
218 ****************************************************************************/
219
220 static NTSTATUS cli_session_setup_plaintext(struct cli_state *cli,
221                                             const char *user, const char *pass,
222                                             const char *workgroup)
223 {
224         uint32 capabilities = cli_session_setup_capabilities(cli);
225         char *p;
226         fstring lanman;
227         
228         fstr_sprintf( lanman, "Samba %s", SAMBA_VERSION_STRING);
229
230         memset(cli->outbuf, '\0', smb_size);
231         cli_set_message(cli->outbuf,13,0,True);
232         SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
233         cli_setup_packet(cli);
234                         
235         SCVAL(cli->outbuf,smb_vwv0,0xFF);
236         SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE);
237         SSVAL(cli->outbuf,smb_vwv3,2);
238         SSVAL(cli->outbuf,smb_vwv4,cli->pid);
239         SIVAL(cli->outbuf,smb_vwv5,cli->sesskey);
240         SSVAL(cli->outbuf,smb_vwv8,0);
241         SIVAL(cli->outbuf,smb_vwv11,capabilities); 
242         p = smb_buf(cli->outbuf);
243         
244         /* check wether to send the ASCII or UNICODE version of the password */
245         
246         if ( (capabilities & CAP_UNICODE) == 0 ) {
247                 p += clistr_push(cli, p, pass, -1, STR_TERMINATE); /* password */
248                 SSVAL(cli->outbuf,smb_vwv7,PTR_DIFF(p, smb_buf(cli->outbuf)));
249         }
250         else {
251                 /* For ucs2 passwords clistr_push calls ucs2_align, which causes
252                  * the space taken by the unicode password to be one byte too
253                  * long (as we're on an odd byte boundary here). Reduce the
254                  * count by 1 to cope with this. Fixes smbclient against NetApp
255                  * servers which can't cope. Fix from
256                  * bryan.kolodziej@allenlund.com in bug #3840.
257                  */
258                 p += clistr_push(cli, p, pass, -1, STR_UNICODE|STR_TERMINATE); /* unicode password */
259                 SSVAL(cli->outbuf,smb_vwv8,PTR_DIFF(p, smb_buf(cli->outbuf))-1);        
260         }
261         
262         p += clistr_push(cli, p, user, -1, STR_TERMINATE); /* username */
263         p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE); /* workgroup */
264         p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE);
265         p += clistr_push(cli, p, lanman, -1, STR_TERMINATE);
266         cli_setup_bcc(cli, p);
267
268         if (!cli_send_smb(cli) || !cli_receive_smb(cli)) {
269                 return cli_nt_error(cli);
270         }
271         
272         show_msg(cli->inbuf);
273         
274         if (cli_is_error(cli)) {
275                 return cli_nt_error(cli);
276         }
277
278         cli->vuid = SVAL(cli->inbuf,smb_uid);
279         p = smb_buf(cli->inbuf);
280         p += clistr_pull(cli, cli->server_os, p, sizeof(fstring), -1, STR_TERMINATE);
281         p += clistr_pull(cli, cli->server_type, p, sizeof(fstring), -1, STR_TERMINATE);
282         p += clistr_pull(cli, cli->server_domain, p, sizeof(fstring), -1, STR_TERMINATE);
283         fstrcpy(cli->user_name, user);
284
285         if (strstr(cli->server_type, "Samba")) {
286                 cli->is_samba = True;
287         }
288
289         return NT_STATUS_OK;
290 }
291
292 /****************************************************************************
293    do a NT1 NTLM/LM encrypted session setup - for when extended security
294    is not negotiated.
295    @param cli client state to create do session setup on
296    @param user username
297    @param pass *either* cleartext password (passlen !=24) or LM response.
298    @param ntpass NT response, implies ntpasslen >=24, implies pass is not clear
299    @param workgroup The user's domain.
300 ****************************************************************************/
301
302 static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user, 
303                                       const char *pass, size_t passlen,
304                                       const char *ntpass, size_t ntpasslen,
305                                       const char *workgroup)
306 {
307         uint32 capabilities = cli_session_setup_capabilities(cli);
308         DATA_BLOB lm_response = data_blob_null;
309         DATA_BLOB nt_response = data_blob_null;
310         DATA_BLOB session_key = data_blob_null;
311         NTSTATUS result;
312         char *p;
313
314         if (passlen == 0) {
315                 /* do nothing - guest login */
316         } else if (passlen != 24) {
317                 if (lp_client_ntlmv2_auth()) {
318                         DATA_BLOB server_chal;
319                         DATA_BLOB names_blob;
320                         server_chal = data_blob(cli->secblob.data, MIN(cli->secblob.length, 8)); 
321
322                         /* note that the 'workgroup' here is a best guess - we don't know
323                            the server's domain at this point.  The 'server name' is also
324                            dodgy... 
325                         */
326                         names_blob = NTLMv2_generate_names_blob(cli->called.name, workgroup);
327
328                         if (!SMBNTLMv2encrypt(user, workgroup, pass, &server_chal, 
329                                               &names_blob,
330                                               &lm_response, &nt_response, &session_key)) {
331                                 data_blob_free(&names_blob);
332                                 data_blob_free(&server_chal);
333                                 return NT_STATUS_ACCESS_DENIED;
334                         }
335                         data_blob_free(&names_blob);
336                         data_blob_free(&server_chal);
337
338                 } else {
339                         uchar nt_hash[16];
340                         E_md4hash(pass, nt_hash);
341
342 #ifdef LANMAN_ONLY
343                         nt_response = data_blob_null;
344 #else
345                         nt_response = data_blob(NULL, 24);
346                         SMBNTencrypt(pass,cli->secblob.data,nt_response.data);
347 #endif
348                         /* non encrypted password supplied. Ignore ntpass. */
349                         if (lp_client_lanman_auth()) {
350                                 lm_response = data_blob(NULL, 24);
351                                 if (!SMBencrypt(pass,cli->secblob.data, lm_response.data)) {
352                                         /* Oops, the LM response is invalid, just put 
353                                            the NT response there instead */
354                                         data_blob_free(&lm_response);
355                                         lm_response = data_blob(nt_response.data, nt_response.length);
356                                 }
357                         } else {
358                                 /* LM disabled, place NT# in LM field instead */
359                                 lm_response = data_blob(nt_response.data, nt_response.length);
360                         }
361
362                         session_key = data_blob(NULL, 16);
363 #ifdef LANMAN_ONLY
364                         E_deshash(pass, session_key.data);
365                         memset(&session_key.data[8], '\0', 8);
366 #else
367                         SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data);
368 #endif
369                 }
370 #ifdef LANMAN_ONLY
371                 cli_simple_set_signing(cli, session_key, lm_response); 
372 #else
373                 cli_simple_set_signing(cli, session_key, nt_response); 
374 #endif
375         } else {
376                 /* pre-encrypted password supplied.  Only used for 
377                    security=server, can't do
378                    signing because we don't have original key */
379
380                 lm_response = data_blob(pass, passlen);
381                 nt_response = data_blob(ntpass, ntpasslen);
382         }
383
384         /* send a session setup command */
385         memset(cli->outbuf,'\0',smb_size);
386
387         cli_set_message(cli->outbuf,13,0,True);
388         SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
389         cli_setup_packet(cli);
390                         
391         SCVAL(cli->outbuf,smb_vwv0,0xFF);
392         SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE);
393         SSVAL(cli->outbuf,smb_vwv3,2);
394         SSVAL(cli->outbuf,smb_vwv4,cli->pid);
395         SIVAL(cli->outbuf,smb_vwv5,cli->sesskey);
396         SSVAL(cli->outbuf,smb_vwv7,lm_response.length);
397         SSVAL(cli->outbuf,smb_vwv8,nt_response.length);
398         SIVAL(cli->outbuf,smb_vwv11,capabilities); 
399         p = smb_buf(cli->outbuf);
400         if (lm_response.length) {
401                 memcpy(p,lm_response.data, lm_response.length); p += lm_response.length;
402         }
403         if (nt_response.length) {
404                 memcpy(p,nt_response.data, nt_response.length); p += nt_response.length;
405         }
406         p += clistr_push(cli, p, user, -1, STR_TERMINATE);
407
408         /* Upper case here might help some NTLMv2 implementations */
409         p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE|STR_UPPER);
410         p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE);
411         p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE);
412         cli_setup_bcc(cli, p);
413
414         if (!cli_send_smb(cli) || !cli_receive_smb(cli)) {
415                 result = cli_nt_error(cli);
416                 goto end;
417         }
418
419         /* show_msg(cli->inbuf); */
420
421         if (cli_is_error(cli)) {
422                 result = cli_nt_error(cli);
423                 goto end;
424         }
425
426         /* use the returned vuid from now on */
427         cli->vuid = SVAL(cli->inbuf,smb_uid);
428         
429         p = smb_buf(cli->inbuf);
430         p += clistr_pull(cli, cli->server_os, p, sizeof(fstring), -1, STR_TERMINATE);
431         p += clistr_pull(cli, cli->server_type, p, sizeof(fstring), -1, STR_TERMINATE);
432         p += clistr_pull(cli, cli->server_domain, p, sizeof(fstring), -1, STR_TERMINATE);
433
434         if (strstr(cli->server_type, "Samba")) {
435                 cli->is_samba = True;
436         }
437
438         fstrcpy(cli->user_name, user);
439
440         if (session_key.data) {
441                 /* Have plaintext orginal */
442                 cli_set_session_key(cli, session_key);
443         }
444
445         result = NT_STATUS_OK;
446 end:    
447         data_blob_free(&lm_response);
448         data_blob_free(&nt_response);
449         data_blob_free(&session_key);
450         return result;
451 }
452
453 /****************************************************************************
454  Send a extended security session setup blob
455 ****************************************************************************/
456
457 static bool cli_session_setup_blob_send(struct cli_state *cli, DATA_BLOB blob)
458 {
459         uint32 capabilities = cli_session_setup_capabilities(cli);
460         char *p;
461
462         capabilities |= CAP_EXTENDED_SECURITY;
463
464         /* send a session setup command */
465         memset(cli->outbuf,'\0',smb_size);
466
467         cli_set_message(cli->outbuf,12,0,True);
468         SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
469
470         cli_setup_packet(cli);
471                         
472         SCVAL(cli->outbuf,smb_vwv0,0xFF);
473         SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE);
474         SSVAL(cli->outbuf,smb_vwv3,2);
475         SSVAL(cli->outbuf,smb_vwv4,1);
476         SIVAL(cli->outbuf,smb_vwv5,0);
477         SSVAL(cli->outbuf,smb_vwv7,blob.length);
478         SIVAL(cli->outbuf,smb_vwv10,capabilities); 
479         p = smb_buf(cli->outbuf);
480         memcpy(p, blob.data, blob.length);
481         p += blob.length;
482         p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE);
483         p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE);
484         cli_setup_bcc(cli, p);
485         return cli_send_smb(cli);
486 }
487
488 /****************************************************************************
489  Send a extended security session setup blob, returning a reply blob.
490 ****************************************************************************/
491
492 static DATA_BLOB cli_session_setup_blob_receive(struct cli_state *cli)
493 {
494         DATA_BLOB blob2 = data_blob_null;
495         char *p;
496         size_t len;
497
498         if (!cli_receive_smb(cli))
499                 return blob2;
500
501         show_msg(cli->inbuf);
502
503         if (cli_is_error(cli) && !NT_STATUS_EQUAL(cli_nt_error(cli),
504                                                   NT_STATUS_MORE_PROCESSING_REQUIRED)) {
505                 return blob2;
506         }
507         
508         /* use the returned vuid from now on */
509         cli->vuid = SVAL(cli->inbuf,smb_uid);
510         
511         p = smb_buf(cli->inbuf);
512
513         blob2 = data_blob(p, SVAL(cli->inbuf, smb_vwv3));
514
515         p += blob2.length;
516         p += clistr_pull(cli, cli->server_os, p, sizeof(fstring), -1, STR_TERMINATE);
517
518         /* w2k with kerberos doesn't properly null terminate this field */
519         len = smb_buflen(cli->inbuf) - PTR_DIFF(p, smb_buf(cli->inbuf));
520         p += clistr_pull(cli, cli->server_type, p, sizeof(fstring), len, 0);
521
522         return blob2;
523 }
524
525 #ifdef HAVE_KRB5
526 /****************************************************************************
527  Send a extended security session setup blob, returning a reply blob.
528 ****************************************************************************/
529
530 /* The following is calculated from :
531  * (smb_size-4) = 35
532  * (smb_wcnt * 2) = 24 (smb_wcnt == 12 in cli_session_setup_blob_send() )
533  * (strlen("Unix") + 1 + strlen("Samba") + 1) * 2 = 22 (unicode strings at
534  * end of packet.
535  */
536
537 #define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22)
538
539 static bool cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob)
540 {
541         int32 remaining = blob.length;
542         int32 cur = 0;
543         DATA_BLOB send_blob = data_blob_null;
544         int32 max_blob_size = 0;
545         DATA_BLOB receive_blob = data_blob_null;
546
547         if (cli->max_xmit < BASE_SESSSETUP_BLOB_PACKET_SIZE + 1) {
548                 DEBUG(0,("cli_session_setup_blob: cli->max_xmit too small "
549                         "(was %u, need minimum %u)\n",
550                         (unsigned int)cli->max_xmit,
551                         BASE_SESSSETUP_BLOB_PACKET_SIZE));
552                 cli_set_nt_error(cli, NT_STATUS_INVALID_PARAMETER);
553                 return False;
554         }
555
556         max_blob_size = cli->max_xmit - BASE_SESSSETUP_BLOB_PACKET_SIZE;
557
558         while ( remaining > 0) {
559                 if (remaining >= max_blob_size) {
560                         send_blob.length = max_blob_size;
561                         remaining -= max_blob_size;
562                 } else {
563                         send_blob.length = remaining; 
564                         remaining = 0;
565                 }
566
567                 send_blob.data =  &blob.data[cur];
568                 cur += send_blob.length;
569
570                 DEBUG(10, ("cli_session_setup_blob: Remaining (%u) sending (%u) current (%u)\n", 
571                         (unsigned int)remaining,
572                         (unsigned int)send_blob.length,
573                         (unsigned int)cur ));
574
575                 if (!cli_session_setup_blob_send(cli, send_blob)) {
576                         DEBUG(0, ("cli_session_setup_blob: send failed\n"));
577                         return False;
578                 }
579
580                 receive_blob = cli_session_setup_blob_receive(cli);
581                 data_blob_free(&receive_blob);
582
583                 if (cli_is_error(cli) &&
584                                 !NT_STATUS_EQUAL( cli_get_nt_error(cli), 
585                                         NT_STATUS_MORE_PROCESSING_REQUIRED)) {
586                         DEBUG(0, ("cli_session_setup_blob: receive failed "
587                                   "(%s)\n", nt_errstr(cli_get_nt_error(cli))));
588                         cli->vuid = 0;
589                         return False;
590                 }
591         }
592
593         return True;
594 }
595
596 /****************************************************************************
597  Use in-memory credentials cache
598 ****************************************************************************/
599
600 static void use_in_memory_ccache(void) {
601         setenv(KRB5_ENV_CCNAME, "MEMORY:cliconnect", 1);
602 }
603
604 /****************************************************************************
605  Do a spnego/kerberos encrypted session setup.
606 ****************************************************************************/
607
608 static ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli, const char *principal, const char *workgroup)
609 {
610         DATA_BLOB negTokenTarg;
611         DATA_BLOB session_key_krb5;
612         NTSTATUS nt_status;
613         int rc;
614
615         cli_temp_set_signing(cli);
616
617         DEBUG(2,("Doing kerberos session setup\n"));
618
619         /* generate the encapsulated kerberos5 ticket */
620         rc = spnego_gen_negTokenTarg(principal, 0, &negTokenTarg, &session_key_krb5, 0, NULL);
621
622         if (rc) {
623                 DEBUG(1, ("cli_session_setup_kerberos: spnego_gen_negTokenTarg failed: %s\n",
624                         error_message(rc)));
625                 return ADS_ERROR_KRB5(rc);
626         }
627
628 #if 0
629         file_save("negTokenTarg.dat", negTokenTarg.data, negTokenTarg.length);
630 #endif
631
632         if (!cli_session_setup_blob(cli, negTokenTarg)) {
633                 nt_status = cli_nt_error(cli);
634                 goto nt_error;
635         }
636
637         if (cli_is_error(cli)) {
638                 nt_status = cli_nt_error(cli);
639                 if (NT_STATUS_IS_OK(nt_status)) {
640                         nt_status = NT_STATUS_UNSUCCESSFUL;
641                 }
642                 goto nt_error;
643         }
644
645         cli_set_session_key(cli, session_key_krb5);
646
647         if (cli_simple_set_signing(
648                     cli, session_key_krb5, data_blob_null)) {
649
650                 /* 'resign' the last message, so we get the right sequence numbers
651                    for checking the first reply from the server */
652                 cli_calculate_sign_mac(cli, cli->outbuf);
653
654                 if (!cli_check_sign_mac(cli, cli->inbuf)) {
655                         nt_status = NT_STATUS_ACCESS_DENIED;
656                         goto nt_error;
657                 }
658         }
659
660         data_blob_free(&negTokenTarg);
661         data_blob_free(&session_key_krb5);
662
663         return ADS_ERROR_NT(NT_STATUS_OK);
664
665 nt_error:
666         data_blob_free(&negTokenTarg);
667         data_blob_free(&session_key_krb5);
668         cli->vuid = 0;
669         return ADS_ERROR_NT(nt_status);
670 }
671 #endif  /* HAVE_KRB5 */
672
673
674 /****************************************************************************
675  Do a spnego/NTLMSSP encrypted session setup.
676 ****************************************************************************/
677
678 static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, 
679                                           const char *pass, const char *domain)
680 {
681         struct ntlmssp_state *ntlmssp_state;
682         NTSTATUS nt_status;
683         int turn = 1;
684         DATA_BLOB msg1;
685         DATA_BLOB blob = data_blob_null;
686         DATA_BLOB blob_in = data_blob_null;
687         DATA_BLOB blob_out = data_blob_null;
688
689         cli_temp_set_signing(cli);
690
691         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_client_start(&ntlmssp_state))) {
692                 return nt_status;
693         }
694         ntlmssp_want_feature(ntlmssp_state, NTLMSSP_FEATURE_SESSION_KEY);
695
696         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, user))) {
697                 return nt_status;
698         }
699         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, domain))) {
700                 return nt_status;
701         }
702         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_password(ntlmssp_state, pass))) {
703                 return nt_status;
704         }
705
706         do {
707                 nt_status = ntlmssp_update(ntlmssp_state, 
708                                                   blob_in, &blob_out);
709                 data_blob_free(&blob_in);
710                 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED) || NT_STATUS_IS_OK(nt_status)) {
711                         if (turn == 1) {
712                                 /* and wrap it in a SPNEGO wrapper */
713                                 msg1 = gen_negTokenInit(OID_NTLMSSP, blob_out);
714                         } else {
715                                 /* wrap it in SPNEGO */
716                                 msg1 = spnego_gen_auth(blob_out);
717                         }
718                 
719                         /* now send that blob on its way */
720                         if (!cli_session_setup_blob_send(cli, msg1)) {
721                                 DEBUG(3, ("Failed to send NTLMSSP/SPNEGO blob to server!\n"));
722                                 nt_status = NT_STATUS_UNSUCCESSFUL;
723                         } else {
724                                 blob = cli_session_setup_blob_receive(cli);
725                                 
726                                 nt_status = cli_nt_error(cli);
727                                 if (cli_is_error(cli) && NT_STATUS_IS_OK(nt_status)) {
728                                         if (cli->smb_rw_error == SMB_READ_BAD_SIG) {
729                                                 nt_status = NT_STATUS_ACCESS_DENIED;
730                                         } else {
731                                                 nt_status = NT_STATUS_UNSUCCESSFUL;
732                                         }
733                                 }
734                         }
735                         data_blob_free(&msg1);
736                 }
737                 
738                 if (!blob.length) {
739                         if (NT_STATUS_IS_OK(nt_status)) {
740                                 nt_status = NT_STATUS_UNSUCCESSFUL;
741                         }
742                 } else if ((turn == 1) && 
743                            NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
744                         DATA_BLOB tmp_blob = data_blob_null;
745                         /* the server might give us back two challenges */
746                         if (!spnego_parse_challenge(blob, &blob_in, 
747                                                     &tmp_blob)) {
748                                 DEBUG(3,("Failed to parse challenges\n"));
749                                 nt_status = NT_STATUS_INVALID_PARAMETER;
750                         }
751                         data_blob_free(&tmp_blob);
752                 } else {
753                         if (!spnego_parse_auth_response(blob, nt_status, OID_NTLMSSP, 
754                                                         &blob_in)) {
755                                 DEBUG(3,("Failed to parse auth response\n"));
756                                 if (NT_STATUS_IS_OK(nt_status) 
757                                     || NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) 
758                                         nt_status = NT_STATUS_INVALID_PARAMETER;
759                         }
760                 }
761                 data_blob_free(&blob);
762                 data_blob_free(&blob_out);
763                 turn++;
764         } while (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED));
765
766         data_blob_free(&blob_in);
767
768         if (NT_STATUS_IS_OK(nt_status)) {
769
770                 DATA_BLOB key = data_blob(ntlmssp_state->session_key.data,
771                                           ntlmssp_state->session_key.length);
772                 DATA_BLOB null_blob = data_blob_null;
773                 bool res;
774
775                 fstrcpy(cli->server_domain, ntlmssp_state->server_domain);
776                 cli_set_session_key(cli, ntlmssp_state->session_key);
777
778                 res = cli_simple_set_signing(cli, key, null_blob);
779
780                 data_blob_free(&key);
781
782                 if (res) {
783                         
784                         /* 'resign' the last message, so we get the right sequence numbers
785                            for checking the first reply from the server */
786                         cli_calculate_sign_mac(cli, cli->outbuf);
787                         
788                         if (!cli_check_sign_mac(cli, cli->inbuf)) {
789                                 nt_status = NT_STATUS_ACCESS_DENIED;
790                         }
791                 }
792         }
793
794         /* we have a reference conter on ntlmssp_state, if we are signing
795            then the state will be kept by the signing engine */
796
797         ntlmssp_end(&ntlmssp_state);
798
799         if (!NT_STATUS_IS_OK(nt_status)) {
800                 cli->vuid = 0;
801         }
802         return nt_status;
803 }
804
805 /****************************************************************************
806  Do a spnego encrypted session setup.
807
808  user_domain: The shortname of the domain the user/machine is a member of.
809  dest_realm: The realm we're connecting to, if NULL we use our default realm.
810 ****************************************************************************/
811
812 ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, 
813                               const char *pass, const char *user_domain,
814                               const char * dest_realm)
815 {
816         char *principal = NULL;
817         char *OIDs[ASN1_MAX_OIDS];
818         int i;
819         DATA_BLOB blob;
820         const char *p = NULL;
821         char *account = NULL;
822
823         DEBUG(3,("Doing spnego session setup (blob length=%lu)\n", (unsigned long)cli->secblob.length));
824
825         /* the server might not even do spnego */
826         if (cli->secblob.length <= 16) {
827                 DEBUG(3,("server didn't supply a full spnego negprot\n"));
828                 goto ntlmssp;
829         }
830
831 #if 0
832         file_save("negprot.dat", cli->secblob.data, cli->secblob.length);
833 #endif
834
835         /* there is 16 bytes of GUID before the real spnego packet starts */
836         blob = data_blob(cli->secblob.data+16, cli->secblob.length-16);
837
838         /* The server sent us the first part of the SPNEGO exchange in the
839          * negprot reply. It is WRONG to depend on the principal sent in the
840          * negprot reply, but right now we do it. If we don't receive one,
841          * we try to best guess, then fall back to NTLM.  */
842         if (!spnego_parse_negTokenInit(blob, OIDs, &principal)) {
843                 data_blob_free(&blob);
844                 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
845         }
846         data_blob_free(&blob);
847
848         /* make sure the server understands kerberos */
849         for (i=0;OIDs[i];i++) {
850                 DEBUG(3,("got OID=%s\n", OIDs[i]));
851                 if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0 ||
852                     strcmp(OIDs[i], OID_KERBEROS5) == 0) {
853                         cli->got_kerberos_mechanism = True;
854                 }
855                 free(OIDs[i]);
856         }
857
858         DEBUG(3,("got principal=%s\n", principal ? principal : "<null>"));
859
860         fstrcpy(cli->user_name, user);
861
862 #ifdef HAVE_KRB5
863         /* If password is set we reauthenticate to kerberos server
864          * and do not store results */
865
866         if (cli->got_kerberos_mechanism && cli->use_kerberos) {
867                 ADS_STATUS rc;
868
869                 if (pass && *pass) {
870                         int ret;
871                         
872                         use_in_memory_ccache();
873                         ret = kerberos_kinit_password(user, pass, 0 /* no time correction for now */, NULL);
874                         
875                         if (ret){
876                                 SAFE_FREE(principal);
877                                 DEBUG(0, ("Kinit failed: %s\n", error_message(ret)));
878                                 if (cli->fallback_after_kerberos)
879                                         goto ntlmssp;
880                                 return ADS_ERROR_KRB5(ret);
881                         }
882                 }
883                 
884                 /* If we get a bad principal, try to guess it if
885                    we have a valid host NetBIOS name.
886                  */
887                 if (strequal(principal, ADS_IGNORE_PRINCIPAL)) {
888                         SAFE_FREE(principal);
889                 }
890
891                 if (principal == NULL &&
892                         !is_ipaddress(cli->desthost) &&
893                         !strequal(star_smbserver_name,
894                                 cli->desthost)) {
895                         char *realm = NULL;
896                         char *machine = NULL;
897                         char *host = NULL;
898                         DEBUG(3,("cli_session_setup_spnego: got a "
899                                 "bad server principal, trying to guess ...\n"));
900
901                         host = strchr_m(cli->desthost, '.');
902                         if (host) {
903                                 machine = SMB_STRNDUP(cli->desthost,
904                                         host - cli->desthost);
905                         } else {
906                                 machine = SMB_STRDUP(cli->desthost);
907                         }
908                         if (machine == NULL) {
909                                 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
910                         }
911
912                         if (dest_realm) {
913                                 realm = SMB_STRDUP(dest_realm);
914                                 strupper_m(realm);
915                         } else {
916                                 realm = kerberos_get_default_realm_from_ccache();
917                         }
918                         if (realm && *realm) {
919                                 if (asprintf(&principal, "%s$@%s",
920                                                 machine, realm) < 0) {
921                                         SAFE_FREE(machine);
922                                         SAFE_FREE(realm);
923                                         return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
924                                 }
925                                 DEBUG(3,("cli_session_setup_spnego: guessed "
926                                         "server principal=%s\n",
927                                         principal ? principal : "<null>"));
928                         }
929                         SAFE_FREE(machine);
930                         SAFE_FREE(realm);
931                 }
932
933                 if (principal) {
934                         rc = cli_session_setup_kerberos(cli, principal,
935                                 dest_realm);
936                         if (ADS_ERR_OK(rc) || !cli->fallback_after_kerberos) {
937                                 SAFE_FREE(principal);
938                                 return rc;
939                         }
940                 }
941         }
942 #endif
943
944         SAFE_FREE(principal);
945
946 ntlmssp:
947
948         account = talloc_strdup(talloc_tos(), user);
949         if (!account) {
950                 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
951         }
952
953         /* when falling back to ntlmssp while authenticating with a machine
954          * account strip off the realm - gd */
955
956         if ((p = strchr_m(user, '@')) != NULL) {
957                 account[PTR_DIFF(p,user)] = '\0';
958         }
959
960         return ADS_ERROR_NT(cli_session_setup_ntlmssp(cli, account, pass, user_domain));
961 }
962
963 /****************************************************************************
964  Send a session setup. The username and workgroup is in UNIX character
965  format and must be converted to DOS codepage format before sending. If the
966  password is in plaintext, the same should be done.
967 ****************************************************************************/
968
969 NTSTATUS cli_session_setup(struct cli_state *cli,
970                            const char *user,
971                            const char *pass, int passlen,
972                            const char *ntpass, int ntpasslen,
973                            const char *workgroup)
974 {
975         char *p;
976         fstring user2;
977
978         if (user) {
979                 fstrcpy(user2, user);
980         } else {
981                 user2[0] ='\0';
982         }
983
984         if (!workgroup) {
985                 workgroup = "";
986         }
987
988         /* allow for workgroups as part of the username */
989         if ((p=strchr_m(user2,'\\')) || (p=strchr_m(user2,'/')) ||
990             (p=strchr_m(user2,*lp_winbind_separator()))) {
991                 *p = 0;
992                 user = p+1;
993                 workgroup = user2;
994         }
995
996         if (cli->protocol < PROTOCOL_LANMAN1) {
997                 return NT_STATUS_OK;
998         }
999
1000         /* now work out what sort of session setup we are going to
1001            do. I have split this into separate functions to make the
1002            flow a bit easier to understand (tridge) */
1003
1004         /* if its an older server then we have to use the older request format */
1005
1006         if (cli->protocol < PROTOCOL_NT1) {
1007                 if (!lp_client_lanman_auth() && passlen != 24 && (*pass)) {
1008                         DEBUG(1, ("Server requested LM password but 'client lanman auth'"
1009                                   " is disabled\n"));
1010                         return NT_STATUS_ACCESS_DENIED;
1011                 }
1012
1013                 if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0 &&
1014                     !lp_client_plaintext_auth() && (*pass)) {
1015                         DEBUG(1, ("Server requested plaintext password but "
1016                                   "'client plaintext auth' is disabled\n"));
1017                         return NT_STATUS_ACCESS_DENIED;
1018                 }
1019
1020                 return cli_session_setup_lanman2(cli, user, pass, passlen,
1021                                                  workgroup);
1022         }
1023
1024         /* if no user is supplied then we have to do an anonymous connection.
1025            passwords are ignored */
1026
1027         if (!user || !*user)
1028                 return cli_session_setup_guest(cli);
1029
1030         /* if the server is share level then send a plaintext null
1031            password at this point. The password is sent in the tree
1032            connect */
1033
1034         if ((cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0) 
1035                 return cli_session_setup_plaintext(cli, user, "", workgroup);
1036
1037         /* if the server doesn't support encryption then we have to use 
1038            plaintext. The second password is ignored */
1039
1040         if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) {
1041                 if (!lp_client_plaintext_auth() && (*pass)) {
1042                         DEBUG(1, ("Server requested plaintext password but "
1043                                   "'client plaintext auth' is disabled\n"));
1044                         return NT_STATUS_ACCESS_DENIED;
1045                 }
1046                 return cli_session_setup_plaintext(cli, user, pass, workgroup);
1047         }
1048
1049         /* if the server supports extended security then use SPNEGO */
1050
1051         if (cli->capabilities & CAP_EXTENDED_SECURITY) {
1052                 ADS_STATUS status = cli_session_setup_spnego(cli, user, pass,
1053                                                              workgroup, NULL);
1054                 if (!ADS_ERR_OK(status)) {
1055                         DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status)));
1056                         return ads_ntstatus(status);
1057                 }
1058         } else {
1059                 NTSTATUS status;
1060
1061                 /* otherwise do a NT1 style session setup */
1062                 status = cli_session_setup_nt1(cli, user, pass, passlen,
1063                                                ntpass, ntpasslen, workgroup);
1064                 if (!NT_STATUS_IS_OK(status)) {
1065                         DEBUG(3,("cli_session_setup: NT1 session setup "
1066                                  "failed: %s\n", nt_errstr(status)));
1067                         return status;
1068                 }
1069         }
1070
1071         if (strstr(cli->server_type, "Samba")) {
1072                 cli->is_samba = True;
1073         }
1074
1075         return NT_STATUS_OK;
1076 }
1077
1078 /****************************************************************************
1079  Send a uloggoff.
1080 *****************************************************************************/
1081
1082 bool cli_ulogoff(struct cli_state *cli)
1083 {
1084         memset(cli->outbuf,'\0',smb_size);
1085         cli_set_message(cli->outbuf,2,0,True);
1086         SCVAL(cli->outbuf,smb_com,SMBulogoffX);
1087         cli_setup_packet(cli);
1088         SSVAL(cli->outbuf,smb_vwv0,0xFF);
1089         SSVAL(cli->outbuf,smb_vwv2,0);  /* no additional info */
1090
1091         cli_send_smb(cli);
1092         if (!cli_receive_smb(cli))
1093                 return False;
1094
1095         if (cli_is_error(cli)) {
1096                 return False;
1097         }
1098
1099         cli->vuid = -1;
1100         return True;
1101 }
1102
1103 /****************************************************************************
1104  Send a tconX.
1105 ****************************************************************************/
1106
1107 bool cli_send_tconX(struct cli_state *cli, 
1108                     const char *share, const char *dev, const char *pass, int passlen)
1109 {
1110         fstring fullshare, pword;
1111         char *p;
1112         memset(cli->outbuf,'\0',smb_size);
1113         memset(cli->inbuf,'\0',smb_size);
1114
1115         fstrcpy(cli->share, share);
1116
1117         /* in user level security don't send a password now */
1118         if (cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {
1119                 passlen = 1;
1120                 pass = "";
1121         } else if (!pass) {
1122                 DEBUG(1, ("Server not using user level security and no password supplied.\n"));
1123                 return False;
1124         }
1125
1126         if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) &&
1127             *pass && passlen != 24) {
1128                 if (!lp_client_lanman_auth()) {
1129                         DEBUG(1, ("Server requested LANMAN password "
1130                                   "(share-level security) but "
1131                                   "'client lanman auth' is disabled\n"));
1132                         return False;
1133                 }
1134
1135                 /*
1136                  * Non-encrypted passwords - convert to DOS codepage before encryption.
1137                  */
1138                 passlen = 24;
1139                 SMBencrypt(pass,cli->secblob.data,(uchar *)pword);
1140         } else {
1141                 if((cli->sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL|NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)) == 0) {
1142                         if (!lp_client_plaintext_auth() && (*pass)) {
1143                                 DEBUG(1, ("Server requested plaintext "
1144                                           "password but 'client plaintext "
1145                                           "auth' is disabled\n"));
1146                                 return False;
1147                         }
1148
1149                         /*
1150                          * Non-encrypted passwords - convert to DOS codepage before using.
1151                          */
1152                         passlen = clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE);
1153                         
1154                 } else {
1155                         if (passlen) {
1156                                 memcpy(pword, pass, passlen);
1157                         }
1158                 }
1159         }
1160
1161         slprintf(fullshare, sizeof(fullshare)-1,
1162                  "\\\\%s\\%s", cli->desthost, share);
1163
1164         cli_set_message(cli->outbuf,4, 0, True);
1165         SCVAL(cli->outbuf,smb_com,SMBtconX);
1166         cli_setup_packet(cli);
1167
1168         SSVAL(cli->outbuf,smb_vwv0,0xFF);
1169         SSVAL(cli->outbuf,smb_vwv2,TCONX_FLAG_EXTENDED_RESPONSE);
1170         SSVAL(cli->outbuf,smb_vwv3,passlen);
1171
1172         p = smb_buf(cli->outbuf);
1173         if (passlen) {
1174                 memcpy(p,pword,passlen);
1175         }
1176         p += passlen;
1177         p += clistr_push(cli, p, fullshare, -1, STR_TERMINATE |STR_UPPER);
1178         p += clistr_push(cli, p, dev, -1, STR_TERMINATE |STR_UPPER | STR_ASCII);
1179
1180         cli_setup_bcc(cli, p);
1181
1182         cli_send_smb(cli);
1183         if (!cli_receive_smb(cli))
1184                 return False;
1185
1186         if (cli_is_error(cli))
1187                 return False;
1188
1189         clistr_pull(cli, cli->dev, smb_buf(cli->inbuf), sizeof(fstring), -1, STR_TERMINATE|STR_ASCII);
1190
1191         if (cli->protocol >= PROTOCOL_NT1 &&
1192             smb_buflen(cli->inbuf) == 3) {
1193                 /* almost certainly win95 - enable bug fixes */
1194                 cli->win95 = True;
1195         }
1196         
1197         /* Make sure that we have the optional support 16-bit field.  WCT > 2 */
1198         /* Avoids issues when connecting to Win9x boxes sharing files */
1199
1200         cli->dfsroot = False;
1201         if ( (CVAL(cli->inbuf, smb_wct))>2 && cli->protocol >= PROTOCOL_LANMAN2 )
1202                 cli->dfsroot = (SVAL( cli->inbuf, smb_vwv2 ) & SMB_SHARE_IN_DFS) ? True : False;
1203
1204         cli->cnum = SVAL(cli->inbuf,smb_tid);
1205         return True;
1206 }
1207
1208 /****************************************************************************
1209  Send a tree disconnect.
1210 ****************************************************************************/
1211
1212 bool cli_tdis(struct cli_state *cli)
1213 {
1214         memset(cli->outbuf,'\0',smb_size);
1215         cli_set_message(cli->outbuf,0,0,True);
1216         SCVAL(cli->outbuf,smb_com,SMBtdis);
1217         SSVAL(cli->outbuf,smb_tid,cli->cnum);
1218         cli_setup_packet(cli);
1219         
1220         cli_send_smb(cli);
1221         if (!cli_receive_smb(cli))
1222                 return False;
1223         
1224         if (cli_is_error(cli)) {
1225                 return False;
1226         }
1227
1228         cli->cnum = -1;
1229         return True;
1230 }
1231
1232 /****************************************************************************
1233  Send a negprot command.
1234 ****************************************************************************/
1235
1236 void cli_negprot_send(struct cli_state *cli)
1237 {
1238         char *p;
1239         int numprots;
1240
1241         if (cli->protocol < PROTOCOL_NT1)
1242                 cli->use_spnego = False;
1243
1244         memset(cli->outbuf,'\0',smb_size);
1245
1246         /* setup the protocol strings */
1247         cli_set_message(cli->outbuf,0,0,True);
1248
1249         p = smb_buf(cli->outbuf);
1250         for (numprots=0;
1251              prots[numprots].name && prots[numprots].prot<=cli->protocol;
1252              numprots++) {
1253                 *p++ = 2;
1254                 p += clistr_push(cli, p, prots[numprots].name, -1, STR_TERMINATE);
1255         }
1256
1257         SCVAL(cli->outbuf,smb_com,SMBnegprot);
1258         cli_setup_bcc(cli, p);
1259         cli_setup_packet(cli);
1260
1261         SCVAL(smb_buf(cli->outbuf),0,2);
1262
1263         cli_send_smb(cli);
1264 }
1265
1266 /****************************************************************************
1267  Send a negprot command.
1268 ****************************************************************************/
1269
1270 bool cli_negprot(struct cli_state *cli)
1271 {
1272         char *p;
1273         int numprots;
1274         int plength;
1275
1276         if (cli->protocol < PROTOCOL_NT1)
1277                 cli->use_spnego = False;
1278
1279         memset(cli->outbuf,'\0',smb_size);
1280
1281         /* setup the protocol strings */
1282         for (plength=0,numprots=0;
1283              prots[numprots].name && prots[numprots].prot<=cli->protocol;
1284              numprots++)
1285                 plength += strlen(prots[numprots].name)+2;
1286     
1287         cli_set_message(cli->outbuf,0,plength,True);
1288
1289         p = smb_buf(cli->outbuf);
1290         for (numprots=0;
1291              prots[numprots].name && prots[numprots].prot<=cli->protocol;
1292              numprots++) {
1293                 *p++ = 2;
1294                 p += clistr_push(cli, p, prots[numprots].name, -1, STR_TERMINATE);
1295         }
1296
1297         SCVAL(cli->outbuf,smb_com,SMBnegprot);
1298         cli_setup_packet(cli);
1299
1300         SCVAL(smb_buf(cli->outbuf),0,2);
1301
1302         cli_send_smb(cli);
1303         if (!cli_receive_smb(cli))
1304                 return False;
1305
1306         show_msg(cli->inbuf);
1307
1308         if (cli_is_error(cli) ||
1309             ((int)SVAL(cli->inbuf,smb_vwv0) >= numprots)) {
1310                 return(False);
1311         }
1312
1313         cli->protocol = prots[SVAL(cli->inbuf,smb_vwv0)].prot;  
1314
1315         if ((cli->protocol < PROTOCOL_NT1) && cli->sign_info.mandatory_signing) {
1316                 DEBUG(0,("cli_negprot: SMB signing is mandatory and the selected protocol level doesn't support it.\n"));
1317                 return False;
1318         }
1319
1320         if (cli->protocol >= PROTOCOL_NT1) {    
1321                 struct timespec ts;
1322                 /* NT protocol */
1323                 cli->sec_mode = CVAL(cli->inbuf,smb_vwv1);
1324                 cli->max_mux = SVAL(cli->inbuf, smb_vwv1+1);
1325                 cli->max_xmit = IVAL(cli->inbuf,smb_vwv3+1);
1326                 cli->sesskey = IVAL(cli->inbuf,smb_vwv7+1);
1327                 cli->serverzone = SVALS(cli->inbuf,smb_vwv15+1);
1328                 cli->serverzone *= 60;
1329                 /* this time arrives in real GMT */
1330                 ts = interpret_long_date(cli->inbuf+smb_vwv11+1);
1331                 cli->servertime = ts.tv_sec;
1332                 cli->secblob = data_blob(smb_buf(cli->inbuf),smb_buflen(cli->inbuf));
1333                 cli->capabilities = IVAL(cli->inbuf,smb_vwv9+1);
1334                 if (cli->capabilities & CAP_RAW_MODE) {
1335                         cli->readbraw_supported = True;
1336                         cli->writebraw_supported = True;      
1337                 }
1338                 /* work out if they sent us a workgroup */
1339                 if (!(cli->capabilities & CAP_EXTENDED_SECURITY) &&
1340                     smb_buflen(cli->inbuf) > 8) {
1341                         clistr_pull(cli, cli->server_domain, 
1342                                     smb_buf(cli->inbuf)+8, sizeof(cli->server_domain),
1343                                     smb_buflen(cli->inbuf)-8, STR_UNICODE|STR_NOALIGN);
1344                 }
1345
1346                 /*
1347                  * As signing is slow we only turn it on if either the client or
1348                  * the server require it. JRA.
1349                  */
1350
1351                 if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) {
1352                         /* Fail if server says signing is mandatory and we don't want to support it. */
1353                         if (!cli->sign_info.allow_smb_signing) {
1354                                 DEBUG(0,("cli_negprot: SMB signing is mandatory and we have disabled it.\n"));
1355                                 return False;
1356                         }
1357                         cli->sign_info.negotiated_smb_signing = True;
1358                         cli->sign_info.mandatory_signing = True;
1359                 } else if (cli->sign_info.mandatory_signing && cli->sign_info.allow_smb_signing) {
1360                         /* Fail if client says signing is mandatory and the server doesn't support it. */
1361                         if (!(cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) {
1362                                 DEBUG(1,("cli_negprot: SMB signing is mandatory and the server doesn't support it.\n"));
1363                                 return False;
1364                         }
1365                         cli->sign_info.negotiated_smb_signing = True;
1366                         cli->sign_info.mandatory_signing = True;
1367                 } else if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) {
1368                         cli->sign_info.negotiated_smb_signing = True;
1369                 }
1370
1371                 if (cli->capabilities & (CAP_LARGE_READX|CAP_LARGE_WRITEX)) {
1372                         SAFE_FREE(cli->outbuf);
1373                         SAFE_FREE(cli->inbuf);
1374                         cli->outbuf = (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE+LARGE_WRITEX_HDR_SIZE+SAFETY_MARGIN);
1375                         cli->inbuf = (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE+LARGE_WRITEX_HDR_SIZE+SAFETY_MARGIN);
1376                         cli->bufsize = CLI_SAMBA_MAX_LARGE_READX_SIZE + LARGE_WRITEX_HDR_SIZE;
1377                 }
1378
1379         } else if (cli->protocol >= PROTOCOL_LANMAN1) {
1380                 cli->use_spnego = False;
1381                 cli->sec_mode = SVAL(cli->inbuf,smb_vwv1);
1382                 cli->max_xmit = SVAL(cli->inbuf,smb_vwv2);
1383                 cli->max_mux = SVAL(cli->inbuf, smb_vwv3); 
1384                 cli->sesskey = IVAL(cli->inbuf,smb_vwv6);
1385                 cli->serverzone = SVALS(cli->inbuf,smb_vwv10);
1386                 cli->serverzone *= 60;
1387                 /* this time is converted to GMT by make_unix_date */
1388                 cli->servertime = cli_make_unix_date(cli,cli->inbuf+smb_vwv8);
1389                 cli->readbraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x1) != 0);
1390                 cli->writebraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x2) != 0);
1391                 cli->secblob = data_blob(smb_buf(cli->inbuf),smb_buflen(cli->inbuf));
1392         } else {
1393                 /* the old core protocol */
1394                 cli->use_spnego = False;
1395                 cli->sec_mode = 0;
1396                 cli->serverzone = get_time_zone(time(NULL));
1397         }
1398
1399         cli->max_xmit = MIN(cli->max_xmit, CLI_BUFFER_SIZE);
1400
1401         /* a way to force ascii SMB */
1402         if (getenv("CLI_FORCE_ASCII"))
1403                 cli->capabilities &= ~CAP_UNICODE;
1404
1405         return True;
1406 }
1407
1408 /****************************************************************************
1409  Send a session request. See rfc1002.txt 4.3 and 4.3.2.
1410 ****************************************************************************/
1411
1412 bool cli_session_request(struct cli_state *cli,
1413                          struct nmb_name *calling, struct nmb_name *called)
1414 {
1415         char *p;
1416         int len = 4;
1417
1418         memcpy(&(cli->calling), calling, sizeof(*calling));
1419         memcpy(&(cli->called ), called , sizeof(*called ));
1420   
1421         /* put in the destination name */
1422         p = cli->outbuf+len;
1423         name_mangle(cli->called .name, p, cli->called .name_type);
1424         len += name_len(p);
1425
1426         /* and my name */
1427         p = cli->outbuf+len;
1428         name_mangle(cli->calling.name, p, cli->calling.name_type);
1429         len += name_len(p);
1430
1431         /* 445 doesn't have session request */
1432         if (cli->port == 445)
1433                 return True;
1434
1435         /* send a session request (RFC 1002) */
1436         /* setup the packet length
1437          * Remove four bytes from the length count, since the length
1438          * field in the NBT Session Service header counts the number
1439          * of bytes which follow.  The cli_send_smb() function knows
1440          * about this and accounts for those four bytes.
1441          * CRH.
1442          */
1443         len -= 4;
1444         _smb_setlen(cli->outbuf,len);
1445         SCVAL(cli->outbuf,0,0x81);
1446
1447         cli_send_smb(cli);
1448         DEBUG(5,("Sent session request\n"));
1449
1450         if (!cli_receive_smb(cli))
1451                 return False;
1452
1453         if (CVAL(cli->inbuf,0) == 0x84) {
1454                 /* C. Hoch  9/14/95 Start */
1455                 /* For information, here is the response structure.
1456                  * We do the byte-twiddling to for portability.
1457                 struct RetargetResponse{
1458                 unsigned char type;
1459                 unsigned char flags;
1460                 int16 length;
1461                 int32 ip_addr;
1462                 int16 port;
1463                 };
1464                 */
1465                 uint16_t port = (CVAL(cli->inbuf,8)<<8)+CVAL(cli->inbuf,9);
1466                 struct in_addr dest_ip;
1467
1468                 /* SESSION RETARGET */
1469                 putip((char *)&dest_ip,cli->inbuf+4);
1470                 in_addr_to_sockaddr_storage(&cli->dest_ss, dest_ip);
1471
1472                 cli->fd = open_socket_out(SOCK_STREAM,
1473                                 &cli->dest_ss,
1474                                 port,
1475                                 LONG_CONNECT_TIMEOUT);
1476                 if (cli->fd == -1)
1477                         return False;
1478
1479                 DEBUG(3,("Retargeted\n"));
1480
1481                 set_socket_options(cli->fd, lp_socket_options());
1482
1483                 /* Try again */
1484                 {
1485                         static int depth;
1486                         bool ret;
1487                         if (depth > 4) {
1488                                 DEBUG(0,("Retarget recursion - failing\n"));
1489                                 return False;
1490                         }
1491                         depth++;
1492                         ret = cli_session_request(cli, calling, called);
1493                         depth--;
1494                         return ret;
1495                 }
1496         } /* C. Hoch 9/14/95 End */
1497
1498         if (CVAL(cli->inbuf,0) != 0x82) {
1499                 /* This is the wrong place to put the error... JRA. */
1500                 cli->rap_error = CVAL(cli->inbuf,4);
1501                 return False;
1502         }
1503         return(True);
1504 }
1505
1506 /****************************************************************************
1507  Open the client sockets.
1508 ****************************************************************************/
1509
1510 NTSTATUS cli_connect(struct cli_state *cli,
1511                 const char *host,
1512                 struct sockaddr_storage *dest_ss)
1513
1514 {
1515         int name_type = 0x20;
1516         TALLOC_CTX *frame = talloc_stackframe();
1517         unsigned int num_addrs = 0;
1518         unsigned int i = 0;
1519         struct sockaddr_storage *ss_arr = NULL;
1520         char *p = NULL;
1521
1522         /* reasonable default hostname */
1523         if (!host) {
1524                 host = star_smbserver_name;
1525         }
1526
1527         fstrcpy(cli->desthost, host);
1528
1529         /* allow hostnames of the form NAME#xx and do a netbios lookup */
1530         if ((p = strchr(cli->desthost, '#'))) {
1531                 name_type = strtol(p+1, NULL, 16);
1532                 *p = 0;
1533         }
1534
1535         if (!dest_ss || is_zero_addr(dest_ss)) {
1536                 NTSTATUS status =resolve_name_list(frame,
1537                                         cli->desthost,
1538                                         name_type,
1539                                         &ss_arr,
1540                                         &num_addrs);
1541                 if (!NT_STATUS_IS_OK(status)) {
1542                         TALLOC_FREE(frame);
1543                         return NT_STATUS_BAD_NETWORK_NAME;
1544                 }
1545         } else {
1546                 num_addrs = 1;
1547                 ss_arr = TALLOC_P(frame, struct sockaddr_storage);
1548                 if (!ss_arr) {
1549                         TALLOC_FREE(frame);
1550                         return NT_STATUS_NO_MEMORY;
1551                 }
1552                 *ss_arr = *dest_ss;
1553         }
1554
1555         for (i = 0; i < num_addrs; i++) {
1556                 cli->dest_ss = ss_arr[i];
1557                 if (getenv("LIBSMB_PROG")) {
1558                         cli->fd = sock_exec(getenv("LIBSMB_PROG"));
1559                 } else {
1560                         /* try 445 first, then 139 */
1561                         uint16_t port = cli->port?cli->port:445;
1562                         cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ss,
1563                                                   port, cli->timeout);
1564                         if (cli->fd == -1 && cli->port == 0) {
1565                                 port = 139;
1566                                 cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ss,
1567                                                           port, cli->timeout);
1568                         }
1569                         if (cli->fd != -1) {
1570                                 cli->port = port;
1571                         }
1572                 }
1573                 if (cli->fd == -1) {
1574                         char addr[INET6_ADDRSTRLEN];
1575                         print_sockaddr(addr, sizeof(addr), &ss_arr[i]);
1576                         DEBUG(2,("Error connecting to %s (%s)\n",
1577                                  dest_ss?addr:host,strerror(errno)));
1578                 } else {
1579                         /* Exit from loop on first connection. */
1580                         break;
1581                 }
1582         }
1583
1584         if (cli->fd == -1) {
1585                 TALLOC_FREE(frame);
1586                 return map_nt_error_from_unix(errno);
1587         }
1588
1589         if (dest_ss) {
1590                 *dest_ss = cli->dest_ss;
1591         }
1592
1593         set_socket_options(cli->fd, lp_socket_options());
1594
1595         TALLOC_FREE(frame);
1596         return NT_STATUS_OK;
1597 }
1598
1599 /**
1600    establishes a connection to after the negprot. 
1601    @param output_cli A fully initialised cli structure, non-null only on success
1602    @param dest_host The netbios name of the remote host
1603    @param dest_ss (optional) The the destination IP, NULL for name based lookup
1604    @param port (optional) The destination port (0 for default)
1605    @param retry bool. Did this connection fail with a retryable error ?
1606
1607 */
1608 NTSTATUS cli_start_connection(struct cli_state **output_cli, 
1609                               const char *my_name, 
1610                               const char *dest_host, 
1611                               struct sockaddr_storage *dest_ss, int port,
1612                               int signing_state, int flags,
1613                               bool *retry) 
1614 {
1615         NTSTATUS nt_status;
1616         struct nmb_name calling;
1617         struct nmb_name called;
1618         struct cli_state *cli;
1619         struct sockaddr_storage ss;
1620
1621         if (retry)
1622                 *retry = False;
1623
1624         if (!my_name) 
1625                 my_name = global_myname();
1626         
1627         if (!(cli = cli_initialise())) {
1628                 return NT_STATUS_NO_MEMORY;
1629         }
1630         
1631         make_nmb_name(&calling, my_name, 0x0);
1632         make_nmb_name(&called , dest_host, 0x20);
1633
1634         if (cli_set_port(cli, port) != port) {
1635                 cli_shutdown(cli);
1636                 return NT_STATUS_UNSUCCESSFUL;
1637         }
1638
1639         cli_set_timeout(cli, 10000); /* 10 seconds. */
1640
1641         if (dest_ss) {
1642                 ss = *dest_ss;
1643         } else {
1644                 zero_sockaddr(&ss);
1645         }
1646
1647 again:
1648
1649         DEBUG(3,("Connecting to host=%s\n", dest_host));
1650
1651         nt_status = cli_connect(cli, dest_host, &ss);
1652         if (!NT_STATUS_IS_OK(nt_status)) {
1653                 char addr[INET6_ADDRSTRLEN];
1654                 print_sockaddr(addr, sizeof(addr), &ss);
1655                 DEBUG(1,("cli_start_connection: failed to connect to %s (%s). Error %s\n",
1656                          nmb_namestr(&called), addr, nt_errstr(nt_status) ));
1657                 cli_shutdown(cli);
1658                 return nt_status;
1659         }
1660
1661         if (retry)
1662                 *retry = True;
1663
1664         if (!cli_session_request(cli, &calling, &called)) {
1665                 char *p;
1666                 DEBUG(1,("session request to %s failed (%s)\n",
1667                          called.name, cli_errstr(cli)));
1668                 if ((p=strchr(called.name, '.')) && !is_ipaddress(called.name)) {
1669                         *p = 0;
1670                         goto again;
1671                 }
1672                 if (strcmp(called.name, star_smbserver_name)) {
1673                         make_nmb_name(&called , star_smbserver_name, 0x20);
1674                         goto again;
1675                 }
1676                 return NT_STATUS_BAD_NETWORK_NAME;
1677         }
1678
1679         cli_setup_signing_state(cli, signing_state);
1680
1681         if (flags & CLI_FULL_CONNECTION_DONT_SPNEGO)
1682                 cli->use_spnego = False;
1683         else if (flags & CLI_FULL_CONNECTION_USE_KERBEROS)
1684                 cli->use_kerberos = True;
1685
1686         if ((flags & CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS) &&
1687              cli->use_kerberos) {
1688                 cli->fallback_after_kerberos = true;
1689         }
1690
1691         if (!cli_negprot(cli)) {
1692                 DEBUG(1,("failed negprot\n"));
1693                 nt_status = cli_nt_error(cli);
1694                 if (NT_STATUS_IS_OK(nt_status)) {
1695                         nt_status = NT_STATUS_UNSUCCESSFUL;
1696                 }
1697                 cli_shutdown(cli);
1698                 return nt_status;
1699         }
1700
1701         *output_cli = cli;
1702         return NT_STATUS_OK;
1703 }
1704
1705
1706 /**
1707    establishes a connection right up to doing tconX, password specified.
1708    @param output_cli A fully initialised cli structure, non-null only on success
1709    @param dest_host The netbios name of the remote host
1710    @param dest_ip (optional) The the destination IP, NULL for name based lookup
1711    @param port (optional) The destination port (0 for default)
1712    @param service (optional) The share to make the connection to.  Should be 'unqualified' in any way.
1713    @param service_type The 'type' of serivice. 
1714    @param user Username, unix string
1715    @param domain User's domain
1716    @param password User's password, unencrypted unix string.
1717    @param retry bool. Did this connection fail with a retryable error ?
1718 */
1719
1720 NTSTATUS cli_full_connection(struct cli_state **output_cli, 
1721                              const char *my_name, 
1722                              const char *dest_host, 
1723                              struct sockaddr_storage *dest_ss, int port,
1724                              const char *service, const char *service_type,
1725                              const char *user, const char *domain, 
1726                              const char *password, int flags,
1727                              int signing_state,
1728                              bool *retry) 
1729 {
1730         NTSTATUS nt_status;
1731         struct cli_state *cli = NULL;
1732         int pw_len = password ? strlen(password)+1 : 0;
1733
1734         *output_cli = NULL;
1735
1736         if (password == NULL) {
1737                 password = "";
1738         }
1739
1740         nt_status = cli_start_connection(&cli, my_name, dest_host,
1741                                          dest_ss, port, signing_state,
1742                                          flags, retry);
1743
1744         if (!NT_STATUS_IS_OK(nt_status)) {
1745                 return nt_status;
1746         }
1747
1748         nt_status = cli_session_setup(cli, user, password, pw_len, password,
1749                                       pw_len, domain);
1750         if (!NT_STATUS_IS_OK(nt_status)) {
1751
1752                 if (!(flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)) {
1753                         DEBUG(1,("failed session setup with %s\n",
1754                                  nt_errstr(nt_status)));
1755                         cli_shutdown(cli);
1756                         return nt_status;
1757                 }
1758
1759                 nt_status = cli_session_setup(cli, "", "", 0, "", 0, domain);
1760                 if (!NT_STATUS_IS_OK(nt_status)) {
1761                         DEBUG(1,("anonymous failed session setup with %s\n",
1762                                  nt_errstr(nt_status)));
1763                         cli_shutdown(cli);
1764                         return nt_status;
1765                 }
1766         }
1767
1768         if (service) {
1769                 if (!cli_send_tconX(cli, service, service_type, password, pw_len)) {
1770                         nt_status = cli_nt_error(cli);
1771                         DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status)));
1772                         cli_shutdown(cli);
1773                         if (NT_STATUS_IS_OK(nt_status)) {
1774                                 nt_status = NT_STATUS_UNSUCCESSFUL;
1775                         }
1776                         return nt_status;
1777                 }
1778         }
1779
1780         cli_init_creds(cli, user, domain, password);
1781
1782         *output_cli = cli;
1783         return NT_STATUS_OK;
1784 }
1785
1786 /****************************************************************************
1787  Attempt a NetBIOS session request, falling back to *SMBSERVER if needed.
1788 ****************************************************************************/
1789
1790 bool attempt_netbios_session_request(struct cli_state **ppcli, const char *srchost, const char *desthost,
1791                                      struct sockaddr_storage *pdest_ss)
1792 {
1793         struct nmb_name calling, called;
1794
1795         make_nmb_name(&calling, srchost, 0x0);
1796
1797         /*
1798          * If the called name is an IP address
1799          * then use *SMBSERVER immediately.
1800          */
1801
1802         if(is_ipaddress(desthost)) {
1803                 make_nmb_name(&called, star_smbserver_name, 0x20);
1804         } else {
1805                 make_nmb_name(&called, desthost, 0x20);
1806         }
1807
1808         if (!cli_session_request(*ppcli, &calling, &called)) {
1809                 NTSTATUS status;
1810                 struct nmb_name smbservername;
1811
1812                 make_nmb_name(&smbservername, star_smbserver_name, 0x20);
1813
1814                 /*
1815                  * If the name wasn't *SMBSERVER then
1816                  * try with *SMBSERVER if the first name fails.
1817                  */
1818
1819                 if (nmb_name_equal(&called, &smbservername)) {
1820
1821                         /*
1822                          * The name used was *SMBSERVER, don't bother with another name.
1823                          */
1824
1825                         DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER \
1826 with error %s.\n", desthost, cli_errstr(*ppcli) ));
1827                         return False;
1828                 }
1829
1830                 /* Try again... */
1831                 cli_shutdown(*ppcli);
1832
1833                 *ppcli = cli_initialise();
1834                 if (!*ppcli) {
1835                         /* Out of memory... */
1836                         return False;
1837                 }
1838
1839                 status = cli_connect(*ppcli, desthost, pdest_ss);
1840                 if (!NT_STATUS_IS_OK(status) ||
1841                                 !cli_session_request(*ppcli, &calling, &smbservername)) {
1842                         DEBUG(0,("attempt_netbios_session_request: %s rejected the session for \
1843 name *SMBSERVER with error %s\n", desthost, cli_errstr(*ppcli) ));
1844                         return False;
1845                 }
1846         }
1847
1848         return True;
1849 }
1850
1851 /****************************************************************************
1852  Send an old style tcon.
1853 ****************************************************************************/
1854 NTSTATUS cli_raw_tcon(struct cli_state *cli, 
1855                       const char *service, const char *pass, const char *dev,
1856                       uint16 *max_xmit, uint16 *tid)
1857 {
1858         char *p;
1859
1860         if (!lp_client_plaintext_auth() && (*pass)) {
1861                 DEBUG(1, ("Server requested plaintext password but 'client "
1862                           "plaintext auth' is disabled\n"));
1863                 return NT_STATUS_ACCESS_DENIED;
1864         }
1865
1866         memset(cli->outbuf,'\0',smb_size);
1867         memset(cli->inbuf,'\0',smb_size);
1868
1869         cli_set_message(cli->outbuf, 0, 0, True);
1870         SCVAL(cli->outbuf,smb_com,SMBtcon);
1871         cli_setup_packet(cli);
1872
1873         p = smb_buf(cli->outbuf);
1874         *p++ = 4; p += clistr_push(cli, p, service, -1, STR_TERMINATE | STR_NOALIGN);
1875         *p++ = 4; p += clistr_push(cli, p, pass, -1, STR_TERMINATE | STR_NOALIGN);
1876         *p++ = 4; p += clistr_push(cli, p, dev, -1, STR_TERMINATE | STR_NOALIGN);
1877
1878         cli_setup_bcc(cli, p);
1879
1880         cli_send_smb(cli);
1881         if (!cli_receive_smb(cli)) {
1882                 return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
1883         }
1884
1885         if (cli_is_error(cli)) {
1886                 return cli_nt_error(cli);
1887         }
1888
1889         *max_xmit = SVAL(cli->inbuf, smb_vwv0);
1890         *tid = SVAL(cli->inbuf, smb_vwv1);
1891
1892         return NT_STATUS_OK;
1893 }
1894
1895 /* Return a cli_state pointing at the IPC$ share for the given server */
1896
1897 struct cli_state *get_ipc_connect(char *server,
1898                                 struct sockaddr_storage *server_ss,
1899                                 const struct user_auth_info *user_info)
1900 {
1901         struct cli_state *cli;
1902         NTSTATUS nt_status;
1903         uint32_t flags = CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
1904
1905         if (user_info->use_kerberos) {
1906                 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
1907         }
1908
1909         nt_status = cli_full_connection(&cli, NULL, server, server_ss, 0, "IPC$", "IPC", 
1910                                         user_info->username ? user_info->username : "",
1911                                         lp_workgroup(),
1912                                         user_info->password ? user_info->password : "",
1913                                         flags,
1914                                         Undefined, NULL);
1915
1916         if (NT_STATUS_IS_OK(nt_status)) {
1917                 return cli;
1918         } else if (is_ipaddress(server)) {
1919             /* windows 9* needs a correct NMB name for connections */
1920             fstring remote_name;
1921
1922             if (name_status_find("*", 0, 0, server_ss, remote_name)) {
1923                 cli = get_ipc_connect(remote_name, server_ss, user_info);
1924                 if (cli)
1925                     return cli;
1926             }
1927         }
1928         return NULL;
1929 }
1930
1931 /*
1932  * Given the IP address of a master browser on the network, return its
1933  * workgroup and connect to it.
1934  *
1935  * This function is provided to allow additional processing beyond what
1936  * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
1937  * browsers and obtain each master browsers' list of domains (in case the
1938  * first master browser is recently on the network and has not yet
1939  * synchronized with other master browsers and therefore does not yet have the
1940  * entire network browse list)
1941  */
1942
1943 struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx,
1944                                 struct ip_service *mb_ip,
1945                                 const struct user_auth_info *user_info,
1946                                 char **pp_workgroup_out)
1947 {
1948         char addr[INET6_ADDRSTRLEN];
1949         fstring name;
1950         struct cli_state *cli;
1951         struct sockaddr_storage server_ss;
1952
1953         *pp_workgroup_out = NULL;
1954
1955         print_sockaddr(addr, sizeof(addr), &mb_ip->ss);
1956         DEBUG(99, ("Looking up name of master browser %s\n",
1957                    addr));
1958
1959         /*
1960          * Do a name status query to find out the name of the master browser.
1961          * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
1962          * master browser will not respond to a wildcard query (or, at least,
1963          * an NT4 server acting as the domain master browser will not).
1964          *
1965          * We might be able to use ONLY the query on MSBROWSE, but that's not
1966          * yet been tested with all Windows versions, so until it is, leave
1967          * the original wildcard query as the first choice and fall back to
1968          * MSBROWSE if the wildcard query fails.
1969          */
1970         if (!name_status_find("*", 0, 0x1d, &mb_ip->ss, name) &&
1971             !name_status_find(MSBROWSE, 1, 0x1d, &mb_ip->ss, name)) {
1972
1973                 DEBUG(99, ("Could not retrieve name status for %s\n",
1974                            addr));
1975                 return NULL;
1976         }
1977
1978         if (!find_master_ip(name, &server_ss)) {
1979                 DEBUG(99, ("Could not find master ip for %s\n", name));
1980                 return NULL;
1981         }
1982
1983         *pp_workgroup_out = talloc_strdup(ctx, name);
1984
1985         DEBUG(4, ("found master browser %s, %s\n", name, addr));
1986
1987         print_sockaddr(addr, sizeof(addr), &server_ss);
1988         cli = get_ipc_connect(addr, &server_ss, user_info);
1989
1990         return cli;
1991 }
1992
1993 /*
1994  * Return the IP address and workgroup of a master browser on the network, and
1995  * connect to it.
1996  */
1997
1998 struct cli_state *get_ipc_connect_master_ip_bcast(TALLOC_CTX *ctx,
1999                                         const struct user_auth_info *user_info,
2000                                         char **pp_workgroup_out)
2001 {
2002         struct ip_service *ip_list;
2003         struct cli_state *cli;
2004         int i, count;
2005
2006         *pp_workgroup_out = NULL;
2007
2008         DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
2009
2010         /* Go looking for workgroups by broadcasting on the local network */
2011
2012         if (!NT_STATUS_IS_OK(name_resolve_bcast(MSBROWSE, 1, &ip_list,
2013                                                 &count))) {
2014                 DEBUG(99, ("No master browsers responded\n"));
2015                 return False;
2016         }
2017
2018         for (i = 0; i < count; i++) {
2019                 char addr[INET6_ADDRSTRLEN];
2020                 print_sockaddr(addr, sizeof(addr), &ip_list[i].ss);
2021                 DEBUG(99, ("Found master browser %s\n", addr));
2022
2023                 cli = get_ipc_connect_master_ip(ctx, &ip_list[i],
2024                                 user_info, pp_workgroup_out);
2025                 if (cli)
2026                         return(cli);
2027         }
2028
2029         return NULL;
2030 }