When using plaintext ucs2 passwords clistr_push calls ucs2_align, which causes
[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 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, DATA_BLOB session_key_krb5)
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                         DATA_BLOB null_blob = data_blob_null;
564
565                         send_blob.length = remaining; 
566                         remaining = 0;
567
568                         /* This is the last packet in the sequence - turn signing on. */
569                         cli_simple_set_signing(cli, session_key_krb5, null_blob); 
570                 }
571
572                 send_blob.data =  &blob.data[cur];
573                 cur += send_blob.length;
574
575                 DEBUG(10, ("cli_session_setup_blob: Remaining (%u) sending (%u) current (%u)\n", 
576                         (unsigned int)remaining,
577                         (unsigned int)send_blob.length,
578                         (unsigned int)cur ));
579
580                 if (!cli_session_setup_blob_send(cli, send_blob)) {
581                         DEBUG(0, ("cli_session_setup_blob: send failed\n"));
582                         return False;
583                 }
584
585                 receive_blob = cli_session_setup_blob_receive(cli);
586                 data_blob_free(&receive_blob);
587
588                 if (cli_is_error(cli) &&
589                                 !NT_STATUS_EQUAL( cli_get_nt_error(cli), 
590                                         NT_STATUS_MORE_PROCESSING_REQUIRED)) {
591                         DEBUG(0, ("cli_session_setup_blob: receive failed "
592                                   "(%s)\n", nt_errstr(cli_get_nt_error(cli))));
593                         cli->vuid = 0;
594                         return False;
595                 }
596         }
597
598         return True;
599 }
600
601 /****************************************************************************
602  Use in-memory credentials cache
603 ****************************************************************************/
604
605 static void use_in_memory_ccache(void) {
606         setenv(KRB5_ENV_CCNAME, "MEMORY:cliconnect", 1);
607 }
608
609 /****************************************************************************
610  Do a spnego/kerberos encrypted session setup.
611 ****************************************************************************/
612
613 static ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli, const char *principal, const char *workgroup)
614 {
615         DATA_BLOB negTokenTarg;
616         DATA_BLOB session_key_krb5;
617         int rc;
618
619         DEBUG(2,("Doing kerberos session setup\n"));
620
621         /* generate the encapsulated kerberos5 ticket */
622         rc = spnego_gen_negTokenTarg(principal, 0, &negTokenTarg, &session_key_krb5, 0, NULL);
623
624         if (rc) {
625                 DEBUG(1, ("cli_session_setup_kerberos: spnego_gen_negTokenTarg failed: %s\n",
626                         error_message(rc)));
627                 return ADS_ERROR_KRB5(rc);
628         }
629
630 #if 0
631         file_save("negTokenTarg.dat", negTokenTarg.data, negTokenTarg.length);
632 #endif
633
634         if (!cli_session_setup_blob(cli, negTokenTarg, session_key_krb5)) {
635                 data_blob_free(&negTokenTarg);
636                 data_blob_free(&session_key_krb5);
637                 return ADS_ERROR_NT(cli_nt_error(cli));
638         }
639
640         cli_set_session_key(cli, session_key_krb5);
641
642         data_blob_free(&negTokenTarg);
643         data_blob_free(&session_key_krb5);
644
645         if (cli_is_error(cli)) {
646                 if (NT_STATUS_IS_OK(cli_nt_error(cli))) {
647                         return ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL);
648                 }
649         } 
650         return ADS_ERROR_NT(cli_nt_error(cli));
651 }
652 #endif  /* HAVE_KRB5 */
653
654
655 /****************************************************************************
656  Do a spnego/NTLMSSP encrypted session setup.
657 ****************************************************************************/
658
659 static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, 
660                                           const char *pass, const char *domain)
661 {
662         struct ntlmssp_state *ntlmssp_state;
663         NTSTATUS nt_status;
664         int turn = 1;
665         DATA_BLOB msg1;
666         DATA_BLOB blob = data_blob_null;
667         DATA_BLOB blob_in = data_blob_null;
668         DATA_BLOB blob_out = data_blob_null;
669
670         cli_temp_set_signing(cli);
671
672         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_client_start(&ntlmssp_state))) {
673                 return nt_status;
674         }
675         ntlmssp_want_feature(ntlmssp_state, NTLMSSP_FEATURE_SESSION_KEY);
676
677         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, user))) {
678                 return nt_status;
679         }
680         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, domain))) {
681                 return nt_status;
682         }
683         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_password(ntlmssp_state, pass))) {
684                 return nt_status;
685         }
686
687         do {
688                 nt_status = ntlmssp_update(ntlmssp_state, 
689                                                   blob_in, &blob_out);
690                 data_blob_free(&blob_in);
691                 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED) || NT_STATUS_IS_OK(nt_status)) {
692                         if (turn == 1) {
693                                 /* and wrap it in a SPNEGO wrapper */
694                                 msg1 = gen_negTokenInit(OID_NTLMSSP, blob_out);
695                         } else {
696                                 /* wrap it in SPNEGO */
697                                 msg1 = spnego_gen_auth(blob_out);
698                         }
699                 
700                         /* now send that blob on its way */
701                         if (!cli_session_setup_blob_send(cli, msg1)) {
702                                 DEBUG(3, ("Failed to send NTLMSSP/SPNEGO blob to server!\n"));
703                                 nt_status = NT_STATUS_UNSUCCESSFUL;
704                         } else {
705                                 blob = cli_session_setup_blob_receive(cli);
706                                 
707                                 nt_status = cli_nt_error(cli);
708                                 if (cli_is_error(cli) && NT_STATUS_IS_OK(nt_status)) {
709                                         if (cli->smb_rw_error == SMB_READ_BAD_SIG) {
710                                                 nt_status = NT_STATUS_ACCESS_DENIED;
711                                         } else {
712                                                 nt_status = NT_STATUS_UNSUCCESSFUL;
713                                         }
714                                 }
715                         }
716                         data_blob_free(&msg1);
717                 }
718                 
719                 if (!blob.length) {
720                         if (NT_STATUS_IS_OK(nt_status)) {
721                                 nt_status = NT_STATUS_UNSUCCESSFUL;
722                         }
723                 } else if ((turn == 1) && 
724                            NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
725                         DATA_BLOB tmp_blob = data_blob_null;
726                         /* the server might give us back two challenges */
727                         if (!spnego_parse_challenge(blob, &blob_in, 
728                                                     &tmp_blob)) {
729                                 DEBUG(3,("Failed to parse challenges\n"));
730                                 nt_status = NT_STATUS_INVALID_PARAMETER;
731                         }
732                         data_blob_free(&tmp_blob);
733                 } else {
734                         if (!spnego_parse_auth_response(blob, nt_status, OID_NTLMSSP, 
735                                                         &blob_in)) {
736                                 DEBUG(3,("Failed to parse auth response\n"));
737                                 if (NT_STATUS_IS_OK(nt_status) 
738                                     || NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) 
739                                         nt_status = NT_STATUS_INVALID_PARAMETER;
740                         }
741                 }
742                 data_blob_free(&blob);
743                 data_blob_free(&blob_out);
744                 turn++;
745         } while (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED));
746
747         data_blob_free(&blob_in);
748
749         if (NT_STATUS_IS_OK(nt_status)) {
750
751                 DATA_BLOB key = data_blob(ntlmssp_state->session_key.data,
752                                           ntlmssp_state->session_key.length);
753                 DATA_BLOB null_blob = data_blob_null;
754                 bool res;
755
756                 fstrcpy(cli->server_domain, ntlmssp_state->server_domain);
757                 cli_set_session_key(cli, ntlmssp_state->session_key);
758
759                 res = cli_simple_set_signing(cli, key, null_blob);
760
761                 data_blob_free(&key);
762
763                 if (res) {
764                         
765                         /* 'resign' the last message, so we get the right sequence numbers
766                            for checking the first reply from the server */
767                         cli_calculate_sign_mac(cli, cli->outbuf);
768                         
769                         if (!cli_check_sign_mac(cli, cli->inbuf)) {
770                                 nt_status = NT_STATUS_ACCESS_DENIED;
771                         }
772                 }
773         }
774
775         /* we have a reference conter on ntlmssp_state, if we are signing
776            then the state will be kept by the signing engine */
777
778         ntlmssp_end(&ntlmssp_state);
779
780         if (!NT_STATUS_IS_OK(nt_status)) {
781                 cli->vuid = 0;
782         }
783         return nt_status;
784 }
785
786 /****************************************************************************
787  Do a spnego encrypted session setup.
788 ****************************************************************************/
789
790 ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, 
791                               const char *pass, const char *domain)
792 {
793         char *principal;
794         char *OIDs[ASN1_MAX_OIDS];
795         int i;
796         bool got_kerberos_mechanism = False;
797         DATA_BLOB blob;
798
799         DEBUG(3,("Doing spnego session setup (blob length=%lu)\n", (unsigned long)cli->secblob.length));
800
801         /* the server might not even do spnego */
802         if (cli->secblob.length <= 16) {
803                 DEBUG(3,("server didn't supply a full spnego negprot\n"));
804                 goto ntlmssp;
805         }
806
807 #if 0
808         file_save("negprot.dat", cli->secblob.data, cli->secblob.length);
809 #endif
810
811         /* there is 16 bytes of GUID before the real spnego packet starts */
812         blob = data_blob(cli->secblob.data+16, cli->secblob.length-16);
813
814         /* the server sent us the first part of the SPNEGO exchange in the negprot 
815            reply */
816         if (!spnego_parse_negTokenInit(blob, OIDs, &principal)) {
817                 data_blob_free(&blob);
818                 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
819         }
820         data_blob_free(&blob);
821
822         /* make sure the server understands kerberos */
823         for (i=0;OIDs[i];i++) {
824                 DEBUG(3,("got OID=%s\n", OIDs[i]));
825                 if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0 ||
826                     strcmp(OIDs[i], OID_KERBEROS5) == 0) {
827                         got_kerberos_mechanism = True;
828                 }
829                 free(OIDs[i]);
830         }
831
832         DEBUG(3,("got principal=%s\n", principal ? principal : "<null>"));
833
834         if (got_kerberos_mechanism && (principal == NULL)) {
835                 /*
836                  * It is WRONG to depend on the principal sent in the negprot
837                  * reply, but right now we do it. So for safety (don't
838                  * segfault later) disable Kerberos when no principal was
839                  * sent. -- VL
840                  */
841                 DEBUG(1, ("Kerberos mech was offered, but no principal was "
842                           "sent, disabling Kerberos\n"));
843                 cli->use_kerberos = False;
844         }
845
846         fstrcpy(cli->user_name, user);
847
848 #ifdef HAVE_KRB5
849         /* If password is set we reauthenticate to kerberos server
850          * and do not store results */
851
852         if (got_kerberos_mechanism && cli->use_kerberos) {
853                 ADS_STATUS rc;
854
855                 if (pass && *pass) {
856                         int ret;
857                         
858                         use_in_memory_ccache();
859                         ret = kerberos_kinit_password(user, pass, 0 /* no time correction for now */, NULL);
860                         
861                         if (ret){
862                                 SAFE_FREE(principal);
863                                 DEBUG(0, ("Kinit failed: %s\n", error_message(ret)));
864                                 if (cli->fallback_after_kerberos)
865                                         goto ntlmssp;
866                                 return ADS_ERROR_KRB5(ret);
867                         }
868                 }
869                 
870                 /* If we get a bad principal, try to guess it if
871                    we have a valid host NetBIOS name.
872                  */
873                 if (strequal(principal, ADS_IGNORE_PRINCIPAL)) {
874                         SAFE_FREE(principal);
875                 }
876
877                 if (principal == NULL &&
878                         !is_ipaddress(cli->desthost) &&
879                         !strequal(star_smbserver_name,
880                                 cli->desthost)) {
881                         char *realm = NULL;
882                         char *machine = NULL;
883                         char *host = NULL;
884                         DEBUG(3,("cli_session_setup_spnego: got a "
885                                 "bad server principal, trying to guess ...\n"));
886
887                         host = strchr_m(cli->desthost, '.');
888                         if (host) {
889                                 machine = SMB_STRNDUP(cli->desthost,
890                                         host - cli->desthost);
891                         } else {
892                                 machine = SMB_STRDUP(cli->desthost);
893                         }
894                         if (machine == NULL) {
895                                 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
896                         }
897
898                         realm = kerberos_get_default_realm_from_ccache();
899                         if (realm && *realm) {
900                                 if (asprintf(&principal, "%s$@%s",
901                                                 machine, realm) < 0) {
902                                         SAFE_FREE(machine);
903                                         SAFE_FREE(realm);
904                                         return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
905                                 }
906                                 DEBUG(3,("cli_session_setup_spnego: guessed "
907                                         "server principal=%s\n",
908                                         principal ? principal : "<null>"));
909                         }
910                         SAFE_FREE(machine);
911                         SAFE_FREE(realm);
912                 }
913
914                 if (principal) {
915                         rc = cli_session_setup_kerberos(cli, principal, domain);
916                         if (ADS_ERR_OK(rc) || !cli->fallback_after_kerberos) {
917                                 SAFE_FREE(principal);
918                                 return rc;
919                         }
920                 }
921         }
922 #endif
923
924         SAFE_FREE(principal);
925
926 ntlmssp:
927
928         return ADS_ERROR_NT(cli_session_setup_ntlmssp(cli, user, pass, domain));
929 }
930
931 /****************************************************************************
932  Send a session setup. The username and workgroup is in UNIX character
933  format and must be converted to DOS codepage format before sending. If the
934  password is in plaintext, the same should be done.
935 ****************************************************************************/
936
937 NTSTATUS cli_session_setup(struct cli_state *cli,
938                            const char *user,
939                            const char *pass, int passlen,
940                            const char *ntpass, int ntpasslen,
941                            const char *workgroup)
942 {
943         char *p;
944         fstring user2;
945
946         if (user) {
947                 fstrcpy(user2, user);
948         } else {
949                 user2[0] ='\0';
950         }
951
952         if (!workgroup) {
953                 workgroup = "";
954         }
955
956         /* allow for workgroups as part of the username */
957         if ((p=strchr_m(user2,'\\')) || (p=strchr_m(user2,'/')) ||
958             (p=strchr_m(user2,*lp_winbind_separator()))) {
959                 *p = 0;
960                 user = p+1;
961                 workgroup = user2;
962         }
963
964         if (cli->protocol < PROTOCOL_LANMAN1) {
965                 return NT_STATUS_OK;
966         }
967
968         /* now work out what sort of session setup we are going to
969            do. I have split this into separate functions to make the
970            flow a bit easier to understand (tridge) */
971
972         /* if its an older server then we have to use the older request format */
973
974         if (cli->protocol < PROTOCOL_NT1) {
975                 if (!lp_client_lanman_auth() && passlen != 24 && (*pass)) {
976                         DEBUG(1, ("Server requested LM password but 'client lanman auth'"
977                                   " is disabled\n"));
978                         return NT_STATUS_ACCESS_DENIED;
979                 }
980
981                 if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0 &&
982                     !lp_client_plaintext_auth() && (*pass)) {
983                         DEBUG(1, ("Server requested plaintext password but "
984                                   "'client plaintext auth' is disabled\n"));
985                         return NT_STATUS_ACCESS_DENIED;
986                 }
987
988                 return cli_session_setup_lanman2(cli, user, pass, passlen,
989                                                  workgroup);
990         }
991
992         /* if no user is supplied then we have to do an anonymous connection.
993            passwords are ignored */
994
995         if (!user || !*user)
996                 return cli_session_setup_guest(cli);
997
998         /* if the server is share level then send a plaintext null
999            password at this point. The password is sent in the tree
1000            connect */
1001
1002         if ((cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0) 
1003                 return cli_session_setup_plaintext(cli, user, "", workgroup);
1004
1005         /* if the server doesn't support encryption then we have to use 
1006            plaintext. The second password is ignored */
1007
1008         if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) {
1009                 if (!lp_client_plaintext_auth() && (*pass)) {
1010                         DEBUG(1, ("Server requested plaintext password but "
1011                                   "'client plaintext auth' is disabled\n"));
1012                         return NT_STATUS_ACCESS_DENIED;
1013                 }
1014                 return cli_session_setup_plaintext(cli, user, pass, workgroup);
1015         }
1016
1017         /* if the server supports extended security then use SPNEGO */
1018
1019         if (cli->capabilities & CAP_EXTENDED_SECURITY) {
1020                 ADS_STATUS status = cli_session_setup_spnego(cli, user, pass, workgroup);
1021                 if (!ADS_ERR_OK(status)) {
1022                         DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status)));
1023                         return ads_ntstatus(status);
1024                 }
1025         } else {
1026                 NTSTATUS status;
1027
1028                 /* otherwise do a NT1 style session setup */
1029                 status = cli_session_setup_nt1(cli, user, pass, passlen,
1030                                                ntpass, ntpasslen, workgroup);
1031                 if (!NT_STATUS_IS_OK(status)) {
1032                         DEBUG(3,("cli_session_setup: NT1 session setup "
1033                                  "failed: %s\n", nt_errstr(status)));
1034                         return status;
1035                 }
1036         }
1037
1038         if (strstr(cli->server_type, "Samba")) {
1039                 cli->is_samba = True;
1040         }
1041
1042         return NT_STATUS_OK;
1043 }
1044
1045 /****************************************************************************
1046  Send a uloggoff.
1047 *****************************************************************************/
1048
1049 bool cli_ulogoff(struct cli_state *cli)
1050 {
1051         memset(cli->outbuf,'\0',smb_size);
1052         cli_set_message(cli->outbuf,2,0,True);
1053         SCVAL(cli->outbuf,smb_com,SMBulogoffX);
1054         cli_setup_packet(cli);
1055         SSVAL(cli->outbuf,smb_vwv0,0xFF);
1056         SSVAL(cli->outbuf,smb_vwv2,0);  /* no additional info */
1057
1058         cli_send_smb(cli);
1059         if (!cli_receive_smb(cli))
1060                 return False;
1061
1062         if (cli_is_error(cli)) {
1063                 return False;
1064         }
1065
1066         cli->cnum = -1;
1067         return True;
1068 }
1069
1070 /****************************************************************************
1071  Send a tconX.
1072 ****************************************************************************/
1073
1074 bool cli_send_tconX(struct cli_state *cli, 
1075                     const char *share, const char *dev, const char *pass, int passlen)
1076 {
1077         fstring fullshare, pword;
1078         char *p;
1079         memset(cli->outbuf,'\0',smb_size);
1080         memset(cli->inbuf,'\0',smb_size);
1081
1082         fstrcpy(cli->share, share);
1083
1084         /* in user level security don't send a password now */
1085         if (cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {
1086                 passlen = 1;
1087                 pass = "";
1088         } else if (!pass) {
1089                 DEBUG(1, ("Server not using user level security and no password supplied.\n"));
1090                 return False;
1091         }
1092
1093         if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) &&
1094             *pass && passlen != 24) {
1095                 if (!lp_client_lanman_auth()) {
1096                         DEBUG(1, ("Server requested LANMAN password (share-level security) but 'client use lanman auth'"
1097                                   " is disabled\n"));
1098                         return False;
1099                 }
1100
1101                 /*
1102                  * Non-encrypted passwords - convert to DOS codepage before encryption.
1103                  */
1104                 passlen = 24;
1105                 SMBencrypt(pass,cli->secblob.data,(uchar *)pword);
1106         } else {
1107                 if((cli->sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL|NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)) == 0) {
1108                         if (!lp_client_plaintext_auth() && (*pass)) {
1109                                 DEBUG(1, ("Server requested plaintext "
1110                                           "password but 'client plaintext "
1111                                           "auth' is disabled\n"));
1112                                 return False;
1113                         }
1114
1115                         /*
1116                          * Non-encrypted passwords - convert to DOS codepage before using.
1117                          */
1118                         passlen = clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE);
1119                         
1120                 } else {
1121                         if (passlen) {
1122                                 memcpy(pword, pass, passlen);
1123                         }
1124                 }
1125         }
1126
1127         slprintf(fullshare, sizeof(fullshare)-1,
1128                  "\\\\%s\\%s", cli->desthost, share);
1129
1130         cli_set_message(cli->outbuf,4, 0, True);
1131         SCVAL(cli->outbuf,smb_com,SMBtconX);
1132         cli_setup_packet(cli);
1133
1134         SSVAL(cli->outbuf,smb_vwv0,0xFF);
1135         SSVAL(cli->outbuf,smb_vwv2,TCONX_FLAG_EXTENDED_RESPONSE);
1136         SSVAL(cli->outbuf,smb_vwv3,passlen);
1137
1138         p = smb_buf(cli->outbuf);
1139         if (passlen) {
1140                 memcpy(p,pword,passlen);
1141         }
1142         p += passlen;
1143         p += clistr_push(cli, p, fullshare, -1, STR_TERMINATE |STR_UPPER);
1144         p += clistr_push(cli, p, dev, -1, STR_TERMINATE |STR_UPPER | STR_ASCII);
1145
1146         cli_setup_bcc(cli, p);
1147
1148         cli_send_smb(cli);
1149         if (!cli_receive_smb(cli))
1150                 return False;
1151
1152         if (cli_is_error(cli))
1153                 return False;
1154
1155         clistr_pull(cli, cli->dev, smb_buf(cli->inbuf), sizeof(fstring), -1, STR_TERMINATE|STR_ASCII);
1156
1157         if (cli->protocol >= PROTOCOL_NT1 &&
1158             smb_buflen(cli->inbuf) == 3) {
1159                 /* almost certainly win95 - enable bug fixes */
1160                 cli->win95 = True;
1161         }
1162         
1163         /* Make sure that we have the optional support 16-bit field.  WCT > 2 */
1164         /* Avoids issues when connecting to Win9x boxes sharing files */
1165
1166         cli->dfsroot = False;
1167         if ( (CVAL(cli->inbuf, smb_wct))>2 && cli->protocol >= PROTOCOL_LANMAN2 )
1168                 cli->dfsroot = (SVAL( cli->inbuf, smb_vwv2 ) & SMB_SHARE_IN_DFS) ? True : False;
1169
1170         cli->cnum = SVAL(cli->inbuf,smb_tid);
1171         return True;
1172 }
1173
1174 /****************************************************************************
1175  Send a tree disconnect.
1176 ****************************************************************************/
1177
1178 bool cli_tdis(struct cli_state *cli)
1179 {
1180         memset(cli->outbuf,'\0',smb_size);
1181         cli_set_message(cli->outbuf,0,0,True);
1182         SCVAL(cli->outbuf,smb_com,SMBtdis);
1183         SSVAL(cli->outbuf,smb_tid,cli->cnum);
1184         cli_setup_packet(cli);
1185         
1186         cli_send_smb(cli);
1187         if (!cli_receive_smb(cli))
1188                 return False;
1189         
1190         if (cli_is_error(cli)) {
1191                 return False;
1192         }
1193
1194         cli->cnum = -1;
1195         return True;
1196 }
1197
1198 /****************************************************************************
1199  Send a negprot command.
1200 ****************************************************************************/
1201
1202 void cli_negprot_send(struct cli_state *cli)
1203 {
1204         char *p;
1205         int numprots;
1206
1207         if (cli->protocol < PROTOCOL_NT1)
1208                 cli->use_spnego = False;
1209
1210         memset(cli->outbuf,'\0',smb_size);
1211
1212         /* setup the protocol strings */
1213         cli_set_message(cli->outbuf,0,0,True);
1214
1215         p = smb_buf(cli->outbuf);
1216         for (numprots=0;
1217              prots[numprots].name && prots[numprots].prot<=cli->protocol;
1218              numprots++) {
1219                 *p++ = 2;
1220                 p += clistr_push(cli, p, prots[numprots].name, -1, STR_TERMINATE);
1221         }
1222
1223         SCVAL(cli->outbuf,smb_com,SMBnegprot);
1224         cli_setup_bcc(cli, p);
1225         cli_setup_packet(cli);
1226
1227         SCVAL(smb_buf(cli->outbuf),0,2);
1228
1229         cli_send_smb(cli);
1230 }
1231
1232 /****************************************************************************
1233  Send a negprot command.
1234 ****************************************************************************/
1235
1236 bool cli_negprot(struct cli_state *cli)
1237 {
1238         char *p;
1239         int numprots;
1240         int plength;
1241
1242         if (cli->protocol < PROTOCOL_NT1)
1243                 cli->use_spnego = False;
1244
1245         memset(cli->outbuf,'\0',smb_size);
1246
1247         /* setup the protocol strings */
1248         for (plength=0,numprots=0;
1249              prots[numprots].name && prots[numprots].prot<=cli->protocol;
1250              numprots++)
1251                 plength += strlen(prots[numprots].name)+2;
1252     
1253         cli_set_message(cli->outbuf,0,plength,True);
1254
1255         p = smb_buf(cli->outbuf);
1256         for (numprots=0;
1257              prots[numprots].name && prots[numprots].prot<=cli->protocol;
1258              numprots++) {
1259                 *p++ = 2;
1260                 p += clistr_push(cli, p, prots[numprots].name, -1, STR_TERMINATE);
1261         }
1262
1263         SCVAL(cli->outbuf,smb_com,SMBnegprot);
1264         cli_setup_packet(cli);
1265
1266         SCVAL(smb_buf(cli->outbuf),0,2);
1267
1268         cli_send_smb(cli);
1269         if (!cli_receive_smb(cli))
1270                 return False;
1271
1272         show_msg(cli->inbuf);
1273
1274         if (cli_is_error(cli) ||
1275             ((int)SVAL(cli->inbuf,smb_vwv0) >= numprots)) {
1276                 return(False);
1277         }
1278
1279         cli->protocol = prots[SVAL(cli->inbuf,smb_vwv0)].prot;  
1280
1281         if ((cli->protocol < PROTOCOL_NT1) && cli->sign_info.mandatory_signing) {
1282                 DEBUG(0,("cli_negprot: SMB signing is mandatory and the selected protocol level doesn't support it.\n"));
1283                 return False;
1284         }
1285
1286         if (cli->protocol >= PROTOCOL_NT1) {    
1287                 struct timespec ts;
1288                 /* NT protocol */
1289                 cli->sec_mode = CVAL(cli->inbuf,smb_vwv1);
1290                 cli->max_mux = SVAL(cli->inbuf, smb_vwv1+1);
1291                 cli->max_xmit = IVAL(cli->inbuf,smb_vwv3+1);
1292                 cli->sesskey = IVAL(cli->inbuf,smb_vwv7+1);
1293                 cli->serverzone = SVALS(cli->inbuf,smb_vwv15+1);
1294                 cli->serverzone *= 60;
1295                 /* this time arrives in real GMT */
1296                 ts = interpret_long_date(cli->inbuf+smb_vwv11+1);
1297                 cli->servertime = ts.tv_sec;
1298                 cli->secblob = data_blob(smb_buf(cli->inbuf),smb_buflen(cli->inbuf));
1299                 cli->capabilities = IVAL(cli->inbuf,smb_vwv9+1);
1300                 if (cli->capabilities & CAP_RAW_MODE) {
1301                         cli->readbraw_supported = True;
1302                         cli->writebraw_supported = True;      
1303                 }
1304                 /* work out if they sent us a workgroup */
1305                 if (!(cli->capabilities & CAP_EXTENDED_SECURITY) &&
1306                     smb_buflen(cli->inbuf) > 8) {
1307                         clistr_pull(cli, cli->server_domain, 
1308                                     smb_buf(cli->inbuf)+8, sizeof(cli->server_domain),
1309                                     smb_buflen(cli->inbuf)-8, STR_UNICODE|STR_NOALIGN);
1310                 }
1311
1312                 /*
1313                  * As signing is slow we only turn it on if either the client or
1314                  * the server require it. JRA.
1315                  */
1316
1317                 if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) {
1318                         /* Fail if server says signing is mandatory and we don't want to support it. */
1319                         if (!cli->sign_info.allow_smb_signing) {
1320                                 DEBUG(0,("cli_negprot: SMB signing is mandatory and we have disabled it.\n"));
1321                                 return False;
1322                         }
1323                         cli->sign_info.negotiated_smb_signing = True;
1324                         cli->sign_info.mandatory_signing = True;
1325                 } else if (cli->sign_info.mandatory_signing && cli->sign_info.allow_smb_signing) {
1326                         /* Fail if client says signing is mandatory and the server doesn't support it. */
1327                         if (!(cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) {
1328                                 DEBUG(1,("cli_negprot: SMB signing is mandatory and the server doesn't support it.\n"));
1329                                 return False;
1330                         }
1331                         cli->sign_info.negotiated_smb_signing = True;
1332                         cli->sign_info.mandatory_signing = True;
1333                 } else if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) {
1334                         cli->sign_info.negotiated_smb_signing = True;
1335                 }
1336
1337                 if (cli->capabilities & (CAP_LARGE_READX|CAP_LARGE_WRITEX)) {
1338                         SAFE_FREE(cli->outbuf);
1339                         SAFE_FREE(cli->inbuf);
1340                         cli->outbuf = (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE+SAFETY_MARGIN);
1341                         cli->inbuf = (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE+SAFETY_MARGIN);
1342                         cli->bufsize = CLI_SAMBA_MAX_LARGE_READX_SIZE;
1343                 }
1344
1345         } else if (cli->protocol >= PROTOCOL_LANMAN1) {
1346                 cli->use_spnego = False;
1347                 cli->sec_mode = SVAL(cli->inbuf,smb_vwv1);
1348                 cli->max_xmit = SVAL(cli->inbuf,smb_vwv2);
1349                 cli->max_mux = SVAL(cli->inbuf, smb_vwv3); 
1350                 cli->sesskey = IVAL(cli->inbuf,smb_vwv6);
1351                 cli->serverzone = SVALS(cli->inbuf,smb_vwv10);
1352                 cli->serverzone *= 60;
1353                 /* this time is converted to GMT by make_unix_date */
1354                 cli->servertime = cli_make_unix_date(cli,cli->inbuf+smb_vwv8);
1355                 cli->readbraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x1) != 0);
1356                 cli->writebraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x2) != 0);
1357                 cli->secblob = data_blob(smb_buf(cli->inbuf),smb_buflen(cli->inbuf));
1358         } else {
1359                 /* the old core protocol */
1360                 cli->use_spnego = False;
1361                 cli->sec_mode = 0;
1362                 cli->serverzone = get_time_zone(time(NULL));
1363         }
1364
1365         cli->max_xmit = MIN(cli->max_xmit, CLI_BUFFER_SIZE);
1366
1367         /* a way to force ascii SMB */
1368         if (getenv("CLI_FORCE_ASCII"))
1369                 cli->capabilities &= ~CAP_UNICODE;
1370
1371         return True;
1372 }
1373
1374 /****************************************************************************
1375  Send a session request. See rfc1002.txt 4.3 and 4.3.2.
1376 ****************************************************************************/
1377
1378 bool cli_session_request(struct cli_state *cli,
1379                          struct nmb_name *calling, struct nmb_name *called)
1380 {
1381         char *p;
1382         int len = 4;
1383
1384         memcpy(&(cli->calling), calling, sizeof(*calling));
1385         memcpy(&(cli->called ), called , sizeof(*called ));
1386   
1387         /* put in the destination name */
1388         p = cli->outbuf+len;
1389         name_mangle(cli->called .name, p, cli->called .name_type);
1390         len += name_len(p);
1391
1392         /* and my name */
1393         p = cli->outbuf+len;
1394         name_mangle(cli->calling.name, p, cli->calling.name_type);
1395         len += name_len(p);
1396
1397         /* 445 doesn't have session request */
1398         if (cli->port == 445)
1399                 return True;
1400
1401         /* send a session request (RFC 1002) */
1402         /* setup the packet length
1403          * Remove four bytes from the length count, since the length
1404          * field in the NBT Session Service header counts the number
1405          * of bytes which follow.  The cli_send_smb() function knows
1406          * about this and accounts for those four bytes.
1407          * CRH.
1408          */
1409         len -= 4;
1410         _smb_setlen(cli->outbuf,len);
1411         SCVAL(cli->outbuf,0,0x81);
1412
1413         cli_send_smb(cli);
1414         DEBUG(5,("Sent session request\n"));
1415
1416         if (!cli_receive_smb(cli))
1417                 return False;
1418
1419         if (CVAL(cli->inbuf,0) == 0x84) {
1420                 /* C. Hoch  9/14/95 Start */
1421                 /* For information, here is the response structure.
1422                  * We do the byte-twiddling to for portability.
1423                 struct RetargetResponse{
1424                 unsigned char type;
1425                 unsigned char flags;
1426                 int16 length;
1427                 int32 ip_addr;
1428                 int16 port;
1429                 };
1430                 */
1431                 uint16_t port = (CVAL(cli->inbuf,8)<<8)+CVAL(cli->inbuf,9);
1432                 struct in_addr dest_ip;
1433
1434                 /* SESSION RETARGET */
1435                 putip((char *)&dest_ip,cli->inbuf+4);
1436                 in_addr_to_sockaddr_storage(&cli->dest_ss, dest_ip);
1437
1438                 cli->fd = open_socket_out(SOCK_STREAM,
1439                                 &cli->dest_ss,
1440                                 port,
1441                                 LONG_CONNECT_TIMEOUT);
1442                 if (cli->fd == -1)
1443                         return False;
1444
1445                 DEBUG(3,("Retargeted\n"));
1446
1447                 set_socket_options(cli->fd, lp_socket_options());
1448
1449                 /* Try again */
1450                 {
1451                         static int depth;
1452                         bool ret;
1453                         if (depth > 4) {
1454                                 DEBUG(0,("Retarget recursion - failing\n"));
1455                                 return False;
1456                         }
1457                         depth++;
1458                         ret = cli_session_request(cli, calling, called);
1459                         depth--;
1460                         return ret;
1461                 }
1462         } /* C. Hoch 9/14/95 End */
1463
1464         if (CVAL(cli->inbuf,0) != 0x82) {
1465                 /* This is the wrong place to put the error... JRA. */
1466                 cli->rap_error = CVAL(cli->inbuf,4);
1467                 return False;
1468         }
1469         return(True);
1470 }
1471
1472 /****************************************************************************
1473  Open the client sockets.
1474 ****************************************************************************/
1475
1476 NTSTATUS cli_connect(struct cli_state *cli,
1477                 const char *host,
1478                 struct sockaddr_storage *dest_ss)
1479
1480 {
1481         int name_type = 0x20;
1482         TALLOC_CTX *frame = talloc_stackframe();
1483         unsigned int num_addrs = 0;
1484         unsigned int i = 0;
1485         struct sockaddr_storage *ss_arr = NULL;
1486         char *p = NULL;
1487
1488         /* reasonable default hostname */
1489         if (!host) {
1490                 host = star_smbserver_name;
1491         }
1492
1493         fstrcpy(cli->desthost, host);
1494         fstr_sprintf(cli->srv_name_slash, "\\\\%s", cli->desthost);
1495         strupper_m(cli->srv_name_slash);
1496
1497         /* allow hostnames of the form NAME#xx and do a netbios lookup */
1498         if ((p = strchr(cli->desthost, '#'))) {
1499                 name_type = strtol(p+1, NULL, 16);
1500                 *p = 0;
1501         }
1502
1503         if (!dest_ss || is_zero_addr(dest_ss)) {
1504                 NTSTATUS status =resolve_name_list(frame,
1505                                         cli->desthost,
1506                                         name_type,
1507                                         &ss_arr,
1508                                         &num_addrs);
1509                 if (!NT_STATUS_IS_OK(status)) {
1510                         TALLOC_FREE(frame);
1511                         return NT_STATUS_BAD_NETWORK_NAME;
1512                 }
1513         } else {
1514                 num_addrs = 1;
1515                 ss_arr = TALLOC_P(frame, struct sockaddr_storage);
1516                 if (!ss_arr) {
1517                         TALLOC_FREE(frame);
1518                         return NT_STATUS_NO_MEMORY;
1519                 }
1520                 *ss_arr = *dest_ss;
1521         }
1522
1523         for (i = 0; i < num_addrs; i++) {
1524                 cli->dest_ss = ss_arr[i];
1525                 if (getenv("LIBSMB_PROG")) {
1526                         cli->fd = sock_exec(getenv("LIBSMB_PROG"));
1527                 } else {
1528                         /* try 445 first, then 139 */
1529                         uint16_t port = cli->port?cli->port:445;
1530                         cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ss,
1531                                                   port, cli->timeout);
1532                         if (cli->fd == -1 && cli->port == 0) {
1533                                 port = 139;
1534                                 cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ss,
1535                                                           port, cli->timeout);
1536                         }
1537                         if (cli->fd != -1) {
1538                                 cli->port = port;
1539                         }
1540                 }
1541                 if (cli->fd == -1) {
1542                         char addr[INET6_ADDRSTRLEN];
1543                         print_sockaddr(addr, sizeof(addr), &ss_arr[i]);
1544                         DEBUG(2,("Error connecting to %s (%s)\n",
1545                                  dest_ss?addr:host,strerror(errno)));
1546                 } else {
1547                         /* Exit from loop on first connection. */
1548                         break;
1549                 }
1550         }
1551
1552         if (cli->fd == -1) {
1553                 TALLOC_FREE(frame);
1554                 return map_nt_error_from_unix(errno);
1555         }
1556
1557         if (dest_ss) {
1558                 *dest_ss = cli->dest_ss;
1559         }
1560
1561         set_socket_options(cli->fd, lp_socket_options());
1562
1563         TALLOC_FREE(frame);
1564         return NT_STATUS_OK;
1565 }
1566
1567 /**
1568    establishes a connection to after the negprot. 
1569    @param output_cli A fully initialised cli structure, non-null only on success
1570    @param dest_host The netbios name of the remote host
1571    @param dest_ss (optional) The the destination IP, NULL for name based lookup
1572    @param port (optional) The destination port (0 for default)
1573    @param retry bool. Did this connection fail with a retryable error ?
1574
1575 */
1576 NTSTATUS cli_start_connection(struct cli_state **output_cli, 
1577                               const char *my_name, 
1578                               const char *dest_host, 
1579                               struct sockaddr_storage *dest_ss, int port,
1580                               int signing_state, int flags,
1581                               bool *retry) 
1582 {
1583         NTSTATUS nt_status;
1584         struct nmb_name calling;
1585         struct nmb_name called;
1586         struct cli_state *cli;
1587         struct sockaddr_storage ss;
1588
1589         if (retry)
1590                 *retry = False;
1591
1592         if (!my_name) 
1593                 my_name = global_myname();
1594         
1595         if (!(cli = cli_initialise())) {
1596                 return NT_STATUS_NO_MEMORY;
1597         }
1598         
1599         make_nmb_name(&calling, my_name, 0x0);
1600         make_nmb_name(&called , dest_host, 0x20);
1601
1602         if (cli_set_port(cli, port) != port) {
1603                 cli_shutdown(cli);
1604                 return NT_STATUS_UNSUCCESSFUL;
1605         }
1606
1607         cli_set_timeout(cli, 10000); /* 10 seconds. */
1608
1609         if (dest_ss) {
1610                 ss = *dest_ss;
1611         } else {
1612                 zero_addr(&ss);
1613         }
1614
1615 again:
1616
1617         DEBUG(3,("Connecting to host=%s\n", dest_host));
1618
1619         nt_status = cli_connect(cli, dest_host, &ss);
1620         if (!NT_STATUS_IS_OK(nt_status)) {
1621                 char addr[INET6_ADDRSTRLEN];
1622                 print_sockaddr(addr, sizeof(addr), &ss);
1623                 DEBUG(1,("cli_start_connection: failed to connect to %s (%s). Error %s\n",
1624                          nmb_namestr(&called), addr, nt_errstr(nt_status) ));
1625                 cli_shutdown(cli);
1626                 return nt_status;
1627         }
1628
1629         if (retry)
1630                 *retry = True;
1631
1632         if (!cli_session_request(cli, &calling, &called)) {
1633                 char *p;
1634                 DEBUG(1,("session request to %s failed (%s)\n",
1635                          called.name, cli_errstr(cli)));
1636                 if ((p=strchr(called.name, '.')) && !is_ipaddress(called.name)) {
1637                         *p = 0;
1638                         goto again;
1639                 }
1640                 if (strcmp(called.name, star_smbserver_name)) {
1641                         make_nmb_name(&called , star_smbserver_name, 0x20);
1642                         goto again;
1643                 }
1644                 return NT_STATUS_BAD_NETWORK_NAME;
1645         }
1646
1647         cli_setup_signing_state(cli, signing_state);
1648
1649         if (flags & CLI_FULL_CONNECTION_DONT_SPNEGO)
1650                 cli->use_spnego = False;
1651         else if (flags & CLI_FULL_CONNECTION_USE_KERBEROS)
1652                 cli->use_kerberos = True;
1653
1654         if (!cli_negprot(cli)) {
1655                 DEBUG(1,("failed negprot\n"));
1656                 nt_status = cli_nt_error(cli);
1657                 if (NT_STATUS_IS_OK(nt_status)) {
1658                         nt_status = NT_STATUS_UNSUCCESSFUL;
1659                 }
1660                 cli_shutdown(cli);
1661                 return nt_status;
1662         }
1663
1664         *output_cli = cli;
1665         return NT_STATUS_OK;
1666 }
1667
1668
1669 /**
1670    establishes a connection right up to doing tconX, password specified.
1671    @param output_cli A fully initialised cli structure, non-null only on success
1672    @param dest_host The netbios name of the remote host
1673    @param dest_ip (optional) The the destination IP, NULL for name based lookup
1674    @param port (optional) The destination port (0 for default)
1675    @param service (optional) The share to make the connection to.  Should be 'unqualified' in any way.
1676    @param service_type The 'type' of serivice. 
1677    @param user Username, unix string
1678    @param domain User's domain
1679    @param password User's password, unencrypted unix string.
1680    @param retry bool. Did this connection fail with a retryable error ?
1681 */
1682
1683 NTSTATUS cli_full_connection(struct cli_state **output_cli, 
1684                              const char *my_name, 
1685                              const char *dest_host, 
1686                              struct sockaddr_storage *dest_ss, int port,
1687                              const char *service, const char *service_type,
1688                              const char *user, const char *domain, 
1689                              const char *password, int flags,
1690                              int signing_state,
1691                              bool *retry) 
1692 {
1693         NTSTATUS nt_status;
1694         struct cli_state *cli = NULL;
1695         int pw_len = password ? strlen(password)+1 : 0;
1696
1697         *output_cli = NULL;
1698
1699         if (password == NULL) {
1700                 password = "";
1701         }
1702
1703         nt_status = cli_start_connection(&cli, my_name, dest_host,
1704                                          dest_ss, port, signing_state,
1705                                          flags, retry);
1706
1707         if (!NT_STATUS_IS_OK(nt_status)) {
1708                 return nt_status;
1709         }
1710
1711         nt_status = cli_session_setup(cli, user, password, pw_len, password,
1712                                       pw_len, domain);
1713         if (!NT_STATUS_IS_OK(nt_status)) {
1714
1715                 if (!(flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)) {
1716                         DEBUG(1,("failed session setup with %s\n",
1717                                  nt_errstr(nt_status)));
1718                         cli_shutdown(cli);
1719                         return nt_status;
1720                 }
1721
1722                 nt_status = cli_session_setup(cli, "", "", 0, "", 0, domain);
1723                 if (!NT_STATUS_IS_OK(nt_status)) {
1724                         DEBUG(1,("anonymous failed session setup with %s\n",
1725                                  nt_errstr(nt_status)));
1726                         cli_shutdown(cli);
1727                         return nt_status;
1728                 }
1729         }
1730
1731         if (service) {
1732                 if (!cli_send_tconX(cli, service, service_type, password, pw_len)) {
1733                         nt_status = cli_nt_error(cli);
1734                         DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status)));
1735                         cli_shutdown(cli);
1736                         if (NT_STATUS_IS_OK(nt_status)) {
1737                                 nt_status = NT_STATUS_UNSUCCESSFUL;
1738                         }
1739                         return nt_status;
1740                 }
1741         }
1742
1743         cli_init_creds(cli, user, domain, password);
1744
1745         *output_cli = cli;
1746         return NT_STATUS_OK;
1747 }
1748
1749 /****************************************************************************
1750  Attempt a NetBIOS session request, falling back to *SMBSERVER if needed.
1751 ****************************************************************************/
1752
1753 bool attempt_netbios_session_request(struct cli_state **ppcli, const char *srchost, const char *desthost,
1754                                      struct sockaddr_storage *pdest_ss)
1755 {
1756         struct nmb_name calling, called;
1757
1758         make_nmb_name(&calling, srchost, 0x0);
1759
1760         /*
1761          * If the called name is an IP address
1762          * then use *SMBSERVER immediately.
1763          */
1764
1765         if(is_ipaddress(desthost)) {
1766                 make_nmb_name(&called, star_smbserver_name, 0x20);
1767         } else {
1768                 make_nmb_name(&called, desthost, 0x20);
1769         }
1770
1771         if (!cli_session_request(*ppcli, &calling, &called)) {
1772                 NTSTATUS status;
1773                 struct nmb_name smbservername;
1774
1775                 make_nmb_name(&smbservername, star_smbserver_name, 0x20);
1776
1777                 /*
1778                  * If the name wasn't *SMBSERVER then
1779                  * try with *SMBSERVER if the first name fails.
1780                  */
1781
1782                 if (nmb_name_equal(&called, &smbservername)) {
1783
1784                         /*
1785                          * The name used was *SMBSERVER, don't bother with another name.
1786                          */
1787
1788                         DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER \
1789 with error %s.\n", desthost, cli_errstr(*ppcli) ));
1790                         return False;
1791                 }
1792
1793                 /* Try again... */
1794                 cli_shutdown(*ppcli);
1795
1796                 *ppcli = cli_initialise();
1797                 if (!*ppcli) {
1798                         /* Out of memory... */
1799                         return False;
1800                 }
1801
1802                 status = cli_connect(*ppcli, desthost, pdest_ss);
1803                 if (!NT_STATUS_IS_OK(status) ||
1804                                 !cli_session_request(*ppcli, &calling, &smbservername)) {
1805                         DEBUG(0,("attempt_netbios_session_request: %s rejected the session for \
1806 name *SMBSERVER with error %s\n", desthost, cli_errstr(*ppcli) ));
1807                         return False;
1808                 }
1809         }
1810
1811         return True;
1812 }
1813
1814 /****************************************************************************
1815  Send an old style tcon.
1816 ****************************************************************************/
1817 NTSTATUS cli_raw_tcon(struct cli_state *cli, 
1818                       const char *service, const char *pass, const char *dev,
1819                       uint16 *max_xmit, uint16 *tid)
1820 {
1821         char *p;
1822
1823         if (!lp_client_plaintext_auth() && (*pass)) {
1824                 DEBUG(1, ("Server requested plaintext password but 'client "
1825                           "plaintext auth' is disabled\n"));
1826                 return NT_STATUS_ACCESS_DENIED;
1827         }
1828
1829         memset(cli->outbuf,'\0',smb_size);
1830         memset(cli->inbuf,'\0',smb_size);
1831
1832         cli_set_message(cli->outbuf, 0, 0, True);
1833         SCVAL(cli->outbuf,smb_com,SMBtcon);
1834         cli_setup_packet(cli);
1835
1836         p = smb_buf(cli->outbuf);
1837         *p++ = 4; p += clistr_push(cli, p, service, -1, STR_TERMINATE | STR_NOALIGN);
1838         *p++ = 4; p += clistr_push(cli, p, pass, -1, STR_TERMINATE | STR_NOALIGN);
1839         *p++ = 4; p += clistr_push(cli, p, dev, -1, STR_TERMINATE | STR_NOALIGN);
1840
1841         cli_setup_bcc(cli, p);
1842
1843         cli_send_smb(cli);
1844         if (!cli_receive_smb(cli)) {
1845                 return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
1846         }
1847
1848         if (cli_is_error(cli)) {
1849                 return cli_nt_error(cli);
1850         }
1851
1852         *max_xmit = SVAL(cli->inbuf, smb_vwv0);
1853         *tid = SVAL(cli->inbuf, smb_vwv1);
1854
1855         return NT_STATUS_OK;
1856 }
1857
1858 /* Return a cli_state pointing at the IPC$ share for the given server */
1859
1860 struct cli_state *get_ipc_connect(char *server,
1861                                 struct sockaddr_storage *server_ss,
1862                                 const struct user_auth_info *user_info)
1863 {
1864         struct cli_state *cli;
1865         NTSTATUS nt_status;
1866
1867         nt_status = cli_full_connection(&cli, NULL, server, server_ss, 0, "IPC$", "IPC", 
1868                                         user_info->username ? user_info->username : "",
1869                                         lp_workgroup(),
1870                                         user_info->password ? user_info->password : "",
1871                                         CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK, Undefined, NULL);
1872
1873         if (NT_STATUS_IS_OK(nt_status)) {
1874                 return cli;
1875         } else if (is_ipaddress(server)) {
1876             /* windows 9* needs a correct NMB name for connections */
1877             fstring remote_name;
1878
1879             if (name_status_find("*", 0, 0, server_ss, remote_name)) {
1880                 cli = get_ipc_connect(remote_name, server_ss, user_info);
1881                 if (cli)
1882                     return cli;
1883             }
1884         }
1885         return NULL;
1886 }
1887
1888 /*
1889  * Given the IP address of a master browser on the network, return its
1890  * workgroup and connect to it.
1891  *
1892  * This function is provided to allow additional processing beyond what
1893  * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
1894  * browsers and obtain each master browsers' list of domains (in case the
1895  * first master browser is recently on the network and has not yet
1896  * synchronized with other master browsers and therefore does not yet have the
1897  * entire network browse list)
1898  */
1899
1900 struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx,
1901                                 struct ip_service *mb_ip,
1902                                 const struct user_auth_info *user_info,
1903                                 char **pp_workgroup_out)
1904 {
1905         char addr[INET6_ADDRSTRLEN];
1906         fstring name;
1907         struct cli_state *cli;
1908         struct sockaddr_storage server_ss;
1909
1910         *pp_workgroup_out = NULL;
1911
1912         print_sockaddr(addr, sizeof(addr), &mb_ip->ss);
1913         DEBUG(99, ("Looking up name of master browser %s\n",
1914                    addr));
1915
1916         /*
1917          * Do a name status query to find out the name of the master browser.
1918          * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
1919          * master browser will not respond to a wildcard query (or, at least,
1920          * an NT4 server acting as the domain master browser will not).
1921          *
1922          * We might be able to use ONLY the query on MSBROWSE, but that's not
1923          * yet been tested with all Windows versions, so until it is, leave
1924          * the original wildcard query as the first choice and fall back to
1925          * MSBROWSE if the wildcard query fails.
1926          */
1927         if (!name_status_find("*", 0, 0x1d, &mb_ip->ss, name) &&
1928             !name_status_find(MSBROWSE, 1, 0x1d, &mb_ip->ss, name)) {
1929
1930                 DEBUG(99, ("Could not retrieve name status for %s\n",
1931                            addr));
1932                 return NULL;
1933         }
1934
1935         if (!find_master_ip(name, &server_ss)) {
1936                 DEBUG(99, ("Could not find master ip for %s\n", name));
1937                 return NULL;
1938         }
1939
1940         *pp_workgroup_out = talloc_strdup(ctx, name);
1941
1942         DEBUG(4, ("found master browser %s, %s\n", name, addr));
1943
1944         print_sockaddr(addr, sizeof(addr), &server_ss);
1945         cli = get_ipc_connect(addr, &server_ss, user_info);
1946
1947         return cli;
1948 }
1949
1950 /*
1951  * Return the IP address and workgroup of a master browser on the network, and
1952  * connect to it.
1953  */
1954
1955 struct cli_state *get_ipc_connect_master_ip_bcast(TALLOC_CTX *ctx,
1956                                         const struct user_auth_info *user_info,
1957                                         char **pp_workgroup_out)
1958 {
1959         struct ip_service *ip_list;
1960         struct cli_state *cli;
1961         int i, count;
1962
1963         *pp_workgroup_out = NULL;
1964
1965         DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
1966
1967         /* Go looking for workgroups by broadcasting on the local network */
1968
1969         if (!NT_STATUS_IS_OK(name_resolve_bcast(MSBROWSE, 1, &ip_list,
1970                                                 &count))) {
1971                 DEBUG(99, ("No master browsers responded\n"));
1972                 return False;
1973         }
1974
1975         for (i = 0; i < count; i++) {
1976                 char addr[INET6_ADDRSTRLEN];
1977                 print_sockaddr(addr, sizeof(addr), &ip_list[i].ss);
1978                 DEBUG(99, ("Found master browser %s\n", addr));
1979
1980                 cli = get_ipc_connect_master_ip(ctx, &ip_list[i],
1981                                 user_info, pp_workgroup_out);
1982                 if (cli)
1983                         return(cli);
1984         }
1985
1986         return NULL;
1987 }