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