Fix bug #9117 - smbclient can't connect to a Windows 7 server using NTLMv2 (crypto...
[samba.git] / source3 / libsmb / cliconnect.c
1 /* 
2    Unix SMB/CIFS implementation.
3    client connect/disconnect routines
4    Copyright (C) Andrew Tridgell 1994-1998
5    Copyright (C) Andrew Bartlett 2001-2003
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "includes.h"
22 #include "../libcli/auth/libcli_auth.h"
23 #include "../libcli/auth/spnego.h"
24 #include "smb_krb5.h"
25
26 static const struct {
27         int prot;
28         const char name[24];
29 } prots[10] = {
30         {PROTOCOL_CORE,         "PC NETWORK PROGRAM 1.0"},
31         {PROTOCOL_COREPLUS,     "MICROSOFT NETWORKS 1.03"},
32         {PROTOCOL_LANMAN1,      "MICROSOFT NETWORKS 3.0"},
33         {PROTOCOL_LANMAN1,      "LANMAN1.0"},
34         {PROTOCOL_LANMAN2,      "LM1.2X002"},
35         {PROTOCOL_LANMAN2,      "DOS LANMAN2.1"},
36         {PROTOCOL_LANMAN2,      "LANMAN2.1"},
37         {PROTOCOL_LANMAN2,      "Samba"},
38         {PROTOCOL_NT1,          "NT LANMAN 1.0"},
39         {PROTOCOL_NT1,          "NT LM 0.12"},
40 };
41
42 #define STAR_SMBSERVER "*SMBSERVER"
43
44 /**
45  * Set the user session key for a connection
46  * @param cli The cli structure to add it too
47  * @param session_key The session key used.  (A copy of this is taken for the cli struct)
48  *
49  */
50
51 static void cli_set_session_key (struct cli_state *cli, const DATA_BLOB session_key) 
52 {
53         cli->user_session_key = data_blob(session_key.data, session_key.length);
54 }
55
56 /****************************************************************************
57  Do an old lanman2 style session setup.
58 ****************************************************************************/
59
60 static NTSTATUS cli_session_setup_lanman2(struct cli_state *cli,
61                                           const char *user, 
62                                           const char *pass, size_t passlen,
63                                           const char *workgroup)
64 {
65         DATA_BLOB session_key = data_blob_null;
66         DATA_BLOB lm_response = data_blob_null;
67         NTSTATUS status;
68         fstring pword;
69         char *p;
70
71         if (passlen > sizeof(pword)-1) {
72                 return NT_STATUS_INVALID_PARAMETER;
73         }
74
75         /* LANMAN servers predate NT status codes and Unicode and ignore those 
76            smb flags so we must disable the corresponding default capabilities  
77            that would otherwise cause the Unicode and NT Status flags to be
78            set (and even returned by the server) */
79
80         cli->capabilities &= ~(CAP_UNICODE | CAP_STATUS32);
81
82         /* if in share level security then don't send a password now */
83         if (!(cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL))
84                 passlen = 0;
85
86         if (passlen > 0 && (cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && passlen != 24) {
87                 /* Encrypted mode needed, and non encrypted password supplied. */
88                 lm_response = data_blob(NULL, 24);
89                 if (!SMBencrypt(pass, cli->secblob.data,(uchar *)lm_response.data)) {
90                         DEBUG(1, ("Password is > 14 chars in length, and is therefore incompatible with Lanman authentication\n"));
91                         return NT_STATUS_ACCESS_DENIED;
92                 }
93         } else if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && passlen == 24) {
94                 /* Encrypted mode needed, and encrypted password supplied. */
95                 lm_response = data_blob(pass, passlen);
96         } else if (passlen > 0) {
97                 /* Plaintext mode needed, assume plaintext supplied. */
98                 passlen = clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE);
99                 lm_response = data_blob(pass, passlen);
100         }
101
102         /* send a session setup command */
103         memset(cli->outbuf,'\0',smb_size);
104         cli_set_message(cli->outbuf,10, 0, True);
105         SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
106         cli_setup_packet(cli);
107         
108         SCVAL(cli->outbuf,smb_vwv0,0xFF);
109         SSVAL(cli->outbuf,smb_vwv2,cli->max_xmit);
110         SSVAL(cli->outbuf,smb_vwv3,2);
111         SSVAL(cli->outbuf,smb_vwv4,1);
112         SIVAL(cli->outbuf,smb_vwv5,cli->sesskey);
113         SSVAL(cli->outbuf,smb_vwv7,lm_response.length);
114
115         p = smb_buf(cli->outbuf);
116         memcpy(p,lm_response.data,lm_response.length);
117         p += lm_response.length;
118         p += clistr_push(cli, p, user, -1, STR_TERMINATE|STR_UPPER);
119         p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE|STR_UPPER);
120         p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE);
121         p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE);
122         cli_setup_bcc(cli, p);
123
124         if (!cli_send_smb(cli) || !cli_receive_smb(cli)) {
125                 return cli_nt_error(cli);
126         }
127
128         show_msg(cli->inbuf);
129
130         if (cli_is_error(cli)) {
131                 return cli_nt_error(cli);
132         }
133         
134         /* use the returned vuid from now on */
135         cli->vuid = SVAL(cli->inbuf,smb_uid);   
136         status = cli_set_username(cli, user);
137         if (!NT_STATUS_IS_OK(status)) {
138                 return status;
139         }
140
141         if (session_key.data) {
142                 /* Have plaintext orginal */
143                 cli_set_session_key(cli, session_key);
144         }
145
146         return NT_STATUS_OK;
147 }
148
149 /****************************************************************************
150  Work out suitable capabilities to offer the server.
151 ****************************************************************************/
152
153 static uint32 cli_session_setup_capabilities(struct cli_state *cli)
154 {
155         uint32 capabilities = CAP_NT_SMBS;
156
157         if (!cli->force_dos_errors)
158                 capabilities |= CAP_STATUS32;
159
160         if (cli->use_level_II_oplocks)
161                 capabilities |= CAP_LEVEL_II_OPLOCKS;
162
163         capabilities |= (cli->capabilities & (CAP_UNICODE|CAP_LARGE_FILES|CAP_LARGE_READX|CAP_LARGE_WRITEX|CAP_DFS));
164         return capabilities;
165 }
166
167 /****************************************************************************
168  Do a NT1 guest session setup.
169 ****************************************************************************/
170
171 struct cli_session_setup_guest_state {
172         struct cli_state *cli;
173         uint16_t vwv[16];
174         struct iovec bytes;
175 };
176
177 static void cli_session_setup_guest_done(struct tevent_req *subreq);
178
179 struct tevent_req *cli_session_setup_guest_create(TALLOC_CTX *mem_ctx,
180                                                   struct event_context *ev,
181                                                   struct cli_state *cli,
182                                                   struct tevent_req **psmbreq)
183 {
184         struct tevent_req *req, *subreq;
185         struct cli_session_setup_guest_state *state;
186         uint16_t *vwv;
187         uint8_t *bytes;
188
189         req = tevent_req_create(mem_ctx, &state,
190                                 struct cli_session_setup_guest_state);
191         if (req == NULL) {
192                 return NULL;
193         }
194         state->cli = cli;
195         vwv = state->vwv;
196
197         SCVAL(vwv+0, 0, 0xFF);
198         SCVAL(vwv+0, 1, 0);
199         SSVAL(vwv+1, 0, 0);
200         SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
201         SSVAL(vwv+3, 0, 2);
202         SSVAL(vwv+4, 0, cli->pid);
203         SIVAL(vwv+5, 0, cli->sesskey);
204         SSVAL(vwv+7, 0, 0);
205         SSVAL(vwv+8, 0, 0);
206         SSVAL(vwv+9, 0, 0);
207         SSVAL(vwv+10, 0, 0);
208         SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli));
209
210         bytes = talloc_array(state, uint8_t, 0);
211
212         bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "",  1, /* username */
213                                    NULL);
214         bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "", 1, /* workgroup */
215                                    NULL);
216         bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Unix", 5, NULL);
217         bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Samba", 6, NULL);
218
219         if (bytes == NULL) {
220                 TALLOC_FREE(req);
221                 return NULL;
222         }
223
224         state->bytes.iov_base = (void *)bytes;
225         state->bytes.iov_len = talloc_get_size(bytes);
226
227         subreq = cli_smb_req_create(state, ev, cli, SMBsesssetupX, 0, 13, vwv,
228                                     1, &state->bytes);
229         if (subreq == NULL) {
230                 TALLOC_FREE(req);
231                 return NULL;
232         }
233         tevent_req_set_callback(subreq, cli_session_setup_guest_done, req);
234         *psmbreq = subreq;
235         return req;
236 }
237
238 struct tevent_req *cli_session_setup_guest_send(TALLOC_CTX *mem_ctx,
239                                                 struct event_context *ev,
240                                                 struct cli_state *cli)
241 {
242         struct tevent_req *req, *subreq;
243         NTSTATUS status;
244
245         req = cli_session_setup_guest_create(mem_ctx, ev, cli, &subreq);
246         if (req == NULL) {
247                 return NULL;
248         }
249
250         status = cli_smb_req_send(subreq);
251         if (NT_STATUS_IS_OK(status)) {
252                 tevent_req_nterror(req, status);
253                 return tevent_req_post(req, ev);
254         }
255         return req;
256 }
257
258 static void cli_session_setup_guest_done(struct tevent_req *subreq)
259 {
260         struct tevent_req *req = tevent_req_callback_data(
261                 subreq, struct tevent_req);
262         struct cli_session_setup_guest_state *state = tevent_req_data(
263                 req, struct cli_session_setup_guest_state);
264         struct cli_state *cli = state->cli;
265         uint32_t num_bytes;
266         char *inbuf;
267         uint8_t *bytes;
268         uint8_t *p;
269         NTSTATUS status;
270
271         status = cli_smb_recv(subreq, 0, NULL, NULL, &num_bytes, &bytes);
272         if (!NT_STATUS_IS_OK(status)) {
273                 TALLOC_FREE(subreq);
274                 tevent_req_nterror(req, status);
275                 return;
276         }
277
278         inbuf = (char *)cli_smb_inbuf(subreq);
279         p = bytes;
280
281         cli->vuid = SVAL(inbuf, smb_uid);
282
283         p += clistr_pull(inbuf, cli->server_os, (char *)p, sizeof(fstring),
284                          bytes+num_bytes-p, STR_TERMINATE);
285         p += clistr_pull(inbuf, cli->server_type, (char *)p, sizeof(fstring),
286                          bytes+num_bytes-p, STR_TERMINATE);
287         p += clistr_pull(inbuf, cli->server_domain, (char *)p, sizeof(fstring),
288                          bytes+num_bytes-p, STR_TERMINATE);
289
290         if (strstr(cli->server_type, "Samba")) {
291                 cli->is_samba = True;
292         }
293
294         TALLOC_FREE(subreq);
295
296         status = cli_set_username(cli, "");
297         if (!NT_STATUS_IS_OK(status)) {
298                 tevent_req_nterror(req, status);
299                 return;
300         }
301         tevent_req_done(req);
302 }
303
304 NTSTATUS cli_session_setup_guest_recv(struct tevent_req *req)
305 {
306         return tevent_req_simple_recv_ntstatus(req);
307 }
308
309 static NTSTATUS cli_session_setup_guest(struct cli_state *cli)
310 {
311         TALLOC_CTX *frame = talloc_stackframe();
312         struct event_context *ev;
313         struct tevent_req *req;
314         NTSTATUS status = NT_STATUS_OK;
315
316         if (cli_has_async_calls(cli)) {
317                 /*
318                  * Can't use sync call while an async call is in flight
319                  */
320                 status = NT_STATUS_INVALID_PARAMETER;
321                 goto fail;
322         }
323
324         ev = event_context_init(frame);
325         if (ev == NULL) {
326                 status = NT_STATUS_NO_MEMORY;
327                 goto fail;
328         }
329
330         req = cli_session_setup_guest_send(frame, ev, cli);
331         if (req == NULL) {
332                 status = NT_STATUS_NO_MEMORY;
333                 goto fail;
334         }
335
336         if (!tevent_req_poll(req, ev)) {
337                 status = map_nt_error_from_unix(errno);
338                 goto fail;
339         }
340
341         status = cli_session_setup_guest_recv(req);
342  fail:
343         TALLOC_FREE(frame);
344         if (!NT_STATUS_IS_OK(status)) {
345                 cli_set_error(cli, status);
346         }
347         return status;
348 }
349
350 /****************************************************************************
351  Do a NT1 plaintext session setup.
352 ****************************************************************************/
353
354 static NTSTATUS cli_session_setup_plaintext(struct cli_state *cli,
355                                             const char *user, const char *pass,
356                                             const char *workgroup)
357 {
358         uint32 capabilities = cli_session_setup_capabilities(cli);
359         char *p;
360         NTSTATUS status;
361         fstring lanman;
362         
363         fstr_sprintf( lanman, "Samba %s", samba_version_string());
364
365         memset(cli->outbuf, '\0', smb_size);
366         cli_set_message(cli->outbuf,13,0,True);
367         SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
368         cli_setup_packet(cli);
369                         
370         SCVAL(cli->outbuf,smb_vwv0,0xFF);
371         SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE);
372         SSVAL(cli->outbuf,smb_vwv3,2);
373         SSVAL(cli->outbuf,smb_vwv4,cli->pid);
374         SIVAL(cli->outbuf,smb_vwv5,cli->sesskey);
375         SSVAL(cli->outbuf,smb_vwv8,0);
376         SIVAL(cli->outbuf,smb_vwv11,capabilities); 
377         p = smb_buf(cli->outbuf);
378         
379         /* check wether to send the ASCII or UNICODE version of the password */
380         
381         if ( (capabilities & CAP_UNICODE) == 0 ) {
382                 p += clistr_push(cli, p, pass, -1, STR_TERMINATE); /* password */
383                 SSVAL(cli->outbuf,smb_vwv7,PTR_DIFF(p, smb_buf(cli->outbuf)));
384         }
385         else {
386                 /* For ucs2 passwords clistr_push calls ucs2_align, which causes
387                  * the space taken by the unicode password to be one byte too
388                  * long (as we're on an odd byte boundary here). Reduce the
389                  * count by 1 to cope with this. Fixes smbclient against NetApp
390                  * servers which can't cope. Fix from
391                  * bryan.kolodziej@allenlund.com in bug #3840.
392                  */
393                 p += clistr_push(cli, p, pass, -1, STR_UNICODE|STR_TERMINATE); /* unicode password */
394                 SSVAL(cli->outbuf,smb_vwv8,PTR_DIFF(p, smb_buf(cli->outbuf))-1);        
395         }
396         
397         p += clistr_push(cli, p, user, -1, STR_TERMINATE); /* username */
398         p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE); /* workgroup */
399         p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE);
400         p += clistr_push(cli, p, lanman, -1, STR_TERMINATE);
401         cli_setup_bcc(cli, p);
402
403         if (!cli_send_smb(cli) || !cli_receive_smb(cli)) {
404                 return cli_nt_error(cli);
405         }
406         
407         show_msg(cli->inbuf);
408         
409         if (cli_is_error(cli)) {
410                 return cli_nt_error(cli);
411         }
412
413         cli->vuid = SVAL(cli->inbuf,smb_uid);
414         p = smb_buf(cli->inbuf);
415         p += clistr_pull(cli->inbuf, cli->server_os, p, sizeof(fstring),
416                          -1, STR_TERMINATE);
417         p += clistr_pull(cli->inbuf, cli->server_type, p, sizeof(fstring),
418                          -1, STR_TERMINATE);
419         p += clistr_pull(cli->inbuf, cli->server_domain, p, sizeof(fstring),
420                          -1, STR_TERMINATE);
421         status = cli_set_username(cli, user);
422         if (!NT_STATUS_IS_OK(status)) {
423                 return status;
424         }
425         if (strstr(cli->server_type, "Samba")) {
426                 cli->is_samba = True;
427         }
428
429         return NT_STATUS_OK;
430 }
431
432 /****************************************************************************
433    do a NT1 NTLM/LM encrypted session setup - for when extended security
434    is not negotiated.
435    @param cli client state to create do session setup on
436    @param user username
437    @param pass *either* cleartext password (passlen !=24) or LM response.
438    @param ntpass NT response, implies ntpasslen >=24, implies pass is not clear
439    @param workgroup The user's domain.
440 ****************************************************************************/
441
442 static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user, 
443                                       const char *pass, size_t passlen,
444                                       const char *ntpass, size_t ntpasslen,
445                                       const char *workgroup)
446 {
447         uint32 capabilities = cli_session_setup_capabilities(cli);
448         DATA_BLOB lm_response = data_blob_null;
449         DATA_BLOB nt_response = data_blob_null;
450         DATA_BLOB session_key = data_blob_null;
451         NTSTATUS result;
452         char *p;
453         bool ok;
454
455         if (passlen == 0) {
456                 /* do nothing - guest login */
457         } else if (passlen != 24) {
458                 if (lp_client_ntlmv2_auth()) {
459                         DATA_BLOB server_chal;
460                         DATA_BLOB names_blob;
461                         server_chal = data_blob(cli->secblob.data, MIN(cli->secblob.length, 8)); 
462
463                         /* note that the 'workgroup' here is a best guess - we don't know
464                            the server's domain at this point.  The 'server name' is also
465                            dodgy... 
466                         */
467                         names_blob = NTLMv2_generate_names_blob(NULL, cli->called.name, workgroup);
468
469                         if (!SMBNTLMv2encrypt(NULL, user, workgroup, pass, &server_chal, 
470                                               &names_blob,
471                                               &lm_response, &nt_response, NULL, &session_key)) {
472                                 data_blob_free(&names_blob);
473                                 data_blob_free(&server_chal);
474                                 return NT_STATUS_ACCESS_DENIED;
475                         }
476                         data_blob_free(&names_blob);
477                         data_blob_free(&server_chal);
478
479                 } else {
480                         uchar nt_hash[16];
481                         E_md4hash(pass, nt_hash);
482
483 #ifdef LANMAN_ONLY
484                         nt_response = data_blob_null;
485 #else
486                         nt_response = data_blob(NULL, 24);
487                         SMBNTencrypt(pass,cli->secblob.data,nt_response.data);
488 #endif
489                         /* non encrypted password supplied. Ignore ntpass. */
490                         if (lp_client_lanman_auth()) {
491                                 lm_response = data_blob(NULL, 24);
492                                 if (!SMBencrypt(pass,cli->secblob.data, lm_response.data)) {
493                                         /* Oops, the LM response is invalid, just put 
494                                            the NT response there instead */
495                                         data_blob_free(&lm_response);
496                                         lm_response = data_blob(nt_response.data, nt_response.length);
497                                 }
498                         } else {
499                                 /* LM disabled, place NT# in LM field instead */
500                                 lm_response = data_blob(nt_response.data, nt_response.length);
501                         }
502
503                         session_key = data_blob(NULL, 16);
504 #ifdef LANMAN_ONLY
505                         E_deshash(pass, session_key.data);
506                         memset(&session_key.data[8], '\0', 8);
507 #else
508                         SMBsesskeygen_ntv1(nt_hash, session_key.data);
509 #endif
510                 }
511                 cli_temp_set_signing(cli);
512         } else {
513                 /* pre-encrypted password supplied.  Only used for 
514                    security=server, can't do
515                    signing because we don't have original key */
516
517                 lm_response = data_blob(pass, passlen);
518                 nt_response = data_blob(ntpass, ntpasslen);
519         }
520
521         /* send a session setup command */
522         memset(cli->outbuf,'\0',smb_size);
523
524         cli_set_message(cli->outbuf,13,0,True);
525         SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
526         cli_setup_packet(cli);
527                         
528         SCVAL(cli->outbuf,smb_vwv0,0xFF);
529         SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE);
530         SSVAL(cli->outbuf,smb_vwv3,2);
531         SSVAL(cli->outbuf,smb_vwv4,cli->pid);
532         SIVAL(cli->outbuf,smb_vwv5,cli->sesskey);
533         SSVAL(cli->outbuf,smb_vwv7,lm_response.length);
534         SSVAL(cli->outbuf,smb_vwv8,nt_response.length);
535         SIVAL(cli->outbuf,smb_vwv11,capabilities); 
536         p = smb_buf(cli->outbuf);
537         if (lm_response.length) {
538                 memcpy(p,lm_response.data, lm_response.length); p += lm_response.length;
539         }
540         if (nt_response.length) {
541                 memcpy(p,nt_response.data, nt_response.length); p += nt_response.length;
542         }
543         p += clistr_push(cli, p, user, -1, STR_TERMINATE);
544
545         /* Upper case here might help some NTLMv2 implementations */
546         p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE|STR_UPPER);
547         p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE);
548         p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE);
549         cli_setup_bcc(cli, p);
550
551         if (!cli_send_smb(cli) || !cli_receive_smb(cli)) {
552                 result = cli_nt_error(cli);
553                 goto end;
554         }
555
556         /* show_msg(cli->inbuf); */
557
558         if (cli_is_error(cli)) {
559                 result = cli_nt_error(cli);
560                 goto end;
561         }
562
563 #ifdef LANMAN_ONLY
564         ok = cli_simple_set_signing(cli, session_key, lm_response);
565 #else
566         ok = cli_simple_set_signing(cli, session_key, nt_response);
567 #endif
568         if (ok) {
569                 if (!cli_check_sign_mac(cli, cli->inbuf, 1)) {
570                         result = NT_STATUS_ACCESS_DENIED;
571                         goto end;
572                 }
573         }
574
575         /* use the returned vuid from now on */
576         cli->vuid = SVAL(cli->inbuf,smb_uid);
577         
578         p = smb_buf(cli->inbuf);
579         p += clistr_pull(cli->inbuf, cli->server_os, p, sizeof(fstring),
580                          -1, STR_TERMINATE);
581         p += clistr_pull(cli->inbuf, cli->server_type, p, sizeof(fstring),
582                          -1, STR_TERMINATE);
583         p += clistr_pull(cli->inbuf, cli->server_domain, p, sizeof(fstring),
584                          -1, STR_TERMINATE);
585
586         if (strstr(cli->server_type, "Samba")) {
587                 cli->is_samba = True;
588         }
589
590         result = cli_set_username(cli, user);
591         if (!NT_STATUS_IS_OK(result)) {
592                 goto end;
593         }
594
595         if (session_key.data) {
596                 /* Have plaintext orginal */
597                 cli_set_session_key(cli, session_key);
598         }
599
600         result = NT_STATUS_OK;
601 end:    
602         data_blob_free(&lm_response);
603         data_blob_free(&nt_response);
604         data_blob_free(&session_key);
605         return result;
606 }
607
608 /****************************************************************************
609  Send a extended security session setup blob
610 ****************************************************************************/
611
612 static bool cli_session_setup_blob_send(struct cli_state *cli, DATA_BLOB blob)
613 {
614         uint32 capabilities = cli_session_setup_capabilities(cli);
615         char *p;
616
617         capabilities |= CAP_EXTENDED_SECURITY;
618
619         /* send a session setup command */
620         memset(cli->outbuf,'\0',smb_size);
621
622         cli_set_message(cli->outbuf,12,0,True);
623         SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
624
625         cli_setup_packet(cli);
626
627         SCVAL(cli->outbuf,smb_vwv0,0xFF);
628         SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE);
629         SSVAL(cli->outbuf,smb_vwv3,2);
630         SSVAL(cli->outbuf,smb_vwv4,1);
631         SIVAL(cli->outbuf,smb_vwv5,0);
632         SSVAL(cli->outbuf,smb_vwv7,blob.length);
633         SIVAL(cli->outbuf,smb_vwv10,capabilities); 
634         p = smb_buf(cli->outbuf);
635         memcpy(p, blob.data, blob.length);
636         p += blob.length;
637         p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE);
638         p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE);
639         cli_setup_bcc(cli, p);
640         return cli_send_smb(cli);
641 }
642
643 /****************************************************************************
644  Send a extended security session setup blob, returning a reply blob.
645 ****************************************************************************/
646
647 static DATA_BLOB cli_session_setup_blob_receive(struct cli_state *cli)
648 {
649         DATA_BLOB blob2 = data_blob_null;
650         char *p;
651         size_t len;
652
653         if (!cli_receive_smb(cli))
654                 return blob2;
655
656         show_msg(cli->inbuf);
657
658         if (cli_is_error(cli) && !NT_STATUS_EQUAL(cli_nt_error(cli),
659                                                   NT_STATUS_MORE_PROCESSING_REQUIRED)) {
660                 return blob2;
661         }
662
663         /* use the returned vuid from now on */
664         cli->vuid = SVAL(cli->inbuf,smb_uid);
665
666         p = smb_buf(cli->inbuf);
667
668         blob2 = data_blob(p, SVAL(cli->inbuf, smb_vwv3));
669
670         p += blob2.length;
671         p += clistr_pull(cli->inbuf, cli->server_os, p, sizeof(fstring),
672                          -1, STR_TERMINATE);
673
674         /* w2k with kerberos doesn't properly null terminate this field */
675         len = smb_bufrem(cli->inbuf, p);
676         if (p + len < cli->inbuf + cli->bufsize+SAFETY_MARGIN - 2) {
677                 char *end_of_buf = p + len;
678
679                 SSVAL(p, len, 0);
680                 /* Now it's null terminated. */
681                 p += clistr_pull(cli->inbuf, cli->server_type, p, sizeof(fstring),
682                         -1, STR_TERMINATE);
683                 /*
684                  * See if there's another string. If so it's the
685                  * server domain (part of the 'standard' Samba
686                  * server signature).
687                  */
688                 if (p < end_of_buf) {
689                         p += clistr_pull(cli->inbuf, cli->server_domain, p, sizeof(fstring),
690                                 -1, STR_TERMINATE);
691                 }
692         } else {
693                 /*
694                  * No room to null terminate so we can't see if there
695                  * is another string (server_domain) afterwards.
696                  */
697                 p += clistr_pull(cli->inbuf, cli->server_type, p, sizeof(fstring),
698                                  len, 0);
699         }
700         return blob2;
701 }
702
703 #ifdef HAVE_KRB5
704 /****************************************************************************
705  Send a extended security session setup blob, returning a reply blob.
706 ****************************************************************************/
707
708 /* The following is calculated from :
709  * (smb_size-4) = 35
710  * (smb_wcnt * 2) = 24 (smb_wcnt == 12 in cli_session_setup_blob_send() )
711  * (strlen("Unix") + 1 + strlen("Samba") + 1) * 2 = 22 (unicode strings at
712  * end of packet.
713  */
714
715 #define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22)
716
717 static bool cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob)
718 {
719         int32 remaining = blob.length;
720         int32 cur = 0;
721         DATA_BLOB send_blob = data_blob_null;
722         int32 max_blob_size = 0;
723         DATA_BLOB receive_blob = data_blob_null;
724
725         if (cli->max_xmit < BASE_SESSSETUP_BLOB_PACKET_SIZE + 1) {
726                 DEBUG(0,("cli_session_setup_blob: cli->max_xmit too small "
727                         "(was %u, need minimum %u)\n",
728                         (unsigned int)cli->max_xmit,
729                         BASE_SESSSETUP_BLOB_PACKET_SIZE));
730                 cli_set_nt_error(cli, NT_STATUS_INVALID_PARAMETER);
731                 return False;
732         }
733
734         max_blob_size = cli->max_xmit - BASE_SESSSETUP_BLOB_PACKET_SIZE;
735
736         while ( remaining > 0) {
737                 if (remaining >= max_blob_size) {
738                         send_blob.length = max_blob_size;
739                         remaining -= max_blob_size;
740                 } else {
741                         send_blob.length = remaining; 
742                         remaining = 0;
743                 }
744
745                 send_blob.data =  &blob.data[cur];
746                 cur += send_blob.length;
747
748                 DEBUG(10, ("cli_session_setup_blob: Remaining (%u) sending (%u) current (%u)\n", 
749                         (unsigned int)remaining,
750                         (unsigned int)send_blob.length,
751                         (unsigned int)cur ));
752
753                 if (!cli_session_setup_blob_send(cli, send_blob)) {
754                         DEBUG(0, ("cli_session_setup_blob: send failed\n"));
755                         return False;
756                 }
757
758                 receive_blob = cli_session_setup_blob_receive(cli);
759                 data_blob_free(&receive_blob);
760
761                 if (cli_is_error(cli) &&
762                                 !NT_STATUS_EQUAL( cli_get_nt_error(cli), 
763                                         NT_STATUS_MORE_PROCESSING_REQUIRED)) {
764                         DEBUG(0, ("cli_session_setup_blob: receive failed "
765                                   "(%s)\n", nt_errstr(cli_get_nt_error(cli))));
766                         cli->vuid = 0;
767                         return False;
768                 }
769         }
770
771         return True;
772 }
773
774 /****************************************************************************
775  Use in-memory credentials cache
776 ****************************************************************************/
777
778 static void use_in_memory_ccache(void) {
779         setenv(KRB5_ENV_CCNAME, "MEMORY:cliconnect", 1);
780 }
781
782 /****************************************************************************
783  Do a spnego/kerberos encrypted session setup.
784 ****************************************************************************/
785
786 static ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli, const char *principal, const char *workgroup)
787 {
788         DATA_BLOB negTokenTarg;
789         DATA_BLOB session_key_krb5;
790         NTSTATUS nt_status;
791         int rc;
792
793         cli_temp_set_signing(cli);
794
795         DEBUG(2,("Doing kerberos session setup\n"));
796
797         /* generate the encapsulated kerberos5 ticket */
798         rc = spnego_gen_negTokenTarg(principal, 0, &negTokenTarg, &session_key_krb5, 0, NULL);
799
800         if (rc) {
801                 DEBUG(1, ("cli_session_setup_kerberos: spnego_gen_negTokenTarg failed: %s\n",
802                         error_message(rc)));
803                 return ADS_ERROR_KRB5(rc);
804         }
805
806 #if 0
807         file_save("negTokenTarg.dat", negTokenTarg.data, negTokenTarg.length);
808 #endif
809
810         if (!cli_session_setup_blob(cli, negTokenTarg)) {
811                 nt_status = cli_nt_error(cli);
812                 goto nt_error;
813         }
814
815         if (cli_is_error(cli)) {
816                 nt_status = cli_nt_error(cli);
817                 if (NT_STATUS_IS_OK(nt_status)) {
818                         nt_status = NT_STATUS_UNSUCCESSFUL;
819                 }
820                 goto nt_error;
821         }
822
823         cli_set_session_key(cli, session_key_krb5);
824
825         if (cli_simple_set_signing(
826                     cli, session_key_krb5, data_blob_null)) {
827
828                 if (!cli_check_sign_mac(cli, cli->inbuf, 1)) {
829                         nt_status = NT_STATUS_ACCESS_DENIED;
830                         goto nt_error;
831                 }
832         }
833
834         data_blob_free(&negTokenTarg);
835         data_blob_free(&session_key_krb5);
836
837         return ADS_ERROR_NT(NT_STATUS_OK);
838
839 nt_error:
840         data_blob_free(&negTokenTarg);
841         data_blob_free(&session_key_krb5);
842         cli->vuid = 0;
843         return ADS_ERROR_NT(nt_status);
844 }
845 #endif  /* HAVE_KRB5 */
846
847
848 /****************************************************************************
849  Do a spnego/NTLMSSP encrypted session setup.
850 ****************************************************************************/
851
852 static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, 
853                                           const char *pass, const char *domain)
854 {
855         struct ntlmssp_state *ntlmssp_state;
856         NTSTATUS nt_status;
857         int turn = 1;
858         DATA_BLOB msg1;
859         DATA_BLOB blob = data_blob_null;
860         DATA_BLOB blob_in = data_blob_null;
861         DATA_BLOB blob_out = data_blob_null;
862
863         cli_temp_set_signing(cli);
864
865         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_client_start(&ntlmssp_state))) {
866                 return nt_status;
867         }
868         ntlmssp_want_feature(ntlmssp_state, NTLMSSP_FEATURE_SESSION_KEY);
869         if (cli->use_ccache) {
870                 ntlmssp_want_feature(ntlmssp_state, NTLMSSP_FEATURE_CCACHE);
871         }
872
873         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, user))) {
874                 return nt_status;
875         }
876         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, domain))) {
877                 return nt_status;
878         }
879         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_password(ntlmssp_state, pass))) {
880                 return nt_status;
881         }
882
883         do {
884                 nt_status = ntlmssp_update(ntlmssp_state, 
885                                                   blob_in, &blob_out);
886                 data_blob_free(&blob_in);
887                 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED) || NT_STATUS_IS_OK(nt_status)) {
888                         if (turn == 1) {
889                                 /* and wrap it in a SPNEGO wrapper */
890                                 msg1 = gen_negTokenInit(OID_NTLMSSP, blob_out);
891                         } else {
892                                 /* wrap it in SPNEGO */
893                                 msg1 = spnego_gen_auth(blob_out);
894                         }
895
896                         /* now send that blob on its way */
897                         if (!cli_session_setup_blob_send(cli, msg1)) {
898                                 DEBUG(3, ("Failed to send NTLMSSP/SPNEGO blob to server!\n"));
899                                 nt_status = NT_STATUS_UNSUCCESSFUL;
900                         } else {
901                                 blob = cli_session_setup_blob_receive(cli);
902
903                                 nt_status = cli_nt_error(cli);
904                                 if (cli_is_error(cli) && NT_STATUS_IS_OK(nt_status)) {
905                                         if (cli->smb_rw_error == SMB_READ_BAD_SIG) {
906                                                 nt_status = NT_STATUS_ACCESS_DENIED;
907                                         } else {
908                                                 nt_status = NT_STATUS_UNSUCCESSFUL;
909                                         }
910                                 }
911                         }
912                         data_blob_free(&msg1);
913                 }
914
915                 if (!blob.length) {
916                         if (NT_STATUS_IS_OK(nt_status)) {
917                                 nt_status = NT_STATUS_UNSUCCESSFUL;
918                         }
919                 } else if ((turn == 1) && 
920                            NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
921                         DATA_BLOB tmp_blob = data_blob_null;
922                         /* the server might give us back two challenges */
923                         if (!spnego_parse_challenge(blob, &blob_in, 
924                                                     &tmp_blob)) {
925                                 DEBUG(3,("Failed to parse challenges\n"));
926                                 nt_status = NT_STATUS_INVALID_PARAMETER;
927                         }
928                         data_blob_free(&tmp_blob);
929                 } else {
930                         if (!spnego_parse_auth_response(blob, nt_status, OID_NTLMSSP, 
931                                                         &blob_in)) {
932                                 DEBUG(3,("Failed to parse auth response\n"));
933                                 if (NT_STATUS_IS_OK(nt_status) 
934                                     || NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) 
935                                         nt_status = NT_STATUS_INVALID_PARAMETER;
936                         }
937                 }
938                 data_blob_free(&blob);
939                 data_blob_free(&blob_out);
940                 turn++;
941         } while (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED));
942
943         data_blob_free(&blob_in);
944
945         if (NT_STATUS_IS_OK(nt_status)) {
946
947                 if (cli->server_domain[0] == '\0') {
948                         fstrcpy(cli->server_domain, ntlmssp_state->server_domain);
949                 }
950                 cli_set_session_key(cli, ntlmssp_state->session_key);
951
952                 if (cli_simple_set_signing(
953                             cli, ntlmssp_state->session_key, data_blob_null)) {
954
955                         if (!cli_check_sign_mac(cli, cli->inbuf, 1)) {
956                                 nt_status = NT_STATUS_ACCESS_DENIED;
957                         }
958                 }
959         }
960
961         /* we have a reference conter on ntlmssp_state, if we are signing
962            then the state will be kept by the signing engine */
963
964         ntlmssp_end(&ntlmssp_state);
965
966         if (!NT_STATUS_IS_OK(nt_status)) {
967                 cli->vuid = 0;
968         }
969         return nt_status;
970 }
971
972 /****************************************************************************
973  Do a spnego encrypted session setup.
974
975  user_domain: The shortname of the domain the user/machine is a member of.
976  dest_realm: The realm we're connecting to, if NULL we use our default realm.
977 ****************************************************************************/
978
979 ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, 
980                               const char *pass, const char *user_domain,
981                               const char * dest_realm)
982 {
983         char *principal = NULL;
984         char *OIDs[ASN1_MAX_OIDS];
985         int i;
986         DATA_BLOB blob;
987         const char *p = NULL;
988         char *account = NULL;
989         NTSTATUS status;
990
991         DEBUG(3,("Doing spnego session setup (blob length=%lu)\n", (unsigned long)cli->secblob.length));
992
993         /* the server might not even do spnego */
994         if (cli->secblob.length <= 16) {
995                 DEBUG(3,("server didn't supply a full spnego negprot\n"));
996                 goto ntlmssp;
997         }
998
999 #if 0
1000         file_save("negprot.dat", cli->secblob.data, cli->secblob.length);
1001 #endif
1002
1003         /* there is 16 bytes of GUID before the real spnego packet starts */
1004         blob = data_blob(cli->secblob.data+16, cli->secblob.length-16);
1005
1006         /* The server sent us the first part of the SPNEGO exchange in the
1007          * negprot reply. It is WRONG to depend on the principal sent in the
1008          * negprot reply, but right now we do it. If we don't receive one,
1009          * we try to best guess, then fall back to NTLM.  */
1010         if (!spnego_parse_negTokenInit(blob, OIDs, &principal) ||
1011                         OIDs[0] == NULL) {
1012                 data_blob_free(&blob);
1013                 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1014         }
1015         data_blob_free(&blob);
1016
1017         /* make sure the server understands kerberos */
1018         for (i=0;OIDs[i];i++) {
1019                 if (i == 0)
1020                         DEBUG(3,("got OID=%s\n", OIDs[i]));
1021                 else
1022                         DEBUGADD(3,("got OID=%s\n", OIDs[i]));
1023                 if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0 ||
1024                     strcmp(OIDs[i], OID_KERBEROS5) == 0) {
1025                         cli->got_kerberos_mechanism = True;
1026                 }
1027                 talloc_free(OIDs[i]);
1028         }
1029
1030         DEBUG(3,("got principal=%s\n", principal ? principal : "<null>"));
1031
1032         status = cli_set_username(cli, user);
1033         if (!NT_STATUS_IS_OK(status)) {
1034                 return ADS_ERROR_NT(status);
1035         }
1036
1037 #ifdef HAVE_KRB5
1038         /* If password is set we reauthenticate to kerberos server
1039          * and do not store results */
1040
1041         if (cli->got_kerberos_mechanism && cli->use_kerberos) {
1042                 ADS_STATUS rc;
1043
1044                 if (pass && *pass) {
1045                         int ret;
1046
1047                         use_in_memory_ccache();
1048                         ret = kerberos_kinit_password(user, pass, 0 /* no time correction for now */, NULL);
1049
1050                         if (ret){
1051                                 TALLOC_FREE(principal);
1052                                 DEBUG(0, ("Kinit failed: %s\n", error_message(ret)));
1053                                 if (cli->fallback_after_kerberos)
1054                                         goto ntlmssp;
1055                                 return ADS_ERROR_KRB5(ret);
1056                         }
1057                 }
1058
1059                 /* We may not be allowed to use the server-supplied SPNEGO principal, or it may not have been supplied to us
1060                  */
1061                 if (!lp_client_use_spnego_principal() || strequal(principal, ADS_IGNORE_PRINCIPAL)) {
1062                         TALLOC_FREE(principal);
1063                 }
1064
1065                 if (principal == NULL &&
1066                         !is_ipaddress(cli->desthost) &&
1067                         !strequal(STAR_SMBSERVER,
1068                                 cli->desthost)) {
1069                         char *realm = NULL;
1070                         char *host = NULL;
1071                         DEBUG(3,("cli_session_setup_spnego: using target "
1072                                  "hostname not SPNEGO principal\n"));
1073
1074                         host = strchr_m(cli->desthost, '.');
1075                         if (dest_realm) {
1076                                 realm = SMB_STRDUP(dest_realm);
1077                                 if (!realm) {
1078                                         return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1079                                 }
1080                                 strupper_m(realm);
1081                         } else {
1082                                 if (host) {
1083                                         /* DNS name. */
1084                                         realm = kerberos_get_realm_from_hostname(cli->desthost);
1085                                 } else {
1086                                         /* NetBIOS name - use our realm. */
1087                                         realm = kerberos_get_default_realm_from_ccache();
1088                                 }
1089                         }
1090
1091                         if (realm == NULL || *realm == '\0') {
1092                                 realm = SMB_STRDUP(lp_realm());
1093                                 if (!realm) {
1094                                         return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1095                                 }
1096                                 strupper_m(realm);
1097                                 DEBUG(3,("cli_session_setup_spnego: cannot "
1098                                         "get realm from dest_realm %s, "
1099                                         "desthost %s. Using default "
1100                                         "smb.conf realm %s\n",
1101                                         dest_realm ? dest_realm : "<null>",
1102                                         cli->desthost,
1103                                         realm));
1104                         }
1105
1106                         principal = talloc_asprintf(talloc_tos(),
1107                                                     "cifs/%s@%s",
1108                                                     cli->desthost,
1109                                                     realm);
1110                         if (!principal) {
1111                                 SAFE_FREE(realm);
1112                                 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1113                         }
1114                         DEBUG(3,("cli_session_setup_spnego: guessed "
1115                                 "server principal=%s\n",
1116                                 principal ? principal : "<null>"));
1117
1118                         SAFE_FREE(realm);
1119                 }
1120
1121                 if (principal) {
1122                         rc = cli_session_setup_kerberos(cli, principal,
1123                                 dest_realm);
1124                         if (ADS_ERR_OK(rc) || !cli->fallback_after_kerberos) {
1125                                 TALLOC_FREE(principal);
1126                                 return rc;
1127                         }
1128                 }
1129         }
1130 #endif
1131
1132         TALLOC_FREE(principal);
1133
1134 ntlmssp:
1135
1136         account = talloc_strdup(talloc_tos(), user);
1137         if (!account) {
1138                 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1139         }
1140
1141         /* when falling back to ntlmssp while authenticating with a machine
1142          * account strip off the realm - gd */
1143
1144         if ((p = strchr_m(user, '@')) != NULL) {
1145                 account[PTR_DIFF(p,user)] = '\0';
1146         }
1147
1148         return ADS_ERROR_NT(cli_session_setup_ntlmssp(cli, account, pass, user_domain));
1149 }
1150
1151 /****************************************************************************
1152  Send a session setup. The username and workgroup is in UNIX character
1153  format and must be converted to DOS codepage format before sending. If the
1154  password is in plaintext, the same should be done.
1155 ****************************************************************************/
1156
1157 NTSTATUS cli_session_setup(struct cli_state *cli,
1158                            const char *user,
1159                            const char *pass, int passlen,
1160                            const char *ntpass, int ntpasslen,
1161                            const char *workgroup)
1162 {
1163         char *p;
1164         fstring user2;
1165
1166         if (user) {
1167                 fstrcpy(user2, user);
1168         } else {
1169                 user2[0] ='\0';
1170         }
1171
1172         if (!workgroup) {
1173                 workgroup = "";
1174         }
1175
1176         /* allow for workgroups as part of the username */
1177         if ((p=strchr_m(user2,'\\')) || (p=strchr_m(user2,'/')) ||
1178             (p=strchr_m(user2,*lp_winbind_separator()))) {
1179                 *p = 0;
1180                 user = p+1;
1181                 strupper_m(user2);
1182                 workgroup = user2;
1183         }
1184
1185         if (cli->protocol < PROTOCOL_LANMAN1) {
1186                 return NT_STATUS_OK;
1187         }
1188
1189         /* now work out what sort of session setup we are going to
1190            do. I have split this into separate functions to make the
1191            flow a bit easier to understand (tridge) */
1192
1193         /* if its an older server then we have to use the older request format */
1194
1195         if (cli->protocol < PROTOCOL_NT1) {
1196                 if (!lp_client_lanman_auth() && passlen != 24 && (*pass)) {
1197                         DEBUG(1, ("Server requested LM password but 'client lanman auth'"
1198                                   " is disabled\n"));
1199                         return NT_STATUS_ACCESS_DENIED;
1200                 }
1201
1202                 if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0 &&
1203                     !lp_client_plaintext_auth() && (*pass)) {
1204                         DEBUG(1, ("Server requested plaintext password but "
1205                                   "'client plaintext auth' is disabled\n"));
1206                         return NT_STATUS_ACCESS_DENIED;
1207                 }
1208
1209                 return cli_session_setup_lanman2(cli, user, pass, passlen,
1210                                                  workgroup);
1211         }
1212
1213         /* if no user is supplied then we have to do an anonymous connection.
1214            passwords are ignored */
1215
1216         if (!user || !*user)
1217                 return cli_session_setup_guest(cli);
1218
1219         /* if the server is share level then send a plaintext null
1220            password at this point. The password is sent in the tree
1221            connect */
1222
1223         if ((cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0) 
1224                 return cli_session_setup_plaintext(cli, user, "", workgroup);
1225
1226         /* if the server doesn't support encryption then we have to use 
1227            plaintext. The second password is ignored */
1228
1229         if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) {
1230                 if (!lp_client_plaintext_auth() && (*pass)) {
1231                         DEBUG(1, ("Server requested plaintext password but "
1232                                   "'client plaintext auth' is disabled\n"));
1233                         return NT_STATUS_ACCESS_DENIED;
1234                 }
1235                 return cli_session_setup_plaintext(cli, user, pass, workgroup);
1236         }
1237
1238         /* if the server supports extended security then use SPNEGO */
1239
1240         if (cli->capabilities & CAP_EXTENDED_SECURITY) {
1241                 ADS_STATUS status = cli_session_setup_spnego(cli, user, pass,
1242                                                              workgroup, NULL);
1243                 if (!ADS_ERR_OK(status)) {
1244                         DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status)));
1245                         return ads_ntstatus(status);
1246                 }
1247         } else {
1248                 NTSTATUS status;
1249
1250                 /* otherwise do a NT1 style session setup */
1251                 status = cli_session_setup_nt1(cli, user, pass, passlen,
1252                                                ntpass, ntpasslen, workgroup);
1253                 if (!NT_STATUS_IS_OK(status)) {
1254                         DEBUG(3,("cli_session_setup: NT1 session setup "
1255                                  "failed: %s\n", nt_errstr(status)));
1256                         return status;
1257                 }
1258         }
1259
1260         if (strstr(cli->server_type, "Samba")) {
1261                 cli->is_samba = True;
1262         }
1263
1264         return NT_STATUS_OK;
1265 }
1266
1267 /****************************************************************************
1268  Send a uloggoff.
1269 *****************************************************************************/
1270
1271 bool cli_ulogoff(struct cli_state *cli)
1272 {
1273         memset(cli->outbuf,'\0',smb_size);
1274         cli_set_message(cli->outbuf,2,0,True);
1275         SCVAL(cli->outbuf,smb_com,SMBulogoffX);
1276         cli_setup_packet(cli);
1277         SSVAL(cli->outbuf,smb_vwv0,0xFF);
1278         SSVAL(cli->outbuf,smb_vwv2,0);  /* no additional info */
1279
1280         cli_send_smb(cli);
1281         if (!cli_receive_smb(cli))
1282                 return False;
1283
1284         if (cli_is_error(cli)) {
1285                 return False;
1286         }
1287
1288         cli->vuid = -1;
1289         return True;
1290 }
1291
1292 /****************************************************************************
1293  Send a tconX.
1294 ****************************************************************************/
1295
1296 struct cli_tcon_andx_state {
1297         struct cli_state *cli;
1298         uint16_t vwv[4];
1299         struct iovec bytes;
1300 };
1301
1302 static void cli_tcon_andx_done(struct tevent_req *subreq);
1303
1304 struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx,
1305                                         struct event_context *ev,
1306                                         struct cli_state *cli,
1307                                         const char *share, const char *dev,
1308                                         const char *pass, int passlen,
1309                                         struct tevent_req **psmbreq)
1310 {
1311         struct tevent_req *req, *subreq;
1312         struct cli_tcon_andx_state *state;
1313         fstring pword;
1314         uint16_t *vwv;
1315         char *tmp = NULL;
1316         uint8_t *bytes;
1317
1318         *psmbreq = NULL;
1319
1320         req = tevent_req_create(mem_ctx, &state, struct cli_tcon_andx_state);
1321         if (req == NULL) {
1322                 return NULL;
1323         }
1324         state->cli = cli;
1325         vwv = state->vwv;
1326
1327         fstrcpy(cli->share, share);
1328
1329         /* in user level security don't send a password now */
1330         if (cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {
1331                 passlen = 1;
1332                 pass = "";
1333         } else if (pass == NULL) {
1334                 DEBUG(1, ("Server not using user level security and no "
1335                           "password supplied.\n"));
1336                 goto access_denied;
1337         }
1338
1339         if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) &&
1340             *pass && passlen != 24) {
1341                 if (!lp_client_lanman_auth()) {
1342                         DEBUG(1, ("Server requested LANMAN password "
1343                                   "(share-level security) but "
1344                                   "'client lanman auth' is disabled\n"));
1345                         goto access_denied;
1346                 }
1347
1348                 /*
1349                  * Non-encrypted passwords - convert to DOS codepage before
1350                  * encryption.
1351                  */
1352                 passlen = 24;
1353                 SMBencrypt(pass, cli->secblob.data, (uchar *)pword);
1354         } else {
1355                 if((cli->sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL
1356                                      |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE))
1357                    == 0) {
1358                         if (!lp_client_plaintext_auth() && (*pass)) {
1359                                 DEBUG(1, ("Server requested plaintext "
1360                                           "password but 'client plaintext "
1361                                           "auth' is disabled\n"));
1362                                 goto access_denied;
1363                         }
1364
1365                         /*
1366                          * Non-encrypted passwords - convert to DOS codepage
1367                          * before using.
1368                          */
1369                         passlen = clistr_push(cli, pword, pass, sizeof(pword),
1370                                               STR_TERMINATE);
1371                         if (passlen == -1) {
1372                                 DEBUG(1, ("clistr_push(pword) failed\n"));
1373                                 goto access_denied;
1374                         }
1375                 } else {
1376                         if (passlen) {
1377                                 memcpy(pword, pass, passlen);
1378                         }
1379                 }
1380         }
1381
1382         SCVAL(vwv+0, 0, 0xFF);
1383         SCVAL(vwv+0, 1, 0);
1384         SSVAL(vwv+1, 0, 0);
1385         SSVAL(vwv+2, 0, TCONX_FLAG_EXTENDED_RESPONSE);
1386         SSVAL(vwv+3, 0, passlen);
1387
1388         if (passlen) {
1389                 bytes = (uint8_t *)talloc_memdup(state, pword, passlen);
1390         } else {
1391                 bytes = talloc_array(state, uint8_t, 0);
1392         }
1393
1394         /*
1395          * Add the sharename
1396          */
1397         tmp = talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
1398                                          cli->desthost, share);
1399         if (tmp == NULL) {
1400                 TALLOC_FREE(req);
1401                 return NULL;
1402         }
1403         bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), tmp, strlen(tmp)+1,
1404                                    NULL);
1405         TALLOC_FREE(tmp);
1406
1407         /*
1408          * Add the devicetype
1409          */
1410         tmp = talloc_strdup_upper(talloc_tos(), dev);
1411         if (tmp == NULL) {
1412                 TALLOC_FREE(req);
1413                 return NULL;
1414         }
1415         bytes = smb_bytes_push_str(bytes, false, tmp, strlen(tmp)+1, NULL);
1416         TALLOC_FREE(tmp);
1417
1418         if (bytes == NULL) {
1419                 TALLOC_FREE(req);
1420                 return NULL;
1421         }
1422
1423         state->bytes.iov_base = (void *)bytes;
1424         state->bytes.iov_len = talloc_get_size(bytes);
1425
1426         subreq = cli_smb_req_create(state, ev, cli, SMBtconX, 0, 4, vwv,
1427                                     1, &state->bytes);
1428         if (subreq == NULL) {
1429                 TALLOC_FREE(req);
1430                 return NULL;
1431         }
1432         tevent_req_set_callback(subreq, cli_tcon_andx_done, req);
1433         *psmbreq = subreq;
1434         return req;
1435
1436  access_denied:
1437         tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1438         return tevent_req_post(req, ev);
1439 }
1440
1441 struct tevent_req *cli_tcon_andx_send(TALLOC_CTX *mem_ctx,
1442                                       struct event_context *ev,
1443                                       struct cli_state *cli,
1444                                       const char *share, const char *dev,
1445                                       const char *pass, int passlen)
1446 {
1447         struct tevent_req *req, *subreq;
1448         NTSTATUS status;
1449
1450         req = cli_tcon_andx_create(mem_ctx, ev, cli, share, dev, pass, passlen,
1451                                    &subreq);
1452         if (req == NULL) {
1453                 return NULL;
1454         }
1455         if (subreq == NULL) {
1456                 return req;
1457         }
1458         status = cli_smb_req_send(subreq);
1459         if (!NT_STATUS_IS_OK(status)) {
1460                 tevent_req_nterror(req, status);
1461                 return tevent_req_post(req, ev);
1462         }
1463         return req;
1464 }
1465
1466 static void cli_tcon_andx_done(struct tevent_req *subreq)
1467 {
1468         struct tevent_req *req = tevent_req_callback_data(
1469                 subreq, struct tevent_req);
1470         struct cli_tcon_andx_state *state = tevent_req_data(
1471                 req, struct cli_tcon_andx_state);
1472         struct cli_state *cli = state->cli;
1473         char *inbuf = (char *)cli_smb_inbuf(subreq);
1474         uint8_t wct;
1475         uint16_t *vwv;
1476         uint32_t num_bytes;
1477         uint8_t *bytes;
1478         NTSTATUS status;
1479
1480         status = cli_smb_recv(subreq, 0, &wct, &vwv, &num_bytes, &bytes);
1481         if (!NT_STATUS_IS_OK(status)) {
1482                 TALLOC_FREE(subreq);
1483                 tevent_req_nterror(req, status);
1484                 return;
1485         }
1486
1487         clistr_pull(inbuf, cli->dev, bytes, sizeof(fstring), num_bytes,
1488                     STR_TERMINATE|STR_ASCII);
1489
1490         if ((cli->protocol >= PROTOCOL_NT1) && (num_bytes == 3)) {
1491                 /* almost certainly win95 - enable bug fixes */
1492                 cli->win95 = True;
1493         }
1494
1495         /*
1496          * Make sure that we have the optional support 16-bit field. WCT > 2.
1497          * Avoids issues when connecting to Win9x boxes sharing files
1498          */
1499
1500         cli->dfsroot = false;
1501
1502         if ((wct > 2) && (cli->protocol >= PROTOCOL_LANMAN2)) {
1503                 cli->dfsroot = ((SVAL(vwv+2, 0) & SMB_SHARE_IN_DFS) != 0);
1504         }
1505
1506         cli->cnum = SVAL(inbuf,smb_tid);
1507         tevent_req_done(req);
1508 }
1509
1510 NTSTATUS cli_tcon_andx_recv(struct tevent_req *req)
1511 {
1512         return tevent_req_simple_recv_ntstatus(req);
1513 }
1514
1515 NTSTATUS cli_tcon_andx(struct cli_state *cli, const char *share,
1516                        const char *dev, const char *pass, int passlen)
1517 {
1518         TALLOC_CTX *frame = talloc_stackframe();
1519         struct event_context *ev;
1520         struct tevent_req *req;
1521         NTSTATUS status = NT_STATUS_OK;
1522
1523         if (cli_has_async_calls(cli)) {
1524                 /*
1525                  * Can't use sync call while an async call is in flight
1526                  */
1527                 status = NT_STATUS_INVALID_PARAMETER;
1528                 goto fail;
1529         }
1530
1531         ev = event_context_init(frame);
1532         if (ev == NULL) {
1533                 status = NT_STATUS_NO_MEMORY;
1534                 goto fail;
1535         }
1536
1537         req = cli_tcon_andx_send(frame, ev, cli, share, dev, pass, passlen);
1538         if (req == NULL) {
1539                 status = NT_STATUS_NO_MEMORY;
1540                 goto fail;
1541         }
1542
1543         if (!tevent_req_poll(req, ev)) {
1544                 status = map_nt_error_from_unix(errno);
1545                 goto fail;
1546         }
1547
1548         status = cli_tcon_andx_recv(req);
1549  fail:
1550         TALLOC_FREE(frame);
1551         if (!NT_STATUS_IS_OK(status)) {
1552                 cli_set_error(cli, status);
1553         }
1554         return status;
1555 }
1556
1557 /****************************************************************************
1558  Send a tree disconnect.
1559 ****************************************************************************/
1560
1561 bool cli_tdis(struct cli_state *cli)
1562 {
1563         memset(cli->outbuf,'\0',smb_size);
1564         cli_set_message(cli->outbuf,0,0,True);
1565         SCVAL(cli->outbuf,smb_com,SMBtdis);
1566         SSVAL(cli->outbuf,smb_tid,cli->cnum);
1567         cli_setup_packet(cli);
1568
1569         cli_send_smb(cli);
1570         if (!cli_receive_smb(cli))
1571                 return False;
1572
1573         if (cli_is_error(cli)) {
1574                 return False;
1575         }
1576
1577         cli->cnum = -1;
1578         return True;
1579 }
1580
1581 /****************************************************************************
1582  Send a negprot command.
1583 ****************************************************************************/
1584
1585 void cli_negprot_sendsync(struct cli_state *cli)
1586 {
1587         char *p;
1588         int numprots;
1589
1590         if (cli->protocol < PROTOCOL_NT1)
1591                 cli->use_spnego = False;
1592
1593         memset(cli->outbuf,'\0',smb_size);
1594
1595         /* setup the protocol strings */
1596         cli_set_message(cli->outbuf,0,0,True);
1597
1598         p = smb_buf(cli->outbuf);
1599         for (numprots=0; numprots < ARRAY_SIZE(prots); numprots++) {
1600                 if (prots[numprots].prot > cli->protocol) {
1601                         break;
1602                 }
1603                 *p++ = 2;
1604                 p += clistr_push(cli, p, prots[numprots].name, -1, STR_TERMINATE);
1605         }
1606
1607         SCVAL(cli->outbuf,smb_com,SMBnegprot);
1608         cli_setup_bcc(cli, p);
1609         cli_setup_packet(cli);
1610
1611         SCVAL(smb_buf(cli->outbuf),0,2);
1612
1613         cli_send_smb(cli);
1614 }
1615
1616 /****************************************************************************
1617  Send a negprot command.
1618 ****************************************************************************/
1619
1620 struct cli_negprot_state {
1621         struct cli_state *cli;
1622 };
1623
1624 static void cli_negprot_done(struct tevent_req *subreq);
1625
1626 struct tevent_req *cli_negprot_send(TALLOC_CTX *mem_ctx,
1627                                     struct event_context *ev,
1628                                     struct cli_state *cli)
1629 {
1630         struct tevent_req *req, *subreq;
1631         struct cli_negprot_state *state;
1632         uint8_t *bytes = NULL;
1633         int numprots;
1634         uint16_t cnum;
1635
1636         req = tevent_req_create(mem_ctx, &state, struct cli_negprot_state);
1637         if (req == NULL) {
1638                 return NULL;
1639         }
1640         state->cli = cli;
1641
1642         if (cli->protocol < PROTOCOL_NT1)
1643                 cli->use_spnego = False;
1644
1645         /* setup the protocol strings */
1646         for (numprots=0; numprots < ARRAY_SIZE(prots); numprots++) {
1647                 uint8_t c = 2;
1648                 if (prots[numprots].prot > cli->protocol) {
1649                         break;
1650                 }
1651                 bytes = (uint8_t *)talloc_append_blob(
1652                         state, bytes, data_blob_const(&c, sizeof(c)));
1653                 if (tevent_req_nomem(bytes, req)) {
1654                         return tevent_req_post(req, ev);
1655                 }
1656                 bytes = smb_bytes_push_str(bytes, false,
1657                                            prots[numprots].name,
1658                                            strlen(prots[numprots].name)+1,
1659                                            NULL);
1660                 if (tevent_req_nomem(bytes, req)) {
1661                         return tevent_req_post(req, ev);
1662                 }
1663         }
1664
1665         cnum = cli->cnum;
1666
1667         cli->cnum = 0;
1668         subreq = cli_smb_send(state, ev, cli, SMBnegprot, 0, 0, NULL,
1669                               talloc_get_size(bytes), bytes);
1670         cli->cnum = cnum;
1671
1672         if (tevent_req_nomem(subreq, req)) {
1673                 return tevent_req_post(req, ev);
1674         }
1675         tevent_req_set_callback(subreq, cli_negprot_done, req);
1676         return req;
1677 }
1678
1679 static void cli_negprot_done(struct tevent_req *subreq)
1680 {
1681         struct tevent_req *req = tevent_req_callback_data(
1682                 subreq, struct tevent_req);
1683         struct cli_negprot_state *state = tevent_req_data(
1684                 req, struct cli_negprot_state);
1685         struct cli_state *cli = state->cli;
1686         uint8_t wct;
1687         uint16_t *vwv;
1688         uint32_t num_bytes;
1689         uint8_t *bytes;
1690         NTSTATUS status;
1691         uint16_t protnum;
1692
1693         status = cli_smb_recv(subreq, 1, &wct, &vwv, &num_bytes, &bytes);
1694         if (!NT_STATUS_IS_OK(status)) {
1695                 TALLOC_FREE(subreq);
1696                 tevent_req_nterror(req, status);
1697                 return;
1698         }
1699
1700         protnum = SVAL(vwv, 0);
1701
1702         if ((protnum >= ARRAY_SIZE(prots))
1703             || (prots[protnum].prot > cli->protocol)) {
1704                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1705                 return;
1706         }
1707
1708         cli->protocol = prots[protnum].prot;
1709
1710         if ((cli->protocol < PROTOCOL_NT1) &&
1711             client_is_signing_mandatory(cli)) {
1712                 DEBUG(0,("cli_negprot: SMB signing is mandatory and the selected protocol level doesn't support it.\n"));
1713                 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1714                 return;
1715         }
1716
1717         if (cli->protocol >= PROTOCOL_NT1) {    
1718                 struct timespec ts;
1719                 bool negotiated_smb_signing = false;
1720
1721                 if (wct != 0x11) {
1722                         tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1723                         return;
1724                 }
1725
1726                 /* NT protocol */
1727                 cli->sec_mode = CVAL(vwv + 1, 0);
1728                 cli->max_mux = SVAL(vwv + 1, 1);
1729                 cli->max_xmit = IVAL(vwv + 3, 1);
1730                 cli->sesskey = IVAL(vwv + 7, 1);
1731                 cli->serverzone = SVALS(vwv + 15, 1);
1732                 cli->serverzone *= 60;
1733                 /* this time arrives in real GMT */
1734                 ts = interpret_long_date(((char *)(vwv+11))+1);
1735                 cli->servertime = ts.tv_sec;
1736                 cli->secblob = data_blob(bytes, num_bytes);
1737                 cli->capabilities = IVAL(vwv + 9, 1);
1738                 if (cli->capabilities & CAP_RAW_MODE) {
1739                         cli->readbraw_supported = True;
1740                         cli->writebraw_supported = True;      
1741                 }
1742                 /* work out if they sent us a workgroup */
1743                 if (!(cli->capabilities & CAP_EXTENDED_SECURITY) &&
1744                     smb_buflen(cli->inbuf) > 8) {
1745                         clistr_pull(cli->inbuf, cli->server_domain,
1746                                     bytes+8, sizeof(cli->server_domain),
1747                                     num_bytes-8,
1748                                     STR_UNICODE|STR_NOALIGN);
1749                 }
1750
1751                 /*
1752                  * As signing is slow we only turn it on if either the client or
1753                  * the server require it. JRA.
1754                  */
1755
1756                 if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) {
1757                         /* Fail if server says signing is mandatory and we don't want to support it. */
1758                         if (!client_is_signing_allowed(cli)) {
1759                                 DEBUG(0,("cli_negprot: SMB signing is mandatory and we have disabled it.\n"));
1760                                 tevent_req_nterror(req,
1761                                                    NT_STATUS_ACCESS_DENIED);
1762                                 return;
1763                         }
1764                         negotiated_smb_signing = true;
1765                 } else if (client_is_signing_mandatory(cli) && client_is_signing_allowed(cli)) {
1766                         /* Fail if client says signing is mandatory and the server doesn't support it. */
1767                         if (!(cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) {
1768                                 DEBUG(1,("cli_negprot: SMB signing is mandatory and the server doesn't support it.\n"));
1769                                 tevent_req_nterror(req,
1770                                                    NT_STATUS_ACCESS_DENIED);
1771                                 return;
1772                         }
1773                         negotiated_smb_signing = true;
1774                 } else if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) {
1775                         negotiated_smb_signing = true;
1776                 }
1777
1778                 if (negotiated_smb_signing) {
1779                         cli_set_signing_negotiated(cli);
1780                 }
1781
1782                 if (cli->capabilities & (CAP_LARGE_READX|CAP_LARGE_WRITEX)) {
1783                         SAFE_FREE(cli->outbuf);
1784                         SAFE_FREE(cli->inbuf);
1785                         cli->outbuf = (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE+LARGE_WRITEX_HDR_SIZE+SAFETY_MARGIN);
1786                         cli->inbuf = (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE+LARGE_WRITEX_HDR_SIZE+SAFETY_MARGIN);
1787                         cli->bufsize = CLI_SAMBA_MAX_LARGE_READX_SIZE + LARGE_WRITEX_HDR_SIZE;
1788                 }
1789
1790         } else if (cli->protocol >= PROTOCOL_LANMAN1) {
1791                 if (wct != 0x0D) {
1792                         tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1793                         return;
1794                 }
1795
1796                 cli->use_spnego = False;
1797                 cli->sec_mode = SVAL(vwv + 1, 0);
1798                 cli->max_xmit = SVAL(vwv + 2, 0);
1799                 cli->max_mux = SVAL(vwv + 3, 0);
1800                 cli->sesskey = IVAL(vwv + 6, 0);
1801                 cli->serverzone = SVALS(vwv + 10, 0);
1802                 cli->serverzone *= 60;
1803                 /* this time is converted to GMT by make_unix_date */
1804                 cli->servertime = cli_make_unix_date(
1805                         cli, (char *)(vwv + 8));
1806                 cli->readbraw_supported = ((SVAL(vwv + 5, 0) & 0x1) != 0);
1807                 cli->writebraw_supported = ((SVAL(vwv + 5, 0) & 0x2) != 0);
1808                 cli->secblob = data_blob(bytes, num_bytes);
1809         } else {
1810                 /* the old core protocol */
1811                 cli->use_spnego = False;
1812                 cli->sec_mode = 0;
1813                 cli->serverzone = get_time_zone(time(NULL));
1814         }
1815
1816         cli->max_xmit = MIN(cli->max_xmit, CLI_BUFFER_SIZE);
1817
1818         /* a way to force ascii SMB */
1819         if (getenv("CLI_FORCE_ASCII"))
1820                 cli->capabilities &= ~CAP_UNICODE;
1821
1822         tevent_req_done(req);
1823 }
1824
1825 NTSTATUS cli_negprot_recv(struct tevent_req *req)
1826 {
1827         return tevent_req_simple_recv_ntstatus(req);
1828 }
1829
1830 NTSTATUS cli_negprot(struct cli_state *cli)
1831 {
1832         TALLOC_CTX *frame = talloc_stackframe();
1833         struct event_context *ev;
1834         struct tevent_req *req;
1835         NTSTATUS status = NT_STATUS_OK;
1836
1837         if (cli_has_async_calls(cli)) {
1838                 /*
1839                  * Can't use sync call while an async call is in flight
1840                  */
1841                 status = NT_STATUS_INVALID_PARAMETER;
1842                 goto fail;
1843         }
1844
1845         ev = event_context_init(frame);
1846         if (ev == NULL) {
1847                 status = NT_STATUS_NO_MEMORY;
1848                 goto fail;
1849         }
1850
1851         req = cli_negprot_send(frame, ev, cli);
1852         if (req == NULL) {
1853                 status = NT_STATUS_NO_MEMORY;
1854                 goto fail;
1855         }
1856
1857         if (!tevent_req_poll(req, ev)) {
1858                 status = map_nt_error_from_unix(errno);
1859                 goto fail;
1860         }
1861
1862         status = cli_negprot_recv(req);
1863  fail:
1864         TALLOC_FREE(frame);
1865         if (!NT_STATUS_IS_OK(status)) {
1866                 cli_set_error(cli, status);
1867         }
1868         return status;
1869 }
1870
1871 /****************************************************************************
1872  Send a session request. See rfc1002.txt 4.3 and 4.3.2.
1873 ****************************************************************************/
1874
1875 bool cli_session_request(struct cli_state *cli,
1876                          struct nmb_name *calling, struct nmb_name *called)
1877 {
1878         char *p;
1879         int len = 4;
1880         int namelen = 0;
1881         char *tmp;
1882
1883         /* 445 doesn't have session request */
1884         if (cli->port == 445)
1885                 return True;
1886
1887         memcpy(&(cli->calling), calling, sizeof(*calling));
1888         memcpy(&(cli->called ), called , sizeof(*called ));
1889
1890         /* put in the destination name */
1891
1892         tmp = name_mangle(talloc_tos(), cli->called.name,
1893                           cli->called.name_type);
1894         if (tmp == NULL) {
1895                 return false;
1896         }
1897
1898         p = cli->outbuf+len;
1899         namelen = name_len((unsigned char *)tmp, talloc_get_size(tmp));
1900         if (namelen > 0) {
1901                 memcpy(p, tmp, namelen);
1902                 len += namelen;
1903         }
1904         TALLOC_FREE(tmp);
1905
1906         /* and my name */
1907
1908         tmp = name_mangle(talloc_tos(), cli->calling.name,
1909                           cli->calling.name_type);
1910         if (tmp == NULL) {
1911                 return false;
1912         }
1913
1914         p = cli->outbuf+len;
1915         namelen = name_len((unsigned char *)tmp, talloc_get_size(tmp));
1916         if (namelen > 0) {
1917                 memcpy(p, tmp, namelen);
1918                 len += namelen;
1919         }
1920         TALLOC_FREE(tmp);
1921
1922         /* send a session request (RFC 1002) */
1923         /* setup the packet length
1924          * Remove four bytes from the length count, since the length
1925          * field in the NBT Session Service header counts the number
1926          * of bytes which follow.  The cli_send_smb() function knows
1927          * about this and accounts for those four bytes.
1928          * CRH.
1929          */
1930         len -= 4;
1931         _smb_setlen(cli->outbuf,len);
1932         SCVAL(cli->outbuf,0,0x81);
1933
1934         cli_send_smb(cli);
1935         DEBUG(5,("Sent session request\n"));
1936
1937         if (!cli_receive_smb(cli))
1938                 return False;
1939
1940         if (CVAL(cli->inbuf,0) == 0x84) {
1941                 /* C. Hoch  9/14/95 Start */
1942                 /* For information, here is the response structure.
1943                  * We do the byte-twiddling to for portability.
1944                 struct RetargetResponse{
1945                 unsigned char type;
1946                 unsigned char flags;
1947                 int16 length;
1948                 int32 ip_addr;
1949                 int16 port;
1950                 };
1951                 */
1952                 uint16_t port = (CVAL(cli->inbuf,8)<<8)+CVAL(cli->inbuf,9);
1953                 struct in_addr dest_ip;
1954                 NTSTATUS status;
1955
1956                 /* SESSION RETARGET */
1957                 putip((char *)&dest_ip,cli->inbuf+4);
1958                 in_addr_to_sockaddr_storage(&cli->dest_ss, dest_ip);
1959
1960                 status = open_socket_out(&cli->dest_ss, port,
1961                                          LONG_CONNECT_TIMEOUT, &cli->fd);
1962                 if (!NT_STATUS_IS_OK(status)) {
1963                         return False;
1964                 }
1965
1966                 DEBUG(3,("Retargeted\n"));
1967
1968                 set_socket_options(cli->fd, lp_socket_options());
1969
1970                 /* Try again */
1971                 {
1972                         static int depth;
1973                         bool ret;
1974                         if (depth > 4) {
1975                                 DEBUG(0,("Retarget recursion - failing\n"));
1976                                 return False;
1977                         }
1978                         depth++;
1979                         ret = cli_session_request(cli, calling, called);
1980                         depth--;
1981                         return ret;
1982                 }
1983         } /* C. Hoch 9/14/95 End */
1984
1985         if (CVAL(cli->inbuf,0) != 0x82) {
1986                 /* This is the wrong place to put the error... JRA. */
1987                 cli->rap_error = CVAL(cli->inbuf,4);
1988                 return False;
1989         }
1990         return(True);
1991 }
1992
1993 struct fd_struct {
1994         int fd;
1995 };
1996
1997 static void smb_sock_connected(struct tevent_req *req)
1998 {
1999         struct fd_struct *pfd = tevent_req_callback_data(
2000                 req, struct fd_struct);
2001         int fd;
2002         NTSTATUS status;
2003
2004         status = open_socket_out_defer_recv(req, &fd);
2005         if (NT_STATUS_IS_OK(status)) {
2006                 pfd->fd = fd;
2007         }
2008 }
2009
2010 static NTSTATUS open_smb_socket(const struct sockaddr_storage *pss,
2011                                 uint16_t *port, int timeout, int *pfd)
2012 {
2013         struct event_context *ev;
2014         struct tevent_req *r139, *r445;
2015         struct fd_struct *fd139, *fd445;
2016         NTSTATUS status = NT_STATUS_NO_MEMORY;
2017
2018         if (*port != 0) {
2019                 return open_socket_out(pss, *port, timeout, pfd);
2020         }
2021
2022         ev = event_context_init(talloc_tos());
2023         if (ev == NULL) {
2024                 return NT_STATUS_NO_MEMORY;
2025         }
2026
2027         fd139 = talloc(ev, struct fd_struct);
2028         if (fd139 == NULL) {
2029                 goto done;
2030         }
2031         fd139->fd = -1;
2032
2033         fd445 = talloc(ev, struct fd_struct);
2034         if (fd445 == NULL) {
2035                 goto done;
2036         }
2037         fd445->fd = -1;
2038
2039         r445 = open_socket_out_defer_send(ev, ev, timeval_set(0, 0),
2040                                           pss, 445, timeout);
2041         r139 = open_socket_out_defer_send(ev, ev, timeval_set(0, 3000),
2042                                           pss, 139, timeout);
2043         if ((r445 == NULL) || (r139 == NULL)) {
2044                 goto done;
2045         }
2046         tevent_req_set_callback(r445, smb_sock_connected, fd445);
2047         tevent_req_set_callback(r139, smb_sock_connected, fd139);
2048
2049         while ((fd445->fd == -1) && (fd139->fd == -1)
2050                && (tevent_req_is_in_progress(r139)
2051                    || tevent_req_is_in_progress(r445))) {
2052                 event_loop_once(ev);
2053         }
2054
2055         if ((fd139->fd != -1) && (fd445->fd != -1)) {
2056                 close(fd139->fd);
2057                 fd139->fd = -1;
2058         }
2059
2060         if (fd445->fd != -1) {
2061                 *port = 445;
2062                 *pfd = fd445->fd;
2063                 status = NT_STATUS_OK;
2064                 goto done;
2065         }
2066         if (fd139->fd != -1) {
2067                 *port = 139;
2068                 *pfd = fd139->fd;
2069                 status = NT_STATUS_OK;
2070                 goto done;
2071         }
2072
2073         status = open_socket_out_defer_recv(r445, &fd445->fd);
2074  done:
2075         TALLOC_FREE(ev);
2076         return status;
2077 }
2078
2079 /****************************************************************************
2080  Open the client sockets.
2081 ****************************************************************************/
2082
2083 NTSTATUS cli_connect(struct cli_state *cli,
2084                 const char *host,
2085                 struct sockaddr_storage *dest_ss)
2086
2087 {
2088         int name_type = 0x20;
2089         TALLOC_CTX *frame = talloc_stackframe();
2090         unsigned int num_addrs = 0;
2091         unsigned int i = 0;
2092         struct sockaddr_storage *ss_arr = NULL;
2093         char *p = NULL;
2094
2095         /* reasonable default hostname */
2096         if (!host) {
2097                 host = STAR_SMBSERVER;
2098         }
2099
2100         fstrcpy(cli->desthost, host);
2101
2102         /* allow hostnames of the form NAME#xx and do a netbios lookup */
2103         if ((p = strchr(cli->desthost, '#'))) {
2104                 name_type = strtol(p+1, NULL, 16);
2105                 *p = 0;
2106         }
2107
2108         if (!dest_ss || is_zero_addr((struct sockaddr *)dest_ss)) {
2109                 NTSTATUS status =resolve_name_list(frame,
2110                                         cli->desthost,
2111                                         name_type,
2112                                         &ss_arr,
2113                                         &num_addrs);
2114                 if (!NT_STATUS_IS_OK(status)) {
2115                         TALLOC_FREE(frame);
2116                         return NT_STATUS_BAD_NETWORK_NAME;
2117                 }
2118         } else {
2119                 num_addrs = 1;
2120                 ss_arr = TALLOC_P(frame, struct sockaddr_storage);
2121                 if (!ss_arr) {
2122                         TALLOC_FREE(frame);
2123                         return NT_STATUS_NO_MEMORY;
2124                 }
2125                 *ss_arr = *dest_ss;
2126         }
2127
2128         for (i = 0; i < num_addrs; i++) {
2129                 cli->dest_ss = ss_arr[i];
2130                 if (getenv("LIBSMB_PROG")) {
2131                         cli->fd = sock_exec(getenv("LIBSMB_PROG"));
2132                 } else {
2133                         uint16_t port = cli->port;
2134                         NTSTATUS status;
2135                         status = open_smb_socket(&cli->dest_ss, &port,
2136                                                  cli->timeout, &cli->fd);
2137                         if (NT_STATUS_IS_OK(status)) {
2138                                 cli->port = port;
2139                         }
2140                 }
2141                 if (cli->fd == -1) {
2142                         char addr[INET6_ADDRSTRLEN];
2143                         print_sockaddr(addr, sizeof(addr), &ss_arr[i]);
2144                         DEBUG(2,("Error connecting to %s (%s)\n",
2145                                  dest_ss?addr:host,strerror(errno)));
2146                 } else {
2147                         /* Exit from loop on first connection. */
2148                         break;
2149                 }
2150         }
2151
2152         if (cli->fd == -1) {
2153                 TALLOC_FREE(frame);
2154                 return map_nt_error_from_unix(errno);
2155         }
2156
2157         if (dest_ss) {
2158                 *dest_ss = cli->dest_ss;
2159         }
2160
2161         set_socket_options(cli->fd, lp_socket_options());
2162
2163         TALLOC_FREE(frame);
2164         return NT_STATUS_OK;
2165 }
2166
2167 /**
2168    establishes a connection to after the negprot. 
2169    @param output_cli A fully initialised cli structure, non-null only on success
2170    @param dest_host The netbios name of the remote host
2171    @param dest_ss (optional) The the destination IP, NULL for name based lookup
2172    @param port (optional) The destination port (0 for default)
2173    @param retry bool. Did this connection fail with a retryable error ?
2174
2175 */
2176 NTSTATUS cli_start_connection(struct cli_state **output_cli, 
2177                               const char *my_name, 
2178                               const char *dest_host, 
2179                               struct sockaddr_storage *dest_ss, int port,
2180                               int signing_state, int flags,
2181                               bool *retry) 
2182 {
2183         NTSTATUS nt_status;
2184         struct nmb_name calling;
2185         struct nmb_name called;
2186         struct cli_state *cli;
2187         struct sockaddr_storage ss;
2188
2189         if (retry)
2190                 *retry = False;
2191
2192         if (!my_name) 
2193                 my_name = global_myname();
2194
2195         if (!(cli = cli_initialise_ex(signing_state))) {
2196                 return NT_STATUS_NO_MEMORY;
2197         }
2198
2199         make_nmb_name(&calling, my_name, 0x0);
2200         make_nmb_name(&called , dest_host, 0x20);
2201
2202         cli_set_port(cli, port);
2203         cli_set_timeout(cli, 10000); /* 10 seconds. */
2204
2205         if (dest_ss) {
2206                 ss = *dest_ss;
2207         } else {
2208                 zero_sockaddr(&ss);
2209         }
2210
2211 again:
2212
2213         DEBUG(3,("Connecting to host=%s\n", dest_host));
2214
2215         nt_status = cli_connect(cli, dest_host, &ss);
2216         if (!NT_STATUS_IS_OK(nt_status)) {
2217                 char addr[INET6_ADDRSTRLEN];
2218                 print_sockaddr(addr, sizeof(addr), &ss);
2219                 DEBUG(1,("cli_start_connection: failed to connect to %s (%s). Error %s\n",
2220                          nmb_namestr(&called), addr, nt_errstr(nt_status) ));
2221                 cli_shutdown(cli);
2222                 return nt_status;
2223         }
2224
2225         if (retry)
2226                 *retry = True;
2227
2228         if (!cli_session_request(cli, &calling, &called)) {
2229                 char *p;
2230                 DEBUG(1,("session request to %s failed (%s)\n",
2231                          called.name, cli_errstr(cli)));
2232                 if ((p=strchr(called.name, '.')) && !is_ipaddress(called.name)) {
2233                         *p = 0;
2234                         goto again;
2235                 }
2236                 if (strcmp(called.name, STAR_SMBSERVER)) {
2237                         make_nmb_name(&called , STAR_SMBSERVER, 0x20);
2238                         goto again;
2239                 }
2240                 return NT_STATUS_BAD_NETWORK_NAME;
2241         }
2242
2243         if (flags & CLI_FULL_CONNECTION_DONT_SPNEGO)
2244                 cli->use_spnego = False;
2245         else if (flags & CLI_FULL_CONNECTION_USE_KERBEROS)
2246                 cli->use_kerberos = True;
2247
2248         if ((flags & CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS) &&
2249              cli->use_kerberos) {
2250                 cli->fallback_after_kerberos = true;
2251         }
2252         if (flags & CLI_FULL_CONNECTION_USE_CCACHE) {
2253                 cli->use_ccache = true;
2254         }
2255
2256         nt_status = cli_negprot(cli);
2257         if (!NT_STATUS_IS_OK(nt_status)) {
2258                 DEBUG(1, ("failed negprot: %s\n", nt_errstr(nt_status)));
2259                 cli_shutdown(cli);
2260                 return nt_status;
2261         }
2262
2263         *output_cli = cli;
2264         return NT_STATUS_OK;
2265 }
2266
2267
2268 /**
2269    establishes a connection right up to doing tconX, password specified.
2270    @param output_cli A fully initialised cli structure, non-null only on success
2271    @param dest_host The netbios name of the remote host
2272    @param dest_ip (optional) The the destination IP, NULL for name based lookup
2273    @param port (optional) The destination port (0 for default)
2274    @param service (optional) The share to make the connection to.  Should be 'unqualified' in any way.
2275    @param service_type The 'type' of serivice. 
2276    @param user Username, unix string
2277    @param domain User's domain
2278    @param password User's password, unencrypted unix string.
2279    @param retry bool. Did this connection fail with a retryable error ?
2280 */
2281
2282 NTSTATUS cli_full_connection(struct cli_state **output_cli, 
2283                              const char *my_name, 
2284                              const char *dest_host, 
2285                              struct sockaddr_storage *dest_ss, int port,
2286                              const char *service, const char *service_type,
2287                              const char *user, const char *domain, 
2288                              const char *password, int flags,
2289                              int signing_state,
2290                              bool *retry) 
2291 {
2292         NTSTATUS nt_status;
2293         struct cli_state *cli = NULL;
2294         int pw_len = password ? strlen(password)+1 : 0;
2295
2296         *output_cli = NULL;
2297
2298         if (password == NULL) {
2299                 password = "";
2300         }
2301
2302         nt_status = cli_start_connection(&cli, my_name, dest_host,
2303                                          dest_ss, port, signing_state,
2304                                          flags, retry);
2305
2306         if (!NT_STATUS_IS_OK(nt_status)) {
2307                 return nt_status;
2308         }
2309
2310         cli->use_oplocks = ((flags & CLI_FULL_CONNECTION_OPLOCKS) != 0);
2311         cli->use_level_II_oplocks =
2312                 ((flags & CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS) != 0);
2313
2314         nt_status = cli_session_setup(cli, user, password, pw_len, password,
2315                                       pw_len, domain);
2316         if (!NT_STATUS_IS_OK(nt_status)) {
2317
2318                 if (!(flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)) {
2319                         DEBUG(1,("failed session setup with %s\n",
2320                                  nt_errstr(nt_status)));
2321                         cli_shutdown(cli);
2322                         return nt_status;
2323                 }
2324
2325                 nt_status = cli_session_setup(cli, "", "", 0, "", 0, domain);
2326                 if (!NT_STATUS_IS_OK(nt_status)) {
2327                         DEBUG(1,("anonymous failed session setup with %s\n",
2328                                  nt_errstr(nt_status)));
2329                         cli_shutdown(cli);
2330                         return nt_status;
2331                 }
2332         }
2333
2334         if (service) {
2335                 nt_status = cli_tcon_andx(cli, service, service_type, password,
2336                                           pw_len);
2337                 if (!NT_STATUS_IS_OK(nt_status)) {
2338                         DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status)));
2339                         cli_shutdown(cli);
2340                         if (NT_STATUS_IS_OK(nt_status)) {
2341                                 nt_status = NT_STATUS_UNSUCCESSFUL;
2342                         }
2343                         return nt_status;
2344                 }
2345         }
2346
2347         nt_status = cli_init_creds(cli, user, domain, password);
2348         if (!NT_STATUS_IS_OK(nt_status)) {
2349                 cli_shutdown(cli);
2350                 return nt_status;
2351         }
2352
2353         *output_cli = cli;
2354         return NT_STATUS_OK;
2355 }
2356
2357 /****************************************************************************
2358  Attempt a NetBIOS session request, falling back to *SMBSERVER if needed.
2359 ****************************************************************************/
2360
2361 bool attempt_netbios_session_request(struct cli_state **ppcli, const char *srchost, const char *desthost,
2362                                      struct sockaddr_storage *pdest_ss)
2363 {
2364         struct nmb_name calling, called;
2365
2366         make_nmb_name(&calling, srchost, 0x0);
2367
2368         /*
2369          * If the called name is an IP address
2370          * then use *SMBSERVER immediately.
2371          */
2372
2373         if(is_ipaddress(desthost)) {
2374                 make_nmb_name(&called, STAR_SMBSERVER, 0x20);
2375         } else {
2376                 make_nmb_name(&called, desthost, 0x20);
2377         }
2378
2379         if (!cli_session_request(*ppcli, &calling, &called)) {
2380                 NTSTATUS status;
2381                 struct nmb_name smbservername;
2382
2383                 make_nmb_name(&smbservername, STAR_SMBSERVER, 0x20);
2384
2385                 /*
2386                  * If the name wasn't *SMBSERVER then
2387                  * try with *SMBSERVER if the first name fails.
2388                  */
2389
2390                 if (nmb_name_equal(&called, &smbservername)) {
2391
2392                         /*
2393                          * The name used was *SMBSERVER, don't bother with another name.
2394                          */
2395
2396                         DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER \
2397 with error %s.\n", desthost, cli_errstr(*ppcli) ));
2398                         return False;
2399                 }
2400
2401                 /* Try again... */
2402                 cli_shutdown(*ppcli);
2403
2404                 *ppcli = cli_initialise();
2405                 if (!*ppcli) {
2406                         /* Out of memory... */
2407                         return False;
2408                 }
2409
2410                 status = cli_connect(*ppcli, desthost, pdest_ss);
2411                 if (!NT_STATUS_IS_OK(status) ||
2412                                 !cli_session_request(*ppcli, &calling, &smbservername)) {
2413                         DEBUG(0,("attempt_netbios_session_request: %s rejected the session for \
2414 name *SMBSERVER with error %s\n", desthost, cli_errstr(*ppcli) ));
2415                         return False;
2416                 }
2417         }
2418
2419         return True;
2420 }
2421
2422 /****************************************************************************
2423  Send an old style tcon.
2424 ****************************************************************************/
2425 NTSTATUS cli_raw_tcon(struct cli_state *cli, 
2426                       const char *service, const char *pass, const char *dev,
2427                       uint16 *max_xmit, uint16 *tid)
2428 {
2429         char *p;
2430
2431         if (!lp_client_plaintext_auth() && (*pass)) {
2432                 DEBUG(1, ("Server requested plaintext password but 'client "
2433                           "plaintext auth' is disabled\n"));
2434                 return NT_STATUS_ACCESS_DENIED;
2435         }
2436
2437         memset(cli->outbuf,'\0',smb_size);
2438         memset(cli->inbuf,'\0',smb_size);
2439
2440         cli_set_message(cli->outbuf, 0, 0, True);
2441         SCVAL(cli->outbuf,smb_com,SMBtcon);
2442         cli_setup_packet(cli);
2443
2444         p = smb_buf(cli->outbuf);
2445         *p++ = 4; p += clistr_push(cli, p, service, -1, STR_TERMINATE | STR_NOALIGN);
2446         *p++ = 4; p += clistr_push(cli, p, pass, -1, STR_TERMINATE | STR_NOALIGN);
2447         *p++ = 4; p += clistr_push(cli, p, dev, -1, STR_TERMINATE | STR_NOALIGN);
2448
2449         cli_setup_bcc(cli, p);
2450
2451         cli_send_smb(cli);
2452         if (!cli_receive_smb(cli)) {
2453                 return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
2454         }
2455
2456         if (cli_is_error(cli)) {
2457                 return cli_nt_error(cli);
2458         }
2459
2460         *max_xmit = SVAL(cli->inbuf, smb_vwv0);
2461         *tid = SVAL(cli->inbuf, smb_vwv1);
2462
2463         return NT_STATUS_OK;
2464 }
2465
2466 /* Return a cli_state pointing at the IPC$ share for the given server */
2467
2468 struct cli_state *get_ipc_connect(char *server,
2469                                 struct sockaddr_storage *server_ss,
2470                                 const struct user_auth_info *user_info)
2471 {
2472         struct cli_state *cli;
2473         NTSTATUS nt_status;
2474         uint32_t flags = CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
2475
2476         if (user_info->use_kerberos) {
2477                 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
2478         }
2479
2480         nt_status = cli_full_connection(&cli, NULL, server, server_ss, 0, "IPC$", "IPC", 
2481                                         user_info->username ? user_info->username : "",
2482                                         lp_workgroup(),
2483                                         user_info->password ? user_info->password : "",
2484                                         flags,
2485                                         Undefined, NULL);
2486
2487         if (NT_STATUS_IS_OK(nt_status)) {
2488                 return cli;
2489         } else if (is_ipaddress(server)) {
2490             /* windows 9* needs a correct NMB name for connections */
2491             fstring remote_name;
2492
2493             if (name_status_find("*", 0, 0, server_ss, remote_name)) {
2494                 cli = get_ipc_connect(remote_name, server_ss, user_info);
2495                 if (cli)
2496                     return cli;
2497             }
2498         }
2499         return NULL;
2500 }
2501
2502 /*
2503  * Given the IP address of a master browser on the network, return its
2504  * workgroup and connect to it.
2505  *
2506  * This function is provided to allow additional processing beyond what
2507  * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
2508  * browsers and obtain each master browsers' list of domains (in case the
2509  * first master browser is recently on the network and has not yet
2510  * synchronized with other master browsers and therefore does not yet have the
2511  * entire network browse list)
2512  */
2513
2514 struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx,
2515                                 struct ip_service *mb_ip,
2516                                 const struct user_auth_info *user_info,
2517                                 char **pp_workgroup_out)
2518 {
2519         char addr[INET6_ADDRSTRLEN];
2520         fstring name;
2521         struct cli_state *cli;
2522         struct sockaddr_storage server_ss;
2523
2524         *pp_workgroup_out = NULL;
2525
2526         print_sockaddr(addr, sizeof(addr), &mb_ip->ss);
2527         DEBUG(99, ("Looking up name of master browser %s\n",
2528                    addr));
2529
2530         /*
2531          * Do a name status query to find out the name of the master browser.
2532          * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
2533          * master browser will not respond to a wildcard query (or, at least,
2534          * an NT4 server acting as the domain master browser will not).
2535          *
2536          * We might be able to use ONLY the query on MSBROWSE, but that's not
2537          * yet been tested with all Windows versions, so until it is, leave
2538          * the original wildcard query as the first choice and fall back to
2539          * MSBROWSE if the wildcard query fails.
2540          */
2541         if (!name_status_find("*", 0, 0x1d, &mb_ip->ss, name) &&
2542             !name_status_find(MSBROWSE, 1, 0x1d, &mb_ip->ss, name)) {
2543
2544                 DEBUG(99, ("Could not retrieve name status for %s\n",
2545                            addr));
2546                 return NULL;
2547         }
2548
2549         if (!find_master_ip(name, &server_ss)) {
2550                 DEBUG(99, ("Could not find master ip for %s\n", name));
2551                 return NULL;
2552         }
2553
2554         *pp_workgroup_out = talloc_strdup(ctx, name);
2555
2556         DEBUG(4, ("found master browser %s, %s\n", name, addr));
2557
2558         print_sockaddr(addr, sizeof(addr), &server_ss);
2559         cli = get_ipc_connect(addr, &server_ss, user_info);
2560
2561         return cli;
2562 }
2563
2564 /*
2565  * Return the IP address and workgroup of a master browser on the network, and
2566  * connect to it.
2567  */
2568
2569 struct cli_state *get_ipc_connect_master_ip_bcast(TALLOC_CTX *ctx,
2570                                         const struct user_auth_info *user_info,
2571                                         char **pp_workgroup_out)
2572 {
2573         struct ip_service *ip_list;
2574         struct cli_state *cli;
2575         int i, count;
2576
2577         *pp_workgroup_out = NULL;
2578
2579         DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
2580
2581         /* Go looking for workgroups by broadcasting on the local network */
2582
2583         if (!NT_STATUS_IS_OK(name_resolve_bcast(MSBROWSE, 1, &ip_list,
2584                                                 &count))) {
2585                 DEBUG(99, ("No master browsers responded\n"));
2586                 return False;
2587         }
2588
2589         for (i = 0; i < count; i++) {
2590                 char addr[INET6_ADDRSTRLEN];
2591                 print_sockaddr(addr, sizeof(addr), &ip_list[i].ss);
2592                 DEBUG(99, ("Found master browser %s\n", addr));
2593
2594                 cli = get_ipc_connect_master_ip(ctx, &ip_list[i],
2595                                 user_info, pp_workgroup_out);
2596                 if (cli)
2597                         return(cli);
2598         }
2599
2600         return NULL;
2601 }