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