s3:libsmb: Only print error message if kerberos use is forced
[samba.git] / source3 / libsmb / cliconnect.c
1 /* 
2    Unix SMB/CIFS implementation.
3    client connect/disconnect routines
4    Copyright (C) Andrew Tridgell 1994-1998
5    Copyright (C) Andrew Bartlett 2001-2003
6    Copyright (C) Volker Lendecke 2011
7    Copyright (C) Jeremy Allison 2011
8
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3 of the License, or
12    (at your option) any later version.
13
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <http://www.gnu.org/licenses/>.
21 */
22
23 #include "includes.h"
24 #include "libsmb/libsmb.h"
25 #include "auth_info.h"
26 #include "../libcli/auth/libcli_auth.h"
27 #include "../libcli/auth/spnego.h"
28 #include "smb_krb5.h"
29 #include "auth/credentials/credentials.h"
30 #include "auth/gensec/gensec.h"
31 #include "auth/ntlmssp/ntlmssp.h"
32 #include "auth_generic.h"
33 #include "libads/kerberos_proto.h"
34 #include "krb5_env.h"
35 #include "../lib/util/tevent_ntstatus.h"
36 #include "async_smb.h"
37 #include "libsmb/nmblib.h"
38 #include "librpc/ndr/libndr.h"
39 #include "../libcli/smb/smbXcli_base.h"
40 #include "../libcli/smb/smb_seal.h"
41 #include "lib/param/param.h"
42 #include "../libcli/smb/smb2_negotiate_context.h"
43
44 #define STAR_SMBSERVER "*SMBSERVER"
45
46 static char *cli_session_setup_get_account(TALLOC_CTX *mem_ctx,
47                                            const char *principal);
48
49 struct cli_credentials *cli_session_creds_init(TALLOC_CTX *mem_ctx,
50                                                const char *username,
51                                                const char *domain,
52                                                const char *realm,
53                                                const char *password,
54                                                bool use_kerberos,
55                                                bool fallback_after_kerberos,
56                                                bool use_ccache,
57                                                bool password_is_nt_hash)
58 {
59         struct loadparm_context *lp_ctx = NULL;
60         struct cli_credentials *creds = NULL;
61         const char *principal = NULL;
62         char *tmp = NULL;
63         char *p = NULL;
64         bool ok;
65
66         creds = cli_credentials_init(mem_ctx);
67         if (creds == NULL) {
68                 return NULL;
69         }
70
71         lp_ctx = loadparm_init_s3(creds, loadparm_s3_helpers());
72         if (lp_ctx == NULL) {
73                 goto fail;
74         }
75         cli_credentials_set_conf(creds, lp_ctx);
76
77         if (username == NULL) {
78                 username = "";
79         }
80
81         if (strlen(username) == 0) {
82                 if (password != NULL && strlen(password) == 0) {
83                         /*
84                          * some callers pass "" as no password
85                          *
86                          * gensec only handles NULL as no password.
87                          */
88                         password = NULL;
89                 }
90                 if (password == NULL) {
91                         cli_credentials_set_anonymous(creds);
92                         return creds;
93                 }
94         }
95
96         tmp = talloc_strdup(creds, username);
97         if (tmp == NULL) {
98                 goto fail;
99         }
100         username = tmp;
101
102         /* allow for workgroups as part of the username */
103         if ((p = strchr_m(tmp, '\\')) ||
104             (p = strchr_m(tmp, '/')) ||
105             (p = strchr_m(tmp, *lp_winbind_separator()))) {
106                 *p = 0;
107                 username = p + 1;
108                 domain = tmp;
109         }
110
111         principal = username;
112         username = cli_session_setup_get_account(creds, principal);
113         if (username == NULL) {
114                 goto fail;
115         }
116         ok = strequal(username, principal);
117         if (ok) {
118                 /*
119                  * Ok still the same, so it's not a principal
120                  */
121                 principal = NULL;
122         }
123
124         if (use_kerberos && fallback_after_kerberos) {
125                 cli_credentials_set_kerberos_state(creds,
126                                                    CRED_AUTO_USE_KERBEROS);
127         } else if (use_kerberos) {
128                 cli_credentials_set_kerberos_state(creds,
129                                                    CRED_MUST_USE_KERBEROS);
130         } else {
131                 cli_credentials_set_kerberos_state(creds,
132                                                    CRED_DONT_USE_KERBEROS);
133         }
134
135         if (use_ccache) {
136                 uint32_t features;
137
138                 features = cli_credentials_get_gensec_features(creds);
139                 features |= GENSEC_FEATURE_NTLM_CCACHE;
140                 cli_credentials_set_gensec_features(creds, features);
141
142                 if (password != NULL && strlen(password) == 0) {
143                         /*
144                          * some callers pass "" as no password
145                          *
146                          * GENSEC_FEATURE_NTLM_CCACHE only handles
147                          * NULL as no password.
148                          */
149                         password = NULL;
150                 }
151         }
152
153         ok = cli_credentials_set_username(creds,
154                                           username,
155                                           CRED_SPECIFIED);
156         if (!ok) {
157                 goto fail;
158         }
159
160         if (domain != NULL) {
161                 ok = cli_credentials_set_domain(creds,
162                                                 domain,
163                                                 CRED_SPECIFIED);
164                 if (!ok) {
165                         goto fail;
166                 }
167         }
168
169         if (principal != NULL) {
170                 ok = cli_credentials_set_principal(creds,
171                                                    principal,
172                                                    CRED_SPECIFIED);
173                 if (!ok) {
174                         goto fail;
175                 }
176         }
177
178         if (realm != NULL) {
179                 ok = cli_credentials_set_realm(creds,
180                                                realm,
181                                                CRED_SPECIFIED);
182                 if (!ok) {
183                         goto fail;
184                 }
185         }
186
187         if (password != NULL && strlen(password) > 0) {
188                 if (password_is_nt_hash) {
189                         struct samr_Password nt_hash;
190                         size_t converted;
191
192                         converted = strhex_to_str((char *)nt_hash.hash,
193                                                   sizeof(nt_hash.hash),
194                                                   password,
195                                                   strlen(password));
196                         if (converted != sizeof(nt_hash.hash)) {
197                                 goto fail;
198                         }
199
200                         ok = cli_credentials_set_nt_hash(creds,
201                                                          &nt_hash,
202                                                          CRED_SPECIFIED);
203                         if (!ok) {
204                                 goto fail;
205                         }
206                 } else {
207                         ok = cli_credentials_set_password(creds,
208                                                           password,
209                                                           CRED_SPECIFIED);
210                         if (!ok) {
211                                 goto fail;
212                         }
213                 }
214         }
215
216         return creds;
217 fail:
218         TALLOC_FREE(creds);
219         return NULL;
220 }
221
222 NTSTATUS cli_session_creds_prepare_krb5(struct cli_state *cli,
223                                         struct cli_credentials *creds)
224 {
225         TALLOC_CTX *frame = talloc_stackframe();
226         const char *user_principal = NULL;
227         const char *user_account = NULL;
228         const char *user_domain = NULL;
229         const char *pass = NULL;
230         const char *target_hostname = NULL;
231         const DATA_BLOB *server_blob = NULL;
232         bool got_kerberos_mechanism = false;
233         enum credentials_use_kerberos krb5_state;
234         bool try_kerberos = false;
235         bool need_kinit = false;
236         bool auth_requested = true;
237         int ret;
238
239         target_hostname = smbXcli_conn_remote_name(cli->conn);
240         server_blob = smbXcli_conn_server_gss_blob(cli->conn);
241
242         /* the server might not even do spnego */
243         if (server_blob != NULL && server_blob->length != 0) {
244                 char *OIDs[ASN1_MAX_OIDS] = { NULL, };
245                 size_t i;
246                 bool ok;
247
248                 /*
249                  * The server sent us the first part of the SPNEGO exchange in the
250                  * negprot reply. It is WRONG to depend on the principal sent in the
251                  * negprot reply, but right now we do it. If we don't receive one,
252                  * we try to best guess, then fall back to NTLM.
253                  */
254                 ok = spnego_parse_negTokenInit(frame,
255                                                *server_blob,
256                                                OIDs,
257                                                NULL,
258                                                NULL);
259                 if (!ok) {
260                         TALLOC_FREE(frame);
261                         return NT_STATUS_INVALID_PARAMETER;
262                 }
263                 if (OIDs[0] == NULL) {
264                         TALLOC_FREE(frame);
265                         return NT_STATUS_INVALID_PARAMETER;
266                 }
267
268                 /* make sure the server understands kerberos */
269                 for (i = 0; OIDs[i] != NULL; i++) {
270                         if (i == 0) {
271                                 DEBUG(3,("got OID=%s\n", OIDs[i]));
272                         } else {
273                                 DEBUGADD(3,("got OID=%s\n", OIDs[i]));
274                         }
275
276                         if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0 ||
277                             strcmp(OIDs[i], OID_KERBEROS5) == 0) {
278                                 got_kerberos_mechanism = true;
279                                 break;
280                         }
281                 }
282         }
283
284         auth_requested = cli_credentials_authentication_requested(creds);
285         if (auth_requested) {
286                 user_principal = cli_credentials_get_principal(creds, frame);
287                 if (user_principal == NULL) {
288                         TALLOC_FREE(frame);
289                         return NT_STATUS_NO_MEMORY;
290                 }
291         }
292         user_account = cli_credentials_get_username(creds);
293         user_domain = cli_credentials_get_domain(creds);
294         pass = cli_credentials_get_password(creds);
295
296         krb5_state = cli_credentials_get_kerberos_state(creds);
297
298         if (krb5_state != CRED_DONT_USE_KERBEROS) {
299                 try_kerberos = true;
300         }
301
302         if (target_hostname == NULL) {
303                 try_kerberos = false;
304         } else if (is_ipaddress(target_hostname)) {
305                 try_kerberos = false;
306         } else if (strequal(target_hostname, "localhost")) {
307                 try_kerberos = false;
308         } else if (strequal(target_hostname, STAR_SMBSERVER)) {
309                 try_kerberos = false;
310         } else if (!auth_requested) {
311                 try_kerberos = false;
312         }
313
314         if (krb5_state == CRED_MUST_USE_KERBEROS && !try_kerberos) {
315                 DEBUG(0, ("Kerberos auth with '%s' (%s\\%s) to access "
316                           "'%s' not possible\n",
317                           user_principal, user_domain, user_account,
318                           target_hostname));
319                 TALLOC_FREE(frame);
320                 return NT_STATUS_ACCESS_DENIED;
321         }
322
323         if (pass == NULL || strlen(pass) == 0) {
324                 need_kinit = false;
325         } else if (krb5_state == CRED_MUST_USE_KERBEROS) {
326                 need_kinit = try_kerberos;
327         } else if (!got_kerberos_mechanism) {
328                 /*
329                  * Most likely the server doesn't support
330                  * Kerberos, don't waste time doing a kinit
331                  */
332                 need_kinit = false;
333         } else {
334                 need_kinit = try_kerberos;
335         }
336
337         if (!need_kinit) {
338                 TALLOC_FREE(frame);
339                 return NT_STATUS_OK;
340         }
341
342
343         /*
344          * TODO: This should be done within the gensec layer
345          * only if required!
346          */
347         setenv(KRB5_ENV_CCNAME, "MEMORY:cliconnect", 1);
348         ret = kerberos_kinit_password(user_principal, pass,
349                                 0 /* no time correction for now */,
350                                 NULL);
351         if (ret != 0) {
352                 int dbglvl = DBGLVL_WARNING;
353
354                 if (krb5_state == CRED_MUST_USE_KERBEROS) {
355                         dbglvl = DBGLVL_ERR;
356                 }
357
358                 DEBUG(dbglvl, ("Kinit for %s to access %s failed: %s\n",
359                                user_principal, target_hostname,
360                                error_message(ret)));
361                 if (krb5_state == CRED_MUST_USE_KERBEROS) {
362                         TALLOC_FREE(frame);
363                         return krb5_to_nt_status(ret);
364                 }
365
366                 /*
367                  * Ignore the error and hope that NTLM will work
368                  */
369         }
370
371         TALLOC_FREE(frame);
372         return NT_STATUS_OK;
373 }
374
375 /********************************************************
376  Utility function to ensure we always return at least
377  a valid char * pointer to an empty string for the
378  cli->server_os, cli->server_type and cli->server_domain
379  strings.
380 *******************************************************/
381
382 static NTSTATUS smb_bytes_talloc_string(TALLOC_CTX *mem_ctx,
383                                         const uint8_t *hdr,
384                                         char **dest,
385                                         uint8_t *src,
386                                         size_t srclen,
387                                         ssize_t *destlen)
388 {
389         *destlen = clistr_pull_talloc(mem_ctx,
390                                 (const char *)hdr,
391                                 SVAL(hdr, HDR_FLG2),
392                                 dest,
393                                 (char *)src,
394                                 srclen,
395                                 STR_TERMINATE);
396         if (*destlen == -1) {
397                 return NT_STATUS_NO_MEMORY;
398         }
399
400         if (*dest == NULL) {
401                 *dest = talloc_strdup(mem_ctx, "");
402                 if (*dest == NULL) {
403                         return NT_STATUS_NO_MEMORY;
404                 }
405         }
406         return NT_STATUS_OK;
407 }
408
409 /****************************************************************************
410  Work out suitable capabilities to offer the server.
411 ****************************************************************************/
412
413 static uint32_t cli_session_setup_capabilities(struct cli_state *cli,
414                                                uint32_t sesssetup_capabilities)
415 {
416         uint32_t client_capabilities = smb1cli_conn_capabilities(cli->conn);
417
418         /*
419          * We only send capabilities based on the mask for:
420          * - client only flags
421          * - flags used in both directions
422          *
423          * We do not echo the server only flags, except some legacy flags.
424          *
425          * SMB_CAP_LEGACY_CLIENT_MASK contains CAP_LARGE_READX and
426          * CAP_LARGE_WRITEX in order to allow us to do large reads
427          * against old Samba releases (<= 3.6.x).
428          */
429         client_capabilities &= (SMB_CAP_BOTH_MASK | SMB_CAP_LEGACY_CLIENT_MASK);
430
431         /*
432          * Session Setup specific flags CAP_DYNAMIC_REAUTH
433          * and CAP_EXTENDED_SECURITY are passed by the caller.
434          * We need that in order to do guest logins even if
435          * CAP_EXTENDED_SECURITY is negotiated.
436          */
437         client_capabilities &= ~(CAP_DYNAMIC_REAUTH|CAP_EXTENDED_SECURITY);
438         sesssetup_capabilities &= (CAP_DYNAMIC_REAUTH|CAP_EXTENDED_SECURITY);
439         client_capabilities |= sesssetup_capabilities;
440
441         return client_capabilities;
442 }
443
444 /****************************************************************************
445  Do a NT1 guest session setup.
446 ****************************************************************************/
447
448 struct cli_session_setup_guest_state {
449         struct cli_state *cli;
450         uint16_t vwv[13];
451         struct iovec bytes;
452 };
453
454 static void cli_session_setup_guest_done(struct tevent_req *subreq);
455
456 struct tevent_req *cli_session_setup_guest_create(TALLOC_CTX *mem_ctx,
457                                                   struct tevent_context *ev,
458                                                   struct cli_state *cli,
459                                                   struct tevent_req **psmbreq)
460 {
461         struct tevent_req *req, *subreq;
462         struct cli_session_setup_guest_state *state;
463         uint16_t *vwv;
464         uint8_t *bytes;
465
466         req = tevent_req_create(mem_ctx, &state,
467                                 struct cli_session_setup_guest_state);
468         if (req == NULL) {
469                 return NULL;
470         }
471         state->cli = cli;
472         vwv = state->vwv;
473
474         SCVAL(vwv+0, 0, 0xFF);
475         SCVAL(vwv+0, 1, 0);
476         SSVAL(vwv+1, 0, 0);
477         SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
478         SSVAL(vwv+3, 0, 2);
479         SSVAL(vwv+4, 0, cli_state_get_vc_num(cli));
480         SIVAL(vwv+5, 0, smb1cli_conn_server_session_key(cli->conn));
481         SSVAL(vwv+7, 0, 0);
482         SSVAL(vwv+8, 0, 0);
483         SSVAL(vwv+9, 0, 0);
484         SSVAL(vwv+10, 0, 0);
485         SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli, 0));
486
487         bytes = talloc_array(state, uint8_t, 0);
488
489         bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "",  1, /* username */
490                                    NULL);
491         bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "", 1, /* workgroup */
492                                    NULL);
493         bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "Unix", 5, NULL);
494         bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "Samba", 6, NULL);
495
496         if (bytes == NULL) {
497                 TALLOC_FREE(req);
498                 return NULL;
499         }
500
501         state->bytes.iov_base = (void *)bytes;
502         state->bytes.iov_len = talloc_get_size(bytes);
503
504         subreq = cli_smb_req_create(state, ev, cli, SMBsesssetupX, 0, 0, 13,
505                         vwv, 1, &state->bytes);
506         if (subreq == NULL) {
507                 TALLOC_FREE(req);
508                 return NULL;
509         }
510         tevent_req_set_callback(subreq, cli_session_setup_guest_done, req);
511         *psmbreq = subreq;
512         return req;
513 }
514
515 struct tevent_req *cli_session_setup_guest_send(TALLOC_CTX *mem_ctx,
516                                                 struct tevent_context *ev,
517                                                 struct cli_state *cli)
518 {
519         struct tevent_req *req, *subreq;
520         NTSTATUS status;
521
522         req = cli_session_setup_guest_create(mem_ctx, ev, cli, &subreq);
523         if (req == NULL) {
524                 return NULL;
525         }
526
527         status = smb1cli_req_chain_submit(&subreq, 1);
528         if (!NT_STATUS_IS_OK(status)) {
529                 tevent_req_nterror(req, status);
530                 return tevent_req_post(req, ev);
531         }
532         return req;
533 }
534
535 static void cli_session_setup_guest_done(struct tevent_req *subreq)
536 {
537         struct tevent_req *req = tevent_req_callback_data(
538                 subreq, struct tevent_req);
539         struct cli_session_setup_guest_state *state = tevent_req_data(
540                 req, struct cli_session_setup_guest_state);
541         struct cli_state *cli = state->cli;
542         uint32_t num_bytes;
543         uint8_t *in;
544         uint8_t *inhdr;
545         uint8_t *bytes;
546         uint8_t *p;
547         NTSTATUS status;
548         ssize_t ret;
549         uint8_t wct;
550         uint16_t *vwv;
551
552         status = cli_smb_recv(subreq, state, &in, 3, &wct, &vwv,
553                               &num_bytes, &bytes);
554         TALLOC_FREE(subreq);
555         if (!NT_STATUS_IS_OK(status)) {
556                 tevent_req_nterror(req, status);
557                 return;
558         }
559
560         inhdr = in + NBT_HDR_SIZE;
561         p = bytes;
562
563         cli_state_set_uid(state->cli, SVAL(inhdr, HDR_UID));
564         smb1cli_session_set_action(cli->smb1.session, SVAL(vwv+2, 0));
565
566         status = smb_bytes_talloc_string(cli,
567                                         inhdr,
568                                         &cli->server_os,
569                                         p,
570                                         bytes+num_bytes-p,
571                                         &ret);
572
573         if (!NT_STATUS_IS_OK(status)) {
574                 tevent_req_nterror(req, status);
575                 return;
576         }
577         p += ret;
578
579         status = smb_bytes_talloc_string(cli,
580                                         inhdr,
581                                         &cli->server_type,
582                                         p,
583                                         bytes+num_bytes-p,
584                                         &ret);
585
586         if (!NT_STATUS_IS_OK(status)) {
587                 tevent_req_nterror(req, status);
588                 return;
589         }
590         p += ret;
591
592         status = smb_bytes_talloc_string(cli,
593                                         inhdr,
594                                         &cli->server_domain,
595                                         p,
596                                         bytes+num_bytes-p,
597                                         &ret);
598
599         if (!NT_STATUS_IS_OK(status)) {
600                 tevent_req_nterror(req, status);
601                 return;
602         }
603         p += ret;
604
605         tevent_req_done(req);
606 }
607
608 NTSTATUS cli_session_setup_guest_recv(struct tevent_req *req)
609 {
610         return tevent_req_simple_recv_ntstatus(req);
611 }
612
613 /* The following is calculated from :
614  * (smb_size-4) = 35
615  * (smb_wcnt * 2) = 24 (smb_wcnt == 12 in cli_session_setup_blob_send() )
616  * (strlen("Unix") + 1 + strlen("Samba") + 1) * 2 = 22 (unicode strings at
617  * end of packet.
618  */
619
620 #define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22)
621
622 struct cli_sesssetup_blob_state {
623         struct tevent_context *ev;
624         struct cli_state *cli;
625         DATA_BLOB blob;
626         uint16_t max_blob_size;
627
628         DATA_BLOB this_blob;
629         struct iovec *recv_iov;
630
631         NTSTATUS status;
632         const uint8_t *inbuf;
633         DATA_BLOB ret_blob;
634
635         char *out_native_os;
636         char *out_native_lm;
637 };
638
639 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state *state,
640                                     struct tevent_req **psubreq);
641 static void cli_sesssetup_blob_done(struct tevent_req *subreq);
642
643 static struct tevent_req *cli_sesssetup_blob_send(TALLOC_CTX *mem_ctx,
644                                                   struct tevent_context *ev,
645                                                   struct cli_state *cli,
646                                                   DATA_BLOB blob)
647 {
648         struct tevent_req *req, *subreq;
649         struct cli_sesssetup_blob_state *state;
650         uint32_t usable_space;
651
652         req = tevent_req_create(mem_ctx, &state,
653                                 struct cli_sesssetup_blob_state);
654         if (req == NULL) {
655                 return NULL;
656         }
657         state->ev = ev;
658         state->blob = blob;
659         state->cli = cli;
660
661         if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
662                 usable_space = UINT16_MAX;
663         } else {
664                 usable_space = cli_state_available_size(cli,
665                                 BASE_SESSSETUP_BLOB_PACKET_SIZE);
666         }
667
668         if (usable_space == 0) {
669                 DEBUG(1, ("cli_session_setup_blob: cli->max_xmit too small "
670                           "(not possible to send %u bytes)\n",
671                           BASE_SESSSETUP_BLOB_PACKET_SIZE + 1));
672                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
673                 return tevent_req_post(req, ev);
674         }
675         state->max_blob_size = MIN(usable_space, 0xFFFF);
676
677         if (!cli_sesssetup_blob_next(state, &subreq)) {
678                 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
679                 return tevent_req_post(req, ev);
680         }
681         tevent_req_set_callback(subreq, cli_sesssetup_blob_done, req);
682         return req;
683 }
684
685 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state *state,
686                                     struct tevent_req **psubreq)
687 {
688         struct tevent_req *subreq;
689         uint16_t thistime;
690
691         thistime = MIN(state->blob.length, state->max_blob_size);
692
693         state->this_blob.data = state->blob.data;
694         state->this_blob.length = thistime;
695
696         state->blob.data += thistime;
697         state->blob.length -= thistime;
698
699         if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
700                 subreq = smb2cli_session_setup_send(state, state->ev,
701                                                     state->cli->conn,
702                                                     state->cli->timeout,
703                                                     state->cli->smb2.session,
704                                                     0, /* in_flags */
705                                                     SMB2_CAP_DFS, /* in_capabilities */
706                                                     0, /* in_channel */
707                                                     0, /* in_previous_session_id */
708                                                     &state->this_blob);
709                 if (subreq == NULL) {
710                         return false;
711                 }
712         } else {
713                 uint16_t in_buf_size = 0;
714                 uint16_t in_mpx_max = 0;
715                 uint16_t in_vc_num = 0;
716                 uint32_t in_sess_key = 0;
717                 uint32_t in_capabilities = 0;
718                 const char *in_native_os = NULL;
719                 const char *in_native_lm = NULL;
720
721                 in_buf_size = CLI_BUFFER_SIZE;
722                 in_mpx_max = smbXcli_conn_max_requests(state->cli->conn);
723                 in_vc_num = cli_state_get_vc_num(state->cli);
724                 in_sess_key = smb1cli_conn_server_session_key(state->cli->conn);
725                 in_capabilities = cli_session_setup_capabilities(state->cli,
726                                                                 CAP_EXTENDED_SECURITY);
727                 in_native_os = "Unix";
728                 in_native_lm = "Samba";
729
730                 /*
731                  * For now we keep the same values as before,
732                  * we may remove these in a separate commit later.
733                  */
734                 in_mpx_max = 2;
735                 in_vc_num = 1;
736                 in_sess_key = 0;
737
738                 subreq = smb1cli_session_setup_ext_send(state, state->ev,
739                                                         state->cli->conn,
740                                                         state->cli->timeout,
741                                                         state->cli->smb1.pid,
742                                                         state->cli->smb1.session,
743                                                         in_buf_size,
744                                                         in_mpx_max,
745                                                         in_vc_num,
746                                                         in_sess_key,
747                                                         state->this_blob,
748                                                         in_capabilities,
749                                                         in_native_os,
750                                                         in_native_lm);
751                 if (subreq == NULL) {
752                         return false;
753                 }
754         }
755         *psubreq = subreq;
756         return true;
757 }
758
759 static void cli_sesssetup_blob_done(struct tevent_req *subreq)
760 {
761         struct tevent_req *req = tevent_req_callback_data(
762                 subreq, struct tevent_req);
763         struct cli_sesssetup_blob_state *state = tevent_req_data(
764                 req, struct cli_sesssetup_blob_state);
765         struct cli_state *cli = state->cli;
766         NTSTATUS status;
767
768         if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
769                 status = smb2cli_session_setup_recv(subreq, state,
770                                                     &state->recv_iov,
771                                                     &state->ret_blob);
772         } else {
773                 status = smb1cli_session_setup_ext_recv(subreq, state,
774                                                         &state->recv_iov,
775                                                         &state->inbuf,
776                                                         &state->ret_blob,
777                                                         &state->out_native_os,
778                                                         &state->out_native_lm);
779         }
780         TALLOC_FREE(subreq);
781         if (!NT_STATUS_IS_OK(status)
782             && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
783                 tevent_req_nterror(req, status);
784                 return;
785         }
786
787         if (cli->server_os == NULL) {
788                 cli->server_os = talloc_move(cli, &state->out_native_os);
789         }
790         if (cli->server_type == NULL) {
791                 cli->server_type = talloc_move(cli, &state->out_native_lm);
792         }
793
794         state->status = status;
795
796         if (state->blob.length != 0) {
797                 /*
798                  * More to send
799                  */
800                 if (!cli_sesssetup_blob_next(state, &subreq)) {
801                         tevent_req_oom(req);
802                         return;
803                 }
804                 tevent_req_set_callback(subreq, cli_sesssetup_blob_done, req);
805                 return;
806         }
807         tevent_req_done(req);
808 }
809
810 static NTSTATUS cli_sesssetup_blob_recv(struct tevent_req *req,
811                                         TALLOC_CTX *mem_ctx,
812                                         DATA_BLOB *pblob,
813                                         const uint8_t **pinbuf,
814                                         struct iovec **precv_iov)
815 {
816         struct cli_sesssetup_blob_state *state = tevent_req_data(
817                 req, struct cli_sesssetup_blob_state);
818         NTSTATUS status;
819         struct iovec *recv_iov;
820
821         if (tevent_req_is_nterror(req, &status)) {
822                 TALLOC_FREE(state->cli->smb2.session);
823                 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
824                 tevent_req_received(req);
825                 return status;
826         }
827
828         recv_iov = talloc_move(mem_ctx, &state->recv_iov);
829         if (pblob != NULL) {
830                 *pblob = state->ret_blob;
831         }
832         if (pinbuf != NULL) {
833                 *pinbuf = state->inbuf;
834         }
835         if (precv_iov != NULL) {
836                 *precv_iov = recv_iov;
837         }
838         /* could be NT_STATUS_MORE_PROCESSING_REQUIRED */
839         status = state->status;
840         tevent_req_received(req);
841         return status;
842 }
843
844 /****************************************************************************
845  Do a spnego/NTLMSSP encrypted session setup.
846 ****************************************************************************/
847
848 struct cli_session_setup_gensec_state {
849         struct tevent_context *ev;
850         struct cli_state *cli;
851         struct auth_generic_state *auth_generic;
852         bool is_anonymous;
853         DATA_BLOB blob_in;
854         const uint8_t *inbuf;
855         struct iovec *recv_iov;
856         DATA_BLOB blob_out;
857         bool local_ready;
858         bool remote_ready;
859         DATA_BLOB session_key;
860 };
861
862 static int cli_session_setup_gensec_state_destructor(
863         struct cli_session_setup_gensec_state *state)
864 {
865         TALLOC_FREE(state->auth_generic);
866         data_blob_clear_free(&state->session_key);
867         return 0;
868 }
869
870 static void cli_session_setup_gensec_local_next(struct tevent_req *req);
871 static void cli_session_setup_gensec_local_done(struct tevent_req *subreq);
872 static void cli_session_setup_gensec_remote_next(struct tevent_req *req);
873 static void cli_session_setup_gensec_remote_done(struct tevent_req *subreq);
874 static void cli_session_setup_gensec_ready(struct tevent_req *req);
875
876 static struct tevent_req *cli_session_setup_gensec_send(
877         TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
878         struct cli_credentials *creds,
879         const char *target_service,
880         const char *target_hostname)
881 {
882         struct tevent_req *req;
883         struct cli_session_setup_gensec_state *state;
884         NTSTATUS status;
885         const DATA_BLOB *b = NULL;
886
887         req = tevent_req_create(mem_ctx, &state,
888                                 struct cli_session_setup_gensec_state);
889         if (req == NULL) {
890                 return NULL;
891         }
892         state->ev = ev;
893         state->cli = cli;
894
895         talloc_set_destructor(
896                 state, cli_session_setup_gensec_state_destructor);
897
898         status = auth_generic_client_prepare(state, &state->auth_generic);
899         if (tevent_req_nterror(req, status)) {
900                 return tevent_req_post(req, ev);
901         }
902
903         status = auth_generic_set_creds(state->auth_generic, creds);
904         if (tevent_req_nterror(req, status)) {
905                 return tevent_req_post(req, ev);
906         }
907
908         gensec_want_feature(state->auth_generic->gensec_security,
909                             GENSEC_FEATURE_SESSION_KEY);
910
911         if (target_service != NULL) {
912                 status = gensec_set_target_service(
913                                 state->auth_generic->gensec_security,
914                                 target_service);
915                 if (tevent_req_nterror(req, status)) {
916                         return tevent_req_post(req, ev);
917                 }
918         }
919
920         if (target_hostname != NULL) {
921                 status = gensec_set_target_hostname(
922                                 state->auth_generic->gensec_security,
923                                 target_hostname);
924                 if (tevent_req_nterror(req, status)) {
925                         return tevent_req_post(req, ev);
926                 }
927         }
928
929         b = smbXcli_conn_server_gss_blob(cli->conn);
930         if (b != NULL) {
931                 state->blob_in = *b;
932         }
933
934         state->is_anonymous = cli_credentials_is_anonymous(state->auth_generic->credentials);
935
936         status = auth_generic_client_start(state->auth_generic,
937                                            GENSEC_OID_SPNEGO);
938         if (tevent_req_nterror(req, status)) {
939                 return tevent_req_post(req, ev);
940         }
941
942         if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
943                 state->cli->smb2.session = smbXcli_session_create(cli,
944                                                                   cli->conn);
945                 if (tevent_req_nomem(state->cli->smb2.session, req)) {
946                         return tevent_req_post(req, ev);
947                 }
948         }
949
950         cli_session_setup_gensec_local_next(req);
951         if (!tevent_req_is_in_progress(req)) {
952                 return tevent_req_post(req, ev);
953         }
954
955         return req;
956 }
957
958 static void cli_session_setup_gensec_local_next(struct tevent_req *req)
959 {
960         struct cli_session_setup_gensec_state *state =
961                 tevent_req_data(req,
962                 struct cli_session_setup_gensec_state);
963         struct tevent_req *subreq = NULL;
964
965         if (state->local_ready) {
966                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
967                 return;
968         }
969
970         subreq = gensec_update_send(state, state->ev,
971                         state->auth_generic->gensec_security,
972                         state->blob_in);
973         if (tevent_req_nomem(subreq, req)) {
974                 return;
975         }
976         tevent_req_set_callback(subreq, cli_session_setup_gensec_local_done, req);
977 }
978
979 static void cli_session_setup_gensec_local_done(struct tevent_req *subreq)
980 {
981         struct tevent_req *req =
982                 tevent_req_callback_data(subreq,
983                 struct tevent_req);
984         struct cli_session_setup_gensec_state *state =
985                 tevent_req_data(req,
986                 struct cli_session_setup_gensec_state);
987         NTSTATUS status;
988
989         status = gensec_update_recv(subreq, state, &state->blob_out);
990         TALLOC_FREE(subreq);
991         state->blob_in = data_blob_null;
992         if (!NT_STATUS_IS_OK(status) &&
993             !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
994         {
995                 tevent_req_nterror(req, status);
996                 return;
997         }
998
999         if (NT_STATUS_IS_OK(status)) {
1000                 state->local_ready = true;
1001         }
1002
1003         if (state->local_ready && state->remote_ready) {
1004                 cli_session_setup_gensec_ready(req);
1005                 return;
1006         }
1007
1008         cli_session_setup_gensec_remote_next(req);
1009 }
1010
1011 static void cli_session_setup_gensec_remote_next(struct tevent_req *req)
1012 {
1013         struct cli_session_setup_gensec_state *state =
1014                 tevent_req_data(req,
1015                 struct cli_session_setup_gensec_state);
1016         struct tevent_req *subreq = NULL;
1017
1018         if (state->remote_ready) {
1019                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1020                 return;
1021         }
1022
1023         subreq = cli_sesssetup_blob_send(state, state->ev,
1024                                          state->cli, state->blob_out);
1025         if (tevent_req_nomem(subreq, req)) {
1026                 return;
1027         }
1028         tevent_req_set_callback(subreq,
1029                                 cli_session_setup_gensec_remote_done,
1030                                 req);
1031 }
1032
1033 static void cli_session_setup_gensec_remote_done(struct tevent_req *subreq)
1034 {
1035         struct tevent_req *req =
1036                 tevent_req_callback_data(subreq,
1037                 struct tevent_req);
1038         struct cli_session_setup_gensec_state *state =
1039                 tevent_req_data(req,
1040                 struct cli_session_setup_gensec_state);
1041         NTSTATUS status;
1042
1043         state->inbuf = NULL;
1044         TALLOC_FREE(state->recv_iov);
1045
1046         status = cli_sesssetup_blob_recv(subreq, state, &state->blob_in,
1047                                          &state->inbuf, &state->recv_iov);
1048         TALLOC_FREE(subreq);
1049         data_blob_free(&state->blob_out);
1050         if (!NT_STATUS_IS_OK(status) &&
1051             !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
1052         {
1053                 tevent_req_nterror(req, status);
1054                 return;
1055         }
1056
1057         if (NT_STATUS_IS_OK(status)) {
1058                 struct smbXcli_session *session = NULL;
1059                 bool is_guest = false;
1060
1061                 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
1062                         session = state->cli->smb2.session;
1063                 } else {
1064                         session = state->cli->smb1.session;
1065                 }
1066
1067                 is_guest = smbXcli_session_is_guest(session);
1068                 if (is_guest) {
1069                         /*
1070                          * We can't finish the gensec handshake, we don't
1071                          * have a negotiated session key.
1072                          *
1073                          * So just pretend we are completely done.
1074                          *
1075                          * Note that smbXcli_session_is_guest()
1076                          * always returns false if we require signing.
1077                          */
1078                         state->blob_in = data_blob_null;
1079                         state->local_ready = true;
1080                 }
1081
1082                 state->remote_ready = true;
1083         }
1084
1085         if (state->local_ready && state->remote_ready) {
1086                 cli_session_setup_gensec_ready(req);
1087                 return;
1088         }
1089
1090         cli_session_setup_gensec_local_next(req);
1091 }
1092
1093 static void cli_session_setup_gensec_ready(struct tevent_req *req)
1094 {
1095         struct cli_session_setup_gensec_state *state =
1096                 tevent_req_data(req,
1097                 struct cli_session_setup_gensec_state);
1098         const char *server_domain = NULL;
1099         NTSTATUS status;
1100
1101         if (state->blob_in.length != 0) {
1102                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1103                 return;
1104         }
1105
1106         if (state->blob_out.length != 0) {
1107                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1108                 return;
1109         }
1110
1111         /*
1112          * gensec_ntlmssp_server_domain() returns NULL
1113          * if NTLMSSP is not used.
1114          *
1115          * We can remove this later
1116          * and leave the server domain empty for SMB2 and above
1117          * in future releases.
1118          */
1119         server_domain = gensec_ntlmssp_server_domain(
1120                                 state->auth_generic->gensec_security);
1121
1122         if (state->cli->server_domain[0] == '\0' && server_domain != NULL) {
1123                 TALLOC_FREE(state->cli->server_domain);
1124                 state->cli->server_domain = talloc_strdup(state->cli,
1125                                         server_domain);
1126                 if (state->cli->server_domain == NULL) {
1127                         tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1128                         return;
1129                 }
1130         }
1131
1132         if (state->is_anonymous) {
1133                 /*
1134                  * Windows server does not set the
1135                  * SMB2_SESSION_FLAG_IS_NULL flag.
1136                  *
1137                  * This fix makes sure we do not try
1138                  * to verify a signature on the final
1139                  * session setup response.
1140                  */
1141                 tevent_req_done(req);
1142                 return;
1143         }
1144
1145         status = gensec_session_key(state->auth_generic->gensec_security,
1146                                     state, &state->session_key);
1147         if (tevent_req_nterror(req, status)) {
1148                 return;
1149         }
1150
1151         if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
1152                 struct smbXcli_session *session = state->cli->smb2.session;
1153
1154                 status = smb2cli_session_set_session_key(session,
1155                                                          state->session_key,
1156                                                          state->recv_iov);
1157                 if (tevent_req_nterror(req, status)) {
1158                         return;
1159                 }
1160         } else {
1161                 struct smbXcli_session *session = state->cli->smb1.session;
1162                 bool active;
1163
1164                 status = smb1cli_session_set_session_key(session,
1165                                                          state->session_key);
1166                 if (tevent_req_nterror(req, status)) {
1167                         return;
1168                 }
1169
1170                 active = smb1cli_conn_activate_signing(state->cli->conn,
1171                                                        state->session_key,
1172                                                        data_blob_null);
1173                 if (active) {
1174                         bool ok;
1175
1176                         ok = smb1cli_conn_check_signing(state->cli->conn,
1177                                                         state->inbuf, 1);
1178                         if (!ok) {
1179                                 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1180                                 return;
1181                         }
1182                 }
1183         }
1184
1185         tevent_req_done(req);
1186 }
1187
1188 static NTSTATUS cli_session_setup_gensec_recv(struct tevent_req *req)
1189 {
1190         struct cli_session_setup_gensec_state *state =
1191                 tevent_req_data(req,
1192                 struct cli_session_setup_gensec_state);
1193         NTSTATUS status;
1194
1195         if (tevent_req_is_nterror(req, &status)) {
1196                 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
1197                 return status;
1198         }
1199         return NT_STATUS_OK;
1200 }
1201
1202 static char *cli_session_setup_get_account(TALLOC_CTX *mem_ctx,
1203                                            const char *principal)
1204 {
1205         char *account, *p;
1206
1207         account = talloc_strdup(mem_ctx, principal);
1208         if (account == NULL) {
1209                 return NULL;
1210         }
1211         p = strchr_m(account, '@');
1212         if (p != NULL) {
1213                 *p = '\0';
1214         }
1215         return account;
1216 }
1217
1218 /****************************************************************************
1219  Do a spnego encrypted session setup.
1220
1221  user_domain: The shortname of the domain the user/machine is a member of.
1222  dest_realm: The realm we're connecting to, if NULL we use our default realm.
1223 ****************************************************************************/
1224
1225 struct cli_session_setup_spnego_state {
1226         ADS_STATUS result;
1227 };
1228
1229 static void cli_session_setup_spnego_done(struct tevent_req *subreq);
1230
1231 static struct tevent_req *cli_session_setup_spnego_send(
1232         TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
1233         struct cli_credentials *creds)
1234 {
1235         struct tevent_req *req, *subreq;
1236         struct cli_session_setup_spnego_state *state;
1237         const char *target_service = NULL;
1238         const char *target_hostname = NULL;
1239         NTSTATUS status;
1240
1241         req = tevent_req_create(mem_ctx, &state,
1242                                 struct cli_session_setup_spnego_state);
1243         if (req == NULL) {
1244                 return NULL;
1245         }
1246
1247         target_service = "cifs";
1248         target_hostname = smbXcli_conn_remote_name(cli->conn);
1249
1250         status = cli_session_creds_prepare_krb5(cli, creds);
1251         if (tevent_req_nterror(req, status)) {
1252                 return tevent_req_post(req, ev);;
1253         }
1254
1255         subreq = cli_session_setup_gensec_send(state, ev, cli, creds,
1256                                                target_service, target_hostname);
1257         if (tevent_req_nomem(subreq, req)) {
1258                 return tevent_req_post(req, ev);
1259         }
1260         tevent_req_set_callback(
1261                 subreq, cli_session_setup_spnego_done, req);
1262         return req;
1263 }
1264
1265 static void cli_session_setup_spnego_done(struct tevent_req *subreq)
1266 {
1267         struct tevent_req *req = tevent_req_callback_data(
1268                 subreq, struct tevent_req);
1269         NTSTATUS status;
1270
1271         status = cli_session_setup_gensec_recv(subreq);
1272         TALLOC_FREE(subreq);
1273         if (tevent_req_nterror(req, status)) {
1274                 return;
1275         }
1276
1277         tevent_req_done(req);
1278 }
1279
1280 static ADS_STATUS cli_session_setup_spnego_recv(struct tevent_req *req)
1281 {
1282         struct cli_session_setup_spnego_state *state = tevent_req_data(
1283                 req, struct cli_session_setup_spnego_state);
1284         NTSTATUS status;
1285
1286         if (tevent_req_is_nterror(req, &status)) {
1287                 state->result = ADS_ERROR_NT(status);
1288         }
1289
1290         return state->result;
1291 }
1292
1293 struct cli_session_setup_creds_state {
1294         struct cli_state *cli;
1295         DATA_BLOB apassword_blob;
1296         DATA_BLOB upassword_blob;
1297         DATA_BLOB lm_session_key;
1298         DATA_BLOB session_key;
1299         char *out_native_os;
1300         char *out_native_lm;
1301         char *out_primary_domain;
1302 };
1303
1304 static void cli_session_setup_creds_cleanup(struct tevent_req *req,
1305                                             enum tevent_req_state req_state)
1306 {
1307         struct cli_session_setup_creds_state *state = tevent_req_data(
1308                 req, struct cli_session_setup_creds_state);
1309
1310         if (req_state != TEVENT_REQ_RECEIVED) {
1311                 return;
1312         }
1313
1314         /*
1315          * We only call data_blob_clear() as
1316          * some of the blobs point to the same memory.
1317          *
1318          * We let the talloc hierachy free the memory.
1319          */
1320         data_blob_clear(&state->apassword_blob);
1321         data_blob_clear(&state->upassword_blob);
1322         data_blob_clear(&state->lm_session_key);
1323         data_blob_clear(&state->session_key);
1324         ZERO_STRUCTP(state);
1325 }
1326
1327 static void cli_session_setup_creds_done_spnego(struct tevent_req *subreq);
1328 static void cli_session_setup_creds_done_nt1(struct tevent_req *subreq);
1329 static void cli_session_setup_creds_done_lm21(struct tevent_req *subreq);
1330
1331 /****************************************************************************
1332  Send a session setup. The username and workgroup is in UNIX character
1333  format and must be converted to DOS codepage format before sending. If the
1334  password is in plaintext, the same should be done.
1335 ****************************************************************************/
1336
1337 struct tevent_req *cli_session_setup_creds_send(TALLOC_CTX *mem_ctx,
1338                                         struct tevent_context *ev,
1339                                         struct cli_state *cli,
1340                                         struct cli_credentials *creds)
1341 {
1342         struct tevent_req *req, *subreq;
1343         struct cli_session_setup_creds_state *state;
1344         uint16_t sec_mode = smb1cli_conn_server_security_mode(cli->conn);
1345         bool use_spnego = false;
1346         int flags = 0;
1347         enum credentials_use_kerberos krb5_state;
1348         uint32_t gensec_features;
1349         const char *username = "";
1350         const char *domain = "";
1351         DATA_BLOB target_info = data_blob_null;
1352         DATA_BLOB challenge = data_blob_null;
1353         uint16_t in_buf_size = 0;
1354         uint16_t in_mpx_max = 0;
1355         uint16_t in_vc_num = 0;
1356         uint32_t in_sess_key = 0;
1357         const char *in_native_os = NULL;
1358         const char *in_native_lm = NULL;
1359         NTSTATUS status;
1360
1361         req = tevent_req_create(mem_ctx, &state,
1362                                 struct cli_session_setup_creds_state);
1363         if (req == NULL) {
1364                 return NULL;
1365         }
1366         state->cli = cli;
1367
1368         tevent_req_set_cleanup_fn(req, cli_session_setup_creds_cleanup);
1369
1370         krb5_state = cli_credentials_get_kerberos_state(creds);
1371         gensec_features = cli_credentials_get_gensec_features(creds);
1372
1373         switch (krb5_state) {
1374         case CRED_MUST_USE_KERBEROS:
1375                 cli->use_kerberos = true;
1376                 cli->fallback_after_kerberos = false;
1377                 break;
1378         case CRED_AUTO_USE_KERBEROS:
1379                 cli->use_kerberos = true;
1380                 cli->fallback_after_kerberos = true;
1381                 break;
1382         case CRED_DONT_USE_KERBEROS:
1383                 cli->use_kerberos = false;
1384                 cli->fallback_after_kerberos = false;
1385                 break;
1386         }
1387
1388         if (gensec_features & GENSEC_FEATURE_NTLM_CCACHE) {
1389                 cli->use_ccache = true;
1390         } else {
1391                 cli->use_ccache = false;
1392         }
1393
1394         /*
1395          * Now work out what sort of session setup we are going to
1396          * do. I have split this into separate functions to make the flow a bit
1397          * easier to understand (tridge).
1398          */
1399         if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_NT1) {
1400                 use_spnego = false;
1401         } else if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
1402                 use_spnego = true;
1403         } else if (smb1cli_conn_capabilities(cli->conn) & CAP_EXTENDED_SECURITY) {
1404                 /*
1405                  * if the server supports extended security then use SPNEGO
1406                  * even for anonymous connections.
1407                  */
1408                 use_spnego = true;
1409         } else {
1410                 use_spnego = false;
1411         }
1412
1413         if (use_spnego) {
1414                 subreq = cli_session_setup_spnego_send(
1415                         state, ev, cli, creds);
1416                 if (tevent_req_nomem(subreq, req)) {
1417                         return tevent_req_post(req, ev);
1418                 }
1419                 tevent_req_set_callback(subreq, cli_session_setup_creds_done_spnego,
1420                                         req);
1421                 return req;
1422         }
1423
1424         if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_LANMAN1) {
1425                 /*
1426                  * SessionSetupAndX was introduced by LANMAN 1.0. So we skip
1427                  * this step against older servers.
1428                  */
1429                 tevent_req_done(req);
1430                 return tevent_req_post(req, ev);
1431         }
1432
1433         if (cli_credentials_is_anonymous(creds)) {
1434                 /*
1435                  * Do an anonymous session setup
1436                  */
1437                 goto non_spnego_creds_done;
1438         }
1439
1440         if ((sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0) {
1441                 /*
1442                  * Do an anonymous session setup,
1443                  * the password is passed via the tree connect.
1444                  */
1445                 goto non_spnego_creds_done;
1446         }
1447
1448         cli_credentials_get_ntlm_username_domain(creds, state,
1449                                                  &username,
1450                                                  &domain);
1451         if (tevent_req_nomem(username, req)) {
1452                 return tevent_req_post(req, ev);
1453         }
1454         if (tevent_req_nomem(domain, req)) {
1455                 return tevent_req_post(req, ev);
1456         }
1457
1458         if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) {
1459                 bool use_unicode = smbXcli_conn_use_unicode(cli->conn);
1460                 uint8_t *bytes = NULL;
1461                 size_t bytes_len = 0;
1462                 const char *pw = cli_credentials_get_password(creds);
1463                 size_t pw_len = 0;
1464
1465                 if (pw == NULL) {
1466                         pw = "";
1467                 }
1468                 pw_len = strlen(pw) + 1;
1469
1470                 if (!lp_client_plaintext_auth()) {
1471                         DEBUG(1, ("Server requested PLAINTEXT password but "
1472                                   "'client plaintext auth = no'\n"));
1473                         tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1474                         return tevent_req_post(req, ev);
1475                 }
1476
1477                 bytes = talloc_array(state, uint8_t, 0);
1478                 bytes = trans2_bytes_push_str(bytes, use_unicode,
1479                                               pw, pw_len, &bytes_len);
1480                 if (tevent_req_nomem(bytes, req)) {
1481                         return tevent_req_post(req, ev);
1482                 }
1483
1484                 if (use_unicode) {
1485                         /*
1486                          * CAP_UNICODE, can only be negotiated by NT1.
1487                          */
1488                         state->upassword_blob = data_blob_const(bytes,
1489                                                                 bytes_len);
1490                 } else {
1491                         state->apassword_blob = data_blob_const(bytes,
1492                                                                 bytes_len);
1493                 }
1494
1495                 goto non_spnego_creds_done;
1496         }
1497
1498         challenge = data_blob_const(smb1cli_conn_server_challenge(cli->conn), 8);
1499
1500         if (smbXcli_conn_protocol(cli->conn) == PROTOCOL_NT1) {
1501                 if (lp_client_ntlmv2_auth() && lp_client_use_spnego()) {
1502                         /*
1503                          * Don't send an NTLMv2 response without NTLMSSP if we
1504                          * want to use spnego support.
1505                          */
1506                         DEBUG(1, ("Server does not support EXTENDED_SECURITY "
1507                                   " but 'client use spnego = yes'"
1508                                   " and 'client ntlmv2 auth = yes' is set\n"));
1509                         tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1510                         return tevent_req_post(req, ev);
1511                 }
1512
1513                 if (lp_client_ntlmv2_auth()) {
1514                         flags |= CLI_CRED_NTLMv2_AUTH;
1515
1516                         /*
1517                          * note that the 'domain' here is a best
1518                          * guess - we don't know the server's domain
1519                          * at this point. Windows clients also don't
1520                          * use hostname...
1521                          */
1522                         target_info = NTLMv2_generate_names_blob(state,
1523                                                                  NULL,
1524                                                                  domain);
1525                         if (tevent_req_nomem(target_info.data, req)) {
1526                                 return tevent_req_post(req, ev);
1527                         }
1528                 } else {
1529                         flags |= CLI_CRED_NTLM_AUTH;
1530                         if (lp_client_lanman_auth()) {
1531                                 flags |= CLI_CRED_LANMAN_AUTH;
1532                         }
1533                 }
1534         } else {
1535                 if (!lp_client_lanman_auth()) {
1536                         DEBUG(1, ("Server requested user level LM password but "
1537                                   "'client lanman auth = no' is set.\n"));
1538                         tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1539                         return tevent_req_post(req, ev);
1540                 }
1541
1542                 flags |= CLI_CRED_LANMAN_AUTH;
1543         }
1544
1545         status = cli_credentials_get_ntlm_response(creds, state, &flags,
1546                                                    challenge, NULL,
1547                                                    target_info,
1548                                                    &state->apassword_blob,
1549                                                    &state->upassword_blob,
1550                                                    &state->lm_session_key,
1551                                                    &state->session_key);
1552         if (tevent_req_nterror(req, status)) {
1553                 return tevent_req_post(req, ev);
1554         }
1555
1556 non_spnego_creds_done:
1557
1558         in_buf_size = CLI_BUFFER_SIZE;
1559         in_mpx_max = smbXcli_conn_max_requests(cli->conn);
1560         in_vc_num = cli_state_get_vc_num(cli);
1561         in_sess_key = smb1cli_conn_server_session_key(cli->conn);
1562         in_native_os = "Unix";
1563         in_native_lm = "Samba";
1564
1565         if (smbXcli_conn_protocol(cli->conn) == PROTOCOL_NT1) {
1566                 uint32_t in_capabilities = 0;
1567
1568                 in_capabilities = cli_session_setup_capabilities(cli, 0);
1569
1570                 /*
1571                  * For now we keep the same values as before,
1572                  * we may remove these in a separate commit later.
1573                  */
1574                 in_mpx_max = 2;
1575
1576                 subreq = smb1cli_session_setup_nt1_send(state, ev,
1577                                                         cli->conn,
1578                                                         cli->timeout,
1579                                                         cli->smb1.pid,
1580                                                         cli->smb1.session,
1581                                                         in_buf_size,
1582                                                         in_mpx_max,
1583                                                         in_vc_num,
1584                                                         in_sess_key,
1585                                                         username,
1586                                                         domain,
1587                                                         state->apassword_blob,
1588                                                         state->upassword_blob,
1589                                                         in_capabilities,
1590                                                         in_native_os,
1591                                                         in_native_lm);
1592                 if (tevent_req_nomem(subreq, req)) {
1593                         return tevent_req_post(req, ev);
1594                 }
1595                 tevent_req_set_callback(subreq, cli_session_setup_creds_done_nt1,
1596                                         req);
1597                 return req;
1598         }
1599
1600         /*
1601          * For now we keep the same values as before,
1602          * we may remove these in a separate commit later.
1603          */
1604         in_mpx_max = 2;
1605         in_vc_num = 1;
1606
1607         subreq = smb1cli_session_setup_lm21_send(state, ev,
1608                                                  cli->conn,
1609                                                  cli->timeout,
1610                                                  cli->smb1.pid,
1611                                                  cli->smb1.session,
1612                                                  in_buf_size,
1613                                                  in_mpx_max,
1614                                                  in_vc_num,
1615                                                  in_sess_key,
1616                                                  username,
1617                                                  domain,
1618                                                  state->apassword_blob,
1619                                                  in_native_os,
1620                                                  in_native_lm);
1621         if (tevent_req_nomem(subreq, req)) {
1622                 return tevent_req_post(req, ev);
1623         }
1624         tevent_req_set_callback(subreq, cli_session_setup_creds_done_lm21,
1625                                 req);
1626         return req;
1627 }
1628
1629 static void cli_session_setup_creds_done_spnego(struct tevent_req *subreq)
1630 {
1631         struct tevent_req *req = tevent_req_callback_data(
1632                 subreq, struct tevent_req);
1633         ADS_STATUS status;
1634
1635         status = cli_session_setup_spnego_recv(subreq);
1636         TALLOC_FREE(subreq);
1637         if (!ADS_ERR_OK(status)) {
1638                 DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status)));
1639                 tevent_req_nterror(req, ads_ntstatus(status));
1640                 return;
1641         }
1642         tevent_req_done(req);
1643 }
1644
1645 static void cli_session_setup_creds_done_nt1(struct tevent_req *subreq)
1646 {
1647         struct tevent_req *req = tevent_req_callback_data(
1648                 subreq, struct tevent_req);
1649         struct cli_session_setup_creds_state *state = tevent_req_data(
1650                 req, struct cli_session_setup_creds_state);
1651         struct cli_state *cli = state->cli;
1652         NTSTATUS status;
1653         struct iovec *recv_iov = NULL;
1654         const uint8_t *inbuf = NULL;
1655         bool ok;
1656
1657         status = smb1cli_session_setup_nt1_recv(subreq, state,
1658                                                 &recv_iov,
1659                                                 &inbuf,
1660                                                 &state->out_native_os,
1661                                                 &state->out_native_lm,
1662                                                 &state->out_primary_domain);
1663         TALLOC_FREE(subreq);
1664         if (!NT_STATUS_IS_OK(status)) {
1665                 DEBUG(3, ("NT1 login failed: %s\n", nt_errstr(status)));
1666                 tevent_req_nterror(req, status);
1667                 return;
1668         }
1669
1670         if (cli->server_os == NULL) {
1671                 cli->server_os = talloc_move(cli, &state->out_native_os);
1672         }
1673         if (cli->server_type == NULL) {
1674                 cli->server_type = talloc_move(cli, &state->out_native_lm);
1675         }
1676         if (cli->server_domain == NULL) {
1677                 cli->server_domain = talloc_move(cli, &state->out_primary_domain);
1678         }
1679
1680         ok = smb1cli_conn_activate_signing(cli->conn,
1681                                            state->session_key,
1682                                            state->upassword_blob);
1683         if (ok) {
1684                 ok = smb1cli_conn_check_signing(cli->conn, inbuf, 1);
1685                 if (!ok) {
1686                         tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1687                         return;
1688                 }
1689         }
1690
1691         if (state->session_key.data) {
1692                 struct smbXcli_session *session = cli->smb1.session;
1693
1694                 status = smb1cli_session_set_session_key(session,
1695                                                          state->session_key);
1696                 if (tevent_req_nterror(req, status)) {
1697                         return;
1698                 }
1699         }
1700
1701         tevent_req_done(req);
1702 }
1703
1704 static void cli_session_setup_creds_done_lm21(struct tevent_req *subreq)
1705 {
1706         struct tevent_req *req = tevent_req_callback_data(
1707                 subreq, struct tevent_req);
1708         struct cli_session_setup_creds_state *state = tevent_req_data(
1709                 req, struct cli_session_setup_creds_state);
1710         struct cli_state *cli = state->cli;
1711         NTSTATUS status;
1712
1713         status = smb1cli_session_setup_lm21_recv(subreq, state,
1714                                                  &state->out_native_os,
1715                                                  &state->out_native_lm);
1716         TALLOC_FREE(subreq);
1717         if (!NT_STATUS_IS_OK(status)) {
1718                 DEBUG(3, ("LM21 login failed: %s\n", nt_errstr(status)));
1719                 tevent_req_nterror(req, status);
1720                 return;
1721         }
1722
1723         if (cli->server_os == NULL) {
1724                 cli->server_os = talloc_move(cli, &state->out_native_os);
1725         }
1726         if (cli->server_type == NULL) {
1727                 cli->server_type = talloc_move(cli, &state->out_native_lm);
1728         }
1729
1730         tevent_req_done(req);
1731 }
1732
1733 NTSTATUS cli_session_setup_creds_recv(struct tevent_req *req)
1734 {
1735         return tevent_req_simple_recv_ntstatus(req);
1736 }
1737
1738 NTSTATUS cli_session_setup_creds(struct cli_state *cli,
1739                                  struct cli_credentials *creds)
1740 {
1741         struct tevent_context *ev;
1742         struct tevent_req *req;
1743         NTSTATUS status = NT_STATUS_NO_MEMORY;
1744
1745         if (smbXcli_conn_has_async_calls(cli->conn)) {
1746                 return NT_STATUS_INVALID_PARAMETER;
1747         }
1748         ev = samba_tevent_context_init(talloc_tos());
1749         if (ev == NULL) {
1750                 goto fail;
1751         }
1752         req = cli_session_setup_creds_send(ev, ev, cli, creds);
1753         if (req == NULL) {
1754                 goto fail;
1755         }
1756         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1757                 goto fail;
1758         }
1759         status = cli_session_setup_creds_recv(req);
1760  fail:
1761         TALLOC_FREE(ev);
1762         return status;
1763 }
1764
1765 NTSTATUS cli_session_setup_anon(struct cli_state *cli)
1766 {
1767         NTSTATUS status = NT_STATUS_NO_MEMORY;
1768         struct cli_credentials *creds = NULL;
1769
1770         creds = cli_credentials_init_anon(cli);
1771         if (creds == NULL) {
1772                 return NT_STATUS_NO_MEMORY;
1773         }
1774
1775         status = cli_session_setup_creds(cli, creds);
1776         TALLOC_FREE(creds);
1777         if (!NT_STATUS_IS_OK(status)) {
1778                 return status;
1779         }
1780
1781         return NT_STATUS_OK;
1782 }
1783
1784 /****************************************************************************
1785  Send a uloggoff.
1786 *****************************************************************************/
1787
1788 struct cli_ulogoff_state {
1789         struct cli_state *cli;
1790         uint16_t vwv[3];
1791 };
1792
1793 static void cli_ulogoff_done(struct tevent_req *subreq);
1794
1795 static struct tevent_req *cli_ulogoff_send(TALLOC_CTX *mem_ctx,
1796                                     struct tevent_context *ev,
1797                                     struct cli_state *cli)
1798 {
1799         struct tevent_req *req, *subreq;
1800         struct cli_ulogoff_state *state;
1801
1802         req = tevent_req_create(mem_ctx, &state, struct cli_ulogoff_state);
1803         if (req == NULL) {
1804                 return NULL;
1805         }
1806         state->cli = cli;
1807
1808         SCVAL(state->vwv+0, 0, 0xFF);
1809         SCVAL(state->vwv+1, 0, 0);
1810         SSVAL(state->vwv+2, 0, 0);
1811
1812         subreq = cli_smb_send(state, ev, cli, SMBulogoffX, 0, 0, 2, state->vwv,
1813                               0, NULL);
1814         if (tevent_req_nomem(subreq, req)) {
1815                 return tevent_req_post(req, ev);
1816         }
1817         tevent_req_set_callback(subreq, cli_ulogoff_done, req);
1818         return req;
1819 }
1820
1821 static void cli_ulogoff_done(struct tevent_req *subreq)
1822 {
1823         struct tevent_req *req = tevent_req_callback_data(
1824                 subreq, struct tevent_req);
1825         struct cli_ulogoff_state *state = tevent_req_data(
1826                 req, struct cli_ulogoff_state);
1827         NTSTATUS status;
1828
1829         status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
1830         if (!NT_STATUS_IS_OK(status)) {
1831                 tevent_req_nterror(req, status);
1832                 return;
1833         }
1834         cli_state_set_uid(state->cli, UID_FIELD_INVALID);
1835         tevent_req_done(req);
1836 }
1837
1838 static NTSTATUS cli_ulogoff_recv(struct tevent_req *req)
1839 {
1840         return tevent_req_simple_recv_ntstatus(req);
1841 }
1842
1843 NTSTATUS cli_ulogoff(struct cli_state *cli)
1844 {
1845         struct tevent_context *ev;
1846         struct tevent_req *req;
1847         NTSTATUS status = NT_STATUS_NO_MEMORY;
1848
1849         if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
1850                 status = smb2cli_logoff(cli->conn,
1851                                         cli->timeout,
1852                                         cli->smb2.session);
1853                 if (!NT_STATUS_IS_OK(status)) {
1854                         return status;
1855                 }
1856                 smb2cli_session_set_id_and_flags(cli->smb2.session,
1857                                                  UINT64_MAX, 0);
1858                 return NT_STATUS_OK;
1859         }
1860
1861         if (smbXcli_conn_has_async_calls(cli->conn)) {
1862                 return NT_STATUS_INVALID_PARAMETER;
1863         }
1864         ev = samba_tevent_context_init(talloc_tos());
1865         if (ev == NULL) {
1866                 goto fail;
1867         }
1868         req = cli_ulogoff_send(ev, ev, cli);
1869         if (req == NULL) {
1870                 goto fail;
1871         }
1872         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1873                 goto fail;
1874         }
1875         status = cli_ulogoff_recv(req);
1876 fail:
1877         TALLOC_FREE(ev);
1878         return status;
1879 }
1880
1881 /****************************************************************************
1882  Send a tconX.
1883 ****************************************************************************/
1884
1885 struct cli_tcon_andx_state {
1886         struct cli_state *cli;
1887         uint16_t vwv[4];
1888         struct iovec bytes;
1889 };
1890
1891 static void cli_tcon_andx_done(struct tevent_req *subreq);
1892
1893 struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx,
1894                                         struct tevent_context *ev,
1895                                         struct cli_state *cli,
1896                                         const char *share, const char *dev,
1897                                         const char *pass, int passlen,
1898                                         struct tevent_req **psmbreq)
1899 {
1900         struct tevent_req *req, *subreq;
1901         struct cli_tcon_andx_state *state;
1902         uint8_t p24[24];
1903         uint16_t *vwv;
1904         char *tmp = NULL;
1905         uint8_t *bytes;
1906         uint16_t sec_mode = smb1cli_conn_server_security_mode(cli->conn);
1907         uint16_t tcon_flags = 0;
1908
1909         *psmbreq = NULL;
1910
1911         req = tevent_req_create(mem_ctx, &state, struct cli_tcon_andx_state);
1912         if (req == NULL) {
1913                 return NULL;
1914         }
1915         state->cli = cli;
1916         vwv = state->vwv;
1917
1918         cli->share = talloc_strdup(cli, share);
1919         if (!cli->share) {
1920                 return NULL;
1921         }
1922
1923         /* in user level security don't send a password now */
1924         if (sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {
1925                 passlen = 1;
1926                 pass = "";
1927         } else if (pass == NULL) {
1928                 DEBUG(1, ("Server not using user level security and no "
1929                           "password supplied.\n"));
1930                 goto access_denied;
1931         }
1932
1933         if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) &&
1934             *pass && passlen != 24) {
1935                 if (!lp_client_lanman_auth()) {
1936                         DEBUG(1, ("Server requested LANMAN password "
1937                                   "(share-level security) but "
1938                                   "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
1939                         goto access_denied;
1940                 }
1941
1942                 /*
1943                  * Non-encrypted passwords - convert to DOS codepage before
1944                  * encryption.
1945                  */
1946                 SMBencrypt(pass, smb1cli_conn_server_challenge(cli->conn), p24);
1947                 passlen = 24;
1948                 pass = (const char *)p24;
1949         } else {
1950                 if((sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL
1951                                      |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE))
1952                    == 0) {
1953                         uint8_t *tmp_pass;
1954
1955                         if (!lp_client_plaintext_auth() && (*pass)) {
1956                                 DEBUG(1, ("Server requested PLAINTEXT "
1957                                           "password but "
1958                                           "'client plaintext auth = no' or 'client ntlmv2 auth = yes'\n"));
1959                                 goto access_denied;
1960                         }
1961
1962                         /*
1963                          * Non-encrypted passwords - convert to DOS codepage
1964                          * before using.
1965                          */
1966                         tmp_pass = talloc_array(talloc_tos(), uint8_t, 0);
1967                         if (tevent_req_nomem(tmp_pass, req)) {
1968                                 return tevent_req_post(req, ev);
1969                         }
1970                         tmp_pass = trans2_bytes_push_str(tmp_pass,
1971                                                          false, /* always DOS */
1972                                                          pass,
1973                                                          passlen,
1974                                                          NULL);
1975                         if (tevent_req_nomem(tmp_pass, req)) {
1976                                 return tevent_req_post(req, ev);
1977                         }
1978                         pass = (const char *)tmp_pass;
1979                         passlen = talloc_get_size(tmp_pass);
1980                 }
1981         }
1982
1983         tcon_flags |= TCONX_FLAG_EXTENDED_RESPONSE;
1984         tcon_flags |= TCONX_FLAG_EXTENDED_SIGNATURES;
1985
1986         SCVAL(vwv+0, 0, 0xFF);
1987         SCVAL(vwv+0, 1, 0);
1988         SSVAL(vwv+1, 0, 0);
1989         SSVAL(vwv+2, 0, tcon_flags);
1990         SSVAL(vwv+3, 0, passlen);
1991
1992         if (passlen && pass) {
1993                 bytes = (uint8_t *)talloc_memdup(state, pass, passlen);
1994         } else {
1995                 bytes = talloc_array(state, uint8_t, 0);
1996         }
1997
1998         /*
1999          * Add the sharename
2000          */
2001         tmp = talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
2002                                          smbXcli_conn_remote_name(cli->conn), share);
2003         if (tmp == NULL) {
2004                 TALLOC_FREE(req);
2005                 return NULL;
2006         }
2007         bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), tmp, strlen(tmp)+1,
2008                                    NULL);
2009         TALLOC_FREE(tmp);
2010
2011         /*
2012          * Add the devicetype
2013          */
2014         tmp = talloc_strdup_upper(talloc_tos(), dev);
2015         if (tmp == NULL) {
2016                 TALLOC_FREE(req);
2017                 return NULL;
2018         }
2019         bytes = smb_bytes_push_str(bytes, false, tmp, strlen(tmp)+1, NULL);
2020         TALLOC_FREE(tmp);
2021
2022         if (bytes == NULL) {
2023                 TALLOC_FREE(req);
2024                 return NULL;
2025         }
2026
2027         state->bytes.iov_base = (void *)bytes;
2028         state->bytes.iov_len = talloc_get_size(bytes);
2029
2030         subreq = cli_smb_req_create(state, ev, cli, SMBtconX, 0, 0, 4, vwv,
2031                                     1, &state->bytes);
2032         if (subreq == NULL) {
2033                 TALLOC_FREE(req);
2034                 return NULL;
2035         }
2036         tevent_req_set_callback(subreq, cli_tcon_andx_done, req);
2037         *psmbreq = subreq;
2038         return req;
2039
2040  access_denied:
2041         tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
2042         return tevent_req_post(req, ev);
2043 }
2044
2045 struct tevent_req *cli_tcon_andx_send(TALLOC_CTX *mem_ctx,
2046                                       struct tevent_context *ev,
2047                                       struct cli_state *cli,
2048                                       const char *share, const char *dev,
2049                                       const char *pass, int passlen)
2050 {
2051         struct tevent_req *req, *subreq;
2052         NTSTATUS status;
2053
2054         req = cli_tcon_andx_create(mem_ctx, ev, cli, share, dev, pass, passlen,
2055                                    &subreq);
2056         if (req == NULL) {
2057                 return NULL;
2058         }
2059         if (subreq == NULL) {
2060                 return req;
2061         }
2062         status = smb1cli_req_chain_submit(&subreq, 1);
2063         if (!NT_STATUS_IS_OK(status)) {
2064                 tevent_req_nterror(req, status);
2065                 return tevent_req_post(req, ev);
2066         }
2067         return req;
2068 }
2069
2070 static void cli_tcon_andx_done(struct tevent_req *subreq)
2071 {
2072         struct tevent_req *req = tevent_req_callback_data(
2073                 subreq, struct tevent_req);
2074         struct cli_tcon_andx_state *state = tevent_req_data(
2075                 req, struct cli_tcon_andx_state);
2076         struct cli_state *cli = state->cli;
2077         uint8_t *in;
2078         uint8_t *inhdr;
2079         uint8_t wct;
2080         uint16_t *vwv;
2081         uint32_t num_bytes;
2082         uint8_t *bytes;
2083         NTSTATUS status;
2084         uint16_t optional_support = 0;
2085
2086         status = cli_smb_recv(subreq, state, &in, 0, &wct, &vwv,
2087                               &num_bytes, &bytes);
2088         TALLOC_FREE(subreq);
2089         if (!NT_STATUS_IS_OK(status)) {
2090                 tevent_req_nterror(req, status);
2091                 return;
2092         }
2093
2094         inhdr = in + NBT_HDR_SIZE;
2095
2096         if (num_bytes) {
2097                 if (clistr_pull_talloc(cli,
2098                                 (const char *)inhdr,
2099                                 SVAL(inhdr, HDR_FLG2),
2100                                 &cli->dev,
2101                                 bytes,
2102                                 num_bytes,
2103                                 STR_TERMINATE|STR_ASCII) == -1) {
2104                         tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2105                         return;
2106                 }
2107         } else {
2108                 cli->dev = talloc_strdup(cli, "");
2109                 if (cli->dev == NULL) {
2110                         tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2111                         return;
2112                 }
2113         }
2114
2115         if ((smbXcli_conn_protocol(cli->conn) >= PROTOCOL_NT1) && (num_bytes == 3)) {
2116                 /* almost certainly win95 - enable bug fixes */
2117                 cli->win95 = True;
2118         }
2119
2120         /*
2121          * Make sure that we have the optional support 16-bit field. WCT > 2.
2122          * Avoids issues when connecting to Win9x boxes sharing files
2123          */
2124
2125         if ((wct > 2) && (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_LANMAN2)) {
2126                 optional_support = SVAL(vwv+2, 0);
2127         }
2128
2129         if (optional_support & SMB_EXTENDED_SIGNATURES) {
2130                 smb1cli_session_protect_session_key(cli->smb1.session);
2131         }
2132
2133         smb1cli_tcon_set_values(state->cli->smb1.tcon,
2134                                 SVAL(inhdr, HDR_TID),
2135                                 optional_support,
2136                                 0, /* maximal_access */
2137                                 0, /* guest_maximal_access */
2138                                 NULL, /* service */
2139                                 NULL); /* fs_type */
2140
2141         tevent_req_done(req);
2142 }
2143
2144 NTSTATUS cli_tcon_andx_recv(struct tevent_req *req)
2145 {
2146         return tevent_req_simple_recv_ntstatus(req);
2147 }
2148
2149 NTSTATUS cli_tcon_andx(struct cli_state *cli, const char *share,
2150                        const char *dev, const char *pass, int passlen)
2151 {
2152         TALLOC_CTX *frame = talloc_stackframe();
2153         struct tevent_context *ev;
2154         struct tevent_req *req;
2155         NTSTATUS status = NT_STATUS_NO_MEMORY;
2156
2157         if (smbXcli_conn_has_async_calls(cli->conn)) {
2158                 /*
2159                  * Can't use sync call while an async call is in flight
2160                  */
2161                 status = NT_STATUS_INVALID_PARAMETER;
2162                 goto fail;
2163         }
2164
2165         ev = samba_tevent_context_init(frame);
2166         if (ev == NULL) {
2167                 goto fail;
2168         }
2169
2170         req = cli_tcon_andx_send(frame, ev, cli, share, dev, pass, passlen);
2171         if (req == NULL) {
2172                 goto fail;
2173         }
2174
2175         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2176                 goto fail;
2177         }
2178
2179         status = cli_tcon_andx_recv(req);
2180  fail:
2181         TALLOC_FREE(frame);
2182         return status;
2183 }
2184
2185 struct cli_tree_connect_state {
2186         struct cli_state *cli;
2187 };
2188
2189 static struct tevent_req *cli_raw_tcon_send(
2190         TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
2191         const char *service, const char *pass, const char *dev);
2192 static NTSTATUS cli_raw_tcon_recv(struct tevent_req *req,
2193                                   uint16_t *max_xmit, uint16_t *tid);
2194
2195 static void cli_tree_connect_smb2_done(struct tevent_req *subreq);
2196 static void cli_tree_connect_andx_done(struct tevent_req *subreq);
2197 static void cli_tree_connect_raw_done(struct tevent_req *subreq);
2198
2199 static struct tevent_req *cli_tree_connect_send(
2200         TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
2201         const char *share, const char *dev, const char *pass)
2202 {
2203         struct tevent_req *req, *subreq;
2204         struct cli_tree_connect_state *state;
2205         int passlen;
2206
2207         if (pass == NULL) {
2208                 pass = "";
2209         }
2210         passlen = strlen(pass) + 1;
2211
2212         req = tevent_req_create(mem_ctx, &state,
2213                                 struct cli_tree_connect_state);
2214         if (req == NULL) {
2215                 return NULL;
2216         }
2217         state->cli = cli;
2218
2219         cli->share = talloc_strdup(cli, share);
2220         if (tevent_req_nomem(cli->share, req)) {
2221                 return tevent_req_post(req, ev);
2222         }
2223
2224         if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
2225                 char *unc;
2226
2227                 cli->smb2.tcon = smbXcli_tcon_create(cli);
2228                 if (tevent_req_nomem(cli->smb2.tcon, req)) {
2229                         return tevent_req_post(req, ev);
2230                 }
2231
2232                 unc = talloc_asprintf(state, "\\\\%s\\%s",
2233                                       smbXcli_conn_remote_name(cli->conn),
2234                                       share);
2235                 if (tevent_req_nomem(unc, req)) {
2236                         return tevent_req_post(req, ev);
2237                 }
2238
2239                 subreq = smb2cli_tcon_send(state, ev, cli->conn, cli->timeout,
2240                                            cli->smb2.session, cli->smb2.tcon,
2241                                            0, /* flags */
2242                                            unc);
2243                 if (tevent_req_nomem(subreq, req)) {
2244                         return tevent_req_post(req, ev);
2245                 }
2246                 tevent_req_set_callback(subreq, cli_tree_connect_smb2_done,
2247                                         req);
2248                 return req;
2249         }
2250
2251         if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_LANMAN1) {
2252                 subreq = cli_tcon_andx_send(state, ev, cli, share, dev,
2253                                             pass, passlen);
2254                 if (tevent_req_nomem(subreq, req)) {
2255                         return tevent_req_post(req, ev);
2256                 }
2257                 tevent_req_set_callback(subreq, cli_tree_connect_andx_done,
2258                                         req);
2259                 return req;
2260         }
2261
2262         subreq = cli_raw_tcon_send(state, ev, cli, share, pass, dev);
2263         if (tevent_req_nomem(subreq, req)) {
2264                 return tevent_req_post(req, ev);
2265         }
2266         tevent_req_set_callback(subreq, cli_tree_connect_raw_done, req);
2267
2268         return req;
2269 }
2270
2271 static void cli_tree_connect_smb2_done(struct tevent_req *subreq)
2272 {
2273         tevent_req_simple_finish_ntstatus(
2274                 subreq, smb2cli_tcon_recv(subreq));
2275 }
2276
2277 static void cli_tree_connect_andx_done(struct tevent_req *subreq)
2278 {
2279         tevent_req_simple_finish_ntstatus(
2280                 subreq, cli_tcon_andx_recv(subreq));
2281 }
2282
2283 static void cli_tree_connect_raw_done(struct tevent_req *subreq)
2284 {
2285         struct tevent_req *req = tevent_req_callback_data(
2286                 subreq, struct tevent_req);
2287         struct cli_tree_connect_state *state = tevent_req_data(
2288                 req, struct cli_tree_connect_state);
2289         NTSTATUS status;
2290         uint16_t max_xmit = 0;
2291         uint16_t tid = 0;
2292
2293         status = cli_raw_tcon_recv(subreq, &max_xmit, &tid);
2294         if (tevent_req_nterror(req, status)) {
2295                 return;
2296         }
2297
2298         smb1cli_tcon_set_values(state->cli->smb1.tcon,
2299                                 tid,
2300                                 0, /* optional_support */
2301                                 0, /* maximal_access */
2302                                 0, /* guest_maximal_access */
2303                                 NULL, /* service */
2304                                 NULL); /* fs_type */
2305
2306         tevent_req_done(req);
2307 }
2308
2309 static NTSTATUS cli_tree_connect_recv(struct tevent_req *req)
2310 {
2311         return tevent_req_simple_recv_ntstatus(req);
2312 }
2313
2314 NTSTATUS cli_tree_connect(struct cli_state *cli, const char *share,
2315                           const char *dev, const char *pass)
2316 {
2317         struct tevent_context *ev;
2318         struct tevent_req *req;
2319         NTSTATUS status = NT_STATUS_NO_MEMORY;
2320
2321         if (smbXcli_conn_has_async_calls(cli->conn)) {
2322                 return NT_STATUS_INVALID_PARAMETER;
2323         }
2324         ev = samba_tevent_context_init(talloc_tos());
2325         if (ev == NULL) {
2326                 goto fail;
2327         }
2328         req = cli_tree_connect_send(ev, ev, cli, share, dev, pass);
2329         if (req == NULL) {
2330                 goto fail;
2331         }
2332         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2333                 goto fail;
2334         }
2335         status = cli_tree_connect_recv(req);
2336 fail:
2337         TALLOC_FREE(ev);
2338         return status;
2339 }
2340
2341 NTSTATUS cli_tree_connect_creds(struct cli_state *cli,
2342                                 const char *share, const char *dev,
2343                                 struct cli_credentials *creds)
2344 {
2345         const char *pw = NULL;
2346
2347         if (creds != NULL) {
2348                 pw = cli_credentials_get_password(creds);
2349         }
2350
2351         return cli_tree_connect(cli, share, dev, pw);
2352 }
2353
2354 /****************************************************************************
2355  Send a tree disconnect.
2356 ****************************************************************************/
2357
2358 struct cli_tdis_state {
2359         struct cli_state *cli;
2360 };
2361
2362 static void cli_tdis_done(struct tevent_req *subreq);
2363
2364 static struct tevent_req *cli_tdis_send(TALLOC_CTX *mem_ctx,
2365                                  struct tevent_context *ev,
2366                                  struct cli_state *cli)
2367 {
2368         struct tevent_req *req, *subreq;
2369         struct cli_tdis_state *state;
2370
2371         req = tevent_req_create(mem_ctx, &state, struct cli_tdis_state);
2372         if (req == NULL) {
2373                 return NULL;
2374         }
2375         state->cli = cli;
2376
2377         subreq = cli_smb_send(state, ev, cli, SMBtdis, 0, 0, 0, NULL, 0, NULL);
2378         if (tevent_req_nomem(subreq, req)) {
2379                 return tevent_req_post(req, ev);
2380         }
2381         tevent_req_set_callback(subreq, cli_tdis_done, req);
2382         return req;
2383 }
2384
2385 static void cli_tdis_done(struct tevent_req *subreq)
2386 {
2387         struct tevent_req *req = tevent_req_callback_data(
2388                 subreq, struct tevent_req);
2389         struct cli_tdis_state *state = tevent_req_data(
2390                 req, struct cli_tdis_state);
2391         NTSTATUS status;
2392
2393         status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
2394         TALLOC_FREE(subreq);
2395         if (!NT_STATUS_IS_OK(status)) {
2396                 tevent_req_nterror(req, status);
2397                 return;
2398         }
2399         cli_state_set_tid(state->cli, UINT16_MAX);
2400         tevent_req_done(req);
2401 }
2402
2403 static NTSTATUS cli_tdis_recv(struct tevent_req *req)
2404 {
2405         return tevent_req_simple_recv_ntstatus(req);
2406 }
2407
2408 NTSTATUS cli_tdis(struct cli_state *cli)
2409 {
2410         struct tevent_context *ev;
2411         struct tevent_req *req;
2412         NTSTATUS status = NT_STATUS_NO_MEMORY;
2413
2414         if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
2415                 return smb2cli_tdis(cli->conn,
2416                                     cli->timeout,
2417                                     cli->smb2.session,
2418                                     cli->smb2.tcon);
2419         }
2420
2421         if (smbXcli_conn_has_async_calls(cli->conn)) {
2422                 return NT_STATUS_INVALID_PARAMETER;
2423         }
2424         ev = samba_tevent_context_init(talloc_tos());
2425         if (ev == NULL) {
2426                 goto fail;
2427         }
2428         req = cli_tdis_send(ev, ev, cli);
2429         if (req == NULL) {
2430                 goto fail;
2431         }
2432         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2433                 goto fail;
2434         }
2435         status = cli_tdis_recv(req);
2436 fail:
2437         TALLOC_FREE(ev);
2438         return status;
2439 }
2440
2441 struct cli_connect_sock_state {
2442         const char **called_names;
2443         const char **calling_names;
2444         int *called_types;
2445         int fd;
2446         uint16_t port;
2447 };
2448
2449 static void cli_connect_sock_done(struct tevent_req *subreq);
2450
2451 /*
2452  * Async only if we don't have to look up the name, i.e. "pss" is set with a
2453  * nonzero address.
2454  */
2455
2456 static struct tevent_req *cli_connect_sock_send(
2457         TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2458         const char *host, int name_type, const struct sockaddr_storage *pss,
2459         const char *myname, uint16_t port)
2460 {
2461         struct tevent_req *req, *subreq;
2462         struct cli_connect_sock_state *state;
2463         const char *prog;
2464         struct sockaddr_storage *addrs;
2465         unsigned i, num_addrs;
2466         NTSTATUS status;
2467
2468         req = tevent_req_create(mem_ctx, &state,
2469                                 struct cli_connect_sock_state);
2470         if (req == NULL) {
2471                 return NULL;
2472         }
2473
2474         prog = getenv("LIBSMB_PROG");
2475         if (prog != NULL) {
2476                 state->fd = sock_exec(prog);
2477                 if (state->fd == -1) {
2478                         status = map_nt_error_from_unix(errno);
2479                         tevent_req_nterror(req, status);
2480                 } else {
2481                         state->port = 0;
2482                         tevent_req_done(req);
2483                 }
2484                 return tevent_req_post(req, ev);
2485         }
2486
2487         if ((pss == NULL) || is_zero_addr(pss)) {
2488
2489                 /*
2490                  * Here we cheat. resolve_name_list is not async at all. So
2491                  * this call will only be really async if the name lookup has
2492                  * been done externally.
2493                  */
2494
2495                 status = resolve_name_list(state, host, name_type,
2496                                            &addrs, &num_addrs);
2497                 if (!NT_STATUS_IS_OK(status)) {
2498                         tevent_req_nterror(req, status);
2499                         return tevent_req_post(req, ev);
2500                 }
2501         } else {
2502                 addrs = talloc_array(state, struct sockaddr_storage, 1);
2503                 if (tevent_req_nomem(addrs, req)) {
2504                         return tevent_req_post(req, ev);
2505                 }
2506                 addrs[0] = *pss;
2507                 num_addrs = 1;
2508         }
2509
2510         state->called_names = talloc_array(state, const char *, num_addrs);
2511         if (tevent_req_nomem(state->called_names, req)) {
2512                 return tevent_req_post(req, ev);
2513         }
2514         state->called_types = talloc_array(state, int, num_addrs);
2515         if (tevent_req_nomem(state->called_types, req)) {
2516                 return tevent_req_post(req, ev);
2517         }
2518         state->calling_names = talloc_array(state, const char *, num_addrs);
2519         if (tevent_req_nomem(state->calling_names, req)) {
2520                 return tevent_req_post(req, ev);
2521         }
2522         for (i=0; i<num_addrs; i++) {
2523                 state->called_names[i] = host;
2524                 state->called_types[i] = name_type;
2525                 state->calling_names[i] = myname;
2526         }
2527
2528         subreq = smbsock_any_connect_send(
2529                 state, ev, addrs, state->called_names, state->called_types,
2530                 state->calling_names, NULL, num_addrs, port);
2531         if (tevent_req_nomem(subreq, req)) {
2532                 return tevent_req_post(req, ev);
2533         }
2534         tevent_req_set_callback(subreq, cli_connect_sock_done, req);
2535         return req;
2536 }
2537
2538 static void cli_connect_sock_done(struct tevent_req *subreq)
2539 {
2540         struct tevent_req *req = tevent_req_callback_data(
2541                 subreq, struct tevent_req);
2542         struct cli_connect_sock_state *state = tevent_req_data(
2543                 req, struct cli_connect_sock_state);
2544         NTSTATUS status;
2545
2546         status = smbsock_any_connect_recv(subreq, &state->fd, NULL,
2547                                           &state->port);
2548         TALLOC_FREE(subreq);
2549         if (tevent_req_nterror(req, status)) {
2550                 return;
2551         }
2552         set_socket_options(state->fd, lp_socket_options());
2553         tevent_req_done(req);
2554 }
2555
2556 static NTSTATUS cli_connect_sock_recv(struct tevent_req *req,
2557                                       int *pfd, uint16_t *pport)
2558 {
2559         struct cli_connect_sock_state *state = tevent_req_data(
2560                 req, struct cli_connect_sock_state);
2561         NTSTATUS status;
2562
2563         if (tevent_req_is_nterror(req, &status)) {
2564                 return status;
2565         }
2566         *pfd = state->fd;
2567         *pport = state->port;
2568         return NT_STATUS_OK;
2569 }
2570
2571 struct cli_connect_nb_state {
2572         const char *desthost;
2573         int signing_state;
2574         int flags;
2575         struct cli_state *cli;
2576 };
2577
2578 static void cli_connect_nb_done(struct tevent_req *subreq);
2579
2580 static struct tevent_req *cli_connect_nb_send(
2581         TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2582         const char *host, const struct sockaddr_storage *dest_ss,
2583         uint16_t port, int name_type, const char *myname,
2584         int signing_state, int flags)
2585 {
2586         struct tevent_req *req, *subreq;
2587         struct cli_connect_nb_state *state;
2588
2589         req = tevent_req_create(mem_ctx, &state, struct cli_connect_nb_state);
2590         if (req == NULL) {
2591                 return NULL;
2592         }
2593         state->signing_state = signing_state;
2594         state->flags = flags;
2595
2596         if (host != NULL) {
2597                 char *p = strchr(host, '#');
2598
2599                 if (p != NULL) {
2600                         name_type = strtol(p+1, NULL, 16);
2601                         host = talloc_strndup(state, host, p - host);
2602                         if (tevent_req_nomem(host, req)) {
2603                                 return tevent_req_post(req, ev);
2604                         }
2605                 }
2606
2607                 state->desthost = host;
2608         } else if (dest_ss != NULL) {
2609                 state->desthost = print_canonical_sockaddr(state, dest_ss);
2610                 if (tevent_req_nomem(state->desthost, req)) {
2611                         return tevent_req_post(req, ev);
2612                 }
2613         } else {
2614                 /* No host or dest_ss given. Error out. */
2615                 tevent_req_error(req, EINVAL);
2616                 return tevent_req_post(req, ev);
2617         }
2618
2619         subreq = cli_connect_sock_send(state, ev, host, name_type, dest_ss,
2620                                        myname, port);
2621         if (tevent_req_nomem(subreq, req)) {
2622                 return tevent_req_post(req, ev);
2623         }
2624         tevent_req_set_callback(subreq, cli_connect_nb_done, req);
2625         return req;
2626 }
2627
2628 static void cli_connect_nb_done(struct tevent_req *subreq)
2629 {
2630         struct tevent_req *req = tevent_req_callback_data(
2631                 subreq, struct tevent_req);
2632         struct cli_connect_nb_state *state = tevent_req_data(
2633                 req, struct cli_connect_nb_state);
2634         NTSTATUS status;
2635         int fd = 0;
2636         uint16_t port;
2637
2638         status = cli_connect_sock_recv(subreq, &fd, &port);
2639         TALLOC_FREE(subreq);
2640         if (tevent_req_nterror(req, status)) {
2641                 return;
2642         }
2643
2644         state->cli = cli_state_create(state, fd, state->desthost, NULL,
2645                                       state->signing_state, state->flags);
2646         if (tevent_req_nomem(state->cli, req)) {
2647                 close(fd);
2648                 return;
2649         }
2650         tevent_req_done(req);
2651 }
2652
2653 static NTSTATUS cli_connect_nb_recv(struct tevent_req *req,
2654                                     struct cli_state **pcli)
2655 {
2656         struct cli_connect_nb_state *state = tevent_req_data(
2657                 req, struct cli_connect_nb_state);
2658         NTSTATUS status;
2659
2660         if (tevent_req_is_nterror(req, &status)) {
2661                 return status;
2662         }
2663         *pcli = talloc_move(NULL, &state->cli);
2664         return NT_STATUS_OK;
2665 }
2666
2667 NTSTATUS cli_connect_nb(const char *host, const struct sockaddr_storage *dest_ss,
2668                         uint16_t port, int name_type, const char *myname,
2669                         int signing_state, int flags, struct cli_state **pcli)
2670 {
2671         struct tevent_context *ev;
2672         struct tevent_req *req;
2673         NTSTATUS status = NT_STATUS_NO_MEMORY;
2674
2675         ev = samba_tevent_context_init(talloc_tos());
2676         if (ev == NULL) {
2677                 goto fail;
2678         }
2679         req = cli_connect_nb_send(ev, ev, host, dest_ss, port, name_type,
2680                                   myname, signing_state, flags);
2681         if (req == NULL) {
2682                 goto fail;
2683         }
2684         if (!tevent_req_set_endtime(req, ev, timeval_current_ofs(20, 0))) {
2685                 goto fail;
2686         }
2687         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2688                 goto fail;
2689         }
2690         status = cli_connect_nb_recv(req, pcli);
2691 fail:
2692         TALLOC_FREE(ev);
2693         return status;
2694 }
2695
2696 struct cli_start_connection_state {
2697         struct tevent_context *ev;
2698         struct cli_state *cli;
2699         int min_protocol;
2700         int max_protocol;
2701 };
2702
2703 static void cli_start_connection_connected(struct tevent_req *subreq);
2704 static void cli_start_connection_done(struct tevent_req *subreq);
2705
2706 /**
2707    establishes a connection to after the negprot. 
2708    @param output_cli A fully initialised cli structure, non-null only on success
2709    @param dest_host The netbios name of the remote host
2710    @param dest_ss (optional) The the destination IP, NULL for name based lookup
2711    @param port (optional) The destination port (0 for default)
2712 */
2713
2714 static struct tevent_req *cli_start_connection_send(
2715         TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2716         const char *my_name, const char *dest_host,
2717         const struct sockaddr_storage *dest_ss, int port,
2718         int signing_state, int flags)
2719 {
2720         struct tevent_req *req, *subreq;
2721         struct cli_start_connection_state *state;
2722
2723         req = tevent_req_create(mem_ctx, &state,
2724                                 struct cli_start_connection_state);
2725         if (req == NULL) {
2726                 return NULL;
2727         }
2728         state->ev = ev;
2729
2730         if (signing_state == SMB_SIGNING_IPC_DEFAULT) {
2731                 state->min_protocol = lp_client_ipc_min_protocol();
2732                 state->max_protocol = lp_client_ipc_max_protocol();
2733         } else {
2734                 state->min_protocol = lp_client_min_protocol();
2735                 state->max_protocol = lp_client_max_protocol();
2736         }
2737
2738         subreq = cli_connect_nb_send(state, ev, dest_host, dest_ss, port,
2739                                      0x20, my_name, signing_state, flags);
2740         if (tevent_req_nomem(subreq, req)) {
2741                 return tevent_req_post(req, ev);
2742         }
2743         tevent_req_set_callback(subreq, cli_start_connection_connected, req);
2744         return req;
2745 }
2746
2747 static void cli_start_connection_connected(struct tevent_req *subreq)
2748 {
2749         struct tevent_req *req = tevent_req_callback_data(
2750                 subreq, struct tevent_req);
2751         struct cli_start_connection_state *state = tevent_req_data(
2752                 req, struct cli_start_connection_state);
2753         NTSTATUS status;
2754
2755         status = cli_connect_nb_recv(subreq, &state->cli);
2756         TALLOC_FREE(subreq);
2757         if (tevent_req_nterror(req, status)) {
2758                 return;
2759         }
2760
2761         subreq = smbXcli_negprot_send(state, state->ev, state->cli->conn,
2762                                       state->cli->timeout,
2763                                       state->min_protocol,
2764                                       state->max_protocol,
2765                                       WINDOWS_CLIENT_PURE_SMB2_NEGPROT_INITIAL_CREDIT_ASK);
2766         if (tevent_req_nomem(subreq, req)) {
2767                 return;
2768         }
2769         tevent_req_set_callback(subreq, cli_start_connection_done, req);
2770 }
2771
2772 static void cli_start_connection_done(struct tevent_req *subreq)
2773 {
2774         struct tevent_req *req = tevent_req_callback_data(
2775                 subreq, struct tevent_req);
2776         struct cli_start_connection_state *state = tevent_req_data(
2777                 req, struct cli_start_connection_state);
2778         NTSTATUS status;
2779
2780         status = smbXcli_negprot_recv(subreq);
2781         TALLOC_FREE(subreq);
2782         if (tevent_req_nterror(req, status)) {
2783                 return;
2784         }
2785
2786         if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
2787                 /* Ensure we ask for some initial credits. */
2788                 smb2cli_conn_set_max_credits(state->cli->conn,
2789                                              DEFAULT_SMB2_MAX_CREDITS);
2790         }
2791
2792         tevent_req_done(req);
2793 }
2794
2795 static NTSTATUS cli_start_connection_recv(struct tevent_req *req,
2796                                           struct cli_state **output_cli)
2797 {
2798         struct cli_start_connection_state *state = tevent_req_data(
2799                 req, struct cli_start_connection_state);
2800         NTSTATUS status;
2801
2802         if (tevent_req_is_nterror(req, &status)) {
2803                 return status;
2804         }
2805         *output_cli = state->cli;
2806
2807         return NT_STATUS_OK;
2808 }
2809
2810 NTSTATUS cli_start_connection(struct cli_state **output_cli, 
2811                               const char *my_name, 
2812                               const char *dest_host, 
2813                               const struct sockaddr_storage *dest_ss, int port,
2814                               int signing_state, int flags)
2815 {
2816         struct tevent_context *ev;
2817         struct tevent_req *req;
2818         NTSTATUS status = NT_STATUS_NO_MEMORY;
2819
2820         ev = samba_tevent_context_init(talloc_tos());
2821         if (ev == NULL) {
2822                 goto fail;
2823         }
2824         req = cli_start_connection_send(ev, ev, my_name, dest_host, dest_ss,
2825                                         port, signing_state, flags);
2826         if (req == NULL) {
2827                 goto fail;
2828         }
2829         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2830                 goto fail;
2831         }
2832         status = cli_start_connection_recv(req, output_cli);
2833 fail:
2834         TALLOC_FREE(ev);
2835         return status;
2836 }
2837
2838 struct cli_smb1_setup_encryption_blob_state {
2839         uint16_t setup[1];
2840         uint8_t param[4];
2841         NTSTATUS status;
2842         DATA_BLOB out;
2843         uint16_t enc_ctx_id;
2844 };
2845
2846 static void cli_smb1_setup_encryption_blob_done(struct tevent_req *subreq);
2847
2848 static struct tevent_req *cli_smb1_setup_encryption_blob_send(TALLOC_CTX *mem_ctx,
2849                                                         struct tevent_context *ev,
2850                                                         struct cli_state *cli,
2851                                                         const DATA_BLOB in)
2852 {
2853         struct tevent_req *req = NULL;
2854         struct cli_smb1_setup_encryption_blob_state *state = NULL;
2855         struct tevent_req *subreq = NULL;
2856
2857         req = tevent_req_create(mem_ctx, &state,
2858                                 struct cli_smb1_setup_encryption_blob_state);
2859         if (req == NULL) {
2860                 return NULL;
2861         }
2862
2863         if (in.length > CLI_BUFFER_SIZE) {
2864                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
2865                 return tevent_req_post(req, ev);
2866         }
2867
2868         SSVAL(state->setup+0,  0, TRANSACT2_SETFSINFO);
2869         SSVAL(state->param, 0, 0);
2870         SSVAL(state->param, 2, SMB_REQUEST_TRANSPORT_ENCRYPTION);
2871
2872         subreq = smb1cli_trans_send(state, ev, cli->conn,
2873                                     SMBtrans2,
2874                                     0, 0, /* _flags */
2875                                     0, 0, /* _flags2 */
2876                                     cli->timeout,
2877                                     cli->smb1.pid,
2878                                     cli->smb1.tcon,
2879                                     cli->smb1.session,
2880                                     NULL, /* pipe_name */
2881                                     0, /* fid */
2882                                     0, /* function */
2883                                     0, /* flags */
2884                                     state->setup, 1, 0,
2885                                     state->param, 4, 2,
2886                                     in.data, in.length, CLI_BUFFER_SIZE);
2887         if (tevent_req_nomem(subreq, req)) {
2888                 return tevent_req_post(req, ev);
2889         }
2890         tevent_req_set_callback(subreq,
2891                                 cli_smb1_setup_encryption_blob_done,
2892                                 req);
2893
2894         return req;
2895 }
2896
2897 static void cli_smb1_setup_encryption_blob_done(struct tevent_req *subreq)
2898 {
2899         struct tevent_req *req =
2900                 tevent_req_callback_data(subreq,
2901                                 struct tevent_req);
2902         struct cli_smb1_setup_encryption_blob_state *state =
2903                 tevent_req_data(req,
2904                 struct cli_smb1_setup_encryption_blob_state);
2905         uint8_t *rparam=NULL, *rdata=NULL;
2906         uint32_t num_rparam, num_rdata;
2907         NTSTATUS status;
2908
2909         status = smb1cli_trans_recv(subreq, state,
2910                                     NULL, /* recv_flags */
2911                                     NULL, 0, NULL, /* rsetup */
2912                                     &rparam, 0, &num_rparam,
2913                                     &rdata, 0, &num_rdata);
2914         TALLOC_FREE(subreq);
2915         state->status = status;
2916         if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
2917                 status = NT_STATUS_OK;
2918         }
2919         if (tevent_req_nterror(req, status)) {
2920                 return;
2921         }
2922
2923         if (num_rparam == 2) {
2924                 state->enc_ctx_id = SVAL(rparam, 0);
2925         }
2926         TALLOC_FREE(rparam);
2927
2928         state->out = data_blob_const(rdata, num_rdata);
2929
2930         tevent_req_done(req);
2931 }
2932
2933 static NTSTATUS cli_smb1_setup_encryption_blob_recv(struct tevent_req *req,
2934                                                     TALLOC_CTX *mem_ctx,
2935                                                     DATA_BLOB *out,
2936                                                     uint16_t *enc_ctx_id)
2937 {
2938         struct cli_smb1_setup_encryption_blob_state *state =
2939                 tevent_req_data(req,
2940                 struct cli_smb1_setup_encryption_blob_state);
2941         NTSTATUS status;
2942
2943         if (tevent_req_is_nterror(req, &status)) {
2944                 tevent_req_received(req);
2945                 return status;
2946         }
2947
2948         status = state->status;
2949
2950         *out = state->out;
2951         talloc_steal(mem_ctx, out->data);
2952
2953         *enc_ctx_id = state->enc_ctx_id;
2954
2955         tevent_req_received(req);
2956         return status;
2957 }
2958
2959 struct cli_smb1_setup_encryption_state {
2960         struct tevent_context *ev;
2961         struct cli_state *cli;
2962         struct smb_trans_enc_state *es;
2963         DATA_BLOB blob_in;
2964         DATA_BLOB blob_out;
2965         bool local_ready;
2966         bool remote_ready;
2967 };
2968
2969 static void cli_smb1_setup_encryption_local_next(struct tevent_req *req);
2970 static void cli_smb1_setup_encryption_local_done(struct tevent_req *subreq);
2971 static void cli_smb1_setup_encryption_remote_next(struct tevent_req *req);
2972 static void cli_smb1_setup_encryption_remote_done(struct tevent_req *subreq);
2973 static void cli_smb1_setup_encryption_ready(struct tevent_req *req);
2974
2975 static struct tevent_req *cli_smb1_setup_encryption_send(TALLOC_CTX *mem_ctx,
2976                                                 struct tevent_context *ev,
2977                                                 struct cli_state *cli,
2978                                                 struct cli_credentials *creds)
2979 {
2980         struct tevent_req *req = NULL;
2981         struct cli_smb1_setup_encryption_state *state = NULL;
2982         struct auth_generic_state *ags = NULL;
2983         const DATA_BLOB *b = NULL;
2984         bool auth_requested = false;
2985         const char *target_service = NULL;
2986         const char *target_hostname = NULL;
2987         NTSTATUS status;
2988
2989         req = tevent_req_create(mem_ctx, &state,
2990                                 struct cli_smb1_setup_encryption_state);
2991         if (req == NULL) {
2992                 return NULL;
2993         }
2994         state->ev = ev;
2995         state->cli = cli;
2996
2997         auth_requested = cli_credentials_authentication_requested(creds);
2998         if (!auth_requested) {
2999                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
3000                 return tevent_req_post(req, ev);
3001         }
3002
3003         target_service = "cifs";
3004         target_hostname = smbXcli_conn_remote_name(cli->conn);
3005
3006         status = cli_session_creds_prepare_krb5(cli, creds);
3007         if (tevent_req_nterror(req, status)) {
3008                 return tevent_req_post(req, ev);
3009         }
3010
3011         state->es = talloc_zero(state, struct smb_trans_enc_state);
3012         if (tevent_req_nomem(state->es, req)) {
3013                 return tevent_req_post(req, ev);
3014         }
3015
3016         status = auth_generic_client_prepare(state->es, &ags);
3017         if (tevent_req_nterror(req, status)) {
3018                 return tevent_req_post(req, ev);
3019         }
3020
3021         gensec_want_feature(ags->gensec_security,
3022                             GENSEC_FEATURE_SIGN);
3023         gensec_want_feature(ags->gensec_security,
3024                             GENSEC_FEATURE_SEAL);
3025
3026         status = auth_generic_set_creds(ags, creds);
3027         if (tevent_req_nterror(req, status)) {
3028                 return tevent_req_post(req, ev);
3029         }
3030
3031         if (target_service != NULL) {
3032                 status = gensec_set_target_service(ags->gensec_security,
3033                                                    target_service);
3034                 if (tevent_req_nterror(req, status)) {
3035                         return tevent_req_post(req, ev);
3036                 }
3037         }
3038
3039         if (target_hostname != NULL) {
3040                 status = gensec_set_target_hostname(ags->gensec_security,
3041                                                     target_hostname);
3042                 if (tevent_req_nterror(req, status)) {
3043                         return tevent_req_post(req, ev);
3044                 }
3045         }
3046
3047         gensec_set_max_update_size(ags->gensec_security,
3048                                    CLI_BUFFER_SIZE);
3049
3050         b = smbXcli_conn_server_gss_blob(state->cli->conn);
3051         if (b != NULL) {
3052                 state->blob_in = *b;
3053         }
3054
3055         status = auth_generic_client_start(ags, GENSEC_OID_SPNEGO);
3056         if (tevent_req_nterror(req, status)) {
3057                 return tevent_req_post(req, ev);
3058         }
3059
3060         /*
3061          * We only need the gensec_security part from here.
3062          */
3063         state->es->gensec_security = talloc_move(state->es,
3064                                                  &ags->gensec_security);
3065         TALLOC_FREE(ags);
3066
3067         cli_smb1_setup_encryption_local_next(req);
3068         if (!tevent_req_is_in_progress(req)) {
3069                 return tevent_req_post(req, ev);
3070         }
3071
3072         return req;
3073 }
3074
3075 static void cli_smb1_setup_encryption_local_next(struct tevent_req *req)
3076 {
3077         struct cli_smb1_setup_encryption_state *state =
3078                 tevent_req_data(req,
3079                 struct cli_smb1_setup_encryption_state);
3080         struct tevent_req *subreq = NULL;
3081
3082         if (state->local_ready) {
3083                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3084                 return;
3085         }
3086
3087         subreq = gensec_update_send(state, state->ev,
3088                         state->es->gensec_security,
3089                         state->blob_in);
3090         if (tevent_req_nomem(subreq, req)) {
3091                 return;
3092         }
3093         tevent_req_set_callback(subreq, cli_smb1_setup_encryption_local_done, req);
3094 }
3095
3096 static void cli_smb1_setup_encryption_local_done(struct tevent_req *subreq)
3097 {
3098         struct tevent_req *req =
3099                 tevent_req_callback_data(subreq,
3100                 struct tevent_req);
3101         struct cli_smb1_setup_encryption_state *state =
3102                 tevent_req_data(req,
3103                 struct cli_smb1_setup_encryption_state);
3104         NTSTATUS status;
3105
3106         status = gensec_update_recv(subreq, state, &state->blob_out);
3107         TALLOC_FREE(subreq);
3108         state->blob_in = data_blob_null;
3109         if (!NT_STATUS_IS_OK(status) &&
3110             !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
3111         {
3112                 tevent_req_nterror(req, status);
3113                 return;
3114         }
3115
3116         if (NT_STATUS_IS_OK(status)) {
3117                 state->local_ready = true;
3118         }
3119
3120         /*
3121          * We always get NT_STATUS_OK from the server even if it is not ready.
3122          * So guess the server is ready when we are ready and already sent
3123          * our last blob to the server.
3124          */
3125         if (state->local_ready && state->blob_out.length == 0) {
3126                 state->remote_ready = true;
3127         }
3128
3129         if (state->local_ready && state->remote_ready) {
3130                 cli_smb1_setup_encryption_ready(req);
3131                 return;
3132         }
3133
3134         cli_smb1_setup_encryption_remote_next(req);
3135 }
3136
3137 static void cli_smb1_setup_encryption_remote_next(struct tevent_req *req)
3138 {
3139         struct cli_smb1_setup_encryption_state *state =
3140                 tevent_req_data(req,
3141                 struct cli_smb1_setup_encryption_state);
3142         struct tevent_req *subreq = NULL;
3143
3144         if (state->remote_ready) {
3145                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3146                 return;
3147         }
3148
3149         subreq = cli_smb1_setup_encryption_blob_send(state, state->ev,
3150                                                      state->cli, state->blob_out);
3151         if (tevent_req_nomem(subreq, req)) {
3152                 return;
3153         }
3154         tevent_req_set_callback(subreq,
3155                                 cli_smb1_setup_encryption_remote_done,
3156                                 req);
3157 }
3158
3159 static void cli_smb1_setup_encryption_remote_done(struct tevent_req *subreq)
3160 {
3161         struct tevent_req *req =
3162                 tevent_req_callback_data(subreq,
3163                 struct tevent_req);
3164         struct cli_smb1_setup_encryption_state *state =
3165                 tevent_req_data(req,
3166                 struct cli_smb1_setup_encryption_state);
3167         NTSTATUS status;
3168
3169         status = cli_smb1_setup_encryption_blob_recv(subreq, state,
3170                                                      &state->blob_in,
3171                                                      &state->es->enc_ctx_num);
3172         TALLOC_FREE(subreq);
3173         data_blob_free(&state->blob_out);
3174         if (!NT_STATUS_IS_OK(status) &&
3175             !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
3176         {
3177                 tevent_req_nterror(req, status);
3178                 return;
3179         }
3180
3181         /*
3182          * We always get NT_STATUS_OK even if the server is not ready.
3183          * So guess the server is ready when we are ready and sent
3184          * our last blob to the server.
3185          */
3186         if (state->local_ready) {
3187                 state->remote_ready = true;
3188         }
3189
3190         if (state->local_ready && state->remote_ready) {
3191                 cli_smb1_setup_encryption_ready(req);
3192                 return;
3193         }
3194
3195         cli_smb1_setup_encryption_local_next(req);
3196 }
3197
3198 static void cli_smb1_setup_encryption_ready(struct tevent_req *req)
3199 {
3200         struct cli_smb1_setup_encryption_state *state =
3201                 tevent_req_data(req,
3202                 struct cli_smb1_setup_encryption_state);
3203         struct smb_trans_enc_state *es = NULL;
3204
3205         if (state->blob_in.length != 0) {
3206                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3207                 return;
3208         }
3209
3210         if (state->blob_out.length != 0) {
3211                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3212                 return;
3213         }
3214
3215         es = talloc_move(state->cli->conn, &state->es);
3216         es->enc_on = true;
3217         smb1cli_conn_set_encryption(state->cli->conn, es);
3218         es = NULL;
3219
3220         tevent_req_done(req);
3221 }
3222
3223 static NTSTATUS cli_smb1_setup_encryption_recv(struct tevent_req *req)
3224 {
3225         return tevent_req_simple_recv_ntstatus(req);
3226 }
3227
3228 NTSTATUS cli_smb1_setup_encryption(struct cli_state *cli,
3229                                    struct cli_credentials *creds)
3230 {
3231         struct tevent_context *ev = NULL;
3232         struct tevent_req *req = NULL;
3233         NTSTATUS status = NT_STATUS_NO_MEMORY;
3234
3235         ev = samba_tevent_context_init(talloc_tos());
3236         if (ev == NULL) {
3237                 goto fail;
3238         }
3239         req = cli_smb1_setup_encryption_send(ev, ev, cli, creds);
3240         if (req == NULL) {
3241                 goto fail;
3242         }
3243         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
3244                 goto fail;
3245         }
3246         status = cli_smb1_setup_encryption_recv(req);
3247  fail:
3248         TALLOC_FREE(ev);
3249         return status;
3250 }
3251
3252 /**
3253    establishes a connection right up to doing tconX, password specified.
3254    @param output_cli A fully initialised cli structure, non-null only on success
3255    @param dest_host The netbios name of the remote host
3256    @param dest_ip (optional) The the destination IP, NULL for name based lookup
3257    @param port (optional) The destination port (0 for default)
3258    @param service (optional) The share to make the connection to.  Should be 'unqualified' in any way.
3259    @param service_type The 'type' of serivice. 
3260    @param creds The used user credentials
3261 */
3262
3263 struct cli_full_connection_creds_state {
3264         struct tevent_context *ev;
3265         const char *service;
3266         const char *service_type;
3267         struct cli_credentials *creds;
3268         int flags;
3269         struct cli_state *cli;
3270 };
3271
3272 static int cli_full_connection_creds_state_destructor(
3273         struct cli_full_connection_creds_state *s)
3274 {
3275         if (s->cli != NULL) {
3276                 cli_shutdown(s->cli);
3277                 s->cli = NULL;
3278         }
3279         return 0;
3280 }
3281
3282 static void cli_full_connection_creds_conn_done(struct tevent_req *subreq);
3283 static void cli_full_connection_creds_sess_start(struct tevent_req *req);
3284 static void cli_full_connection_creds_sess_done(struct tevent_req *subreq);
3285 static void cli_full_connection_creds_tcon_start(struct tevent_req *req);
3286 static void cli_full_connection_creds_tcon_done(struct tevent_req *subreq);
3287
3288 struct tevent_req *cli_full_connection_creds_send(
3289         TALLOC_CTX *mem_ctx, struct tevent_context *ev,
3290         const char *my_name, const char *dest_host,
3291         const struct sockaddr_storage *dest_ss, int port,
3292         const char *service, const char *service_type,
3293         struct cli_credentials *creds,
3294         int flags, int signing_state)
3295 {
3296         struct tevent_req *req, *subreq;
3297         struct cli_full_connection_creds_state *state;
3298         enum credentials_use_kerberos krb5_state;
3299         uint32_t gensec_features = 0;
3300
3301         req = tevent_req_create(mem_ctx, &state,
3302                                 struct cli_full_connection_creds_state);
3303         if (req == NULL) {
3304                 return NULL;
3305         }
3306         talloc_set_destructor(state, cli_full_connection_creds_state_destructor);
3307
3308         flags &= ~CLI_FULL_CONNECTION_USE_KERBEROS;
3309         flags &= ~CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS;
3310         flags &= ~CLI_FULL_CONNECTION_USE_CCACHE;
3311         flags &= ~CLI_FULL_CONNECTION_USE_NT_HASH;
3312
3313         krb5_state = cli_credentials_get_kerberos_state(creds);
3314         switch (krb5_state) {
3315         case CRED_MUST_USE_KERBEROS:
3316                 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
3317                 flags &= ~CLI_FULL_CONNECTION_DONT_SPNEGO;
3318                 break;
3319         case CRED_AUTO_USE_KERBEROS:
3320                 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
3321                 flags |= CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS;
3322                 break;
3323         case CRED_DONT_USE_KERBEROS:
3324                 break;
3325         }
3326
3327         gensec_features = cli_credentials_get_gensec_features(creds);
3328         if (gensec_features & GENSEC_FEATURE_NTLM_CCACHE) {
3329                 flags |= CLI_FULL_CONNECTION_USE_CCACHE;
3330         }
3331
3332         state->ev = ev;
3333         state->service = service;
3334         state->service_type = service_type;
3335         state->creds = creds;
3336         state->flags = flags;
3337
3338         subreq = cli_start_connection_send(
3339                 state, ev, my_name, dest_host, dest_ss, port,
3340                 signing_state, flags);
3341         if (tevent_req_nomem(subreq, req)) {
3342                 return tevent_req_post(req, ev);
3343         }
3344         tevent_req_set_callback(subreq,
3345                                 cli_full_connection_creds_conn_done,
3346                                 req);
3347         return req;
3348 }
3349
3350 static void cli_full_connection_creds_conn_done(struct tevent_req *subreq)
3351 {
3352         struct tevent_req *req = tevent_req_callback_data(
3353                 subreq, struct tevent_req);
3354         struct cli_full_connection_creds_state *state = tevent_req_data(
3355                 req, struct cli_full_connection_creds_state);
3356         NTSTATUS status;
3357
3358         status = cli_start_connection_recv(subreq, &state->cli);
3359         TALLOC_FREE(subreq);
3360         if (tevent_req_nterror(req, status)) {
3361                 return;
3362         }
3363
3364         cli_full_connection_creds_sess_start(req);
3365 }
3366
3367 static void cli_full_connection_creds_sess_start(struct tevent_req *req)
3368 {
3369         struct cli_full_connection_creds_state *state = tevent_req_data(
3370                 req, struct cli_full_connection_creds_state);
3371         struct tevent_req *subreq = NULL;
3372
3373         subreq = cli_session_setup_creds_send(
3374                 state, state->ev, state->cli, state->creds);
3375         if (tevent_req_nomem(subreq, req)) {
3376                 return;
3377         }
3378         tevent_req_set_callback(subreq,
3379                                 cli_full_connection_creds_sess_done,
3380                                 req);
3381 }
3382
3383 static void cli_full_connection_creds_sess_done(struct tevent_req *subreq)
3384 {
3385         struct tevent_req *req = tevent_req_callback_data(
3386                 subreq, struct tevent_req);
3387         struct cli_full_connection_creds_state *state = tevent_req_data(
3388                 req, struct cli_full_connection_creds_state);
3389         NTSTATUS status;
3390
3391         status = cli_session_setup_creds_recv(subreq);
3392         TALLOC_FREE(subreq);
3393
3394         if (!NT_STATUS_IS_OK(status) &&
3395             (state->flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)) {
3396
3397                 state->flags &= ~CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
3398
3399                 state->creds = cli_credentials_init_anon(state);
3400                 if (tevent_req_nomem(state->creds, req)) {
3401                         return;
3402                 }
3403
3404                 cli_full_connection_creds_sess_start(req);
3405                 return;
3406         }
3407
3408         if (tevent_req_nterror(req, status)) {
3409                 return;
3410         }
3411
3412         cli_full_connection_creds_tcon_start(req);
3413 }
3414
3415 static void cli_full_connection_creds_tcon_start(struct tevent_req *req)
3416 {
3417         struct cli_full_connection_creds_state *state = tevent_req_data(
3418                 req, struct cli_full_connection_creds_state);
3419         struct tevent_req *subreq = NULL;
3420         const char *password = NULL;
3421
3422         if (state->service == NULL) {
3423                 tevent_req_done(req);
3424                 return;
3425         }
3426
3427         password = cli_credentials_get_password(state->creds);
3428
3429         subreq = cli_tree_connect_send(state, state->ev,
3430                                        state->cli,
3431                                        state->service,
3432                                        state->service_type,
3433                                        password);
3434         if (tevent_req_nomem(subreq, req)) {
3435                 return;
3436         }
3437         tevent_req_set_callback(subreq,
3438                                 cli_full_connection_creds_tcon_done,
3439                                 req);
3440 }
3441
3442 static void cli_full_connection_creds_tcon_done(struct tevent_req *subreq)
3443 {
3444         struct tevent_req *req = tevent_req_callback_data(
3445                 subreq, struct tevent_req);
3446         NTSTATUS status;
3447
3448         status = cli_tree_connect_recv(subreq);
3449         TALLOC_FREE(subreq);
3450         if (tevent_req_nterror(req, status)) {
3451                 return;
3452         }
3453
3454         tevent_req_done(req);
3455 }
3456
3457 NTSTATUS cli_full_connection_creds_recv(struct tevent_req *req,
3458                                   struct cli_state **output_cli)
3459 {
3460         struct cli_full_connection_creds_state *state = tevent_req_data(
3461                 req, struct cli_full_connection_creds_state);
3462         NTSTATUS status;
3463
3464         if (tevent_req_is_nterror(req, &status)) {
3465                 return status;
3466         }
3467         *output_cli = state->cli;
3468         talloc_set_destructor(state, NULL);
3469         return NT_STATUS_OK;
3470 }
3471
3472 NTSTATUS cli_full_connection_creds(struct cli_state **output_cli,
3473                                    const char *my_name,
3474                                    const char *dest_host,
3475                                    const struct sockaddr_storage *dest_ss, int port,
3476                                    const char *service, const char *service_type,
3477                                    struct cli_credentials *creds,
3478                                    int flags,
3479                                    int signing_state)
3480 {
3481         struct tevent_context *ev;
3482         struct tevent_req *req;
3483         NTSTATUS status = NT_STATUS_NO_MEMORY;
3484
3485         ev = samba_tevent_context_init(talloc_tos());
3486         if (ev == NULL) {
3487                 goto fail;
3488         }
3489         req = cli_full_connection_creds_send(
3490                 ev, ev, my_name, dest_host, dest_ss, port, service,
3491                 service_type, creds, flags, signing_state);
3492         if (req == NULL) {
3493                 goto fail;
3494         }
3495         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
3496                 goto fail;
3497         }
3498         status = cli_full_connection_creds_recv(req, output_cli);
3499  fail:
3500         TALLOC_FREE(ev);
3501         return status;
3502 }
3503
3504 NTSTATUS cli_full_connection(struct cli_state **output_cli,
3505                              const char *my_name,
3506                              const char *dest_host,
3507                              const struct sockaddr_storage *dest_ss, int port,
3508                              const char *service, const char *service_type,
3509                              const char *user, const char *domain,
3510                              const char *password, int flags,
3511                              int signing_state)
3512 {
3513         TALLOC_CTX *frame = talloc_stackframe();
3514         NTSTATUS status;
3515         bool use_kerberos = false;
3516         bool fallback_after_kerberos = false;
3517         bool use_ccache = false;
3518         bool pw_nt_hash = false;
3519         struct cli_credentials *creds = NULL;
3520
3521         if (flags & CLI_FULL_CONNECTION_USE_KERBEROS) {
3522                 use_kerberos = true;
3523         }
3524
3525         if (flags & CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS) {
3526                 fallback_after_kerberos = true;
3527         }
3528
3529         if (flags & CLI_FULL_CONNECTION_USE_CCACHE) {
3530                 use_ccache = true;
3531         }
3532
3533         if (flags & CLI_FULL_CONNECTION_USE_NT_HASH) {
3534                 pw_nt_hash = true;
3535         }
3536
3537         creds = cli_session_creds_init(frame,
3538                                        user,
3539                                        domain,
3540                                        NULL, /* realm (use default) */
3541                                        password,
3542                                        use_kerberos,
3543                                        fallback_after_kerberos,
3544                                        use_ccache,
3545                                        pw_nt_hash);
3546         if (creds == NULL) {
3547                 TALLOC_FREE(frame);
3548                 return NT_STATUS_NO_MEMORY;
3549         }
3550
3551         status = cli_full_connection_creds(output_cli, my_name,
3552                                            dest_host, dest_ss, port,
3553                                            service, service_type,
3554                                            creds, flags, signing_state);
3555         if (!NT_STATUS_IS_OK(status)) {
3556                 TALLOC_FREE(frame);
3557                 return status;
3558         }
3559
3560         TALLOC_FREE(frame);
3561         return NT_STATUS_OK;
3562 }
3563
3564 /****************************************************************************
3565  Send an old style tcon.
3566 ****************************************************************************/
3567 struct cli_raw_tcon_state {
3568         uint16_t *ret_vwv;
3569 };
3570
3571 static void cli_raw_tcon_done(struct tevent_req *subreq);
3572
3573 static struct tevent_req *cli_raw_tcon_send(
3574         TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
3575         const char *service, const char *pass, const char *dev)
3576 {
3577         struct tevent_req *req, *subreq;
3578         struct cli_raw_tcon_state *state;
3579         uint8_t *bytes;
3580
3581         req = tevent_req_create(mem_ctx, &state, struct cli_raw_tcon_state);
3582         if (req == NULL) {
3583                 return NULL;
3584         }
3585
3586         if (!lp_client_plaintext_auth() && (*pass)) {
3587                 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
3588                           " or 'client ntlmv2 auth = yes'\n"));
3589                 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
3590                 return tevent_req_post(req, ev);
3591         }
3592
3593         bytes = talloc_array(state, uint8_t, 0);
3594         bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3595         bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3596                                    service, strlen(service)+1, NULL);
3597         bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3598         bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3599                                    pass, strlen(pass)+1, NULL);
3600         bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3601         bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3602                                    dev, strlen(dev)+1, NULL);
3603
3604         if (tevent_req_nomem(bytes, req)) {
3605                 return tevent_req_post(req, ev);
3606         }
3607
3608         subreq = cli_smb_send(state, ev, cli, SMBtcon, 0, 0, 0, NULL,
3609                               talloc_get_size(bytes), bytes);
3610         if (tevent_req_nomem(subreq, req)) {
3611                 return tevent_req_post(req, ev);
3612         }
3613         tevent_req_set_callback(subreq, cli_raw_tcon_done, req);
3614         return req;
3615 }
3616
3617 static void cli_raw_tcon_done(struct tevent_req *subreq)
3618 {
3619         struct tevent_req *req = tevent_req_callback_data(
3620                 subreq, struct tevent_req);
3621         struct cli_raw_tcon_state *state = tevent_req_data(
3622                 req, struct cli_raw_tcon_state);
3623         NTSTATUS status;
3624
3625         status = cli_smb_recv(subreq, state, NULL, 2, NULL, &state->ret_vwv,
3626                               NULL, NULL);
3627         TALLOC_FREE(subreq);
3628         if (tevent_req_nterror(req, status)) {
3629                 return;
3630         }
3631         tevent_req_done(req);
3632 }
3633
3634 static NTSTATUS cli_raw_tcon_recv(struct tevent_req *req,
3635                                   uint16_t *max_xmit, uint16_t *tid)
3636 {
3637         struct cli_raw_tcon_state *state = tevent_req_data(
3638                 req, struct cli_raw_tcon_state);
3639         NTSTATUS status;
3640
3641         if (tevent_req_is_nterror(req, &status)) {
3642                 return status;
3643         }
3644         *max_xmit = SVAL(state->ret_vwv + 0, 0);
3645         *tid = SVAL(state->ret_vwv + 1, 0);
3646         return NT_STATUS_OK;
3647 }
3648
3649 NTSTATUS cli_raw_tcon(struct cli_state *cli,
3650                       const char *service, const char *pass, const char *dev,
3651                       uint16_t *max_xmit, uint16_t *tid)
3652 {
3653         struct tevent_context *ev;
3654         struct tevent_req *req;
3655         NTSTATUS status = NT_STATUS_NO_MEMORY;
3656
3657         ev = samba_tevent_context_init(talloc_tos());
3658         if (ev == NULL) {
3659                 goto fail;
3660         }
3661         req = cli_raw_tcon_send(ev, ev, cli, service, pass, dev);
3662         if (req == NULL) {
3663                 goto fail;
3664         }
3665         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
3666                 goto fail;
3667         }
3668         status = cli_raw_tcon_recv(req, max_xmit, tid);
3669 fail:
3670         TALLOC_FREE(ev);
3671         return status;
3672 }
3673
3674 /* Return a cli_state pointing at the IPC$ share for the given server */
3675
3676 struct cli_state *get_ipc_connect(char *server,
3677                                 struct sockaddr_storage *server_ss,
3678                                 const struct user_auth_info *user_info)
3679 {
3680         struct cli_state *cli;
3681         NTSTATUS nt_status;
3682         uint32_t flags = CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
3683
3684         if (get_cmdline_auth_info_use_kerberos(user_info)) {
3685                 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
3686         }
3687
3688         nt_status = cli_full_connection(&cli, NULL, server, server_ss, 0, "IPC$", "IPC", 
3689                                         get_cmdline_auth_info_username(user_info),
3690                                         lp_workgroup(),
3691                                         get_cmdline_auth_info_password(user_info),
3692                                         flags,
3693                                         SMB_SIGNING_DEFAULT);
3694
3695         if (NT_STATUS_IS_OK(nt_status)) {
3696                 return cli;
3697         } else if (is_ipaddress(server)) {
3698             /* windows 9* needs a correct NMB name for connections */
3699             fstring remote_name;
3700
3701             if (name_status_find("*", 0, 0, server_ss, remote_name)) {
3702                 cli = get_ipc_connect(remote_name, server_ss, user_info);
3703                 if (cli)
3704                     return cli;
3705             }
3706         }
3707         return NULL;
3708 }
3709
3710 /*
3711  * Given the IP address of a master browser on the network, return its
3712  * workgroup and connect to it.
3713  *
3714  * This function is provided to allow additional processing beyond what
3715  * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
3716  * browsers and obtain each master browsers' list of domains (in case the
3717  * first master browser is recently on the network and has not yet
3718  * synchronized with other master browsers and therefore does not yet have the
3719  * entire network browse list)
3720  */
3721
3722 struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx,
3723                                 struct sockaddr_storage *mb_ip,
3724                                 const struct user_auth_info *user_info,
3725                                 char **pp_workgroup_out)
3726 {
3727         char addr[INET6_ADDRSTRLEN];
3728         fstring name;
3729         struct cli_state *cli;
3730         struct sockaddr_storage server_ss;
3731
3732         *pp_workgroup_out = NULL;
3733
3734         print_sockaddr(addr, sizeof(addr), mb_ip);
3735         DEBUG(99, ("Looking up name of master browser %s\n",
3736                    addr));
3737
3738         /*
3739          * Do a name status query to find out the name of the master browser.
3740          * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
3741          * master browser will not respond to a wildcard query (or, at least,
3742          * an NT4 server acting as the domain master browser will not).
3743          *
3744          * We might be able to use ONLY the query on MSBROWSE, but that's not
3745          * yet been tested with all Windows versions, so until it is, leave
3746          * the original wildcard query as the first choice and fall back to
3747          * MSBROWSE if the wildcard query fails.
3748          */
3749         if (!name_status_find("*", 0, 0x1d, mb_ip, name) &&
3750             !name_status_find(MSBROWSE, 1, 0x1d, mb_ip, name)) {
3751
3752                 DEBUG(99, ("Could not retrieve name status for %s\n",
3753                            addr));
3754                 return NULL;
3755         }
3756
3757         if (!find_master_ip(name, &server_ss)) {
3758                 DEBUG(99, ("Could not find master ip for %s\n", name));
3759                 return NULL;
3760         }
3761
3762         *pp_workgroup_out = talloc_strdup(ctx, name);
3763
3764         DEBUG(4, ("found master browser %s, %s\n", name, addr));
3765
3766         print_sockaddr(addr, sizeof(addr), &server_ss);
3767         cli = get_ipc_connect(addr, &server_ss, user_info);
3768
3769         return cli;
3770 }
3771
3772 /*
3773  * Return the IP address and workgroup of a master browser on the network, and
3774  * connect to it.
3775  */
3776
3777 struct cli_state *get_ipc_connect_master_ip_bcast(TALLOC_CTX *ctx,
3778                                         const struct user_auth_info *user_info,
3779                                         char **pp_workgroup_out)
3780 {
3781         struct sockaddr_storage *ip_list;
3782         struct cli_state *cli;
3783         int i, count;
3784         NTSTATUS status;
3785
3786         *pp_workgroup_out = NULL;
3787
3788         DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
3789
3790         /* Go looking for workgroups by broadcasting on the local network */
3791
3792         status = name_resolve_bcast(MSBROWSE, 1, talloc_tos(),
3793                                     &ip_list, &count);
3794         if (!NT_STATUS_IS_OK(status)) {
3795                 DEBUG(99, ("No master browsers responded: %s\n",
3796                            nt_errstr(status)));
3797                 return NULL;
3798         }
3799
3800         for (i = 0; i < count; i++) {
3801                 char addr[INET6_ADDRSTRLEN];
3802                 print_sockaddr(addr, sizeof(addr), &ip_list[i]);
3803                 DEBUG(99, ("Found master browser %s\n", addr));
3804
3805                 cli = get_ipc_connect_master_ip(ctx, &ip_list[i],
3806                                 user_info, pp_workgroup_out);
3807                 if (cli)
3808                         return(cli);
3809         }
3810
3811         return NULL;
3812 }