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