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