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