Convert cli_session_setup_guest to tevent_req
[samba.git] / source3 / libsmb / cliconnect.c
1 /* 
2    Unix SMB/CIFS implementation.
3    client connect/disconnect routines
4    Copyright (C) Andrew Tridgell 1994-1998
5    Copyright (C) Andrew Bartlett 2001-2003
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "includes.h"
22
23 static const struct {
24         int prot;
25         const char name[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 async_req *cli_negprot_send(TALLOC_CTX *mem_ctx,
1495                                    struct event_context *ev,
1496                                    struct cli_state *cli)
1497 {
1498         struct async_req *result;
1499         uint8_t *bytes = NULL;
1500         int numprots;
1501
1502         if (cli->protocol < PROTOCOL_NT1)
1503                 cli->use_spnego = False;
1504
1505         /* setup the protocol strings */
1506         for (numprots=0; numprots < ARRAY_SIZE(prots); numprots++) {
1507                 uint8_t c = 2;
1508                 if (prots[numprots].prot > cli->protocol) {
1509                         break;
1510                 }
1511                 bytes = (uint8_t *)talloc_append_blob(
1512                         talloc_tos(), bytes, data_blob_const(&c, sizeof(c)));
1513                 if (bytes == NULL) {
1514                         return NULL;
1515                 }
1516                 bytes = smb_bytes_push_str(bytes, false,
1517                                            prots[numprots].name,
1518                                            strlen(prots[numprots].name)+1,
1519                                            NULL);
1520                 if (bytes == NULL) {
1521                         return NULL;
1522                 }
1523         }
1524
1525         result = cli_request_send(mem_ctx, ev, cli, SMBnegprot, 0, 0, NULL, 0,
1526                                   talloc_get_size(bytes), bytes);
1527         TALLOC_FREE(bytes);
1528         return result;
1529 }
1530
1531 NTSTATUS cli_negprot_recv(struct async_req *req)
1532 {
1533         struct cli_request *cli_req = talloc_get_type_abort(
1534                 req->private_data, struct cli_request);
1535         struct cli_state *cli = cli_req->cli;
1536         uint8_t wct;
1537         uint16_t *vwv;
1538         uint16_t num_bytes;
1539         uint8_t *bytes;
1540         NTSTATUS status;
1541         uint16_t protnum;
1542
1543         if (async_req_is_nterror(req, &status)) {
1544                 return status;
1545         }
1546
1547         status = cli_pull_reply(req, &wct, &vwv, &num_bytes, &bytes);
1548         if (!NT_STATUS_IS_OK(status)) {
1549                 return status;
1550         }
1551
1552         protnum = SVAL(vwv, 0);
1553
1554         if ((protnum >= ARRAY_SIZE(prots))
1555             || (prots[protnum].prot > cli_req->cli->protocol)) {
1556                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
1557         }
1558
1559         cli->protocol = prots[protnum].prot;
1560
1561         if ((cli->protocol < PROTOCOL_NT1) &&
1562             client_is_signing_mandatory(cli)) {
1563                 DEBUG(0,("cli_negprot: SMB signing is mandatory and the selected protocol level doesn't support it.\n"));
1564                 return NT_STATUS_ACCESS_DENIED;
1565         }
1566
1567         if (cli->protocol >= PROTOCOL_NT1) {    
1568                 struct timespec ts;
1569                 bool negotiated_smb_signing = false;
1570
1571                 /* NT protocol */
1572                 cli->sec_mode = CVAL(vwv + 1, 0);
1573                 cli->max_mux = SVAL(vwv + 1, 1);
1574                 cli->max_xmit = IVAL(vwv + 3, 1);
1575                 cli->sesskey = IVAL(vwv + 7, 1);
1576                 cli->serverzone = SVALS(vwv + 15, 1);
1577                 cli->serverzone *= 60;
1578                 /* this time arrives in real GMT */
1579                 ts = interpret_long_date(((char *)(vwv+11))+1);
1580                 cli->servertime = ts.tv_sec;
1581                 cli->secblob = data_blob(bytes, num_bytes);
1582                 cli->capabilities = IVAL(vwv + 9, 1);
1583                 if (cli->capabilities & CAP_RAW_MODE) {
1584                         cli->readbraw_supported = True;
1585                         cli->writebraw_supported = True;      
1586                 }
1587                 /* work out if they sent us a workgroup */
1588                 if (!(cli->capabilities & CAP_EXTENDED_SECURITY) &&
1589                     smb_buflen(cli->inbuf) > 8) {
1590                         clistr_pull(cli->inbuf, cli->server_domain,
1591                                     bytes+8, sizeof(cli->server_domain),
1592                                     num_bytes-8,
1593                                     STR_UNICODE|STR_NOALIGN);
1594                 }
1595
1596                 /*
1597                  * As signing is slow we only turn it on if either the client or
1598                  * the server require it. JRA.
1599                  */
1600
1601                 if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) {
1602                         /* Fail if server says signing is mandatory and we don't want to support it. */
1603                         if (!client_is_signing_allowed(cli)) {
1604                                 DEBUG(0,("cli_negprot: SMB signing is mandatory and we have disabled it.\n"));
1605                                 return NT_STATUS_ACCESS_DENIED;
1606                         }
1607                         negotiated_smb_signing = true;
1608                 } else if (client_is_signing_mandatory(cli) && client_is_signing_allowed(cli)) {
1609                         /* Fail if client says signing is mandatory and the server doesn't support it. */
1610                         if (!(cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) {
1611                                 DEBUG(1,("cli_negprot: SMB signing is mandatory and the server doesn't support it.\n"));
1612                                 return NT_STATUS_ACCESS_DENIED;
1613                         }
1614                         negotiated_smb_signing = true;
1615                 } else if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) {
1616                         negotiated_smb_signing = true;
1617                 }
1618
1619                 if (negotiated_smb_signing) {
1620                         cli_set_signing_negotiated(cli);
1621                 }
1622
1623                 if (cli->capabilities & (CAP_LARGE_READX|CAP_LARGE_WRITEX)) {
1624                         SAFE_FREE(cli->outbuf);
1625                         SAFE_FREE(cli->inbuf);
1626                         cli->outbuf = (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE+LARGE_WRITEX_HDR_SIZE+SAFETY_MARGIN);
1627                         cli->inbuf = (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE+LARGE_WRITEX_HDR_SIZE+SAFETY_MARGIN);
1628                         cli->bufsize = CLI_SAMBA_MAX_LARGE_READX_SIZE + LARGE_WRITEX_HDR_SIZE;
1629                 }
1630
1631         } else if (cli->protocol >= PROTOCOL_LANMAN1) {
1632                 cli->use_spnego = False;
1633                 cli->sec_mode = SVAL(vwv + 1, 0);
1634                 cli->max_xmit = SVAL(vwv + 2, 0);
1635                 cli->max_mux = SVAL(vwv + 3, 0);
1636                 cli->sesskey = IVAL(vwv + 6, 0);
1637                 cli->serverzone = SVALS(vwv + 10, 0);
1638                 cli->serverzone *= 60;
1639                 /* this time is converted to GMT by make_unix_date */
1640                 cli->servertime = cli_make_unix_date(
1641                         cli, (char *)(vwv + 8));
1642                 cli->readbraw_supported = ((SVAL(vwv + 5, 0) & 0x1) != 0);
1643                 cli->writebraw_supported = ((SVAL(vwv + 5, 0) & 0x2) != 0);
1644                 cli->secblob = data_blob(bytes, num_bytes);
1645         } else {
1646                 /* the old core protocol */
1647                 cli->use_spnego = False;
1648                 cli->sec_mode = 0;
1649                 cli->serverzone = get_time_zone(time(NULL));
1650         }
1651
1652         cli->max_xmit = MIN(cli->max_xmit, CLI_BUFFER_SIZE);
1653
1654         /* a way to force ascii SMB */
1655         if (getenv("CLI_FORCE_ASCII"))
1656                 cli->capabilities &= ~CAP_UNICODE;
1657
1658         return NT_STATUS_OK;
1659 }
1660
1661 NTSTATUS cli_negprot(struct cli_state *cli)
1662 {
1663         TALLOC_CTX *frame = talloc_stackframe();
1664         struct event_context *ev;
1665         struct async_req *req;
1666         NTSTATUS status = NT_STATUS_NO_MEMORY;
1667
1668         if (cli->fd_event != NULL) {
1669                 /*
1670                  * Can't use sync call while an async call is in flight
1671                  */
1672                 cli_set_error(cli, NT_STATUS_INVALID_PARAMETER);
1673                 goto fail;
1674         }
1675
1676         ev = event_context_init(frame);
1677         if (ev == NULL) {
1678                 goto fail;
1679         }
1680
1681         req = cli_negprot_send(frame, ev, cli);
1682         if (req == NULL) {
1683                 goto fail;
1684         }
1685
1686         while (req->state < ASYNC_REQ_DONE) {
1687                 event_loop_once(ev);
1688         }
1689
1690         status = cli_negprot_recv(req);
1691  fail:
1692         TALLOC_FREE(frame);
1693         return status;
1694 }
1695
1696 /****************************************************************************
1697  Send a session request. See rfc1002.txt 4.3 and 4.3.2.
1698 ****************************************************************************/
1699
1700 bool cli_session_request(struct cli_state *cli,
1701                          struct nmb_name *calling, struct nmb_name *called)
1702 {
1703         char *p;
1704         int len = 4;
1705         char *tmp;
1706
1707         /* 445 doesn't have session request */
1708         if (cli->port == 445)
1709                 return True;
1710
1711         memcpy(&(cli->calling), calling, sizeof(*calling));
1712         memcpy(&(cli->called ), called , sizeof(*called ));
1713
1714         /* put in the destination name */
1715
1716         tmp = name_mangle(talloc_tos(), cli->called.name,
1717                           cli->called.name_type);
1718         if (tmp == NULL) {
1719                 return false;
1720         }
1721
1722         p = cli->outbuf+len;
1723         memcpy(p, tmp, name_len(tmp));
1724         len += name_len(tmp);
1725         TALLOC_FREE(tmp);
1726
1727         /* and my name */
1728
1729         tmp = name_mangle(talloc_tos(), cli->calling.name,
1730                           cli->calling.name_type);
1731         if (tmp == NULL) {
1732                 return false;
1733         }
1734
1735         p = cli->outbuf+len;
1736         memcpy(p, tmp, name_len(tmp));
1737         len += name_len(tmp);
1738         TALLOC_FREE(tmp);
1739
1740         /* send a session request (RFC 1002) */
1741         /* setup the packet length
1742          * Remove four bytes from the length count, since the length
1743          * field in the NBT Session Service header counts the number
1744          * of bytes which follow.  The cli_send_smb() function knows
1745          * about this and accounts for those four bytes.
1746          * CRH.
1747          */
1748         len -= 4;
1749         _smb_setlen(cli->outbuf,len);
1750         SCVAL(cli->outbuf,0,0x81);
1751
1752         cli_send_smb(cli);
1753         DEBUG(5,("Sent session request\n"));
1754
1755         if (!cli_receive_smb(cli))
1756                 return False;
1757
1758         if (CVAL(cli->inbuf,0) == 0x84) {
1759                 /* C. Hoch  9/14/95 Start */
1760                 /* For information, here is the response structure.
1761                  * We do the byte-twiddling to for portability.
1762                 struct RetargetResponse{
1763                 unsigned char type;
1764                 unsigned char flags;
1765                 int16 length;
1766                 int32 ip_addr;
1767                 int16 port;
1768                 };
1769                 */
1770                 uint16_t port = (CVAL(cli->inbuf,8)<<8)+CVAL(cli->inbuf,9);
1771                 struct in_addr dest_ip;
1772                 NTSTATUS status;
1773
1774                 /* SESSION RETARGET */
1775                 putip((char *)&dest_ip,cli->inbuf+4);
1776                 in_addr_to_sockaddr_storage(&cli->dest_ss, dest_ip);
1777
1778                 status = open_socket_out(&cli->dest_ss, port,
1779                                          LONG_CONNECT_TIMEOUT, &cli->fd);
1780                 if (!NT_STATUS_IS_OK(status)) {
1781                         return False;
1782                 }
1783
1784                 DEBUG(3,("Retargeted\n"));
1785
1786                 set_socket_options(cli->fd, lp_socket_options());
1787
1788                 /* Try again */
1789                 {
1790                         static int depth;
1791                         bool ret;
1792                         if (depth > 4) {
1793                                 DEBUG(0,("Retarget recursion - failing\n"));
1794                                 return False;
1795                         }
1796                         depth++;
1797                         ret = cli_session_request(cli, calling, called);
1798                         depth--;
1799                         return ret;
1800                 }
1801         } /* C. Hoch 9/14/95 End */
1802
1803         if (CVAL(cli->inbuf,0) != 0x82) {
1804                 /* This is the wrong place to put the error... JRA. */
1805                 cli->rap_error = CVAL(cli->inbuf,4);
1806                 return False;
1807         }
1808         return(True);
1809 }
1810
1811 struct fd_struct {
1812         int fd;
1813 };
1814
1815 static void smb_sock_connected(struct tevent_req *req)
1816 {
1817         struct fd_struct *pfd = tevent_req_callback_data(
1818                 req, struct fd_struct);
1819         int fd;
1820         NTSTATUS status;
1821
1822         status = open_socket_out_defer_recv(req, &fd);
1823         if (NT_STATUS_IS_OK(status)) {
1824                 pfd->fd = fd;
1825         }
1826 }
1827
1828 static NTSTATUS open_smb_socket(const struct sockaddr_storage *pss,
1829                                 uint16_t *port, int timeout, int *pfd)
1830 {
1831         struct event_context *ev;
1832         struct tevent_req *r139, *r445;
1833         struct fd_struct *fd139, *fd445;
1834         NTSTATUS status = NT_STATUS_NO_MEMORY;
1835
1836         if (*port != 0) {
1837                 return open_socket_out(pss, *port, timeout, pfd);
1838         }
1839
1840         ev = event_context_init(talloc_tos());
1841         if (ev == NULL) {
1842                 return NT_STATUS_NO_MEMORY;
1843         }
1844
1845         fd139 = talloc(ev, struct fd_struct);
1846         if (fd139 == NULL) {
1847                 goto done;
1848         }
1849         fd139->fd = -1;
1850
1851         fd445 = talloc(ev, struct fd_struct);
1852         if (fd445 == NULL) {
1853                 goto done;
1854         }
1855         fd445->fd = -1;
1856
1857         r445 = open_socket_out_defer_send(ev, ev, timeval_set(0, 0),
1858                                           pss, 445, timeout);
1859         r139 = open_socket_out_defer_send(ev, ev, timeval_set(0, 3000),
1860                                           pss, 139, timeout);
1861         if ((r445 == NULL) || (r139 == NULL)) {
1862                 goto done;
1863         }
1864         tevent_req_set_callback(r445, smb_sock_connected, fd445);
1865         tevent_req_set_callback(r139, smb_sock_connected, fd139);
1866
1867         while ((fd445->fd == -1) && (fd139->fd == -1)
1868                && (tevent_req_is_in_progress(r139)
1869                    || tevent_req_is_in_progress(r445))) {
1870                 event_loop_once(ev);
1871         }
1872
1873         if ((fd139->fd != -1) && (fd445->fd != -1)) {
1874                 close(fd139->fd);
1875                 fd139->fd = -1;
1876         }
1877
1878         if (fd445->fd != -1) {
1879                 *port = 445;
1880                 *pfd = fd445->fd;
1881                 status = NT_STATUS_OK;
1882                 goto done;
1883         }
1884         if (fd139->fd != -1) {
1885                 *port = 139;
1886                 *pfd = fd139->fd;
1887                 status = NT_STATUS_OK;
1888                 goto done;
1889         }
1890
1891         status = open_socket_out_defer_recv(r445, &fd445->fd);
1892  done:
1893         TALLOC_FREE(ev);
1894         return status;
1895 }
1896
1897 /****************************************************************************
1898  Open the client sockets.
1899 ****************************************************************************/
1900
1901 NTSTATUS cli_connect(struct cli_state *cli,
1902                 const char *host,
1903                 struct sockaddr_storage *dest_ss)
1904
1905 {
1906         int name_type = 0x20;
1907         TALLOC_CTX *frame = talloc_stackframe();
1908         unsigned int num_addrs = 0;
1909         unsigned int i = 0;
1910         struct sockaddr_storage *ss_arr = NULL;
1911         char *p = NULL;
1912
1913         /* reasonable default hostname */
1914         if (!host) {
1915                 host = STAR_SMBSERVER;
1916         }
1917
1918         fstrcpy(cli->desthost, host);
1919
1920         /* allow hostnames of the form NAME#xx and do a netbios lookup */
1921         if ((p = strchr(cli->desthost, '#'))) {
1922                 name_type = strtol(p+1, NULL, 16);
1923                 *p = 0;
1924         }
1925
1926         if (!dest_ss || is_zero_addr((struct sockaddr *)dest_ss)) {
1927                 NTSTATUS status =resolve_name_list(frame,
1928                                         cli->desthost,
1929                                         name_type,
1930                                         &ss_arr,
1931                                         &num_addrs);
1932                 if (!NT_STATUS_IS_OK(status)) {
1933                         TALLOC_FREE(frame);
1934                         return NT_STATUS_BAD_NETWORK_NAME;
1935                 }
1936         } else {
1937                 num_addrs = 1;
1938                 ss_arr = TALLOC_P(frame, struct sockaddr_storage);
1939                 if (!ss_arr) {
1940                         TALLOC_FREE(frame);
1941                         return NT_STATUS_NO_MEMORY;
1942                 }
1943                 *ss_arr = *dest_ss;
1944         }
1945
1946         for (i = 0; i < num_addrs; i++) {
1947                 cli->dest_ss = ss_arr[i];
1948                 if (getenv("LIBSMB_PROG")) {
1949                         cli->fd = sock_exec(getenv("LIBSMB_PROG"));
1950                 } else {
1951                         uint16_t port = cli->port;
1952                         NTSTATUS status;
1953                         status = open_smb_socket(&cli->dest_ss, &port,
1954                                                  cli->timeout, &cli->fd);
1955                         if (NT_STATUS_IS_OK(status)) {
1956                                 cli->port = port;
1957                         }
1958                 }
1959                 if (cli->fd == -1) {
1960                         char addr[INET6_ADDRSTRLEN];
1961                         print_sockaddr(addr, sizeof(addr), &ss_arr[i]);
1962                         DEBUG(2,("Error connecting to %s (%s)\n",
1963                                  dest_ss?addr:host,strerror(errno)));
1964                 } else {
1965                         /* Exit from loop on first connection. */
1966                         break;
1967                 }
1968         }
1969
1970         if (cli->fd == -1) {
1971                 TALLOC_FREE(frame);
1972                 return map_nt_error_from_unix(errno);
1973         }
1974
1975         if (dest_ss) {
1976                 *dest_ss = cli->dest_ss;
1977         }
1978
1979         set_socket_options(cli->fd, lp_socket_options());
1980
1981         TALLOC_FREE(frame);
1982         return NT_STATUS_OK;
1983 }
1984
1985 /**
1986    establishes a connection to after the negprot. 
1987    @param output_cli A fully initialised cli structure, non-null only on success
1988    @param dest_host The netbios name of the remote host
1989    @param dest_ss (optional) The the destination IP, NULL for name based lookup
1990    @param port (optional) The destination port (0 for default)
1991    @param retry bool. Did this connection fail with a retryable error ?
1992
1993 */
1994 NTSTATUS cli_start_connection(struct cli_state **output_cli, 
1995                               const char *my_name, 
1996                               const char *dest_host, 
1997                               struct sockaddr_storage *dest_ss, int port,
1998                               int signing_state, int flags,
1999                               bool *retry) 
2000 {
2001         NTSTATUS nt_status;
2002         struct nmb_name calling;
2003         struct nmb_name called;
2004         struct cli_state *cli;
2005         struct sockaddr_storage ss;
2006
2007         if (retry)
2008                 *retry = False;
2009
2010         if (!my_name) 
2011                 my_name = global_myname();
2012
2013         if (!(cli = cli_initialise_ex(signing_state))) {
2014                 return NT_STATUS_NO_MEMORY;
2015         }
2016
2017         make_nmb_name(&calling, my_name, 0x0);
2018         make_nmb_name(&called , dest_host, 0x20);
2019
2020         cli_set_port(cli, port);
2021         cli_set_timeout(cli, 10000); /* 10 seconds. */
2022
2023         if (dest_ss) {
2024                 ss = *dest_ss;
2025         } else {
2026                 zero_sockaddr(&ss);
2027         }
2028
2029 again:
2030
2031         DEBUG(3,("Connecting to host=%s\n", dest_host));
2032
2033         nt_status = cli_connect(cli, dest_host, &ss);
2034         if (!NT_STATUS_IS_OK(nt_status)) {
2035                 char addr[INET6_ADDRSTRLEN];
2036                 print_sockaddr(addr, sizeof(addr), &ss);
2037                 DEBUG(1,("cli_start_connection: failed to connect to %s (%s). Error %s\n",
2038                          nmb_namestr(&called), addr, nt_errstr(nt_status) ));
2039                 cli_shutdown(cli);
2040                 return nt_status;
2041         }
2042
2043         if (retry)
2044                 *retry = True;
2045
2046         if (!cli_session_request(cli, &calling, &called)) {
2047                 char *p;
2048                 DEBUG(1,("session request to %s failed (%s)\n",
2049                          called.name, cli_errstr(cli)));
2050                 if ((p=strchr(called.name, '.')) && !is_ipaddress(called.name)) {
2051                         *p = 0;
2052                         goto again;
2053                 }
2054                 if (strcmp(called.name, STAR_SMBSERVER)) {
2055                         make_nmb_name(&called , STAR_SMBSERVER, 0x20);
2056                         goto again;
2057                 }
2058                 return NT_STATUS_BAD_NETWORK_NAME;
2059         }
2060
2061         if (flags & CLI_FULL_CONNECTION_DONT_SPNEGO)
2062                 cli->use_spnego = False;
2063         else if (flags & CLI_FULL_CONNECTION_USE_KERBEROS)
2064                 cli->use_kerberos = True;
2065
2066         if ((flags & CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS) &&
2067              cli->use_kerberos) {
2068                 cli->fallback_after_kerberos = true;
2069         }
2070
2071         nt_status = cli_negprot(cli);
2072         if (!NT_STATUS_IS_OK(nt_status)) {
2073                 DEBUG(1, ("failed negprot: %s\n", nt_errstr(nt_status)));
2074                 cli_shutdown(cli);
2075                 return nt_status;
2076         }
2077
2078         *output_cli = cli;
2079         return NT_STATUS_OK;
2080 }
2081
2082
2083 /**
2084    establishes a connection right up to doing tconX, password specified.
2085    @param output_cli A fully initialised cli structure, non-null only on success
2086    @param dest_host The netbios name of the remote host
2087    @param dest_ip (optional) The the destination IP, NULL for name based lookup
2088    @param port (optional) The destination port (0 for default)
2089    @param service (optional) The share to make the connection to.  Should be 'unqualified' in any way.
2090    @param service_type The 'type' of serivice. 
2091    @param user Username, unix string
2092    @param domain User's domain
2093    @param password User's password, unencrypted unix string.
2094    @param retry bool. Did this connection fail with a retryable error ?
2095 */
2096
2097 NTSTATUS cli_full_connection(struct cli_state **output_cli, 
2098                              const char *my_name, 
2099                              const char *dest_host, 
2100                              struct sockaddr_storage *dest_ss, int port,
2101                              const char *service, const char *service_type,
2102                              const char *user, const char *domain, 
2103                              const char *password, int flags,
2104                              int signing_state,
2105                              bool *retry) 
2106 {
2107         NTSTATUS nt_status;
2108         struct cli_state *cli = NULL;
2109         int pw_len = password ? strlen(password)+1 : 0;
2110
2111         *output_cli = NULL;
2112
2113         if (password == NULL) {
2114                 password = "";
2115         }
2116
2117         nt_status = cli_start_connection(&cli, my_name, dest_host,
2118                                          dest_ss, port, signing_state,
2119                                          flags, retry);
2120
2121         if (!NT_STATUS_IS_OK(nt_status)) {
2122                 return nt_status;
2123         }
2124
2125         nt_status = cli_session_setup(cli, user, password, pw_len, password,
2126                                       pw_len, domain);
2127         if (!NT_STATUS_IS_OK(nt_status)) {
2128
2129                 if (!(flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)) {
2130                         DEBUG(1,("failed session setup with %s\n",
2131                                  nt_errstr(nt_status)));
2132                         cli_shutdown(cli);
2133                         return nt_status;
2134                 }
2135
2136                 nt_status = cli_session_setup(cli, "", "", 0, "", 0, domain);
2137                 if (!NT_STATUS_IS_OK(nt_status)) {
2138                         DEBUG(1,("anonymous failed session setup with %s\n",
2139                                  nt_errstr(nt_status)));
2140                         cli_shutdown(cli);
2141                         return nt_status;
2142                 }
2143         }
2144
2145         if (service) {
2146                 nt_status = cli_tcon_andx(cli, service, service_type, password,
2147                                           pw_len);
2148                 if (!NT_STATUS_IS_OK(nt_status)) {
2149                         DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status)));
2150                         cli_shutdown(cli);
2151                         if (NT_STATUS_IS_OK(nt_status)) {
2152                                 nt_status = NT_STATUS_UNSUCCESSFUL;
2153                         }
2154                         return nt_status;
2155                 }
2156         }
2157
2158         nt_status = cli_init_creds(cli, user, domain, password);
2159         if (!NT_STATUS_IS_OK(nt_status)) {
2160                 cli_shutdown(cli);
2161                 return nt_status;
2162         }
2163
2164         *output_cli = cli;
2165         return NT_STATUS_OK;
2166 }
2167
2168 /****************************************************************************
2169  Attempt a NetBIOS session request, falling back to *SMBSERVER if needed.
2170 ****************************************************************************/
2171
2172 bool attempt_netbios_session_request(struct cli_state **ppcli, const char *srchost, const char *desthost,
2173                                      struct sockaddr_storage *pdest_ss)
2174 {
2175         struct nmb_name calling, called;
2176
2177         make_nmb_name(&calling, srchost, 0x0);
2178
2179         /*
2180          * If the called name is an IP address
2181          * then use *SMBSERVER immediately.
2182          */
2183
2184         if(is_ipaddress(desthost)) {
2185                 make_nmb_name(&called, STAR_SMBSERVER, 0x20);
2186         } else {
2187                 make_nmb_name(&called, desthost, 0x20);
2188         }
2189
2190         if (!cli_session_request(*ppcli, &calling, &called)) {
2191                 NTSTATUS status;
2192                 struct nmb_name smbservername;
2193
2194                 make_nmb_name(&smbservername, STAR_SMBSERVER, 0x20);
2195
2196                 /*
2197                  * If the name wasn't *SMBSERVER then
2198                  * try with *SMBSERVER if the first name fails.
2199                  */
2200
2201                 if (nmb_name_equal(&called, &smbservername)) {
2202
2203                         /*
2204                          * The name used was *SMBSERVER, don't bother with another name.
2205                          */
2206
2207                         DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER \
2208 with error %s.\n", desthost, cli_errstr(*ppcli) ));
2209                         return False;
2210                 }
2211
2212                 /* Try again... */
2213                 cli_shutdown(*ppcli);
2214
2215                 *ppcli = cli_initialise();
2216                 if (!*ppcli) {
2217                         /* Out of memory... */
2218                         return False;
2219                 }
2220
2221                 status = cli_connect(*ppcli, desthost, pdest_ss);
2222                 if (!NT_STATUS_IS_OK(status) ||
2223                                 !cli_session_request(*ppcli, &calling, &smbservername)) {
2224                         DEBUG(0,("attempt_netbios_session_request: %s rejected the session for \
2225 name *SMBSERVER with error %s\n", desthost, cli_errstr(*ppcli) ));
2226                         return False;
2227                 }
2228         }
2229
2230         return True;
2231 }
2232
2233 /****************************************************************************
2234  Send an old style tcon.
2235 ****************************************************************************/
2236 NTSTATUS cli_raw_tcon(struct cli_state *cli, 
2237                       const char *service, const char *pass, const char *dev,
2238                       uint16 *max_xmit, uint16 *tid)
2239 {
2240         char *p;
2241
2242         if (!lp_client_plaintext_auth() && (*pass)) {
2243                 DEBUG(1, ("Server requested plaintext password but 'client "
2244                           "plaintext auth' is disabled\n"));
2245                 return NT_STATUS_ACCESS_DENIED;
2246         }
2247
2248         memset(cli->outbuf,'\0',smb_size);
2249         memset(cli->inbuf,'\0',smb_size);
2250
2251         cli_set_message(cli->outbuf, 0, 0, True);
2252         SCVAL(cli->outbuf,smb_com,SMBtcon);
2253         cli_setup_packet(cli);
2254
2255         p = smb_buf(cli->outbuf);
2256         *p++ = 4; p += clistr_push(cli, p, service, -1, STR_TERMINATE | STR_NOALIGN);
2257         *p++ = 4; p += clistr_push(cli, p, pass, -1, STR_TERMINATE | STR_NOALIGN);
2258         *p++ = 4; p += clistr_push(cli, p, dev, -1, STR_TERMINATE | STR_NOALIGN);
2259
2260         cli_setup_bcc(cli, p);
2261
2262         cli_send_smb(cli);
2263         if (!cli_receive_smb(cli)) {
2264                 return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
2265         }
2266
2267         if (cli_is_error(cli)) {
2268                 return cli_nt_error(cli);
2269         }
2270
2271         *max_xmit = SVAL(cli->inbuf, smb_vwv0);
2272         *tid = SVAL(cli->inbuf, smb_vwv1);
2273
2274         return NT_STATUS_OK;
2275 }
2276
2277 /* Return a cli_state pointing at the IPC$ share for the given server */
2278
2279 struct cli_state *get_ipc_connect(char *server,
2280                                 struct sockaddr_storage *server_ss,
2281                                 const struct user_auth_info *user_info)
2282 {
2283         struct cli_state *cli;
2284         NTSTATUS nt_status;
2285         uint32_t flags = CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
2286
2287         if (user_info->use_kerberos) {
2288                 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
2289         }
2290
2291         nt_status = cli_full_connection(&cli, NULL, server, server_ss, 0, "IPC$", "IPC", 
2292                                         user_info->username ? user_info->username : "",
2293                                         lp_workgroup(),
2294                                         user_info->password ? user_info->password : "",
2295                                         flags,
2296                                         Undefined, NULL);
2297
2298         if (NT_STATUS_IS_OK(nt_status)) {
2299                 return cli;
2300         } else if (is_ipaddress(server)) {
2301             /* windows 9* needs a correct NMB name for connections */
2302             fstring remote_name;
2303
2304             if (name_status_find("*", 0, 0, server_ss, remote_name)) {
2305                 cli = get_ipc_connect(remote_name, server_ss, user_info);
2306                 if (cli)
2307                     return cli;
2308             }
2309         }
2310         return NULL;
2311 }
2312
2313 /*
2314  * Given the IP address of a master browser on the network, return its
2315  * workgroup and connect to it.
2316  *
2317  * This function is provided to allow additional processing beyond what
2318  * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
2319  * browsers and obtain each master browsers' list of domains (in case the
2320  * first master browser is recently on the network and has not yet
2321  * synchronized with other master browsers and therefore does not yet have the
2322  * entire network browse list)
2323  */
2324
2325 struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx,
2326                                 struct ip_service *mb_ip,
2327                                 const struct user_auth_info *user_info,
2328                                 char **pp_workgroup_out)
2329 {
2330         char addr[INET6_ADDRSTRLEN];
2331         fstring name;
2332         struct cli_state *cli;
2333         struct sockaddr_storage server_ss;
2334
2335         *pp_workgroup_out = NULL;
2336
2337         print_sockaddr(addr, sizeof(addr), &mb_ip->ss);
2338         DEBUG(99, ("Looking up name of master browser %s\n",
2339                    addr));
2340
2341         /*
2342          * Do a name status query to find out the name of the master browser.
2343          * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
2344          * master browser will not respond to a wildcard query (or, at least,
2345          * an NT4 server acting as the domain master browser will not).
2346          *
2347          * We might be able to use ONLY the query on MSBROWSE, but that's not
2348          * yet been tested with all Windows versions, so until it is, leave
2349          * the original wildcard query as the first choice and fall back to
2350          * MSBROWSE if the wildcard query fails.
2351          */
2352         if (!name_status_find("*", 0, 0x1d, &mb_ip->ss, name) &&
2353             !name_status_find(MSBROWSE, 1, 0x1d, &mb_ip->ss, name)) {
2354
2355                 DEBUG(99, ("Could not retrieve name status for %s\n",
2356                            addr));
2357                 return NULL;
2358         }
2359
2360         if (!find_master_ip(name, &server_ss)) {
2361                 DEBUG(99, ("Could not find master ip for %s\n", name));
2362                 return NULL;
2363         }
2364
2365         *pp_workgroup_out = talloc_strdup(ctx, name);
2366
2367         DEBUG(4, ("found master browser %s, %s\n", name, addr));
2368
2369         print_sockaddr(addr, sizeof(addr), &server_ss);
2370         cli = get_ipc_connect(addr, &server_ss, user_info);
2371
2372         return cli;
2373 }
2374
2375 /*
2376  * Return the IP address and workgroup of a master browser on the network, and
2377  * connect to it.
2378  */
2379
2380 struct cli_state *get_ipc_connect_master_ip_bcast(TALLOC_CTX *ctx,
2381                                         const struct user_auth_info *user_info,
2382                                         char **pp_workgroup_out)
2383 {
2384         struct ip_service *ip_list;
2385         struct cli_state *cli;
2386         int i, count;
2387
2388         *pp_workgroup_out = NULL;
2389
2390         DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
2391
2392         /* Go looking for workgroups by broadcasting on the local network */
2393
2394         if (!NT_STATUS_IS_OK(name_resolve_bcast(MSBROWSE, 1, &ip_list,
2395                                                 &count))) {
2396                 DEBUG(99, ("No master browsers responded\n"));
2397                 return False;
2398         }
2399
2400         for (i = 0; i < count; i++) {
2401                 char addr[INET6_ADDRSTRLEN];
2402                 print_sockaddr(addr, sizeof(addr), &ip_list[i].ss);
2403                 DEBUG(99, ("Found master browser %s\n", addr));
2404
2405                 cli = get_ipc_connect_master_ip(ctx, &ip_list[i],
2406                                 user_info, pp_workgroup_out);
2407                 if (cli)
2408                         return(cli);
2409         }
2410
2411         return NULL;
2412 }