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