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