s3:libsmb: don't use gensec_ntlmssp_server_domain()
[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         NTSTATUS status;
1246
1247         if (state->blob_in.length != 0) {
1248                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1249                 return;
1250         }
1251
1252         if (state->blob_out.length != 0) {
1253                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1254                 return;
1255         }
1256
1257         if (state->is_anonymous) {
1258                 /*
1259                  * Windows server does not set the
1260                  * SMB2_SESSION_FLAG_IS_NULL flag.
1261                  *
1262                  * This fix makes sure we do not try
1263                  * to verify a signature on the final
1264                  * session setup response.
1265                  */
1266                 tevent_req_done(req);
1267                 return;
1268         }
1269
1270         status = gensec_session_key(state->auth_generic->gensec_security,
1271                                     state, &state->session_key);
1272         if (tevent_req_nterror(req, status)) {
1273                 return;
1274         }
1275
1276         if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
1277                 struct smbXcli_session *session = state->cli->smb2.session;
1278
1279                 status = smb2cli_session_set_session_key(session,
1280                                                          state->session_key,
1281                                                          state->recv_iov);
1282                 if (tevent_req_nterror(req, status)) {
1283                         return;
1284                 }
1285                 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB3_00
1286                     && lp_debug_encryption())
1287                 {
1288                         cli_session_dump_keys(state, session, state->session_key);
1289                 }
1290         } else {
1291                 struct smbXcli_session *session = state->cli->smb1.session;
1292                 bool active;
1293
1294                 status = smb1cli_session_set_session_key(session,
1295                                                          state->session_key);
1296                 if (tevent_req_nterror(req, status)) {
1297                         return;
1298                 }
1299
1300                 active = smb1cli_conn_activate_signing(state->cli->conn,
1301                                                        state->session_key,
1302                                                        data_blob_null);
1303                 if (active) {
1304                         bool ok;
1305
1306                         ok = smb1cli_conn_check_signing(state->cli->conn,
1307                                                         state->inbuf, 1);
1308                         if (!ok) {
1309                                 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1310                                 return;
1311                         }
1312                 }
1313         }
1314
1315         tevent_req_done(req);
1316 }
1317
1318 static NTSTATUS cli_session_setup_gensec_recv(struct tevent_req *req)
1319 {
1320         struct cli_session_setup_gensec_state *state =
1321                 tevent_req_data(req,
1322                 struct cli_session_setup_gensec_state);
1323         NTSTATUS status;
1324
1325         if (tevent_req_is_nterror(req, &status)) {
1326                 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
1327                 return status;
1328         }
1329         return NT_STATUS_OK;
1330 }
1331
1332 static char *cli_session_setup_get_account(TALLOC_CTX *mem_ctx,
1333                                            const char *principal)
1334 {
1335         char *account, *p;
1336
1337         account = talloc_strdup(mem_ctx, principal);
1338         if (account == NULL) {
1339                 return NULL;
1340         }
1341         p = strchr_m(account, '@');
1342         if (p != NULL) {
1343                 *p = '\0';
1344         }
1345         return account;
1346 }
1347
1348 /****************************************************************************
1349  Do a spnego encrypted session setup.
1350
1351  user_domain: The shortname of the domain the user/machine is a member of.
1352  dest_realm: The realm we're connecting to, if NULL we use our default realm.
1353 ****************************************************************************/
1354
1355 struct cli_session_setup_spnego_state {
1356         ADS_STATUS result;
1357 };
1358
1359 static void cli_session_setup_spnego_done(struct tevent_req *subreq);
1360
1361 static struct tevent_req *cli_session_setup_spnego_send(
1362         TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
1363         struct cli_credentials *creds)
1364 {
1365         struct tevent_req *req, *subreq;
1366         struct cli_session_setup_spnego_state *state;
1367         const char *target_service = NULL;
1368         const char *target_hostname = NULL;
1369         NTSTATUS status;
1370
1371         req = tevent_req_create(mem_ctx, &state,
1372                                 struct cli_session_setup_spnego_state);
1373         if (req == NULL) {
1374                 return NULL;
1375         }
1376
1377         target_service = "cifs";
1378         target_hostname = smbXcli_conn_remote_name(cli->conn);
1379
1380         status = cli_session_creds_prepare_krb5(cli, creds);
1381         if (tevent_req_nterror(req, status)) {
1382                 return tevent_req_post(req, ev);
1383         }
1384
1385         subreq = cli_session_setup_gensec_send(state, ev, cli, creds,
1386                                                target_service, target_hostname);
1387         if (tevent_req_nomem(subreq, req)) {
1388                 return tevent_req_post(req, ev);
1389         }
1390         tevent_req_set_callback(
1391                 subreq, cli_session_setup_spnego_done, req);
1392         return req;
1393 }
1394
1395 static void cli_session_setup_spnego_done(struct tevent_req *subreq)
1396 {
1397         struct tevent_req *req = tevent_req_callback_data(
1398                 subreq, struct tevent_req);
1399         NTSTATUS status;
1400
1401         status = cli_session_setup_gensec_recv(subreq);
1402         TALLOC_FREE(subreq);
1403         if (tevent_req_nterror(req, status)) {
1404                 return;
1405         }
1406
1407         tevent_req_done(req);
1408 }
1409
1410 static ADS_STATUS cli_session_setup_spnego_recv(struct tevent_req *req)
1411 {
1412         struct cli_session_setup_spnego_state *state = tevent_req_data(
1413                 req, struct cli_session_setup_spnego_state);
1414         NTSTATUS status;
1415
1416         if (tevent_req_is_nterror(req, &status)) {
1417                 state->result = ADS_ERROR_NT(status);
1418         }
1419
1420         return state->result;
1421 }
1422
1423 struct cli_session_setup_creds_state {
1424         struct cli_state *cli;
1425         DATA_BLOB apassword_blob;
1426         DATA_BLOB upassword_blob;
1427         DATA_BLOB lm_session_key;
1428         DATA_BLOB session_key;
1429         char *out_native_os;
1430         char *out_native_lm;
1431         char *out_primary_domain;
1432 };
1433
1434 static void cli_session_setup_creds_cleanup(struct tevent_req *req,
1435                                             enum tevent_req_state req_state)
1436 {
1437         struct cli_session_setup_creds_state *state = tevent_req_data(
1438                 req, struct cli_session_setup_creds_state);
1439
1440         if (req_state != TEVENT_REQ_RECEIVED) {
1441                 return;
1442         }
1443
1444         /*
1445          * We only call data_blob_clear() as
1446          * some of the blobs point to the same memory.
1447          *
1448          * We let the talloc hierachy free the memory.
1449          */
1450         data_blob_clear(&state->apassword_blob);
1451         data_blob_clear(&state->upassword_blob);
1452         data_blob_clear(&state->lm_session_key);
1453         data_blob_clear(&state->session_key);
1454         ZERO_STRUCTP(state);
1455 }
1456
1457 static void cli_session_setup_creds_done_spnego(struct tevent_req *subreq);
1458 static void cli_session_setup_creds_done_nt1(struct tevent_req *subreq);
1459 static void cli_session_setup_creds_done_lm21(struct tevent_req *subreq);
1460
1461 /****************************************************************************
1462  Send a session setup. The username and workgroup is in UNIX character
1463  format and must be converted to DOS codepage format before sending. If the
1464  password is in plaintext, the same should be done.
1465 ****************************************************************************/
1466
1467 struct tevent_req *cli_session_setup_creds_send(TALLOC_CTX *mem_ctx,
1468                                         struct tevent_context *ev,
1469                                         struct cli_state *cli,
1470                                         struct cli_credentials *creds)
1471 {
1472         struct tevent_req *req, *subreq;
1473         struct cli_session_setup_creds_state *state;
1474         uint16_t sec_mode = smb1cli_conn_server_security_mode(cli->conn);
1475         bool use_spnego = false;
1476         int flags = 0;
1477         enum credentials_use_kerberos krb5_state;
1478         uint32_t gensec_features;
1479         const char *username = "";
1480         const char *domain = "";
1481         DATA_BLOB target_info = data_blob_null;
1482         DATA_BLOB challenge = data_blob_null;
1483         uint16_t in_buf_size = 0;
1484         uint16_t in_mpx_max = 0;
1485         uint16_t in_vc_num = 0;
1486         uint32_t in_sess_key = 0;
1487         const char *in_native_os = NULL;
1488         const char *in_native_lm = NULL;
1489         NTSTATUS status;
1490
1491         req = tevent_req_create(mem_ctx, &state,
1492                                 struct cli_session_setup_creds_state);
1493         if (req == NULL) {
1494                 return NULL;
1495         }
1496         state->cli = cli;
1497
1498         tevent_req_set_cleanup_fn(req, cli_session_setup_creds_cleanup);
1499
1500         krb5_state = cli_credentials_get_kerberos_state(creds);
1501         gensec_features = cli_credentials_get_gensec_features(creds);
1502
1503         switch (krb5_state) {
1504         case CRED_MUST_USE_KERBEROS:
1505                 cli->use_kerberos = true;
1506                 cli->fallback_after_kerberos = false;
1507                 break;
1508         case CRED_AUTO_USE_KERBEROS:
1509                 cli->use_kerberos = true;
1510                 cli->fallback_after_kerberos = true;
1511                 break;
1512         case CRED_DONT_USE_KERBEROS:
1513                 cli->use_kerberos = false;
1514                 cli->fallback_after_kerberos = false;
1515                 break;
1516         }
1517
1518         if (gensec_features & GENSEC_FEATURE_NTLM_CCACHE) {
1519                 cli->use_ccache = true;
1520         } else {
1521                 cli->use_ccache = false;
1522         }
1523
1524         /*
1525          * Now work out what sort of session setup we are going to
1526          * do. I have split this into separate functions to make the flow a bit
1527          * easier to understand (tridge).
1528          */
1529         if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_NT1) {
1530                 use_spnego = false;
1531         } else if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
1532                 use_spnego = true;
1533         } else if (smb1cli_conn_capabilities(cli->conn) & CAP_EXTENDED_SECURITY) {
1534                 /*
1535                  * if the server supports extended security then use SPNEGO
1536                  * even for anonymous connections.
1537                  */
1538                 use_spnego = true;
1539         } else {
1540                 use_spnego = false;
1541         }
1542
1543         if (use_spnego) {
1544                 subreq = cli_session_setup_spnego_send(
1545                         state, ev, cli, creds);
1546                 if (tevent_req_nomem(subreq, req)) {
1547                         return tevent_req_post(req, ev);
1548                 }
1549                 tevent_req_set_callback(subreq, cli_session_setup_creds_done_spnego,
1550                                         req);
1551                 return req;
1552         }
1553
1554         if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_LANMAN1) {
1555                 /*
1556                  * SessionSetupAndX was introduced by LANMAN 1.0. So we skip
1557                  * this step against older servers.
1558                  */
1559                 tevent_req_done(req);
1560                 return tevent_req_post(req, ev);
1561         }
1562
1563         if (cli_credentials_is_anonymous(creds)) {
1564                 /*
1565                  * Do an anonymous session setup
1566                  */
1567                 goto non_spnego_creds_done;
1568         }
1569
1570         if ((sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0) {
1571                 /*
1572                  * Do an anonymous session setup,
1573                  * the password is passed via the tree connect.
1574                  */
1575                 goto non_spnego_creds_done;
1576         }
1577
1578         cli_credentials_get_ntlm_username_domain(creds, state,
1579                                                  &username,
1580                                                  &domain);
1581         if (tevent_req_nomem(username, req)) {
1582                 return tevent_req_post(req, ev);
1583         }
1584         if (tevent_req_nomem(domain, req)) {
1585                 return tevent_req_post(req, ev);
1586         }
1587
1588         if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) {
1589                 bool use_unicode = smbXcli_conn_use_unicode(cli->conn);
1590                 uint8_t *bytes = NULL;
1591                 size_t bytes_len = 0;
1592                 const char *pw = cli_credentials_get_password(creds);
1593                 size_t pw_len = 0;
1594
1595                 if (pw == NULL) {
1596                         pw = "";
1597                 }
1598                 pw_len = strlen(pw) + 1;
1599
1600                 if (!lp_client_plaintext_auth()) {
1601                         DEBUG(1, ("Server requested PLAINTEXT password but "
1602                                   "'client plaintext auth = no'\n"));
1603                         tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1604                         return tevent_req_post(req, ev);
1605                 }
1606
1607                 bytes = talloc_array(state, uint8_t, 0);
1608                 bytes = trans2_bytes_push_str(bytes, use_unicode,
1609                                               pw, pw_len, &bytes_len);
1610                 if (tevent_req_nomem(bytes, req)) {
1611                         return tevent_req_post(req, ev);
1612                 }
1613
1614                 if (use_unicode) {
1615                         /*
1616                          * CAP_UNICODE, can only be negotiated by NT1.
1617                          */
1618                         state->upassword_blob = data_blob_const(bytes,
1619                                                                 bytes_len);
1620                 } else {
1621                         state->apassword_blob = data_blob_const(bytes,
1622                                                                 bytes_len);
1623                 }
1624
1625                 goto non_spnego_creds_done;
1626         }
1627
1628         challenge = data_blob_const(smb1cli_conn_server_challenge(cli->conn), 8);
1629
1630         if (smbXcli_conn_protocol(cli->conn) == PROTOCOL_NT1) {
1631                 if (lp_client_ntlmv2_auth() && lp_client_use_spnego()) {
1632                         /*
1633                          * Don't send an NTLMv2 response without NTLMSSP if we
1634                          * want to use spnego support.
1635                          */
1636                         DEBUG(1, ("Server does not support EXTENDED_SECURITY "
1637                                   " but 'client use spnego = yes'"
1638                                   " and 'client ntlmv2 auth = yes' is set\n"));
1639                         tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1640                         return tevent_req_post(req, ev);
1641                 }
1642
1643                 if (lp_client_ntlmv2_auth()) {
1644                         flags |= CLI_CRED_NTLMv2_AUTH;
1645
1646                         /*
1647                          * note that the 'domain' here is a best
1648                          * guess - we don't know the server's domain
1649                          * at this point. Windows clients also don't
1650                          * use hostname...
1651                          */
1652                         target_info = NTLMv2_generate_names_blob(state,
1653                                                                  NULL,
1654                                                                  domain);
1655                         if (tevent_req_nomem(target_info.data, req)) {
1656                                 return tevent_req_post(req, ev);
1657                         }
1658                 } else {
1659                         flags |= CLI_CRED_NTLM_AUTH;
1660                         if (lp_client_lanman_auth()) {
1661                                 flags |= CLI_CRED_LANMAN_AUTH;
1662                         }
1663                 }
1664         } else {
1665                 if (!lp_client_lanman_auth()) {
1666                         DEBUG(1, ("Server requested user level LM password but "
1667                                   "'client lanman auth = no' is set.\n"));
1668                         tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1669                         return tevent_req_post(req, ev);
1670                 }
1671
1672                 flags |= CLI_CRED_LANMAN_AUTH;
1673         }
1674
1675         status = cli_credentials_get_ntlm_response(creds, state, &flags,
1676                                                    challenge, NULL,
1677                                                    target_info,
1678                                                    &state->apassword_blob,
1679                                                    &state->upassword_blob,
1680                                                    &state->lm_session_key,
1681                                                    &state->session_key);
1682         if (tevent_req_nterror(req, status)) {
1683                 return tevent_req_post(req, ev);
1684         }
1685
1686 non_spnego_creds_done:
1687
1688         in_buf_size = CLI_BUFFER_SIZE;
1689         in_mpx_max = smbXcli_conn_max_requests(cli->conn);
1690         in_vc_num = cli_state_get_vc_num(cli);
1691         in_sess_key = smb1cli_conn_server_session_key(cli->conn);
1692         in_native_os = "Unix";
1693         in_native_lm = "Samba";
1694
1695         if (smbXcli_conn_protocol(cli->conn) == PROTOCOL_NT1) {
1696                 uint32_t in_capabilities = 0;
1697
1698                 in_capabilities = cli_session_setup_capabilities(cli, 0);
1699
1700                 /*
1701                  * For now we keep the same values as before,
1702                  * we may remove these in a separate commit later.
1703                  */
1704                 in_mpx_max = 2;
1705
1706                 subreq = smb1cli_session_setup_nt1_send(state, ev,
1707                                                         cli->conn,
1708                                                         cli->timeout,
1709                                                         cli->smb1.pid,
1710                                                         cli->smb1.session,
1711                                                         in_buf_size,
1712                                                         in_mpx_max,
1713                                                         in_vc_num,
1714                                                         in_sess_key,
1715                                                         username,
1716                                                         domain,
1717                                                         state->apassword_blob,
1718                                                         state->upassword_blob,
1719                                                         in_capabilities,
1720                                                         in_native_os,
1721                                                         in_native_lm);
1722                 if (tevent_req_nomem(subreq, req)) {
1723                         return tevent_req_post(req, ev);
1724                 }
1725                 tevent_req_set_callback(subreq, cli_session_setup_creds_done_nt1,
1726                                         req);
1727                 return req;
1728         }
1729
1730         /*
1731          * For now we keep the same values as before,
1732          * we may remove these in a separate commit later.
1733          */
1734         in_mpx_max = 2;
1735         in_vc_num = 1;
1736
1737         subreq = smb1cli_session_setup_lm21_send(state, ev,
1738                                                  cli->conn,
1739                                                  cli->timeout,
1740                                                  cli->smb1.pid,
1741                                                  cli->smb1.session,
1742                                                  in_buf_size,
1743                                                  in_mpx_max,
1744                                                  in_vc_num,
1745                                                  in_sess_key,
1746                                                  username,
1747                                                  domain,
1748                                                  state->apassword_blob,
1749                                                  in_native_os,
1750                                                  in_native_lm);
1751         if (tevent_req_nomem(subreq, req)) {
1752                 return tevent_req_post(req, ev);
1753         }
1754         tevent_req_set_callback(subreq, cli_session_setup_creds_done_lm21,
1755                                 req);
1756         return req;
1757 }
1758
1759 static void cli_session_setup_creds_done_spnego(struct tevent_req *subreq)
1760 {
1761         struct tevent_req *req = tevent_req_callback_data(
1762                 subreq, struct tevent_req);
1763         ADS_STATUS status;
1764
1765         status = cli_session_setup_spnego_recv(subreq);
1766         TALLOC_FREE(subreq);
1767         if (!ADS_ERR_OK(status)) {
1768                 DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status)));
1769                 tevent_req_nterror(req, ads_ntstatus(status));
1770                 return;
1771         }
1772         tevent_req_done(req);
1773 }
1774
1775 static void cli_session_setup_creds_done_nt1(struct tevent_req *subreq)
1776 {
1777         struct tevent_req *req = tevent_req_callback_data(
1778                 subreq, struct tevent_req);
1779         struct cli_session_setup_creds_state *state = tevent_req_data(
1780                 req, struct cli_session_setup_creds_state);
1781         struct cli_state *cli = state->cli;
1782         NTSTATUS status;
1783         struct iovec *recv_iov = NULL;
1784         const uint8_t *inbuf = NULL;
1785         bool ok;
1786
1787         status = smb1cli_session_setup_nt1_recv(subreq, state,
1788                                                 &recv_iov,
1789                                                 &inbuf,
1790                                                 &state->out_native_os,
1791                                                 &state->out_native_lm,
1792                                                 &state->out_primary_domain);
1793         TALLOC_FREE(subreq);
1794         if (!NT_STATUS_IS_OK(status)) {
1795                 DEBUG(3, ("NT1 login failed: %s\n", nt_errstr(status)));
1796                 tevent_req_nterror(req, status);
1797                 return;
1798         }
1799
1800         status = cli_state_update_after_sesssetup(state->cli,
1801                                                   state->out_native_os,
1802                                                   state->out_native_lm,
1803                                                   state->out_primary_domain);
1804         if (tevent_req_nterror(req, status)) {
1805                 return;
1806         }
1807
1808         ok = smb1cli_conn_activate_signing(cli->conn,
1809                                            state->session_key,
1810                                            state->upassword_blob);
1811         if (ok) {
1812                 ok = smb1cli_conn_check_signing(cli->conn, inbuf, 1);
1813                 if (!ok) {
1814                         tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1815                         return;
1816                 }
1817         }
1818
1819         if (state->session_key.data) {
1820                 struct smbXcli_session *session = cli->smb1.session;
1821
1822                 status = smb1cli_session_set_session_key(session,
1823                                                          state->session_key);
1824                 if (tevent_req_nterror(req, status)) {
1825                         return;
1826                 }
1827         }
1828
1829         tevent_req_done(req);
1830 }
1831
1832 static void cli_session_setup_creds_done_lm21(struct tevent_req *subreq)
1833 {
1834         struct tevent_req *req = tevent_req_callback_data(
1835                 subreq, struct tevent_req);
1836         struct cli_session_setup_creds_state *state = tevent_req_data(
1837                 req, struct cli_session_setup_creds_state);
1838         NTSTATUS status;
1839
1840         status = smb1cli_session_setup_lm21_recv(subreq, state,
1841                                                  &state->out_native_os,
1842                                                  &state->out_native_lm);
1843         TALLOC_FREE(subreq);
1844         if (!NT_STATUS_IS_OK(status)) {
1845                 DEBUG(3, ("LM21 login failed: %s\n", nt_errstr(status)));
1846                 tevent_req_nterror(req, status);
1847                 return;
1848         }
1849
1850         status = cli_state_update_after_sesssetup(state->cli,
1851                                                   state->out_native_os,
1852                                                   state->out_native_lm,
1853                                                   NULL);
1854         if (tevent_req_nterror(req, status)) {
1855                 return;
1856         }
1857
1858         tevent_req_done(req);
1859 }
1860
1861 NTSTATUS cli_session_setup_creds_recv(struct tevent_req *req)
1862 {
1863         return tevent_req_simple_recv_ntstatus(req);
1864 }
1865
1866 NTSTATUS cli_session_setup_creds(struct cli_state *cli,
1867                                  struct cli_credentials *creds)
1868 {
1869         struct tevent_context *ev;
1870         struct tevent_req *req;
1871         NTSTATUS status = NT_STATUS_NO_MEMORY;
1872
1873         if (smbXcli_conn_has_async_calls(cli->conn)) {
1874                 return NT_STATUS_INVALID_PARAMETER;
1875         }
1876         ev = samba_tevent_context_init(talloc_tos());
1877         if (ev == NULL) {
1878                 goto fail;
1879         }
1880         req = cli_session_setup_creds_send(ev, ev, cli, creds);
1881         if (req == NULL) {
1882                 goto fail;
1883         }
1884         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1885                 goto fail;
1886         }
1887         status = cli_session_setup_creds_recv(req);
1888  fail:
1889         TALLOC_FREE(ev);
1890         return status;
1891 }
1892
1893 NTSTATUS cli_session_setup_anon(struct cli_state *cli)
1894 {
1895         NTSTATUS status = NT_STATUS_NO_MEMORY;
1896         struct cli_credentials *creds = NULL;
1897
1898         creds = cli_credentials_init_anon(cli);
1899         if (creds == NULL) {
1900                 return NT_STATUS_NO_MEMORY;
1901         }
1902
1903         status = cli_session_setup_creds(cli, creds);
1904         TALLOC_FREE(creds);
1905         if (!NT_STATUS_IS_OK(status)) {
1906                 return status;
1907         }
1908
1909         return NT_STATUS_OK;
1910 }
1911
1912 /****************************************************************************
1913  Send a uloggoff.
1914 *****************************************************************************/
1915
1916 struct cli_ulogoff_state {
1917         struct cli_state *cli;
1918         uint16_t vwv[3];
1919 };
1920
1921 static void cli_ulogoff_done(struct tevent_req *subreq);
1922
1923 static struct tevent_req *cli_ulogoff_send(TALLOC_CTX *mem_ctx,
1924                                     struct tevent_context *ev,
1925                                     struct cli_state *cli)
1926 {
1927         struct tevent_req *req, *subreq;
1928         struct cli_ulogoff_state *state;
1929
1930         req = tevent_req_create(mem_ctx, &state, struct cli_ulogoff_state);
1931         if (req == NULL) {
1932                 return NULL;
1933         }
1934         state->cli = cli;
1935
1936         SCVAL(state->vwv+0, 0, 0xFF);
1937         SCVAL(state->vwv+1, 0, 0);
1938         SSVAL(state->vwv+2, 0, 0);
1939
1940         subreq = cli_smb_send(state, ev, cli, SMBulogoffX, 0, 0, 2, state->vwv,
1941                               0, NULL);
1942         if (tevent_req_nomem(subreq, req)) {
1943                 return tevent_req_post(req, ev);
1944         }
1945         tevent_req_set_callback(subreq, cli_ulogoff_done, req);
1946         return req;
1947 }
1948
1949 static void cli_ulogoff_done(struct tevent_req *subreq)
1950 {
1951         struct tevent_req *req = tevent_req_callback_data(
1952                 subreq, struct tevent_req);
1953         struct cli_ulogoff_state *state = tevent_req_data(
1954                 req, struct cli_ulogoff_state);
1955         NTSTATUS status;
1956
1957         status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
1958         if (!NT_STATUS_IS_OK(status)) {
1959                 tevent_req_nterror(req, status);
1960                 return;
1961         }
1962         cli_state_set_uid(state->cli, UID_FIELD_INVALID);
1963         tevent_req_done(req);
1964 }
1965
1966 static NTSTATUS cli_ulogoff_recv(struct tevent_req *req)
1967 {
1968         return tevent_req_simple_recv_ntstatus(req);
1969 }
1970
1971 NTSTATUS cli_ulogoff(struct cli_state *cli)
1972 {
1973         struct tevent_context *ev;
1974         struct tevent_req *req;
1975         NTSTATUS status = NT_STATUS_NO_MEMORY;
1976
1977         if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
1978                 status = smb2cli_logoff(cli->conn,
1979                                         cli->timeout,
1980                                         cli->smb2.session);
1981                 if (!NT_STATUS_IS_OK(status)) {
1982                         return status;
1983                 }
1984                 smb2cli_session_set_id_and_flags(cli->smb2.session,
1985                                                  UINT64_MAX, 0);
1986                 return NT_STATUS_OK;
1987         }
1988
1989         if (smbXcli_conn_has_async_calls(cli->conn)) {
1990                 return NT_STATUS_INVALID_PARAMETER;
1991         }
1992         ev = samba_tevent_context_init(talloc_tos());
1993         if (ev == NULL) {
1994                 goto fail;
1995         }
1996         req = cli_ulogoff_send(ev, ev, cli);
1997         if (req == NULL) {
1998                 goto fail;
1999         }
2000         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2001                 goto fail;
2002         }
2003         status = cli_ulogoff_recv(req);
2004 fail:
2005         TALLOC_FREE(ev);
2006         return status;
2007 }
2008
2009 /****************************************************************************
2010  Send a tconX.
2011 ****************************************************************************/
2012
2013 struct cli_tcon_andx_state {
2014         struct cli_state *cli;
2015         uint16_t vwv[4];
2016         struct iovec bytes;
2017 };
2018
2019 static void cli_tcon_andx_done(struct tevent_req *subreq);
2020
2021 struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx,
2022                                         struct tevent_context *ev,
2023                                         struct cli_state *cli,
2024                                         const char *share, const char *dev,
2025                                         const char *pass, int passlen,
2026                                         struct tevent_req **psmbreq)
2027 {
2028         struct tevent_req *req, *subreq;
2029         struct cli_tcon_andx_state *state;
2030         uint8_t p24[24];
2031         uint16_t *vwv;
2032         char *tmp = NULL;
2033         uint8_t *bytes;
2034         uint16_t sec_mode = smb1cli_conn_server_security_mode(cli->conn);
2035         uint16_t tcon_flags = 0;
2036
2037         *psmbreq = NULL;
2038
2039         req = tevent_req_create(mem_ctx, &state, struct cli_tcon_andx_state);
2040         if (req == NULL) {
2041                 return NULL;
2042         }
2043         state->cli = cli;
2044         vwv = state->vwv;
2045
2046         TALLOC_FREE(cli->smb1.tcon);
2047         cli->smb1.tcon = smbXcli_tcon_create(cli);
2048         if (tevent_req_nomem(cli->smb1.tcon, req)) {
2049                 return tevent_req_post(req, ev);
2050         }
2051         smb1cli_tcon_set_id(cli->smb1.tcon, UINT16_MAX);
2052
2053         cli->share = talloc_strdup(cli, share);
2054         if (!cli->share) {
2055                 return NULL;
2056         }
2057
2058         /* in user level security don't send a password now */
2059         if (sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {
2060                 passlen = 1;
2061                 pass = "";
2062         } else if (pass == NULL) {
2063                 DEBUG(1, ("Server not using user level security and no "
2064                           "password supplied.\n"));
2065                 goto access_denied;
2066         }
2067
2068         if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) &&
2069             *pass && passlen != 24) {
2070                 if (!lp_client_lanman_auth()) {
2071                         DEBUG(1, ("Server requested LANMAN password "
2072                                   "(share-level security) but "
2073                                   "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2074                         goto access_denied;
2075                 }
2076
2077                 /*
2078                  * Non-encrypted passwords - convert to DOS codepage before
2079                  * encryption.
2080                  */
2081                 SMBencrypt(pass, smb1cli_conn_server_challenge(cli->conn), p24);
2082                 passlen = 24;
2083                 pass = (const char *)p24;
2084         } else {
2085                 if((sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL
2086                                      |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE))
2087                    == 0) {
2088                         uint8_t *tmp_pass;
2089
2090                         if (!lp_client_plaintext_auth() && (*pass)) {
2091                                 DEBUG(1, ("Server requested PLAINTEXT "
2092                                           "password but "
2093                                           "'client plaintext auth = no' or 'client ntlmv2 auth = yes'\n"));
2094                                 goto access_denied;
2095                         }
2096
2097                         /*
2098                          * Non-encrypted passwords - convert to DOS codepage
2099                          * before using.
2100                          */
2101                         tmp_pass = talloc_array(talloc_tos(), uint8_t, 0);
2102                         if (tevent_req_nomem(tmp_pass, req)) {
2103                                 return tevent_req_post(req, ev);
2104                         }
2105                         tmp_pass = trans2_bytes_push_str(tmp_pass,
2106                                                          false, /* always DOS */
2107                                                          pass,
2108                                                          passlen,
2109                                                          NULL);
2110                         if (tevent_req_nomem(tmp_pass, req)) {
2111                                 return tevent_req_post(req, ev);
2112                         }
2113                         pass = (const char *)tmp_pass;
2114                         passlen = talloc_get_size(tmp_pass);
2115                 }
2116         }
2117
2118         tcon_flags |= TCONX_FLAG_EXTENDED_RESPONSE;
2119         tcon_flags |= TCONX_FLAG_EXTENDED_SIGNATURES;
2120
2121         SCVAL(vwv+0, 0, 0xFF);
2122         SCVAL(vwv+0, 1, 0);
2123         SSVAL(vwv+1, 0, 0);
2124         SSVAL(vwv+2, 0, tcon_flags);
2125         SSVAL(vwv+3, 0, passlen);
2126
2127         if (passlen && pass) {
2128                 bytes = (uint8_t *)talloc_memdup(state, pass, passlen);
2129         } else {
2130                 bytes = talloc_array(state, uint8_t, 0);
2131         }
2132
2133         /*
2134          * Add the sharename
2135          */
2136         tmp = talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
2137                                          smbXcli_conn_remote_name(cli->conn), share);
2138         if (tmp == NULL) {
2139                 TALLOC_FREE(req);
2140                 return NULL;
2141         }
2142         bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), tmp, strlen(tmp)+1,
2143                                    NULL);
2144         TALLOC_FREE(tmp);
2145
2146         /*
2147          * Add the devicetype
2148          */
2149         tmp = talloc_strdup_upper(talloc_tos(), dev);
2150         if (tmp == NULL) {
2151                 TALLOC_FREE(req);
2152                 return NULL;
2153         }
2154         bytes = smb_bytes_push_str(bytes, false, tmp, strlen(tmp)+1, NULL);
2155         TALLOC_FREE(tmp);
2156
2157         if (bytes == NULL) {
2158                 TALLOC_FREE(req);
2159                 return NULL;
2160         }
2161
2162         state->bytes.iov_base = (void *)bytes;
2163         state->bytes.iov_len = talloc_get_size(bytes);
2164
2165         subreq = cli_smb_req_create(state, ev, cli, SMBtconX, 0, 0, 4, vwv,
2166                                     1, &state->bytes);
2167         if (subreq == NULL) {
2168                 TALLOC_FREE(req);
2169                 return NULL;
2170         }
2171         tevent_req_set_callback(subreq, cli_tcon_andx_done, req);
2172         *psmbreq = subreq;
2173         return req;
2174
2175  access_denied:
2176         tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
2177         return tevent_req_post(req, ev);
2178 }
2179
2180 struct tevent_req *cli_tcon_andx_send(TALLOC_CTX *mem_ctx,
2181                                       struct tevent_context *ev,
2182                                       struct cli_state *cli,
2183                                       const char *share, const char *dev,
2184                                       const char *pass, int passlen)
2185 {
2186         struct tevent_req *req, *subreq;
2187         NTSTATUS status;
2188
2189         req = cli_tcon_andx_create(mem_ctx, ev, cli, share, dev, pass, passlen,
2190                                    &subreq);
2191         if (req == NULL) {
2192                 return NULL;
2193         }
2194         if (subreq == NULL) {
2195                 return req;
2196         }
2197         status = smb1cli_req_chain_submit(&subreq, 1);
2198         if (!NT_STATUS_IS_OK(status)) {
2199                 tevent_req_nterror(req, status);
2200                 return tevent_req_post(req, ev);
2201         }
2202         return req;
2203 }
2204
2205 static void cli_tcon_andx_done(struct tevent_req *subreq)
2206 {
2207         struct tevent_req *req = tevent_req_callback_data(
2208                 subreq, struct tevent_req);
2209         struct cli_tcon_andx_state *state = tevent_req_data(
2210                 req, struct cli_tcon_andx_state);
2211         struct cli_state *cli = state->cli;
2212         uint8_t *in;
2213         uint8_t *inhdr;
2214         uint8_t wct;
2215         uint16_t *vwv;
2216         uint32_t num_bytes;
2217         uint8_t *bytes;
2218         NTSTATUS status;
2219         uint16_t optional_support = 0;
2220
2221         status = cli_smb_recv(subreq, state, &in, 0, &wct, &vwv,
2222                               &num_bytes, &bytes);
2223         TALLOC_FREE(subreq);
2224         if (!NT_STATUS_IS_OK(status)) {
2225                 tevent_req_nterror(req, status);
2226                 return;
2227         }
2228
2229         inhdr = in + NBT_HDR_SIZE;
2230
2231         if (num_bytes) {
2232                 if (clistr_pull_talloc(cli,
2233                                 (const char *)inhdr,
2234                                 SVAL(inhdr, HDR_FLG2),
2235                                 &cli->dev,
2236                                 bytes,
2237                                 num_bytes,
2238                                 STR_TERMINATE|STR_ASCII) == -1) {
2239                         tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2240                         return;
2241                 }
2242         } else {
2243                 cli->dev = talloc_strdup(cli, "");
2244                 if (cli->dev == NULL) {
2245                         tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2246                         return;
2247                 }
2248         }
2249
2250         if ((smbXcli_conn_protocol(cli->conn) >= PROTOCOL_NT1) && (num_bytes == 3)) {
2251                 /* almost certainly win95 - enable bug fixes */
2252                 cli->win95 = True;
2253         }
2254
2255         /*
2256          * Make sure that we have the optional support 16-bit field. WCT > 2.
2257          * Avoids issues when connecting to Win9x boxes sharing files
2258          */
2259
2260         if ((wct > 2) && (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_LANMAN2)) {
2261                 optional_support = SVAL(vwv+2, 0);
2262         }
2263
2264         if (optional_support & SMB_EXTENDED_SIGNATURES) {
2265                 smb1cli_session_protect_session_key(cli->smb1.session);
2266         }
2267
2268         smb1cli_tcon_set_values(state->cli->smb1.tcon,
2269                                 SVAL(inhdr, HDR_TID),
2270                                 optional_support,
2271                                 0, /* maximal_access */
2272                                 0, /* guest_maximal_access */
2273                                 NULL, /* service */
2274                                 NULL); /* fs_type */
2275
2276         tevent_req_done(req);
2277 }
2278
2279 NTSTATUS cli_tcon_andx_recv(struct tevent_req *req)
2280 {
2281         return tevent_req_simple_recv_ntstatus(req);
2282 }
2283
2284 NTSTATUS cli_tcon_andx(struct cli_state *cli, const char *share,
2285                        const char *dev, const char *pass, int passlen)
2286 {
2287         TALLOC_CTX *frame = talloc_stackframe();
2288         struct tevent_context *ev;
2289         struct tevent_req *req;
2290         NTSTATUS status = NT_STATUS_NO_MEMORY;
2291
2292         if (smbXcli_conn_has_async_calls(cli->conn)) {
2293                 /*
2294                  * Can't use sync call while an async call is in flight
2295                  */
2296                 status = NT_STATUS_INVALID_PARAMETER;
2297                 goto fail;
2298         }
2299
2300         ev = samba_tevent_context_init(frame);
2301         if (ev == NULL) {
2302                 goto fail;
2303         }
2304
2305         req = cli_tcon_andx_send(frame, ev, cli, share, dev, pass, passlen);
2306         if (req == NULL) {
2307                 goto fail;
2308         }
2309
2310         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2311                 goto fail;
2312         }
2313
2314         status = cli_tcon_andx_recv(req);
2315  fail:
2316         TALLOC_FREE(frame);
2317         return status;
2318 }
2319
2320 struct cli_tree_connect_state {
2321         struct cli_state *cli;
2322 };
2323
2324 static struct tevent_req *cli_raw_tcon_send(
2325         TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
2326         const char *service, const char *pass, const char *dev);
2327 static NTSTATUS cli_raw_tcon_recv(struct tevent_req *req,
2328                                   uint16_t *max_xmit, uint16_t *tid);
2329
2330 static void cli_tree_connect_smb2_done(struct tevent_req *subreq);
2331 static void cli_tree_connect_andx_done(struct tevent_req *subreq);
2332 static void cli_tree_connect_raw_done(struct tevent_req *subreq);
2333
2334 static struct tevent_req *cli_tree_connect_send(
2335         TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
2336         const char *share, const char *dev, const char *pass)
2337 {
2338         struct tevent_req *req, *subreq;
2339         struct cli_tree_connect_state *state;
2340         int passlen;
2341
2342         if (pass == NULL) {
2343                 pass = "";
2344         }
2345         passlen = strlen(pass) + 1;
2346
2347         req = tevent_req_create(mem_ctx, &state,
2348                                 struct cli_tree_connect_state);
2349         if (req == NULL) {
2350                 return NULL;
2351         }
2352         state->cli = cli;
2353
2354         cli->share = talloc_strdup(cli, share);
2355         if (tevent_req_nomem(cli->share, req)) {
2356                 return tevent_req_post(req, ev);
2357         }
2358
2359         if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
2360                 char *unc;
2361
2362                 TALLOC_FREE(cli->smb2.tcon);
2363                 cli->smb2.tcon = smbXcli_tcon_create(cli);
2364                 if (tevent_req_nomem(cli->smb2.tcon, req)) {
2365                         return tevent_req_post(req, ev);
2366                 }
2367
2368                 unc = talloc_asprintf(state, "\\\\%s\\%s",
2369                                       smbXcli_conn_remote_name(cli->conn),
2370                                       share);
2371                 if (tevent_req_nomem(unc, req)) {
2372                         return tevent_req_post(req, ev);
2373                 }
2374
2375                 subreq = smb2cli_tcon_send(state, ev, cli->conn, cli->timeout,
2376                                            cli->smb2.session, cli->smb2.tcon,
2377                                            0, /* flags */
2378                                            unc);
2379                 if (tevent_req_nomem(subreq, req)) {
2380                         return tevent_req_post(req, ev);
2381                 }
2382                 tevent_req_set_callback(subreq, cli_tree_connect_smb2_done,
2383                                         req);
2384                 return req;
2385         }
2386
2387         if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_LANMAN1) {
2388                 subreq = cli_tcon_andx_send(state, ev, cli, share, dev,
2389                                             pass, passlen);
2390                 if (tevent_req_nomem(subreq, req)) {
2391                         return tevent_req_post(req, ev);
2392                 }
2393                 tevent_req_set_callback(subreq, cli_tree_connect_andx_done,
2394                                         req);
2395                 return req;
2396         }
2397
2398         subreq = cli_raw_tcon_send(state, ev, cli, share, pass, dev);
2399         if (tevent_req_nomem(subreq, req)) {
2400                 return tevent_req_post(req, ev);
2401         }
2402         tevent_req_set_callback(subreq, cli_tree_connect_raw_done, req);
2403
2404         return req;
2405 }
2406
2407 static void cli_tree_connect_smb2_done(struct tevent_req *subreq)
2408 {
2409         tevent_req_simple_finish_ntstatus(
2410                 subreq, smb2cli_tcon_recv(subreq));
2411 }
2412
2413 static void cli_tree_connect_andx_done(struct tevent_req *subreq)
2414 {
2415         tevent_req_simple_finish_ntstatus(
2416                 subreq, cli_tcon_andx_recv(subreq));
2417 }
2418
2419 static void cli_tree_connect_raw_done(struct tevent_req *subreq)
2420 {
2421         struct tevent_req *req = tevent_req_callback_data(
2422                 subreq, struct tevent_req);
2423         struct cli_tree_connect_state *state = tevent_req_data(
2424                 req, struct cli_tree_connect_state);
2425         NTSTATUS status;
2426         uint16_t max_xmit = 0;
2427         uint16_t tid = 0;
2428
2429         status = cli_raw_tcon_recv(subreq, &max_xmit, &tid);
2430         if (tevent_req_nterror(req, status)) {
2431                 return;
2432         }
2433
2434         smb1cli_tcon_set_values(state->cli->smb1.tcon,
2435                                 tid,
2436                                 0, /* optional_support */
2437                                 0, /* maximal_access */
2438                                 0, /* guest_maximal_access */
2439                                 NULL, /* service */
2440                                 NULL); /* fs_type */
2441
2442         tevent_req_done(req);
2443 }
2444
2445 static NTSTATUS cli_tree_connect_recv(struct tevent_req *req)
2446 {
2447         return tevent_req_simple_recv_ntstatus(req);
2448 }
2449
2450 NTSTATUS cli_tree_connect(struct cli_state *cli, const char *share,
2451                           const char *dev, const char *pass)
2452 {
2453         struct tevent_context *ev;
2454         struct tevent_req *req;
2455         NTSTATUS status = NT_STATUS_NO_MEMORY;
2456
2457         if (smbXcli_conn_has_async_calls(cli->conn)) {
2458                 return NT_STATUS_INVALID_PARAMETER;
2459         }
2460         ev = samba_tevent_context_init(talloc_tos());
2461         if (ev == NULL) {
2462                 goto fail;
2463         }
2464         req = cli_tree_connect_send(ev, ev, cli, share, dev, pass);
2465         if (req == NULL) {
2466                 goto fail;
2467         }
2468         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2469                 goto fail;
2470         }
2471         status = cli_tree_connect_recv(req);
2472 fail:
2473         TALLOC_FREE(ev);
2474         return status;
2475 }
2476
2477 NTSTATUS cli_tree_connect_creds(struct cli_state *cli,
2478                                 const char *share, const char *dev,
2479                                 struct cli_credentials *creds)
2480 {
2481         const char *pw = NULL;
2482
2483         if (creds != NULL) {
2484                 pw = cli_credentials_get_password(creds);
2485         }
2486
2487         return cli_tree_connect(cli, share, dev, pw);
2488 }
2489
2490 /****************************************************************************
2491  Send a tree disconnect.
2492 ****************************************************************************/
2493
2494 struct cli_tdis_state {
2495         struct cli_state *cli;
2496 };
2497
2498 static void cli_tdis_done(struct tevent_req *subreq);
2499
2500 static struct tevent_req *cli_tdis_send(TALLOC_CTX *mem_ctx,
2501                                  struct tevent_context *ev,
2502                                  struct cli_state *cli)
2503 {
2504         struct tevent_req *req, *subreq;
2505         struct cli_tdis_state *state;
2506
2507         req = tevent_req_create(mem_ctx, &state, struct cli_tdis_state);
2508         if (req == NULL) {
2509                 return NULL;
2510         }
2511         state->cli = cli;
2512
2513         subreq = cli_smb_send(state, ev, cli, SMBtdis, 0, 0, 0, NULL, 0, NULL);
2514         if (tevent_req_nomem(subreq, req)) {
2515                 return tevent_req_post(req, ev);
2516         }
2517         tevent_req_set_callback(subreq, cli_tdis_done, req);
2518         return req;
2519 }
2520
2521 static void cli_tdis_done(struct tevent_req *subreq)
2522 {
2523         struct tevent_req *req = tevent_req_callback_data(
2524                 subreq, struct tevent_req);
2525         struct cli_tdis_state *state = tevent_req_data(
2526                 req, struct cli_tdis_state);
2527         NTSTATUS status;
2528
2529         status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
2530         TALLOC_FREE(subreq);
2531         if (!NT_STATUS_IS_OK(status)) {
2532                 tevent_req_nterror(req, status);
2533                 return;
2534         }
2535         TALLOC_FREE(state->cli->smb1.tcon);
2536         tevent_req_done(req);
2537 }
2538
2539 static NTSTATUS cli_tdis_recv(struct tevent_req *req)
2540 {
2541         return tevent_req_simple_recv_ntstatus(req);
2542 }
2543
2544 NTSTATUS cli_tdis(struct cli_state *cli)
2545 {
2546         struct tevent_context *ev;
2547         struct tevent_req *req;
2548         NTSTATUS status = NT_STATUS_NO_MEMORY;
2549
2550         if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
2551                 status = smb2cli_tdis(cli->conn,
2552                                     cli->timeout,
2553                                     cli->smb2.session,
2554                                     cli->smb2.tcon);
2555                 if (NT_STATUS_IS_OK(status)) {
2556                         TALLOC_FREE(cli->smb2.tcon);
2557                 }
2558                 return status;
2559         }
2560
2561         if (smbXcli_conn_has_async_calls(cli->conn)) {
2562                 return NT_STATUS_INVALID_PARAMETER;
2563         }
2564         ev = samba_tevent_context_init(talloc_tos());
2565         if (ev == NULL) {
2566                 goto fail;
2567         }
2568         req = cli_tdis_send(ev, ev, cli);
2569         if (req == NULL) {
2570                 goto fail;
2571         }
2572         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2573                 goto fail;
2574         }
2575         status = cli_tdis_recv(req);
2576 fail:
2577         TALLOC_FREE(ev);
2578         return status;
2579 }
2580
2581 struct cli_connect_sock_state {
2582         const char **called_names;
2583         const char **calling_names;
2584         int *called_types;
2585         int fd;
2586         uint16_t port;
2587 };
2588
2589 static void cli_connect_sock_done(struct tevent_req *subreq);
2590
2591 /*
2592  * Async only if we don't have to look up the name, i.e. "pss" is set with a
2593  * nonzero address.
2594  */
2595
2596 static struct tevent_req *cli_connect_sock_send(
2597         TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2598         const char *host, int name_type, const struct sockaddr_storage *pss,
2599         const char *myname, uint16_t port)
2600 {
2601         struct tevent_req *req, *subreq;
2602         struct cli_connect_sock_state *state;
2603         struct sockaddr_storage *addrs;
2604         unsigned i, num_addrs;
2605         NTSTATUS status;
2606
2607         req = tevent_req_create(mem_ctx, &state,
2608                                 struct cli_connect_sock_state);
2609         if (req == NULL) {
2610                 return NULL;
2611         }
2612
2613         if ((pss == NULL) || is_zero_addr(pss)) {
2614
2615                 /*
2616                  * Here we cheat. resolve_name_list is not async at all. So
2617                  * this call will only be really async if the name lookup has
2618                  * been done externally.
2619                  */
2620
2621                 status = resolve_name_list(state, host, name_type,
2622                                            &addrs, &num_addrs);
2623                 if (!NT_STATUS_IS_OK(status)) {
2624                         tevent_req_nterror(req, status);
2625                         return tevent_req_post(req, ev);
2626                 }
2627         } else {
2628                 addrs = talloc_array(state, struct sockaddr_storage, 1);
2629                 if (tevent_req_nomem(addrs, req)) {
2630                         return tevent_req_post(req, ev);
2631                 }
2632                 addrs[0] = *pss;
2633                 num_addrs = 1;
2634         }
2635
2636         state->called_names = talloc_array(state, const char *, num_addrs);
2637         if (tevent_req_nomem(state->called_names, req)) {
2638                 return tevent_req_post(req, ev);
2639         }
2640         state->called_types = talloc_array(state, int, num_addrs);
2641         if (tevent_req_nomem(state->called_types, req)) {
2642                 return tevent_req_post(req, ev);
2643         }
2644         state->calling_names = talloc_array(state, const char *, num_addrs);
2645         if (tevent_req_nomem(state->calling_names, req)) {
2646                 return tevent_req_post(req, ev);
2647         }
2648         for (i=0; i<num_addrs; i++) {
2649                 state->called_names[i] = host;
2650                 state->called_types[i] = name_type;
2651                 state->calling_names[i] = myname;
2652         }
2653
2654         subreq = smbsock_any_connect_send(
2655                 state, ev, addrs, state->called_names, state->called_types,
2656                 state->calling_names, NULL, num_addrs, port);
2657         if (tevent_req_nomem(subreq, req)) {
2658                 return tevent_req_post(req, ev);
2659         }
2660         tevent_req_set_callback(subreq, cli_connect_sock_done, req);
2661         return req;
2662 }
2663
2664 static void cli_connect_sock_done(struct tevent_req *subreq)
2665 {
2666         struct tevent_req *req = tevent_req_callback_data(
2667                 subreq, struct tevent_req);
2668         struct cli_connect_sock_state *state = tevent_req_data(
2669                 req, struct cli_connect_sock_state);
2670         NTSTATUS status;
2671
2672         status = smbsock_any_connect_recv(subreq, &state->fd, NULL,
2673                                           &state->port);
2674         TALLOC_FREE(subreq);
2675         if (tevent_req_nterror(req, status)) {
2676                 return;
2677         }
2678         set_socket_options(state->fd, lp_socket_options());
2679         tevent_req_done(req);
2680 }
2681
2682 static NTSTATUS cli_connect_sock_recv(struct tevent_req *req,
2683                                       int *pfd, uint16_t *pport)
2684 {
2685         struct cli_connect_sock_state *state = tevent_req_data(
2686                 req, struct cli_connect_sock_state);
2687         NTSTATUS status;
2688
2689         if (tevent_req_is_nterror(req, &status)) {
2690                 return status;
2691         }
2692         *pfd = state->fd;
2693         *pport = state->port;
2694         return NT_STATUS_OK;
2695 }
2696
2697 struct cli_connect_nb_state {
2698         const char *desthost;
2699         int signing_state;
2700         int flags;
2701         struct cli_state *cli;
2702 };
2703
2704 static void cli_connect_nb_done(struct tevent_req *subreq);
2705
2706 static struct tevent_req *cli_connect_nb_send(
2707         TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2708         const char *host, const struct sockaddr_storage *dest_ss,
2709         uint16_t port, int name_type, const char *myname,
2710         int signing_state, int flags)
2711 {
2712         struct tevent_req *req, *subreq;
2713         struct cli_connect_nb_state *state;
2714
2715         req = tevent_req_create(mem_ctx, &state, struct cli_connect_nb_state);
2716         if (req == NULL) {
2717                 return NULL;
2718         }
2719         state->signing_state = signing_state;
2720         state->flags = flags;
2721
2722         if (host != NULL) {
2723                 char *p = strchr(host, '#');
2724
2725                 if (p != NULL) {
2726                         name_type = strtol(p+1, NULL, 16);
2727                         host = talloc_strndup(state, host, p - host);
2728                         if (tevent_req_nomem(host, req)) {
2729                                 return tevent_req_post(req, ev);
2730                         }
2731                 }
2732
2733                 state->desthost = host;
2734         } else if (dest_ss != NULL) {
2735                 state->desthost = print_canonical_sockaddr(state, dest_ss);
2736                 if (tevent_req_nomem(state->desthost, req)) {
2737                         return tevent_req_post(req, ev);
2738                 }
2739         } else {
2740                 /* No host or dest_ss given. Error out. */
2741                 tevent_req_error(req, EINVAL);
2742                 return tevent_req_post(req, ev);
2743         }
2744
2745         subreq = cli_connect_sock_send(state, ev, host, name_type, dest_ss,
2746                                        myname, port);
2747         if (tevent_req_nomem(subreq, req)) {
2748                 return tevent_req_post(req, ev);
2749         }
2750         tevent_req_set_callback(subreq, cli_connect_nb_done, req);
2751         return req;
2752 }
2753
2754 static void cli_connect_nb_done(struct tevent_req *subreq)
2755 {
2756         struct tevent_req *req = tevent_req_callback_data(
2757                 subreq, struct tevent_req);
2758         struct cli_connect_nb_state *state = tevent_req_data(
2759                 req, struct cli_connect_nb_state);
2760         NTSTATUS status;
2761         int fd = 0;
2762         uint16_t port;
2763
2764         status = cli_connect_sock_recv(subreq, &fd, &port);
2765         TALLOC_FREE(subreq);
2766         if (tevent_req_nterror(req, status)) {
2767                 return;
2768         }
2769
2770         state->cli = cli_state_create(state, fd, state->desthost,
2771                                       state->signing_state, state->flags);
2772         if (tevent_req_nomem(state->cli, req)) {
2773                 close(fd);
2774                 return;
2775         }
2776         tevent_req_done(req);
2777 }
2778
2779 static NTSTATUS cli_connect_nb_recv(struct tevent_req *req,
2780                                     struct cli_state **pcli)
2781 {
2782         struct cli_connect_nb_state *state = tevent_req_data(
2783                 req, struct cli_connect_nb_state);
2784         NTSTATUS status;
2785
2786         if (tevent_req_is_nterror(req, &status)) {
2787                 return status;
2788         }
2789         *pcli = talloc_move(NULL, &state->cli);
2790         return NT_STATUS_OK;
2791 }
2792
2793 NTSTATUS cli_connect_nb(const char *host, const struct sockaddr_storage *dest_ss,
2794                         uint16_t port, int name_type, const char *myname,
2795                         int signing_state, int flags, struct cli_state **pcli)
2796 {
2797         struct tevent_context *ev;
2798         struct tevent_req *req;
2799         NTSTATUS status = NT_STATUS_NO_MEMORY;
2800
2801         ev = samba_tevent_context_init(talloc_tos());
2802         if (ev == NULL) {
2803                 goto fail;
2804         }
2805         req = cli_connect_nb_send(ev, ev, host, dest_ss, port, name_type,
2806                                   myname, signing_state, flags);
2807         if (req == NULL) {
2808                 goto fail;
2809         }
2810         if (!tevent_req_set_endtime(req, ev, timeval_current_ofs(20, 0))) {
2811                 goto fail;
2812         }
2813         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2814                 goto fail;
2815         }
2816         status = cli_connect_nb_recv(req, pcli);
2817 fail:
2818         TALLOC_FREE(ev);
2819         return status;
2820 }
2821
2822 struct cli_start_connection_state {
2823         struct tevent_context *ev;
2824         struct cli_state *cli;
2825         int min_protocol;
2826         int max_protocol;
2827 };
2828
2829 static void cli_start_connection_connected(struct tevent_req *subreq);
2830 static void cli_start_connection_done(struct tevent_req *subreq);
2831
2832 /**
2833    establishes a connection to after the negprot. 
2834    @param output_cli A fully initialised cli structure, non-null only on success
2835    @param dest_host The netbios name of the remote host
2836    @param dest_ss (optional) The the destination IP, NULL for name based lookup
2837    @param port (optional) The destination port (0 for default)
2838 */
2839
2840 static struct tevent_req *cli_start_connection_send(
2841         TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2842         const char *my_name, const char *dest_host,
2843         const struct sockaddr_storage *dest_ss, int port,
2844         int signing_state, int flags)
2845 {
2846         struct tevent_req *req, *subreq;
2847         struct cli_start_connection_state *state;
2848
2849         req = tevent_req_create(mem_ctx, &state,
2850                                 struct cli_start_connection_state);
2851         if (req == NULL) {
2852                 return NULL;
2853         }
2854         state->ev = ev;
2855
2856         if (signing_state == SMB_SIGNING_IPC_DEFAULT) {
2857                 state->min_protocol = lp_client_ipc_min_protocol();
2858                 state->max_protocol = lp_client_ipc_max_protocol();
2859         } else {
2860                 state->min_protocol = lp_client_min_protocol();
2861                 state->max_protocol = lp_client_max_protocol();
2862         }
2863
2864         if (flags & CLI_FULL_CONNECTION_FORCE_SMB1) {
2865                 state->max_protocol = MIN(state->max_protocol, PROTOCOL_NT1);
2866         }
2867
2868         if (flags & CLI_FULL_CONNECTION_DISABLE_SMB1) {
2869                 state->min_protocol = MAX(state->max_protocol, PROTOCOL_SMB2_02);
2870                 state->max_protocol = MAX(state->max_protocol, PROTOCOL_LATEST);
2871         }
2872
2873         subreq = cli_connect_nb_send(state, ev, dest_host, dest_ss, port,
2874                                      0x20, my_name, signing_state, flags);
2875         if (tevent_req_nomem(subreq, req)) {
2876                 return tevent_req_post(req, ev);
2877         }
2878         tevent_req_set_callback(subreq, cli_start_connection_connected, req);
2879         return req;
2880 }
2881
2882 static void cli_start_connection_connected(struct tevent_req *subreq)
2883 {
2884         struct tevent_req *req = tevent_req_callback_data(
2885                 subreq, struct tevent_req);
2886         struct cli_start_connection_state *state = tevent_req_data(
2887                 req, struct cli_start_connection_state);
2888         NTSTATUS status;
2889
2890         status = cli_connect_nb_recv(subreq, &state->cli);
2891         TALLOC_FREE(subreq);
2892         if (tevent_req_nterror(req, status)) {
2893                 return;
2894         }
2895
2896         subreq = smbXcli_negprot_send(state, state->ev, state->cli->conn,
2897                                       state->cli->timeout,
2898                                       state->min_protocol,
2899                                       state->max_protocol,
2900                                       WINDOWS_CLIENT_PURE_SMB2_NEGPROT_INITIAL_CREDIT_ASK);
2901         if (tevent_req_nomem(subreq, req)) {
2902                 return;
2903         }
2904         tevent_req_set_callback(subreq, cli_start_connection_done, req);
2905 }
2906
2907 static void cli_start_connection_done(struct tevent_req *subreq)
2908 {
2909         struct tevent_req *req = tevent_req_callback_data(
2910                 subreq, struct tevent_req);
2911         struct cli_start_connection_state *state = tevent_req_data(
2912                 req, struct cli_start_connection_state);
2913         NTSTATUS status;
2914
2915         status = smbXcli_negprot_recv(subreq);
2916         TALLOC_FREE(subreq);
2917         if (tevent_req_nterror(req, status)) {
2918                 return;
2919         }
2920
2921         status = cli_state_update_after_negprot(state->cli);
2922         if (tevent_req_nterror(req, status)) {
2923                 return;
2924         }
2925
2926         tevent_req_done(req);
2927 }
2928
2929 static NTSTATUS cli_start_connection_recv(struct tevent_req *req,
2930                                           struct cli_state **output_cli)
2931 {
2932         struct cli_start_connection_state *state = tevent_req_data(
2933                 req, struct cli_start_connection_state);
2934         NTSTATUS status;
2935
2936         if (tevent_req_is_nterror(req, &status)) {
2937                 return status;
2938         }
2939         *output_cli = state->cli;
2940
2941         return NT_STATUS_OK;
2942 }
2943
2944 NTSTATUS cli_start_connection(struct cli_state **output_cli, 
2945                               const char *my_name, 
2946                               const char *dest_host, 
2947                               const struct sockaddr_storage *dest_ss, int port,
2948                               int signing_state, int flags)
2949 {
2950         struct tevent_context *ev;
2951         struct tevent_req *req;
2952         NTSTATUS status = NT_STATUS_NO_MEMORY;
2953
2954         ev = samba_tevent_context_init(talloc_tos());
2955         if (ev == NULL) {
2956                 goto fail;
2957         }
2958         req = cli_start_connection_send(ev, ev, my_name, dest_host, dest_ss,
2959                                         port, signing_state, flags);
2960         if (req == NULL) {
2961                 goto fail;
2962         }
2963         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2964                 goto fail;
2965         }
2966         status = cli_start_connection_recv(req, output_cli);
2967 fail:
2968         TALLOC_FREE(ev);
2969         return status;
2970 }
2971
2972 struct cli_smb1_setup_encryption_blob_state {
2973         uint16_t setup[1];
2974         uint8_t param[4];
2975         NTSTATUS status;
2976         DATA_BLOB out;
2977         uint16_t enc_ctx_id;
2978 };
2979
2980 static void cli_smb1_setup_encryption_blob_done(struct tevent_req *subreq);
2981
2982 static struct tevent_req *cli_smb1_setup_encryption_blob_send(TALLOC_CTX *mem_ctx,
2983                                                         struct tevent_context *ev,
2984                                                         struct cli_state *cli,
2985                                                         const DATA_BLOB in)
2986 {
2987         struct tevent_req *req = NULL;
2988         struct cli_smb1_setup_encryption_blob_state *state = NULL;
2989         struct tevent_req *subreq = NULL;
2990
2991         req = tevent_req_create(mem_ctx, &state,
2992                                 struct cli_smb1_setup_encryption_blob_state);
2993         if (req == NULL) {
2994                 return NULL;
2995         }
2996
2997         if (in.length > CLI_BUFFER_SIZE) {
2998                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
2999                 return tevent_req_post(req, ev);
3000         }
3001
3002         SSVAL(state->setup+0,  0, TRANSACT2_SETFSINFO);
3003         SSVAL(state->param, 0, 0);
3004         SSVAL(state->param, 2, SMB_REQUEST_TRANSPORT_ENCRYPTION);
3005
3006         subreq = smb1cli_trans_send(state, ev, cli->conn,
3007                                     SMBtrans2,
3008                                     0, 0, /* _flags */
3009                                     0, 0, /* _flags2 */
3010                                     cli->timeout,
3011                                     cli->smb1.pid,
3012                                     cli->smb1.tcon,
3013                                     cli->smb1.session,
3014                                     NULL, /* pipe_name */
3015                                     0, /* fid */
3016                                     0, /* function */
3017                                     0, /* flags */
3018                                     state->setup, 1, 0,
3019                                     state->param, 4, 2,
3020                                     in.data, in.length, CLI_BUFFER_SIZE);
3021         if (tevent_req_nomem(subreq, req)) {
3022                 return tevent_req_post(req, ev);
3023         }
3024         tevent_req_set_callback(subreq,
3025                                 cli_smb1_setup_encryption_blob_done,
3026                                 req);
3027
3028         return req;
3029 }
3030
3031 static void cli_smb1_setup_encryption_blob_done(struct tevent_req *subreq)
3032 {
3033         struct tevent_req *req =
3034                 tevent_req_callback_data(subreq,
3035                                 struct tevent_req);
3036         struct cli_smb1_setup_encryption_blob_state *state =
3037                 tevent_req_data(req,
3038                 struct cli_smb1_setup_encryption_blob_state);
3039         uint8_t *rparam=NULL, *rdata=NULL;
3040         uint32_t num_rparam, num_rdata;
3041         NTSTATUS status;
3042
3043         status = smb1cli_trans_recv(subreq, state,
3044                                     NULL, /* recv_flags */
3045                                     NULL, 0, NULL, /* rsetup */
3046                                     &rparam, 0, &num_rparam,
3047                                     &rdata, 0, &num_rdata);
3048         TALLOC_FREE(subreq);
3049         state->status = status;
3050         if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
3051                 status = NT_STATUS_OK;
3052         }
3053         if (tevent_req_nterror(req, status)) {
3054                 return;
3055         }
3056
3057         if (num_rparam == 2) {
3058                 state->enc_ctx_id = SVAL(rparam, 0);
3059         }
3060         TALLOC_FREE(rparam);
3061
3062         state->out = data_blob_const(rdata, num_rdata);
3063
3064         tevent_req_done(req);
3065 }
3066
3067 static NTSTATUS cli_smb1_setup_encryption_blob_recv(struct tevent_req *req,
3068                                                     TALLOC_CTX *mem_ctx,
3069                                                     DATA_BLOB *out,
3070                                                     uint16_t *enc_ctx_id)
3071 {
3072         struct cli_smb1_setup_encryption_blob_state *state =
3073                 tevent_req_data(req,
3074                 struct cli_smb1_setup_encryption_blob_state);
3075         NTSTATUS status;
3076
3077         if (tevent_req_is_nterror(req, &status)) {
3078                 tevent_req_received(req);
3079                 return status;
3080         }
3081
3082         status = state->status;
3083
3084         *out = state->out;
3085         talloc_steal(mem_ctx, out->data);
3086
3087         *enc_ctx_id = state->enc_ctx_id;
3088
3089         tevent_req_received(req);
3090         return status;
3091 }
3092
3093 struct cli_smb1_setup_encryption_state {
3094         struct tevent_context *ev;
3095         struct cli_state *cli;
3096         struct smb_trans_enc_state *es;
3097         DATA_BLOB blob_in;
3098         DATA_BLOB blob_out;
3099         bool local_ready;
3100         bool remote_ready;
3101 };
3102
3103 static void cli_smb1_setup_encryption_local_next(struct tevent_req *req);
3104 static void cli_smb1_setup_encryption_local_done(struct tevent_req *subreq);
3105 static void cli_smb1_setup_encryption_remote_next(struct tevent_req *req);
3106 static void cli_smb1_setup_encryption_remote_done(struct tevent_req *subreq);
3107 static void cli_smb1_setup_encryption_ready(struct tevent_req *req);
3108
3109 static struct tevent_req *cli_smb1_setup_encryption_send(TALLOC_CTX *mem_ctx,
3110                                                 struct tevent_context *ev,
3111                                                 struct cli_state *cli,
3112                                                 struct cli_credentials *creds)
3113 {
3114         struct tevent_req *req = NULL;
3115         struct cli_smb1_setup_encryption_state *state = NULL;
3116         struct auth_generic_state *ags = NULL;
3117         const DATA_BLOB *b = NULL;
3118         bool auth_requested = false;
3119         const char *target_service = NULL;
3120         const char *target_hostname = NULL;
3121         NTSTATUS status;
3122
3123         req = tevent_req_create(mem_ctx, &state,
3124                                 struct cli_smb1_setup_encryption_state);
3125         if (req == NULL) {
3126                 return NULL;
3127         }
3128         state->ev = ev;
3129         state->cli = cli;
3130
3131         auth_requested = cli_credentials_authentication_requested(creds);
3132         if (!auth_requested) {
3133                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
3134                 return tevent_req_post(req, ev);
3135         }
3136
3137         target_service = "cifs";
3138         target_hostname = smbXcli_conn_remote_name(cli->conn);
3139
3140         status = cli_session_creds_prepare_krb5(cli, creds);
3141         if (tevent_req_nterror(req, status)) {
3142                 return tevent_req_post(req, ev);
3143         }
3144
3145         state->es = talloc_zero(state, struct smb_trans_enc_state);
3146         if (tevent_req_nomem(state->es, req)) {
3147                 return tevent_req_post(req, ev);
3148         }
3149
3150         status = auth_generic_client_prepare(state->es, &ags);
3151         if (tevent_req_nterror(req, status)) {
3152                 return tevent_req_post(req, ev);
3153         }
3154
3155         gensec_want_feature(ags->gensec_security,
3156                             GENSEC_FEATURE_SIGN);
3157         gensec_want_feature(ags->gensec_security,
3158                             GENSEC_FEATURE_SEAL);
3159
3160         status = auth_generic_set_creds(ags, creds);
3161         if (tevent_req_nterror(req, status)) {
3162                 return tevent_req_post(req, ev);
3163         }
3164
3165         if (target_service != NULL) {
3166                 status = gensec_set_target_service(ags->gensec_security,
3167                                                    target_service);
3168                 if (tevent_req_nterror(req, status)) {
3169                         return tevent_req_post(req, ev);
3170                 }
3171         }
3172
3173         if (target_hostname != NULL) {
3174                 status = gensec_set_target_hostname(ags->gensec_security,
3175                                                     target_hostname);
3176                 if (tevent_req_nterror(req, status)) {
3177                         return tevent_req_post(req, ev);
3178                 }
3179         }
3180
3181         gensec_set_max_update_size(ags->gensec_security,
3182                                    CLI_BUFFER_SIZE);
3183
3184         b = smbXcli_conn_server_gss_blob(state->cli->conn);
3185         if (b != NULL) {
3186                 state->blob_in = *b;
3187         }
3188
3189         status = auth_generic_client_start(ags, GENSEC_OID_SPNEGO);
3190         if (tevent_req_nterror(req, status)) {
3191                 return tevent_req_post(req, ev);
3192         }
3193
3194         /*
3195          * We only need the gensec_security part from here.
3196          */
3197         state->es->gensec_security = talloc_move(state->es,
3198                                                  &ags->gensec_security);
3199         TALLOC_FREE(ags);
3200
3201         cli_smb1_setup_encryption_local_next(req);
3202         if (!tevent_req_is_in_progress(req)) {
3203                 return tevent_req_post(req, ev);
3204         }
3205
3206         return req;
3207 }
3208
3209 static void cli_smb1_setup_encryption_local_next(struct tevent_req *req)
3210 {
3211         struct cli_smb1_setup_encryption_state *state =
3212                 tevent_req_data(req,
3213                 struct cli_smb1_setup_encryption_state);
3214         struct tevent_req *subreq = NULL;
3215
3216         if (state->local_ready) {
3217                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3218                 return;
3219         }
3220
3221         subreq = gensec_update_send(state, state->ev,
3222                         state->es->gensec_security,
3223                         state->blob_in);
3224         if (tevent_req_nomem(subreq, req)) {
3225                 return;
3226         }
3227         tevent_req_set_callback(subreq, cli_smb1_setup_encryption_local_done, req);
3228 }
3229
3230 static void cli_smb1_setup_encryption_local_done(struct tevent_req *subreq)
3231 {
3232         struct tevent_req *req =
3233                 tevent_req_callback_data(subreq,
3234                 struct tevent_req);
3235         struct cli_smb1_setup_encryption_state *state =
3236                 tevent_req_data(req,
3237                 struct cli_smb1_setup_encryption_state);
3238         NTSTATUS status;
3239
3240         status = gensec_update_recv(subreq, state, &state->blob_out);
3241         TALLOC_FREE(subreq);
3242         state->blob_in = data_blob_null;
3243         if (!NT_STATUS_IS_OK(status) &&
3244             !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
3245         {
3246                 tevent_req_nterror(req, status);
3247                 return;
3248         }
3249
3250         if (NT_STATUS_IS_OK(status)) {
3251                 state->local_ready = true;
3252         }
3253
3254         /*
3255          * We always get NT_STATUS_OK from the server even if it is not ready.
3256          * So guess the server is ready when we are ready and already sent
3257          * our last blob to the server.
3258          */
3259         if (state->local_ready && state->blob_out.length == 0) {
3260                 state->remote_ready = true;
3261         }
3262
3263         if (state->local_ready && state->remote_ready) {
3264                 cli_smb1_setup_encryption_ready(req);
3265                 return;
3266         }
3267
3268         cli_smb1_setup_encryption_remote_next(req);
3269 }
3270
3271 static void cli_smb1_setup_encryption_remote_next(struct tevent_req *req)
3272 {
3273         struct cli_smb1_setup_encryption_state *state =
3274                 tevent_req_data(req,
3275                 struct cli_smb1_setup_encryption_state);
3276         struct tevent_req *subreq = NULL;
3277
3278         if (state->remote_ready) {
3279                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3280                 return;
3281         }
3282
3283         subreq = cli_smb1_setup_encryption_blob_send(state, state->ev,
3284                                                      state->cli, state->blob_out);
3285         if (tevent_req_nomem(subreq, req)) {
3286                 return;
3287         }
3288         tevent_req_set_callback(subreq,
3289                                 cli_smb1_setup_encryption_remote_done,
3290                                 req);
3291 }
3292
3293 static void cli_smb1_setup_encryption_remote_done(struct tevent_req *subreq)
3294 {
3295         struct tevent_req *req =
3296                 tevent_req_callback_data(subreq,
3297                 struct tevent_req);
3298         struct cli_smb1_setup_encryption_state *state =
3299                 tevent_req_data(req,
3300                 struct cli_smb1_setup_encryption_state);
3301         NTSTATUS status;
3302
3303         status = cli_smb1_setup_encryption_blob_recv(subreq, state,
3304                                                      &state->blob_in,
3305                                                      &state->es->enc_ctx_num);
3306         TALLOC_FREE(subreq);
3307         data_blob_free(&state->blob_out);
3308         if (!NT_STATUS_IS_OK(status) &&
3309             !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
3310         {
3311                 tevent_req_nterror(req, status);
3312                 return;
3313         }
3314
3315         /*
3316          * We always get NT_STATUS_OK even if the server is not ready.
3317          * So guess the server is ready when we are ready and sent
3318          * our last blob to the server.
3319          */
3320         if (state->local_ready) {
3321                 state->remote_ready = true;
3322         }
3323
3324         if (state->local_ready && state->remote_ready) {
3325                 cli_smb1_setup_encryption_ready(req);
3326                 return;
3327         }
3328
3329         cli_smb1_setup_encryption_local_next(req);
3330 }
3331
3332 static void cli_smb1_setup_encryption_ready(struct tevent_req *req)
3333 {
3334         struct cli_smb1_setup_encryption_state *state =
3335                 tevent_req_data(req,
3336                 struct cli_smb1_setup_encryption_state);
3337         struct smb_trans_enc_state *es = NULL;
3338
3339         if (state->blob_in.length != 0) {
3340                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3341                 return;
3342         }
3343
3344         if (state->blob_out.length != 0) {
3345                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3346                 return;
3347         }
3348
3349         es = talloc_move(state->cli->conn, &state->es);
3350         es->enc_on = true;
3351         smb1cli_conn_set_encryption(state->cli->conn, es);
3352         es = NULL;
3353
3354         tevent_req_done(req);
3355 }
3356
3357 static NTSTATUS cli_smb1_setup_encryption_recv(struct tevent_req *req)
3358 {
3359         return tevent_req_simple_recv_ntstatus(req);
3360 }
3361
3362 NTSTATUS cli_smb1_setup_encryption(struct cli_state *cli,
3363                                    struct cli_credentials *creds)
3364 {
3365         struct tevent_context *ev = NULL;
3366         struct tevent_req *req = NULL;
3367         NTSTATUS status = NT_STATUS_NO_MEMORY;
3368
3369         ev = samba_tevent_context_init(talloc_tos());
3370         if (ev == NULL) {
3371                 goto fail;
3372         }
3373         req = cli_smb1_setup_encryption_send(ev, ev, cli, creds);
3374         if (req == NULL) {
3375                 goto fail;
3376         }
3377         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
3378                 goto fail;
3379         }
3380         status = cli_smb1_setup_encryption_recv(req);
3381  fail:
3382         TALLOC_FREE(ev);
3383         return status;
3384 }
3385
3386 /**
3387    establishes a connection right up to doing tconX, password specified.
3388    @param output_cli A fully initialised cli structure, non-null only on success
3389    @param dest_host The netbios name of the remote host
3390    @param dest_ip (optional) The the destination IP, NULL for name based lookup
3391    @param port (optional) The destination port (0 for default)
3392    @param service (optional) The share to make the connection to.  Should be 'unqualified' in any way.
3393    @param service_type The 'type' of serivice. 
3394    @param creds The used user credentials
3395 */
3396
3397 struct cli_full_connection_creds_state {
3398         struct tevent_context *ev;
3399         const char *service;
3400         const char *service_type;
3401         struct cli_credentials *creds;
3402         int flags;
3403         struct cli_state *cli;
3404 };
3405
3406 static int cli_full_connection_creds_state_destructor(
3407         struct cli_full_connection_creds_state *s)
3408 {
3409         if (s->cli != NULL) {
3410                 cli_shutdown(s->cli);
3411                 s->cli = NULL;
3412         }
3413         return 0;
3414 }
3415
3416 static void cli_full_connection_creds_conn_done(struct tevent_req *subreq);
3417 static void cli_full_connection_creds_sess_start(struct tevent_req *req);
3418 static void cli_full_connection_creds_sess_done(struct tevent_req *subreq);
3419 static void cli_full_connection_creds_tcon_start(struct tevent_req *req);
3420 static void cli_full_connection_creds_tcon_done(struct tevent_req *subreq);
3421
3422 struct tevent_req *cli_full_connection_creds_send(
3423         TALLOC_CTX *mem_ctx, struct tevent_context *ev,
3424         const char *my_name, const char *dest_host,
3425         const struct sockaddr_storage *dest_ss, int port,
3426         const char *service, const char *service_type,
3427         struct cli_credentials *creds,
3428         int flags, int signing_state)
3429 {
3430         struct tevent_req *req, *subreq;
3431         struct cli_full_connection_creds_state *state;
3432         enum credentials_use_kerberos krb5_state;
3433         uint32_t gensec_features = 0;
3434
3435         req = tevent_req_create(mem_ctx, &state,
3436                                 struct cli_full_connection_creds_state);
3437         if (req == NULL) {
3438                 return NULL;
3439         }
3440         talloc_set_destructor(state, cli_full_connection_creds_state_destructor);
3441
3442         flags &= ~CLI_FULL_CONNECTION_USE_KERBEROS;
3443         flags &= ~CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS;
3444         flags &= ~CLI_FULL_CONNECTION_USE_CCACHE;
3445         flags &= ~CLI_FULL_CONNECTION_USE_NT_HASH;
3446
3447         krb5_state = cli_credentials_get_kerberos_state(creds);
3448         switch (krb5_state) {
3449         case CRED_MUST_USE_KERBEROS:
3450                 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
3451                 flags &= ~CLI_FULL_CONNECTION_DONT_SPNEGO;
3452                 break;
3453         case CRED_AUTO_USE_KERBEROS:
3454                 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
3455                 flags |= CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS;
3456                 break;
3457         case CRED_DONT_USE_KERBEROS:
3458                 break;
3459         }
3460
3461         gensec_features = cli_credentials_get_gensec_features(creds);
3462         if (gensec_features & GENSEC_FEATURE_NTLM_CCACHE) {
3463                 flags |= CLI_FULL_CONNECTION_USE_CCACHE;
3464         }
3465
3466         state->ev = ev;
3467         state->service = service;
3468         state->service_type = service_type;
3469         state->creds = creds;
3470         state->flags = flags;
3471
3472         subreq = cli_start_connection_send(
3473                 state, ev, my_name, dest_host, dest_ss, port,
3474                 signing_state, flags);
3475         if (tevent_req_nomem(subreq, req)) {
3476                 return tevent_req_post(req, ev);
3477         }
3478         tevent_req_set_callback(subreq,
3479                                 cli_full_connection_creds_conn_done,
3480                                 req);
3481         return req;
3482 }
3483
3484 static void cli_full_connection_creds_conn_done(struct tevent_req *subreq)
3485 {
3486         struct tevent_req *req = tevent_req_callback_data(
3487                 subreq, struct tevent_req);
3488         struct cli_full_connection_creds_state *state = tevent_req_data(
3489                 req, struct cli_full_connection_creds_state);
3490         NTSTATUS status;
3491
3492         status = cli_start_connection_recv(subreq, &state->cli);
3493         TALLOC_FREE(subreq);
3494         if (tevent_req_nterror(req, status)) {
3495                 return;
3496         }
3497
3498         cli_full_connection_creds_sess_start(req);
3499 }
3500
3501 static void cli_full_connection_creds_sess_start(struct tevent_req *req)
3502 {
3503         struct cli_full_connection_creds_state *state = tevent_req_data(
3504                 req, struct cli_full_connection_creds_state);
3505         struct tevent_req *subreq = NULL;
3506
3507         subreq = cli_session_setup_creds_send(
3508                 state, state->ev, state->cli, state->creds);
3509         if (tevent_req_nomem(subreq, req)) {
3510                 return;
3511         }
3512         tevent_req_set_callback(subreq,
3513                                 cli_full_connection_creds_sess_done,
3514                                 req);
3515 }
3516
3517 static void cli_full_connection_creds_sess_done(struct tevent_req *subreq)
3518 {
3519         struct tevent_req *req = tevent_req_callback_data(
3520                 subreq, struct tevent_req);
3521         struct cli_full_connection_creds_state *state = tevent_req_data(
3522                 req, struct cli_full_connection_creds_state);
3523         NTSTATUS status;
3524
3525         status = cli_session_setup_creds_recv(subreq);
3526         TALLOC_FREE(subreq);
3527
3528         if (!NT_STATUS_IS_OK(status) &&
3529             (state->flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)) {
3530
3531                 state->flags &= ~CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
3532
3533                 state->creds = cli_credentials_init_anon(state);
3534                 if (tevent_req_nomem(state->creds, req)) {
3535                         return;
3536                 }
3537
3538                 cli_full_connection_creds_sess_start(req);
3539                 return;
3540         }
3541
3542         if (tevent_req_nterror(req, status)) {
3543                 return;
3544         }
3545
3546         cli_full_connection_creds_tcon_start(req);
3547 }
3548
3549 static void cli_full_connection_creds_tcon_start(struct tevent_req *req)
3550 {
3551         struct cli_full_connection_creds_state *state = tevent_req_data(
3552                 req, struct cli_full_connection_creds_state);
3553         struct tevent_req *subreq = NULL;
3554         const char *password = NULL;
3555
3556         if (state->service == NULL) {
3557                 tevent_req_done(req);
3558                 return;
3559         }
3560
3561         password = cli_credentials_get_password(state->creds);
3562
3563         subreq = cli_tree_connect_send(state, state->ev,
3564                                        state->cli,
3565                                        state->service,
3566                                        state->service_type,
3567                                        password);
3568         if (tevent_req_nomem(subreq, req)) {
3569                 return;
3570         }
3571         tevent_req_set_callback(subreq,
3572                                 cli_full_connection_creds_tcon_done,
3573                                 req);
3574 }
3575
3576 static void cli_full_connection_creds_tcon_done(struct tevent_req *subreq)
3577 {
3578         struct tevent_req *req = tevent_req_callback_data(
3579                 subreq, struct tevent_req);
3580         NTSTATUS status;
3581
3582         status = cli_tree_connect_recv(subreq);
3583         TALLOC_FREE(subreq);
3584         if (tevent_req_nterror(req, status)) {
3585                 return;
3586         }
3587
3588         tevent_req_done(req);
3589 }
3590
3591 NTSTATUS cli_full_connection_creds_recv(struct tevent_req *req,
3592                                   struct cli_state **output_cli)
3593 {
3594         struct cli_full_connection_creds_state *state = tevent_req_data(
3595                 req, struct cli_full_connection_creds_state);
3596         NTSTATUS status;
3597
3598         if (tevent_req_is_nterror(req, &status)) {
3599                 return status;
3600         }
3601         *output_cli = state->cli;
3602         talloc_set_destructor(state, NULL);
3603         return NT_STATUS_OK;
3604 }
3605
3606 NTSTATUS cli_full_connection_creds(struct cli_state **output_cli,
3607                                    const char *my_name,
3608                                    const char *dest_host,
3609                                    const struct sockaddr_storage *dest_ss, int port,
3610                                    const char *service, const char *service_type,
3611                                    struct cli_credentials *creds,
3612                                    int flags,
3613                                    int signing_state)
3614 {
3615         struct tevent_context *ev;
3616         struct tevent_req *req;
3617         NTSTATUS status = NT_STATUS_NO_MEMORY;
3618
3619         ev = samba_tevent_context_init(talloc_tos());
3620         if (ev == NULL) {
3621                 goto fail;
3622         }
3623         req = cli_full_connection_creds_send(
3624                 ev, ev, my_name, dest_host, dest_ss, port, service,
3625                 service_type, creds, flags, signing_state);
3626         if (req == NULL) {
3627                 goto fail;
3628         }
3629         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
3630                 goto fail;
3631         }
3632         status = cli_full_connection_creds_recv(req, output_cli);
3633  fail:
3634         TALLOC_FREE(ev);
3635         return status;
3636 }
3637
3638 NTSTATUS cli_full_connection(struct cli_state **output_cli,
3639                              const char *my_name,
3640                              const char *dest_host,
3641                              const struct sockaddr_storage *dest_ss, int port,
3642                              const char *service, const char *service_type,
3643                              const char *user, const char *domain,
3644                              const char *password, int flags,
3645                              int signing_state)
3646 {
3647         TALLOC_CTX *frame = talloc_stackframe();
3648         NTSTATUS status;
3649         bool use_kerberos = false;
3650         bool fallback_after_kerberos = false;
3651         bool use_ccache = false;
3652         bool pw_nt_hash = false;
3653         struct cli_credentials *creds = NULL;
3654
3655         if (flags & CLI_FULL_CONNECTION_USE_KERBEROS) {
3656                 use_kerberos = true;
3657         }
3658
3659         if (flags & CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS) {
3660                 fallback_after_kerberos = true;
3661         }
3662
3663         if (flags & CLI_FULL_CONNECTION_USE_CCACHE) {
3664                 use_ccache = true;
3665         }
3666
3667         if (flags & CLI_FULL_CONNECTION_USE_NT_HASH) {
3668                 pw_nt_hash = true;
3669         }
3670
3671         creds = cli_session_creds_init(frame,
3672                                        user,
3673                                        domain,
3674                                        NULL, /* realm (use default) */
3675                                        password,
3676                                        use_kerberos,
3677                                        fallback_after_kerberos,
3678                                        use_ccache,
3679                                        pw_nt_hash);
3680         if (creds == NULL) {
3681                 TALLOC_FREE(frame);
3682                 return NT_STATUS_NO_MEMORY;
3683         }
3684
3685         status = cli_full_connection_creds(output_cli, my_name,
3686                                            dest_host, dest_ss, port,
3687                                            service, service_type,
3688                                            creds, flags, signing_state);
3689         if (!NT_STATUS_IS_OK(status)) {
3690                 TALLOC_FREE(frame);
3691                 return status;
3692         }
3693
3694         TALLOC_FREE(frame);
3695         return NT_STATUS_OK;
3696 }
3697
3698 /****************************************************************************
3699  Send an old style tcon.
3700 ****************************************************************************/
3701 struct cli_raw_tcon_state {
3702         uint16_t *ret_vwv;
3703 };
3704
3705 static void cli_raw_tcon_done(struct tevent_req *subreq);
3706
3707 static struct tevent_req *cli_raw_tcon_send(
3708         TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
3709         const char *service, const char *pass, const char *dev)
3710 {
3711         struct tevent_req *req, *subreq;
3712         struct cli_raw_tcon_state *state;
3713         uint8_t *bytes;
3714
3715         req = tevent_req_create(mem_ctx, &state, struct cli_raw_tcon_state);
3716         if (req == NULL) {
3717                 return NULL;
3718         }
3719
3720         if (!lp_client_plaintext_auth() && (*pass)) {
3721                 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
3722                           " or 'client ntlmv2 auth = yes'\n"));
3723                 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
3724                 return tevent_req_post(req, ev);
3725         }
3726
3727         TALLOC_FREE(cli->smb1.tcon);
3728         cli->smb1.tcon = smbXcli_tcon_create(cli);
3729         if (tevent_req_nomem(cli->smb1.tcon, req)) {
3730                 return tevent_req_post(req, ev);
3731         }
3732         smb1cli_tcon_set_id(cli->smb1.tcon, UINT16_MAX);
3733
3734         bytes = talloc_array(state, uint8_t, 0);
3735         bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3736         bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3737                                    service, strlen(service)+1, NULL);
3738         bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3739         bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3740                                    pass, strlen(pass)+1, NULL);
3741         bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3742         bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3743                                    dev, strlen(dev)+1, NULL);
3744
3745         if (tevent_req_nomem(bytes, req)) {
3746                 return tevent_req_post(req, ev);
3747         }
3748
3749         subreq = cli_smb_send(state, ev, cli, SMBtcon, 0, 0, 0, NULL,
3750                               talloc_get_size(bytes), bytes);
3751         if (tevent_req_nomem(subreq, req)) {
3752                 return tevent_req_post(req, ev);
3753         }
3754         tevent_req_set_callback(subreq, cli_raw_tcon_done, req);
3755         return req;
3756 }
3757
3758 static void cli_raw_tcon_done(struct tevent_req *subreq)
3759 {
3760         struct tevent_req *req = tevent_req_callback_data(
3761                 subreq, struct tevent_req);
3762         struct cli_raw_tcon_state *state = tevent_req_data(
3763                 req, struct cli_raw_tcon_state);
3764         NTSTATUS status;
3765
3766         status = cli_smb_recv(subreq, state, NULL, 2, NULL, &state->ret_vwv,
3767                               NULL, NULL);
3768         TALLOC_FREE(subreq);
3769         if (tevent_req_nterror(req, status)) {
3770                 return;
3771         }
3772         tevent_req_done(req);
3773 }
3774
3775 static NTSTATUS cli_raw_tcon_recv(struct tevent_req *req,
3776                                   uint16_t *max_xmit, uint16_t *tid)
3777 {
3778         struct cli_raw_tcon_state *state = tevent_req_data(
3779                 req, struct cli_raw_tcon_state);
3780         NTSTATUS status;
3781
3782         if (tevent_req_is_nterror(req, &status)) {
3783                 return status;
3784         }
3785         *max_xmit = SVAL(state->ret_vwv + 0, 0);
3786         *tid = SVAL(state->ret_vwv + 1, 0);
3787         return NT_STATUS_OK;
3788 }
3789
3790 NTSTATUS cli_raw_tcon(struct cli_state *cli,
3791                       const char *service, const char *pass, const char *dev,
3792                       uint16_t *max_xmit, uint16_t *tid)
3793 {
3794         struct tevent_context *ev;
3795         struct tevent_req *req;
3796         NTSTATUS status = NT_STATUS_NO_MEMORY;
3797
3798         ev = samba_tevent_context_init(talloc_tos());
3799         if (ev == NULL) {
3800                 goto fail;
3801         }
3802         req = cli_raw_tcon_send(ev, ev, cli, service, pass, dev);
3803         if (req == NULL) {
3804                 goto fail;
3805         }
3806         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
3807                 goto fail;
3808         }
3809         status = cli_raw_tcon_recv(req, max_xmit, tid);
3810 fail:
3811         TALLOC_FREE(ev);
3812         return status;
3813 }
3814
3815 /* Return a cli_state pointing at the IPC$ share for the given server */
3816
3817 struct cli_state *get_ipc_connect(char *server,
3818                                 struct sockaddr_storage *server_ss,
3819                                 const struct user_auth_info *user_info)
3820 {
3821         struct cli_state *cli;
3822         NTSTATUS nt_status;
3823         uint32_t flags = CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
3824
3825         if (get_cmdline_auth_info_use_kerberos(user_info)) {
3826                 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
3827         }
3828
3829         flags |= CLI_FULL_CONNECTION_FORCE_SMB1;
3830
3831         nt_status = cli_full_connection(&cli, NULL, server, server_ss, 0, "IPC$", "IPC", 
3832                                         get_cmdline_auth_info_username(user_info),
3833                                         lp_workgroup(),
3834                                         get_cmdline_auth_info_password(user_info),
3835                                         flags,
3836                                         SMB_SIGNING_DEFAULT);
3837
3838         if (NT_STATUS_IS_OK(nt_status)) {
3839                 return cli;
3840         } else if (is_ipaddress(server)) {
3841             /* windows 9* needs a correct NMB name for connections */
3842             fstring remote_name;
3843
3844             if (name_status_find("*", 0, 0, server_ss, remote_name)) {
3845                 cli = get_ipc_connect(remote_name, server_ss, user_info);
3846                 if (cli)
3847                     return cli;
3848             }
3849         }
3850         return NULL;
3851 }
3852
3853 /*
3854  * Given the IP address of a master browser on the network, return its
3855  * workgroup and connect to it.
3856  *
3857  * This function is provided to allow additional processing beyond what
3858  * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
3859  * browsers and obtain each master browsers' list of domains (in case the
3860  * first master browser is recently on the network and has not yet
3861  * synchronized with other master browsers and therefore does not yet have the
3862  * entire network browse list)
3863  */
3864
3865 struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx,
3866                                 struct sockaddr_storage *mb_ip,
3867                                 const struct user_auth_info *user_info,
3868                                 char **pp_workgroup_out)
3869 {
3870         char addr[INET6_ADDRSTRLEN];
3871         fstring name;
3872         struct cli_state *cli;
3873         struct sockaddr_storage server_ss;
3874
3875         *pp_workgroup_out = NULL;
3876
3877         print_sockaddr(addr, sizeof(addr), mb_ip);
3878         DEBUG(99, ("Looking up name of master browser %s\n",
3879                    addr));
3880
3881         /*
3882          * Do a name status query to find out the name of the master browser.
3883          * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
3884          * master browser will not respond to a wildcard query (or, at least,
3885          * an NT4 server acting as the domain master browser will not).
3886          *
3887          * We might be able to use ONLY the query on MSBROWSE, but that's not
3888          * yet been tested with all Windows versions, so until it is, leave
3889          * the original wildcard query as the first choice and fall back to
3890          * MSBROWSE if the wildcard query fails.
3891          */
3892         if (!name_status_find("*", 0, 0x1d, mb_ip, name) &&
3893             !name_status_find(MSBROWSE, 1, 0x1d, mb_ip, name)) {
3894
3895                 DEBUG(99, ("Could not retrieve name status for %s\n",
3896                            addr));
3897                 return NULL;
3898         }
3899
3900         if (!find_master_ip(name, &server_ss)) {
3901                 DEBUG(99, ("Could not find master ip for %s\n", name));
3902                 return NULL;
3903         }
3904
3905         *pp_workgroup_out = talloc_strdup(ctx, name);
3906
3907         DEBUG(4, ("found master browser %s, %s\n", name, addr));
3908
3909         print_sockaddr(addr, sizeof(addr), &server_ss);
3910         cli = get_ipc_connect(addr, &server_ss, user_info);
3911
3912         return cli;
3913 }
3914
3915 /*
3916  * Return the IP address and workgroup of a master browser on the network, and
3917  * connect to it.
3918  */
3919
3920 struct cli_state *get_ipc_connect_master_ip_bcast(TALLOC_CTX *ctx,
3921                                         const struct user_auth_info *user_info,
3922                                         char **pp_workgroup_out)
3923 {
3924         struct sockaddr_storage *ip_list;
3925         struct cli_state *cli;
3926         int i, count;
3927         NTSTATUS status;
3928
3929         *pp_workgroup_out = NULL;
3930
3931         DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
3932
3933         /* Go looking for workgroups by broadcasting on the local network */
3934
3935         status = name_resolve_bcast(MSBROWSE, 1, talloc_tos(),
3936                                     &ip_list, &count);
3937         if (!NT_STATUS_IS_OK(status)) {
3938                 DEBUG(99, ("No master browsers responded: %s\n",
3939                            nt_errstr(status)));
3940                 return NULL;
3941         }
3942
3943         for (i = 0; i < count; i++) {
3944                 char addr[INET6_ADDRSTRLEN];
3945                 print_sockaddr(addr, sizeof(addr), &ip_list[i]);
3946                 DEBUG(99, ("Found master browser %s\n", addr));
3947
3948                 cli = get_ipc_connect_master_ip(ctx, &ip_list[i],
3949                                 user_info, pp_workgroup_out);
3950                 if (cli)
3951                         return(cli);
3952         }
3953
3954         return NULL;
3955 }