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