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