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