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