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