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