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