libsmb: Fix whitespace and a typo
[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 (tevent_req_nterror(req, status)) {
1746                 DEBUG(3, ("NT1 login failed: %s\n", nt_errstr(status)));
1747                 return;
1748         }
1749
1750         status = cli_state_update_after_sesssetup(state->cli,
1751                                                   state->out_native_os,
1752                                                   state->out_native_lm,
1753                                                   state->out_primary_domain);
1754         if (tevent_req_nterror(req, status)) {
1755                 return;
1756         }
1757
1758         ok = smb1cli_conn_activate_signing(cli->conn,
1759                                            state->session_key,
1760                                            state->upassword_blob);
1761         if (ok) {
1762                 ok = smb1cli_conn_check_signing(cli->conn, inbuf, 1);
1763                 if (!ok) {
1764                         tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1765                         return;
1766                 }
1767         }
1768
1769         if (state->session_key.data) {
1770                 struct smbXcli_session *session = cli->smb1.session;
1771
1772                 status = smb1cli_session_set_session_key(session,
1773                                                          state->session_key);
1774                 if (tevent_req_nterror(req, status)) {
1775                         return;
1776                 }
1777         }
1778
1779         tevent_req_done(req);
1780 }
1781
1782 static void cli_session_setup_creds_done_lm21(struct tevent_req *subreq)
1783 {
1784         struct tevent_req *req = tevent_req_callback_data(
1785                 subreq, struct tevent_req);
1786         struct cli_session_setup_creds_state *state = tevent_req_data(
1787                 req, struct cli_session_setup_creds_state);
1788         NTSTATUS status;
1789
1790         status = smb1cli_session_setup_lm21_recv(subreq, state,
1791                                                  &state->out_native_os,
1792                                                  &state->out_native_lm);
1793         TALLOC_FREE(subreq);
1794         if (tevent_req_nterror(req, status)) {
1795                 DEBUG(3, ("LM21 login failed: %s\n", nt_errstr(status)));
1796                 return;
1797         }
1798
1799         status = cli_state_update_after_sesssetup(state->cli,
1800                                                   state->out_native_os,
1801                                                   state->out_native_lm,
1802                                                   NULL);
1803         if (tevent_req_nterror(req, status)) {
1804                 return;
1805         }
1806
1807         tevent_req_done(req);
1808 }
1809
1810 NTSTATUS cli_session_setup_creds_recv(struct tevent_req *req)
1811 {
1812         return tevent_req_simple_recv_ntstatus(req);
1813 }
1814
1815 NTSTATUS cli_session_setup_creds(struct cli_state *cli,
1816                                  struct cli_credentials *creds)
1817 {
1818         struct tevent_context *ev;
1819         struct tevent_req *req;
1820         NTSTATUS status = NT_STATUS_NO_MEMORY;
1821
1822         if (smbXcli_conn_has_async_calls(cli->conn)) {
1823                 return NT_STATUS_INVALID_PARAMETER;
1824         }
1825         ev = samba_tevent_context_init(talloc_tos());
1826         if (ev == NULL) {
1827                 goto fail;
1828         }
1829         req = cli_session_setup_creds_send(ev, ev, cli, creds);
1830         if (req == NULL) {
1831                 goto fail;
1832         }
1833         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1834                 goto fail;
1835         }
1836         status = cli_session_setup_creds_recv(req);
1837  fail:
1838         TALLOC_FREE(ev);
1839         return status;
1840 }
1841
1842 NTSTATUS cli_session_setup_anon(struct cli_state *cli)
1843 {
1844         NTSTATUS status;
1845         struct cli_credentials *creds = NULL;
1846
1847         creds = cli_credentials_init_anon(cli);
1848         if (creds == NULL) {
1849                 return NT_STATUS_NO_MEMORY;
1850         }
1851
1852         status = cli_session_setup_creds(cli, creds);
1853         TALLOC_FREE(creds);
1854         if (!NT_STATUS_IS_OK(status)) {
1855                 return status;
1856         }
1857
1858         return NT_STATUS_OK;
1859 }
1860
1861 /****************************************************************************
1862  Send a uloggoff.
1863 *****************************************************************************/
1864
1865 struct cli_ulogoff_state {
1866         struct cli_state *cli;
1867         uint16_t vwv[3];
1868 };
1869
1870 static void cli_ulogoff_done(struct tevent_req *subreq);
1871
1872 static struct tevent_req *cli_ulogoff_send(TALLOC_CTX *mem_ctx,
1873                                     struct tevent_context *ev,
1874                                     struct cli_state *cli)
1875 {
1876         struct tevent_req *req, *subreq;
1877         struct cli_ulogoff_state *state;
1878
1879         req = tevent_req_create(mem_ctx, &state, struct cli_ulogoff_state);
1880         if (req == NULL) {
1881                 return NULL;
1882         }
1883         state->cli = cli;
1884
1885         SCVAL(state->vwv+0, 0, 0xFF);
1886         SCVAL(state->vwv+1, 0, 0);
1887         SSVAL(state->vwv+2, 0, 0);
1888
1889         subreq = cli_smb_send(state, ev, cli, SMBulogoffX, 0, 0, 2, state->vwv,
1890                               0, NULL);
1891         if (tevent_req_nomem(subreq, req)) {
1892                 return tevent_req_post(req, ev);
1893         }
1894         tevent_req_set_callback(subreq, cli_ulogoff_done, req);
1895         return req;
1896 }
1897
1898 static void cli_ulogoff_done(struct tevent_req *subreq)
1899 {
1900         struct tevent_req *req = tevent_req_callback_data(
1901                 subreq, struct tevent_req);
1902         struct cli_ulogoff_state *state = tevent_req_data(
1903                 req, struct cli_ulogoff_state);
1904         NTSTATUS status;
1905
1906         status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
1907         if (tevent_req_nterror(req, status)) {
1908                 return;
1909         }
1910         cli_state_set_uid(state->cli, UID_FIELD_INVALID);
1911         tevent_req_done(req);
1912 }
1913
1914 static NTSTATUS cli_ulogoff_recv(struct tevent_req *req)
1915 {
1916         return tevent_req_simple_recv_ntstatus(req);
1917 }
1918
1919 NTSTATUS cli_ulogoff(struct cli_state *cli)
1920 {
1921         struct tevent_context *ev;
1922         struct tevent_req *req;
1923         NTSTATUS status = NT_STATUS_NO_MEMORY;
1924
1925         if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
1926                 status = smb2cli_logoff(cli->conn,
1927                                         cli->timeout,
1928                                         cli->smb2.session);
1929                 if (!NT_STATUS_IS_OK(status)) {
1930                         return status;
1931                 }
1932                 smb2cli_session_set_id_and_flags(cli->smb2.session,
1933                                                  UINT64_MAX, 0);
1934                 return NT_STATUS_OK;
1935         }
1936
1937         if (smbXcli_conn_has_async_calls(cli->conn)) {
1938                 return NT_STATUS_INVALID_PARAMETER;
1939         }
1940         ev = samba_tevent_context_init(talloc_tos());
1941         if (ev == NULL) {
1942                 goto fail;
1943         }
1944         req = cli_ulogoff_send(ev, ev, cli);
1945         if (req == NULL) {
1946                 goto fail;
1947         }
1948         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1949                 goto fail;
1950         }
1951         status = cli_ulogoff_recv(req);
1952 fail:
1953         TALLOC_FREE(ev);
1954         return status;
1955 }
1956
1957 /****************************************************************************
1958  Send a tconX.
1959 ****************************************************************************/
1960
1961 struct cli_tcon_andx_state {
1962         struct cli_state *cli;
1963         uint16_t vwv[4];
1964         struct iovec bytes;
1965 };
1966
1967 static void cli_tcon_andx_done(struct tevent_req *subreq);
1968
1969 struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx,
1970                                         struct tevent_context *ev,
1971                                         struct cli_state *cli,
1972                                         const char *share, const char *dev,
1973                                         const char *pass, int passlen,
1974                                         struct tevent_req **psmbreq)
1975 {
1976         struct tevent_req *req, *subreq;
1977         struct cli_tcon_andx_state *state;
1978         uint8_t p24[24];
1979         uint16_t *vwv;
1980         char *tmp = NULL;
1981         uint8_t *bytes;
1982         uint16_t sec_mode = smb1cli_conn_server_security_mode(cli->conn);
1983         uint16_t tcon_flags = 0;
1984
1985         *psmbreq = NULL;
1986
1987         req = tevent_req_create(mem_ctx, &state, struct cli_tcon_andx_state);
1988         if (req == NULL) {
1989                 return NULL;
1990         }
1991         state->cli = cli;
1992         vwv = state->vwv;
1993
1994         TALLOC_FREE(cli->smb1.tcon);
1995         cli->smb1.tcon = smbXcli_tcon_create(cli);
1996         if (tevent_req_nomem(cli->smb1.tcon, req)) {
1997                 return tevent_req_post(req, ev);
1998         }
1999         smb1cli_tcon_set_id(cli->smb1.tcon, UINT16_MAX);
2000
2001         cli->share = talloc_strdup(cli, share);
2002         if (!cli->share) {
2003                 return NULL;
2004         }
2005
2006         /* in user level security don't send a password now */
2007         if (sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {
2008                 passlen = 1;
2009                 pass = "";
2010         } else if (pass == NULL) {
2011                 DEBUG(1, ("Server not using user level security and no "
2012                           "password supplied.\n"));
2013                 goto access_denied;
2014         }
2015
2016         if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) &&
2017             *pass && passlen != 24) {
2018                 if (!lp_client_lanman_auth()) {
2019                         DEBUG(1, ("Server requested LANMAN password "
2020                                   "(share-level security) but "
2021                                   "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2022                         goto access_denied;
2023                 }
2024
2025                 /*
2026                  * Non-encrypted passwords - convert to DOS codepage before
2027                  * encryption.
2028                  */
2029                 SMBencrypt(pass, smb1cli_conn_server_challenge(cli->conn), p24);
2030                 passlen = 24;
2031                 pass = (const char *)p24;
2032         } else {
2033                 if((sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL
2034                                      |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE))
2035                    == 0) {
2036                         uint8_t *tmp_pass;
2037
2038                         if (!lp_client_plaintext_auth() && (*pass)) {
2039                                 DEBUG(1, ("Server requested PLAINTEXT "
2040                                           "password but "
2041                                           "'client plaintext auth = no' or 'client ntlmv2 auth = yes'\n"));
2042                                 goto access_denied;
2043                         }
2044
2045                         /*
2046                          * Non-encrypted passwords - convert to DOS codepage
2047                          * before using.
2048                          */
2049                         tmp_pass = talloc_array(talloc_tos(), uint8_t, 0);
2050                         if (tevent_req_nomem(tmp_pass, req)) {
2051                                 return tevent_req_post(req, ev);
2052                         }
2053                         tmp_pass = trans2_bytes_push_str(tmp_pass,
2054                                                          false, /* always DOS */
2055                                                          pass,
2056                                                          passlen,
2057                                                          NULL);
2058                         if (tevent_req_nomem(tmp_pass, req)) {
2059                                 return tevent_req_post(req, ev);
2060                         }
2061                         pass = (const char *)tmp_pass;
2062                         passlen = talloc_get_size(tmp_pass);
2063                 }
2064         }
2065
2066         tcon_flags |= TCONX_FLAG_EXTENDED_RESPONSE;
2067         tcon_flags |= TCONX_FLAG_EXTENDED_SIGNATURES;
2068
2069         SCVAL(vwv+0, 0, 0xFF);
2070         SCVAL(vwv+0, 1, 0);
2071         SSVAL(vwv+1, 0, 0);
2072         SSVAL(vwv+2, 0, tcon_flags);
2073         SSVAL(vwv+3, 0, passlen);
2074
2075         if (passlen && pass) {
2076                 bytes = (uint8_t *)talloc_memdup(state, pass, passlen);
2077         } else {
2078                 bytes = talloc_array(state, uint8_t, 0);
2079         }
2080
2081         /*
2082          * Add the sharename
2083          */
2084         tmp = talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
2085                                          smbXcli_conn_remote_name(cli->conn), share);
2086         if (tmp == NULL) {
2087                 TALLOC_FREE(req);
2088                 return NULL;
2089         }
2090         bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), tmp, strlen(tmp)+1,
2091                                    NULL);
2092         TALLOC_FREE(tmp);
2093
2094         /*
2095          * Add the devicetype
2096          */
2097         tmp = talloc_strdup_upper(talloc_tos(), dev);
2098         if (tmp == NULL) {
2099                 TALLOC_FREE(req);
2100                 return NULL;
2101         }
2102         bytes = smb_bytes_push_str(bytes, false, tmp, strlen(tmp)+1, NULL);
2103         TALLOC_FREE(tmp);
2104
2105         if (bytes == NULL) {
2106                 TALLOC_FREE(req);
2107                 return NULL;
2108         }
2109
2110         state->bytes.iov_base = (void *)bytes;
2111         state->bytes.iov_len = talloc_get_size(bytes);
2112
2113         subreq = cli_smb_req_create(state, ev, cli, SMBtconX, 0, 0, 4, vwv,
2114                                     1, &state->bytes);
2115         if (subreq == NULL) {
2116                 TALLOC_FREE(req);
2117                 return NULL;
2118         }
2119         tevent_req_set_callback(subreq, cli_tcon_andx_done, req);
2120         *psmbreq = subreq;
2121         return req;
2122
2123  access_denied:
2124         tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
2125         return tevent_req_post(req, ev);
2126 }
2127
2128 struct tevent_req *cli_tcon_andx_send(TALLOC_CTX *mem_ctx,
2129                                       struct tevent_context *ev,
2130                                       struct cli_state *cli,
2131                                       const char *share, const char *dev,
2132                                       const char *pass, int passlen)
2133 {
2134         struct tevent_req *req, *subreq;
2135         NTSTATUS status;
2136
2137         req = cli_tcon_andx_create(mem_ctx, ev, cli, share, dev, pass, passlen,
2138                                    &subreq);
2139         if (req == NULL) {
2140                 return NULL;
2141         }
2142         if (subreq == NULL) {
2143                 return req;
2144         }
2145         status = smb1cli_req_chain_submit(&subreq, 1);
2146         if (tevent_req_nterror(req, status)) {
2147                 return tevent_req_post(req, ev);
2148         }
2149         return req;
2150 }
2151
2152 static void cli_tcon_andx_done(struct tevent_req *subreq)
2153 {
2154         struct tevent_req *req = tevent_req_callback_data(
2155                 subreq, struct tevent_req);
2156         struct cli_tcon_andx_state *state = tevent_req_data(
2157                 req, struct cli_tcon_andx_state);
2158         struct cli_state *cli = state->cli;
2159         uint8_t *in;
2160         uint8_t *inhdr;
2161         uint8_t wct;
2162         uint16_t *vwv;
2163         uint32_t num_bytes;
2164         uint8_t *bytes;
2165         NTSTATUS status;
2166         uint16_t optional_support = 0;
2167
2168         status = cli_smb_recv(subreq, state, &in, 0, &wct, &vwv,
2169                               &num_bytes, &bytes);
2170         TALLOC_FREE(subreq);
2171         if (tevent_req_nterror(req, status)) {
2172                 return;
2173         }
2174
2175         inhdr = in + NBT_HDR_SIZE;
2176
2177         if (num_bytes) {
2178                 if (pull_string_talloc(cli,
2179                                        (const char *)inhdr,
2180                                        SVAL(inhdr, HDR_FLG2),
2181                                        &cli->dev,
2182                                        bytes,
2183                                        num_bytes,
2184                                        STR_TERMINATE|STR_ASCII) == -1) {
2185                         tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2186                         return;
2187                 }
2188         } else {
2189                 cli->dev = talloc_strdup(cli, "");
2190                 if (cli->dev == NULL) {
2191                         tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2192                         return;
2193                 }
2194         }
2195
2196         if ((smbXcli_conn_protocol(cli->conn) >= PROTOCOL_NT1) && (num_bytes == 3)) {
2197                 /* almost certainly win95 - enable bug fixes */
2198                 cli->win95 = True;
2199         }
2200
2201         /*
2202          * Make sure that we have the optional support 16-bit field. WCT > 2.
2203          * Avoids issues when connecting to Win9x boxes sharing files
2204          */
2205
2206         if ((wct > 2) && (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_LANMAN2)) {
2207                 optional_support = SVAL(vwv+2, 0);
2208         }
2209
2210         if (optional_support & SMB_EXTENDED_SIGNATURES) {
2211                 smb1cli_session_protect_session_key(cli->smb1.session);
2212         }
2213
2214         smb1cli_tcon_set_values(state->cli->smb1.tcon,
2215                                 SVAL(inhdr, HDR_TID),
2216                                 optional_support,
2217                                 0, /* maximal_access */
2218                                 0, /* guest_maximal_access */
2219                                 NULL, /* service */
2220                                 NULL); /* fs_type */
2221
2222         tevent_req_done(req);
2223 }
2224
2225 NTSTATUS cli_tcon_andx_recv(struct tevent_req *req)
2226 {
2227         return tevent_req_simple_recv_ntstatus(req);
2228 }
2229
2230 NTSTATUS cli_tcon_andx(struct cli_state *cli, const char *share,
2231                        const char *dev, const char *pass, int passlen)
2232 {
2233         TALLOC_CTX *frame = talloc_stackframe();
2234         struct tevent_context *ev;
2235         struct tevent_req *req;
2236         NTSTATUS status = NT_STATUS_NO_MEMORY;
2237
2238         if (smbXcli_conn_has_async_calls(cli->conn)) {
2239                 /*
2240                  * Can't use sync call while an async call is in flight
2241                  */
2242                 status = NT_STATUS_INVALID_PARAMETER;
2243                 goto fail;
2244         }
2245
2246         ev = samba_tevent_context_init(frame);
2247         if (ev == NULL) {
2248                 goto fail;
2249         }
2250
2251         req = cli_tcon_andx_send(frame, ev, cli, share, dev, pass, passlen);
2252         if (req == NULL) {
2253                 goto fail;
2254         }
2255
2256         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2257                 goto fail;
2258         }
2259
2260         status = cli_tcon_andx_recv(req);
2261  fail:
2262         TALLOC_FREE(frame);
2263         return status;
2264 }
2265
2266 struct cli_tree_connect_state {
2267         struct cli_state *cli;
2268 };
2269
2270 static struct tevent_req *cli_raw_tcon_send(
2271         TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
2272         const char *service, const char *pass, const char *dev);
2273 static NTSTATUS cli_raw_tcon_recv(struct tevent_req *req,
2274                                   uint16_t *max_xmit, uint16_t *tid);
2275
2276 static void cli_tree_connect_smb2_done(struct tevent_req *subreq);
2277 static void cli_tree_connect_andx_done(struct tevent_req *subreq);
2278 static void cli_tree_connect_raw_done(struct tevent_req *subreq);
2279
2280 static struct tevent_req *cli_tree_connect_send(
2281         TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
2282         const char *share, const char *dev, const char *pass)
2283 {
2284         struct tevent_req *req, *subreq;
2285         struct cli_tree_connect_state *state;
2286         int passlen;
2287
2288         if (pass == NULL) {
2289                 pass = "";
2290         }
2291         passlen = strlen(pass) + 1;
2292
2293         req = tevent_req_create(mem_ctx, &state,
2294                                 struct cli_tree_connect_state);
2295         if (req == NULL) {
2296                 return NULL;
2297         }
2298         state->cli = cli;
2299
2300         cli->share = talloc_strdup(cli, share);
2301         if (tevent_req_nomem(cli->share, req)) {
2302                 return tevent_req_post(req, ev);
2303         }
2304
2305         if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
2306                 char *unc;
2307
2308                 TALLOC_FREE(cli->smb2.tcon);
2309                 cli->smb2.tcon = smbXcli_tcon_create(cli);
2310                 if (tevent_req_nomem(cli->smb2.tcon, req)) {
2311                         return tevent_req_post(req, ev);
2312                 }
2313
2314                 unc = talloc_asprintf(state, "\\\\%s\\%s",
2315                                       smbXcli_conn_remote_name(cli->conn),
2316                                       share);
2317                 if (tevent_req_nomem(unc, req)) {
2318                         return tevent_req_post(req, ev);
2319                 }
2320
2321                 subreq = smb2cli_tcon_send(state, ev, cli->conn, cli->timeout,
2322                                            cli->smb2.session, cli->smb2.tcon,
2323                                            0, /* flags */
2324                                            unc);
2325                 if (tevent_req_nomem(subreq, req)) {
2326                         return tevent_req_post(req, ev);
2327                 }
2328                 tevent_req_set_callback(subreq, cli_tree_connect_smb2_done,
2329                                         req);
2330                 return req;
2331         }
2332
2333         if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_LANMAN1) {
2334                 subreq = cli_tcon_andx_send(state, ev, cli, share, dev,
2335                                             pass, passlen);
2336                 if (tevent_req_nomem(subreq, req)) {
2337                         return tevent_req_post(req, ev);
2338                 }
2339                 tevent_req_set_callback(subreq, cli_tree_connect_andx_done,
2340                                         req);
2341                 return req;
2342         }
2343
2344         subreq = cli_raw_tcon_send(state, ev, cli, share, pass, dev);
2345         if (tevent_req_nomem(subreq, req)) {
2346                 return tevent_req_post(req, ev);
2347         }
2348         tevent_req_set_callback(subreq, cli_tree_connect_raw_done, req);
2349
2350         return req;
2351 }
2352
2353 static void cli_tree_connect_smb2_done(struct tevent_req *subreq)
2354 {
2355         NTSTATUS status = smb2cli_tcon_recv(subreq);
2356         tevent_req_simple_finish_ntstatus(subreq, status);
2357 }
2358
2359 static void cli_tree_connect_andx_done(struct tevent_req *subreq)
2360 {
2361         NTSTATUS status = cli_tcon_andx_recv(subreq);
2362         tevent_req_simple_finish_ntstatus(subreq, status);
2363 }
2364
2365 static void cli_tree_connect_raw_done(struct tevent_req *subreq)
2366 {
2367         struct tevent_req *req = tevent_req_callback_data(
2368                 subreq, struct tevent_req);
2369         struct cli_tree_connect_state *state = tevent_req_data(
2370                 req, struct cli_tree_connect_state);
2371         NTSTATUS status;
2372         uint16_t max_xmit = 0;
2373         uint16_t tid = 0;
2374
2375         status = cli_raw_tcon_recv(subreq, &max_xmit, &tid);
2376         if (tevent_req_nterror(req, status)) {
2377                 return;
2378         }
2379
2380         smb1cli_tcon_set_values(state->cli->smb1.tcon,
2381                                 tid,
2382                                 0, /* optional_support */
2383                                 0, /* maximal_access */
2384                                 0, /* guest_maximal_access */
2385                                 NULL, /* service */
2386                                 NULL); /* fs_type */
2387
2388         tevent_req_done(req);
2389 }
2390
2391 static NTSTATUS cli_tree_connect_recv(struct tevent_req *req)
2392 {
2393         return tevent_req_simple_recv_ntstatus(req);
2394 }
2395
2396 NTSTATUS cli_tree_connect(struct cli_state *cli, const char *share,
2397                           const char *dev, const char *pass)
2398 {
2399         struct tevent_context *ev;
2400         struct tevent_req *req;
2401         NTSTATUS status = NT_STATUS_NO_MEMORY;
2402
2403         if (smbXcli_conn_has_async_calls(cli->conn)) {
2404                 return NT_STATUS_INVALID_PARAMETER;
2405         }
2406         ev = samba_tevent_context_init(talloc_tos());
2407         if (ev == NULL) {
2408                 goto fail;
2409         }
2410         req = cli_tree_connect_send(ev, ev, cli, share, dev, pass);
2411         if (req == NULL) {
2412                 goto fail;
2413         }
2414         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2415                 goto fail;
2416         }
2417         status = cli_tree_connect_recv(req);
2418 fail:
2419         TALLOC_FREE(ev);
2420         return status;
2421 }
2422
2423 NTSTATUS cli_tree_connect_creds(struct cli_state *cli,
2424                                 const char *share, const char *dev,
2425                                 struct cli_credentials *creds)
2426 {
2427         const char *pw = NULL;
2428
2429         if (creds != NULL) {
2430                 pw = cli_credentials_get_password(creds);
2431         }
2432
2433         return cli_tree_connect(cli, share, dev, pw);
2434 }
2435
2436 /****************************************************************************
2437  Send a tree disconnect.
2438 ****************************************************************************/
2439
2440 struct cli_tdis_state {
2441         struct cli_state *cli;
2442 };
2443
2444 static void cli_tdis_done(struct tevent_req *subreq);
2445
2446 static struct tevent_req *cli_tdis_send(TALLOC_CTX *mem_ctx,
2447                                  struct tevent_context *ev,
2448                                  struct cli_state *cli)
2449 {
2450         struct tevent_req *req, *subreq;
2451         struct cli_tdis_state *state;
2452
2453         req = tevent_req_create(mem_ctx, &state, struct cli_tdis_state);
2454         if (req == NULL) {
2455                 return NULL;
2456         }
2457         state->cli = cli;
2458
2459         subreq = cli_smb_send(state, ev, cli, SMBtdis, 0, 0, 0, NULL, 0, NULL);
2460         if (tevent_req_nomem(subreq, req)) {
2461                 return tevent_req_post(req, ev);
2462         }
2463         tevent_req_set_callback(subreq, cli_tdis_done, req);
2464         return req;
2465 }
2466
2467 static void cli_tdis_done(struct tevent_req *subreq)
2468 {
2469         struct tevent_req *req = tevent_req_callback_data(
2470                 subreq, struct tevent_req);
2471         struct cli_tdis_state *state = tevent_req_data(
2472                 req, struct cli_tdis_state);
2473         NTSTATUS status;
2474
2475         status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
2476         TALLOC_FREE(subreq);
2477         if (tevent_req_nterror(req, status)) {
2478                 return;
2479         }
2480         TALLOC_FREE(state->cli->smb1.tcon);
2481         tevent_req_done(req);
2482 }
2483
2484 static NTSTATUS cli_tdis_recv(struct tevent_req *req)
2485 {
2486         return tevent_req_simple_recv_ntstatus(req);
2487 }
2488
2489 NTSTATUS cli_tdis(struct cli_state *cli)
2490 {
2491         struct tevent_context *ev;
2492         struct tevent_req *req;
2493         NTSTATUS status = NT_STATUS_NO_MEMORY;
2494
2495         if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
2496                 status = smb2cli_tdis(cli->conn,
2497                                     cli->timeout,
2498                                     cli->smb2.session,
2499                                     cli->smb2.tcon);
2500                 if (NT_STATUS_IS_OK(status)) {
2501                         TALLOC_FREE(cli->smb2.tcon);
2502                 }
2503                 return status;
2504         }
2505
2506         if (smbXcli_conn_has_async_calls(cli->conn)) {
2507                 return NT_STATUS_INVALID_PARAMETER;
2508         }
2509         ev = samba_tevent_context_init(talloc_tos());
2510         if (ev == NULL) {
2511                 goto fail;
2512         }
2513         req = cli_tdis_send(ev, ev, cli);
2514         if (req == NULL) {
2515                 goto fail;
2516         }
2517         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2518                 goto fail;
2519         }
2520         status = cli_tdis_recv(req);
2521 fail:
2522         TALLOC_FREE(ev);
2523         return status;
2524 }
2525
2526 struct cli_connect_sock_state {
2527         const char **called_names;
2528         const char **calling_names;
2529         int *called_types;
2530         int fd;
2531         uint16_t port;
2532 };
2533
2534 static void cli_connect_sock_done(struct tevent_req *subreq);
2535
2536 /*
2537  * Async only if we don't have to look up the name, i.e. "pss" is set with a
2538  * nonzero address.
2539  */
2540
2541 static struct tevent_req *cli_connect_sock_send(
2542         TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2543         const char *host, int name_type, const struct sockaddr_storage *pss,
2544         const char *myname, uint16_t port)
2545 {
2546         struct tevent_req *req, *subreq;
2547         struct cli_connect_sock_state *state;
2548         struct sockaddr_storage *addrs = NULL;
2549         unsigned i;
2550         unsigned num_addrs = 0;
2551         NTSTATUS status;
2552
2553         req = tevent_req_create(mem_ctx, &state,
2554                                 struct cli_connect_sock_state);
2555         if (req == NULL) {
2556                 return NULL;
2557         }
2558
2559         if ((pss == NULL) || is_zero_addr(pss)) {
2560
2561                 /*
2562                  * Here we cheat. resolve_name_list is not async at all. So
2563                  * this call will only be really async if the name lookup has
2564                  * been done externally.
2565                  */
2566
2567                 status = resolve_name_list(state, host, name_type,
2568                                            &addrs, &num_addrs);
2569                 if (tevent_req_nterror(req, status)) {
2570                         return tevent_req_post(req, ev);
2571                 }
2572         } else {
2573                 addrs = talloc_array(state, struct sockaddr_storage, 1);
2574                 if (tevent_req_nomem(addrs, req)) {
2575                         return tevent_req_post(req, ev);
2576                 }
2577                 addrs[0] = *pss;
2578                 num_addrs = 1;
2579         }
2580
2581         state->called_names = talloc_array(state, const char *, num_addrs);
2582         if (tevent_req_nomem(state->called_names, req)) {
2583                 return tevent_req_post(req, ev);
2584         }
2585         state->called_types = talloc_array(state, int, num_addrs);
2586         if (tevent_req_nomem(state->called_types, req)) {
2587                 return tevent_req_post(req, ev);
2588         }
2589         state->calling_names = talloc_array(state, const char *, num_addrs);
2590         if (tevent_req_nomem(state->calling_names, req)) {
2591                 return tevent_req_post(req, ev);
2592         }
2593         for (i=0; i<num_addrs; i++) {
2594                 state->called_names[i] = host;
2595                 state->called_types[i] = name_type;
2596                 state->calling_names[i] = myname;
2597         }
2598
2599         subreq = smbsock_any_connect_send(
2600                 state, ev, addrs, state->called_names, state->called_types,
2601                 state->calling_names, NULL, num_addrs, port);
2602         if (tevent_req_nomem(subreq, req)) {
2603                 return tevent_req_post(req, ev);
2604         }
2605         tevent_req_set_callback(subreq, cli_connect_sock_done, req);
2606         return req;
2607 }
2608
2609 static void cli_connect_sock_done(struct tevent_req *subreq)
2610 {
2611         struct tevent_req *req = tevent_req_callback_data(
2612                 subreq, struct tevent_req);
2613         struct cli_connect_sock_state *state = tevent_req_data(
2614                 req, struct cli_connect_sock_state);
2615         NTSTATUS status;
2616
2617         status = smbsock_any_connect_recv(subreq, &state->fd, NULL,
2618                                           &state->port);
2619         TALLOC_FREE(subreq);
2620         if (tevent_req_nterror(req, status)) {
2621                 return;
2622         }
2623         set_socket_options(state->fd, lp_socket_options());
2624         tevent_req_done(req);
2625 }
2626
2627 static NTSTATUS cli_connect_sock_recv(struct tevent_req *req,
2628                                       int *pfd, uint16_t *pport)
2629 {
2630         struct cli_connect_sock_state *state = tevent_req_data(
2631                 req, struct cli_connect_sock_state);
2632         NTSTATUS status;
2633
2634         if (tevent_req_is_nterror(req, &status)) {
2635                 return status;
2636         }
2637         *pfd = state->fd;
2638         *pport = state->port;
2639         return NT_STATUS_OK;
2640 }
2641
2642 struct cli_connect_nb_state {
2643         const char *desthost;
2644         enum smb_signing_setting signing_state;
2645         int flags;
2646         struct cli_state *cli;
2647 };
2648
2649 static void cli_connect_nb_done(struct tevent_req *subreq);
2650
2651 static struct tevent_req *cli_connect_nb_send(
2652         TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2653         const char *host, const struct sockaddr_storage *dest_ss,
2654         uint16_t port, int name_type, const char *myname,
2655         enum smb_signing_setting signing_state, int flags)
2656 {
2657         struct tevent_req *req, *subreq;
2658         struct cli_connect_nb_state *state;
2659
2660         req = tevent_req_create(mem_ctx, &state, struct cli_connect_nb_state);
2661         if (req == NULL) {
2662                 return NULL;
2663         }
2664         state->signing_state = signing_state;
2665         state->flags = flags;
2666
2667         if (host != NULL) {
2668                 char *p = strchr(host, '#');
2669
2670                 if (p != NULL) {
2671                         name_type = strtol(p+1, NULL, 16);
2672                         host = talloc_strndup(state, host, p - host);
2673                         if (tevent_req_nomem(host, req)) {
2674                                 return tevent_req_post(req, ev);
2675                         }
2676                 }
2677
2678                 state->desthost = host;
2679         } else if (dest_ss != NULL) {
2680                 state->desthost = print_canonical_sockaddr(state, dest_ss);
2681                 if (tevent_req_nomem(state->desthost, req)) {
2682                         return tevent_req_post(req, ev);
2683                 }
2684         } else {
2685                 /* No host or dest_ss given. Error out. */
2686                 tevent_req_error(req, EINVAL);
2687                 return tevent_req_post(req, ev);
2688         }
2689
2690         subreq = cli_connect_sock_send(state, ev, host, name_type, dest_ss,
2691                                        myname, port);
2692         if (tevent_req_nomem(subreq, req)) {
2693                 return tevent_req_post(req, ev);
2694         }
2695         tevent_req_set_callback(subreq, cli_connect_nb_done, req);
2696         return req;
2697 }
2698
2699 static void cli_connect_nb_done(struct tevent_req *subreq)
2700 {
2701         struct tevent_req *req = tevent_req_callback_data(
2702                 subreq, struct tevent_req);
2703         struct cli_connect_nb_state *state = tevent_req_data(
2704                 req, struct cli_connect_nb_state);
2705         NTSTATUS status;
2706         int fd = 0;
2707         uint16_t port;
2708
2709         status = cli_connect_sock_recv(subreq, &fd, &port);
2710         TALLOC_FREE(subreq);
2711         if (tevent_req_nterror(req, status)) {
2712                 return;
2713         }
2714
2715         state->cli = cli_state_create(state, fd, state->desthost,
2716                                       state->signing_state, state->flags);
2717         if (tevent_req_nomem(state->cli, req)) {
2718                 close(fd);
2719                 return;
2720         }
2721         tevent_req_done(req);
2722 }
2723
2724 static NTSTATUS cli_connect_nb_recv(struct tevent_req *req,
2725                                     struct cli_state **pcli)
2726 {
2727         struct cli_connect_nb_state *state = tevent_req_data(
2728                 req, struct cli_connect_nb_state);
2729         NTSTATUS status;
2730
2731         if (tevent_req_is_nterror(req, &status)) {
2732                 return status;
2733         }
2734         *pcli = talloc_move(NULL, &state->cli);
2735         return NT_STATUS_OK;
2736 }
2737
2738 NTSTATUS cli_connect_nb(const char *host, const struct sockaddr_storage *dest_ss,
2739                         uint16_t port, int name_type, const char *myname,
2740                         enum smb_signing_setting signing_state, int flags, struct cli_state **pcli)
2741 {
2742         struct tevent_context *ev;
2743         struct tevent_req *req;
2744         NTSTATUS status = NT_STATUS_NO_MEMORY;
2745
2746         ev = samba_tevent_context_init(talloc_tos());
2747         if (ev == NULL) {
2748                 goto fail;
2749         }
2750         req = cli_connect_nb_send(ev, ev, host, dest_ss, port, name_type,
2751                                   myname, signing_state, flags);
2752         if (req == NULL) {
2753                 goto fail;
2754         }
2755         if (!tevent_req_set_endtime(req, ev, timeval_current_ofs(20, 0))) {
2756                 goto fail;
2757         }
2758         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2759                 goto fail;
2760         }
2761         status = cli_connect_nb_recv(req, pcli);
2762 fail:
2763         TALLOC_FREE(ev);
2764         return status;
2765 }
2766
2767 struct cli_start_connection_state {
2768         struct tevent_context *ev;
2769         struct cli_state *cli;
2770         int min_protocol;
2771         int max_protocol;
2772         struct smb2_negotiate_contexts *negotiate_contexts;
2773 };
2774
2775 static void cli_start_connection_connected(struct tevent_req *subreq);
2776 static void cli_start_connection_done(struct tevent_req *subreq);
2777
2778 /**
2779    establishes a connection to after the negprot.
2780    @param output_cli A fully initialised cli structure, non-null only on success
2781    @param dest_host The netbios name of the remote host
2782    @param dest_ss (optional) The destination IP, NULL for name based lookup
2783    @param port (optional) The destination port (0 for default)
2784 */
2785
2786 static struct tevent_req *cli_start_connection_send(
2787         TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2788         const char *my_name, const char *dest_host,
2789         const struct sockaddr_storage *dest_ss, int port,
2790         enum smb_signing_setting signing_state, int flags,
2791         struct smb2_negotiate_contexts *negotiate_contexts)
2792 {
2793         struct tevent_req *req, *subreq;
2794         struct cli_start_connection_state *state;
2795
2796         req = tevent_req_create(mem_ctx, &state,
2797                                 struct cli_start_connection_state);
2798         if (req == NULL) {
2799                 return NULL;
2800         }
2801         state->ev = ev;
2802
2803         if (flags & CLI_FULL_CONNECTION_IPC) {
2804                 state->min_protocol = lp_client_ipc_min_protocol();
2805                 state->max_protocol = lp_client_ipc_max_protocol();
2806         } else {
2807                 state->min_protocol = lp_client_min_protocol();
2808                 state->max_protocol = lp_client_max_protocol();
2809         }
2810
2811         if (flags & CLI_FULL_CONNECTION_FORCE_SMB1) {
2812                 state->max_protocol = MIN(state->max_protocol,
2813                                           PROTOCOL_NT1);
2814                 state->min_protocol = MIN(state->min_protocol,
2815                                           state->max_protocol);
2816         }
2817
2818         if (flags & CLI_FULL_CONNECTION_DISABLE_SMB1) {
2819                 state->min_protocol = MAX(state->min_protocol,
2820                                           PROTOCOL_SMB2_02);
2821                 state->max_protocol = MAX(state->max_protocol,
2822                                           state->min_protocol);
2823         }
2824
2825         state->negotiate_contexts = talloc_zero(
2826                 state, struct smb2_negotiate_contexts);
2827         if (tevent_req_nomem(state->negotiate_contexts, req)) {
2828                 return tevent_req_post(req, ev);
2829         }
2830
2831         if (flags & CLI_FULL_CONNECTION_REQUEST_POSIX) {
2832                 NTSTATUS status;
2833
2834                 status = smb2_negotiate_context_add(
2835                         state->negotiate_contexts,
2836                         state->negotiate_contexts,
2837                         SMB2_POSIX_EXTENSIONS_AVAILABLE,
2838                         (const uint8_t *)SMB2_CREATE_TAG_POSIX,
2839                         strlen(SMB2_CREATE_TAG_POSIX));
2840                 if (tevent_req_nterror(req, status)) {
2841                         return tevent_req_post(req, ev);
2842                 }
2843         }
2844
2845         if (negotiate_contexts != NULL) {
2846                 uint16_t i;
2847
2848                 for (i=0; i<negotiate_contexts->num_contexts; i++) {
2849                         struct smb2_negotiate_context *ctx =
2850                                 &negotiate_contexts->contexts[i];
2851                         NTSTATUS status;
2852
2853                         status = smb2_negotiate_context_add(
2854                                 state->negotiate_contexts,
2855                                 state->negotiate_contexts,
2856                                 ctx->type,
2857                                 ctx->data.data,
2858                                 ctx->data.length);
2859                         if (tevent_req_nterror(req, status)) {
2860                                 return tevent_req_post(req, ev);
2861                         }
2862                 }
2863         }
2864
2865         subreq = cli_connect_nb_send(state, ev, dest_host, dest_ss, port,
2866                                      0x20, my_name, signing_state, flags);
2867         if (tevent_req_nomem(subreq, req)) {
2868                 return tevent_req_post(req, ev);
2869         }
2870         tevent_req_set_callback(subreq, cli_start_connection_connected, req);
2871         return req;
2872 }
2873
2874 static void cli_start_connection_connected(struct tevent_req *subreq)
2875 {
2876         struct tevent_req *req = tevent_req_callback_data(
2877                 subreq, struct tevent_req);
2878         struct cli_start_connection_state *state = tevent_req_data(
2879                 req, struct cli_start_connection_state);
2880         NTSTATUS status;
2881
2882         status = cli_connect_nb_recv(subreq, &state->cli);
2883         TALLOC_FREE(subreq);
2884         if (tevent_req_nterror(req, status)) {
2885                 return;
2886         }
2887
2888         subreq = smbXcli_negprot_send(
2889                 state,
2890                 state->ev,
2891                 state->cli->conn,
2892                 state->cli->timeout,
2893                 state->min_protocol,
2894                 state->max_protocol,
2895                 WINDOWS_CLIENT_PURE_SMB2_NEGPROT_INITIAL_CREDIT_ASK,
2896                 state->negotiate_contexts);
2897         if (tevent_req_nomem(subreq, req)) {
2898                 return;
2899         }
2900         tevent_req_set_callback(subreq, cli_start_connection_done, req);
2901 }
2902
2903 static void cli_start_connection_done(struct tevent_req *subreq)
2904 {
2905         struct tevent_req *req = tevent_req_callback_data(
2906                 subreq, struct tevent_req);
2907         struct cli_start_connection_state *state = tevent_req_data(
2908                 req, struct cli_start_connection_state);
2909         NTSTATUS status;
2910
2911         status = smbXcli_negprot_recv(subreq, NULL, NULL);
2912         TALLOC_FREE(subreq);
2913         if (tevent_req_nterror(req, status)) {
2914                 return;
2915         }
2916
2917         if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
2918                 /* Ensure we ask for some initial credits. */
2919                 smb2cli_conn_set_max_credits(state->cli->conn,
2920                                              DEFAULT_SMB2_MAX_CREDITS);
2921         }
2922
2923         tevent_req_done(req);
2924 }
2925
2926 static NTSTATUS cli_start_connection_recv(struct tevent_req *req,
2927                                           struct cli_state **output_cli)
2928 {
2929         struct cli_start_connection_state *state = tevent_req_data(
2930                 req, struct cli_start_connection_state);
2931         NTSTATUS status;
2932
2933         if (tevent_req_is_nterror(req, &status)) {
2934                 return status;
2935         }
2936         *output_cli = state->cli;
2937
2938         return NT_STATUS_OK;
2939 }
2940
2941 NTSTATUS cli_start_connection(struct cli_state **output_cli,
2942                               const char *my_name,
2943                               const char *dest_host,
2944                               const struct sockaddr_storage *dest_ss, int port,
2945                               enum smb_signing_setting signing_state, int flags)
2946 {
2947         struct tevent_context *ev;
2948         struct tevent_req *req;
2949         NTSTATUS status = NT_STATUS_NO_MEMORY;
2950
2951         ev = samba_tevent_context_init(talloc_tos());
2952         if (ev == NULL) {
2953                 goto fail;
2954         }
2955         req = cli_start_connection_send(ev, ev, my_name, dest_host, dest_ss,
2956                                         port, signing_state, flags, NULL);
2957         if (req == NULL) {
2958                 goto fail;
2959         }
2960         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2961                 goto fail;
2962         }
2963         status = cli_start_connection_recv(req, output_cli);
2964 fail:
2965         TALLOC_FREE(ev);
2966         return status;
2967 }
2968
2969 struct cli_smb1_setup_encryption_blob_state {
2970         uint16_t setup[1];
2971         uint8_t param[4];
2972         NTSTATUS status;
2973         DATA_BLOB out;
2974         uint16_t enc_ctx_id;
2975 };
2976
2977 static void cli_smb1_setup_encryption_blob_done(struct tevent_req *subreq);
2978
2979 static struct tevent_req *cli_smb1_setup_encryption_blob_send(TALLOC_CTX *mem_ctx,
2980                                                         struct tevent_context *ev,
2981                                                         struct cli_state *cli,
2982                                                         const DATA_BLOB in)
2983 {
2984         struct tevent_req *req = NULL;
2985         struct cli_smb1_setup_encryption_blob_state *state = NULL;
2986         struct tevent_req *subreq = NULL;
2987
2988         req = tevent_req_create(mem_ctx, &state,
2989                                 struct cli_smb1_setup_encryption_blob_state);
2990         if (req == NULL) {
2991                 return NULL;
2992         }
2993
2994         if (in.length > CLI_BUFFER_SIZE) {
2995                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
2996                 return tevent_req_post(req, ev);
2997         }
2998
2999         SSVAL(state->setup+0,  0, TRANSACT2_SETFSINFO);
3000         SSVAL(state->param, 0, 0);
3001         SSVAL(state->param, 2, SMB_REQUEST_TRANSPORT_ENCRYPTION);
3002
3003         subreq = smb1cli_trans_send(state, ev, cli->conn,
3004                                     SMBtrans2,
3005                                     0, 0, /* _flags */
3006                                     0, 0, /* _flags2 */
3007                                     cli->timeout,
3008                                     cli->smb1.pid,
3009                                     cli->smb1.tcon,
3010                                     cli->smb1.session,
3011                                     NULL, /* pipe_name */
3012                                     0, /* fid */
3013                                     0, /* function */
3014                                     0, /* flags */
3015                                     state->setup, 1, 0,
3016                                     state->param, 4, 2,
3017                                     in.data, in.length, CLI_BUFFER_SIZE);
3018         if (tevent_req_nomem(subreq, req)) {
3019                 return tevent_req_post(req, ev);
3020         }
3021         tevent_req_set_callback(subreq,
3022                                 cli_smb1_setup_encryption_blob_done,
3023                                 req);
3024
3025         return req;
3026 }
3027
3028 static void cli_smb1_setup_encryption_blob_done(struct tevent_req *subreq)
3029 {
3030         struct tevent_req *req =
3031                 tevent_req_callback_data(subreq,
3032                                 struct tevent_req);
3033         struct cli_smb1_setup_encryption_blob_state *state =
3034                 tevent_req_data(req,
3035                 struct cli_smb1_setup_encryption_blob_state);
3036         uint8_t *rparam=NULL, *rdata=NULL;
3037         uint32_t num_rparam, num_rdata;
3038         NTSTATUS status;
3039
3040         status = smb1cli_trans_recv(subreq, state,
3041                                     NULL, /* recv_flags */
3042                                     NULL, 0, NULL, /* rsetup */
3043                                     &rparam, 0, &num_rparam,
3044                                     &rdata, 0, &num_rdata);
3045         TALLOC_FREE(subreq);
3046         state->status = status;
3047         if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
3048                 status = NT_STATUS_OK;
3049         }
3050         if (tevent_req_nterror(req, status)) {
3051                 return;
3052         }
3053
3054         if (num_rparam == 2) {
3055                 state->enc_ctx_id = SVAL(rparam, 0);
3056         }
3057         TALLOC_FREE(rparam);
3058
3059         state->out = data_blob_const(rdata, num_rdata);
3060
3061         tevent_req_done(req);
3062 }
3063
3064 static NTSTATUS cli_smb1_setup_encryption_blob_recv(struct tevent_req *req,
3065                                                     TALLOC_CTX *mem_ctx,
3066                                                     DATA_BLOB *out,
3067                                                     uint16_t *enc_ctx_id)
3068 {
3069         struct cli_smb1_setup_encryption_blob_state *state =
3070                 tevent_req_data(req,
3071                 struct cli_smb1_setup_encryption_blob_state);
3072         NTSTATUS status;
3073
3074         if (tevent_req_is_nterror(req, &status)) {
3075                 tevent_req_received(req);
3076                 return status;
3077         }
3078
3079         status = state->status;
3080
3081         *out = state->out;
3082         talloc_steal(mem_ctx, out->data);
3083
3084         *enc_ctx_id = state->enc_ctx_id;
3085
3086         tevent_req_received(req);
3087         return status;
3088 }
3089
3090 struct cli_smb1_setup_encryption_state {
3091         struct tevent_context *ev;
3092         struct cli_state *cli;
3093         struct smb_trans_enc_state *es;
3094         DATA_BLOB blob_in;
3095         DATA_BLOB blob_out;
3096         bool local_ready;
3097         bool remote_ready;
3098 };
3099
3100 static void cli_smb1_setup_encryption_local_next(struct tevent_req *req);
3101 static void cli_smb1_setup_encryption_local_done(struct tevent_req *subreq);
3102 static void cli_smb1_setup_encryption_remote_next(struct tevent_req *req);
3103 static void cli_smb1_setup_encryption_remote_done(struct tevent_req *subreq);
3104 static void cli_smb1_setup_encryption_ready(struct tevent_req *req);
3105
3106 static struct tevent_req *cli_smb1_setup_encryption_send(TALLOC_CTX *mem_ctx,
3107                                                 struct tevent_context *ev,
3108                                                 struct cli_state *cli,
3109                                                 struct cli_credentials *creds)
3110 {
3111         struct tevent_req *req = NULL;
3112         struct cli_smb1_setup_encryption_state *state = NULL;
3113         struct auth_generic_state *ags = NULL;
3114         const DATA_BLOB *b = NULL;
3115         bool auth_requested = false;
3116         const char *target_service = NULL;
3117         const char *target_hostname = NULL;
3118         NTSTATUS status;
3119
3120         req = tevent_req_create(mem_ctx, &state,
3121                                 struct cli_smb1_setup_encryption_state);
3122         if (req == NULL) {
3123                 return NULL;
3124         }
3125         state->ev = ev;
3126         state->cli = cli;
3127
3128         auth_requested = cli_credentials_authentication_requested(creds);
3129         if (!auth_requested) {
3130                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
3131                 return tevent_req_post(req, ev);
3132         }
3133
3134         target_service = "cifs";
3135         target_hostname = smbXcli_conn_remote_name(cli->conn);
3136
3137         status = cli_session_creds_prepare_krb5(cli, creds);
3138         if (tevent_req_nterror(req, status)) {
3139                 return tevent_req_post(req, ev);
3140         }
3141
3142         state->es = talloc_zero(state, struct smb_trans_enc_state);
3143         if (tevent_req_nomem(state->es, req)) {
3144                 return tevent_req_post(req, ev);
3145         }
3146
3147         status = auth_generic_client_prepare(state->es, &ags);
3148         if (tevent_req_nterror(req, status)) {
3149                 return tevent_req_post(req, ev);
3150         }
3151
3152         gensec_want_feature(ags->gensec_security,
3153                             GENSEC_FEATURE_SIGN);
3154         gensec_want_feature(ags->gensec_security,
3155                             GENSEC_FEATURE_SEAL);
3156
3157         status = auth_generic_set_creds(ags, creds);
3158         if (tevent_req_nterror(req, status)) {
3159                 return tevent_req_post(req, ev);
3160         }
3161
3162         if (target_service != NULL) {
3163                 status = gensec_set_target_service(ags->gensec_security,
3164                                                    target_service);
3165                 if (tevent_req_nterror(req, status)) {
3166                         return tevent_req_post(req, ev);
3167                 }
3168         }
3169
3170         if (target_hostname != NULL) {
3171                 status = gensec_set_target_hostname(ags->gensec_security,
3172                                                     target_hostname);
3173                 if (tevent_req_nterror(req, status)) {
3174                         return tevent_req_post(req, ev);
3175                 }
3176         }
3177
3178         gensec_set_max_update_size(ags->gensec_security,
3179                                    CLI_BUFFER_SIZE);
3180
3181         b = smbXcli_conn_server_gss_blob(state->cli->conn);
3182         if (b != NULL) {
3183                 state->blob_in = *b;
3184         }
3185
3186         status = auth_generic_client_start(ags, GENSEC_OID_SPNEGO);
3187         if (tevent_req_nterror(req, status)) {
3188                 return tevent_req_post(req, ev);
3189         }
3190
3191         /*
3192          * We only need the gensec_security part from here.
3193          */
3194         state->es->gensec_security = talloc_move(state->es,
3195                                                  &ags->gensec_security);
3196         TALLOC_FREE(ags);
3197
3198         cli_smb1_setup_encryption_local_next(req);
3199         if (!tevent_req_is_in_progress(req)) {
3200                 return tevent_req_post(req, ev);
3201         }
3202
3203         return req;
3204 }
3205
3206 static void cli_smb1_setup_encryption_local_next(struct tevent_req *req)
3207 {
3208         struct cli_smb1_setup_encryption_state *state =
3209                 tevent_req_data(req,
3210                 struct cli_smb1_setup_encryption_state);
3211         struct tevent_req *subreq = NULL;
3212
3213         if (state->local_ready) {
3214                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3215                 return;
3216         }
3217
3218         subreq = gensec_update_send(state, state->ev,
3219                         state->es->gensec_security,
3220                         state->blob_in);
3221         if (tevent_req_nomem(subreq, req)) {
3222                 return;
3223         }
3224         tevent_req_set_callback(subreq, cli_smb1_setup_encryption_local_done, req);
3225 }
3226
3227 static void cli_smb1_setup_encryption_local_done(struct tevent_req *subreq)
3228 {
3229         struct tevent_req *req =
3230                 tevent_req_callback_data(subreq,
3231                 struct tevent_req);
3232         struct cli_smb1_setup_encryption_state *state =
3233                 tevent_req_data(req,
3234                 struct cli_smb1_setup_encryption_state);
3235         NTSTATUS status;
3236
3237         status = gensec_update_recv(subreq, state, &state->blob_out);
3238         TALLOC_FREE(subreq);
3239         state->blob_in = data_blob_null;
3240         if (!NT_STATUS_IS_OK(status) &&
3241             !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
3242         {
3243                 tevent_req_nterror(req, status);
3244                 return;
3245         }
3246
3247         if (NT_STATUS_IS_OK(status)) {
3248                 state->local_ready = true;
3249         }
3250
3251         /*
3252          * We always get NT_STATUS_OK from the server even if it is not ready.
3253          * So guess the server is ready when we are ready and already sent
3254          * our last blob to the server.
3255          */
3256         if (state->local_ready && state->blob_out.length == 0) {
3257                 state->remote_ready = true;
3258         }
3259
3260         if (state->local_ready && state->remote_ready) {
3261                 cli_smb1_setup_encryption_ready(req);
3262                 return;
3263         }
3264
3265         cli_smb1_setup_encryption_remote_next(req);
3266 }
3267
3268 static void cli_smb1_setup_encryption_remote_next(struct tevent_req *req)
3269 {
3270         struct cli_smb1_setup_encryption_state *state =
3271                 tevent_req_data(req,
3272                 struct cli_smb1_setup_encryption_state);
3273         struct tevent_req *subreq = NULL;
3274
3275         if (state->remote_ready) {
3276                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3277                 return;
3278         }
3279
3280         subreq = cli_smb1_setup_encryption_blob_send(state, state->ev,
3281                                                      state->cli, state->blob_out);
3282         if (tevent_req_nomem(subreq, req)) {
3283                 return;
3284         }
3285         tevent_req_set_callback(subreq,
3286                                 cli_smb1_setup_encryption_remote_done,
3287                                 req);
3288 }
3289
3290 static void cli_smb1_setup_encryption_remote_done(struct tevent_req *subreq)
3291 {
3292         struct tevent_req *req =
3293                 tevent_req_callback_data(subreq,
3294                 struct tevent_req);
3295         struct cli_smb1_setup_encryption_state *state =
3296                 tevent_req_data(req,
3297                 struct cli_smb1_setup_encryption_state);
3298         NTSTATUS status;
3299
3300         status = cli_smb1_setup_encryption_blob_recv(subreq, state,
3301                                                      &state->blob_in,
3302                                                      &state->es->enc_ctx_num);
3303         TALLOC_FREE(subreq);
3304         data_blob_free(&state->blob_out);
3305         if (!NT_STATUS_IS_OK(status) &&
3306             !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
3307         {
3308                 tevent_req_nterror(req, status);
3309                 return;
3310         }
3311
3312         /*
3313          * We always get NT_STATUS_OK even if the server is not ready.
3314          * So guess the server is ready when we are ready and sent
3315          * our last blob to the server.
3316          */
3317         if (state->local_ready) {
3318                 state->remote_ready = true;
3319         }
3320
3321         if (state->local_ready && state->remote_ready) {
3322                 cli_smb1_setup_encryption_ready(req);
3323                 return;
3324         }
3325
3326         cli_smb1_setup_encryption_local_next(req);
3327 }
3328
3329 static void cli_smb1_setup_encryption_ready(struct tevent_req *req)
3330 {
3331         struct cli_smb1_setup_encryption_state *state =
3332                 tevent_req_data(req,
3333                 struct cli_smb1_setup_encryption_state);
3334         struct smb_trans_enc_state *es = NULL;
3335
3336         if (state->blob_in.length != 0) {
3337                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3338                 return;
3339         }
3340
3341         if (state->blob_out.length != 0) {
3342                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3343                 return;
3344         }
3345
3346         es = talloc_move(state->cli->conn, &state->es);
3347         es->enc_on = true;
3348         smb1cli_conn_set_encryption(state->cli->conn, es);
3349         es = NULL;
3350
3351         tevent_req_done(req);
3352 }
3353
3354 static NTSTATUS cli_smb1_setup_encryption_recv(struct tevent_req *req)
3355 {
3356         return tevent_req_simple_recv_ntstatus(req);
3357 }
3358
3359 NTSTATUS cli_smb1_setup_encryption(struct cli_state *cli,
3360                                    struct cli_credentials *creds)
3361 {
3362         struct tevent_context *ev = NULL;
3363         struct tevent_req *req = NULL;
3364         NTSTATUS status = NT_STATUS_NO_MEMORY;
3365
3366         ev = samba_tevent_context_init(talloc_tos());
3367         if (ev == NULL) {
3368                 goto fail;
3369         }
3370         req = cli_smb1_setup_encryption_send(ev, ev, cli, creds);
3371         if (req == NULL) {
3372                 goto fail;
3373         }
3374         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
3375                 goto fail;
3376         }
3377         status = cli_smb1_setup_encryption_recv(req);
3378  fail:
3379         TALLOC_FREE(ev);
3380         return status;
3381 }
3382
3383 /**
3384    establishes a connection right up to doing tconX, password specified.
3385    @param output_cli A fully initialised cli structure, non-null only on success
3386    @param dest_host The netbios name of the remote host
3387    @param dest_ip (optional) The the destination IP, NULL for name based lookup
3388    @param port (optional) The destination port (0 for default)
3389    @param service (optional) The share to make the connection to.  Should be 'unqualified' in any way.
3390    @param service_type The 'type' of service.
3391    @param creds The used user credentials
3392 */
3393
3394 struct cli_full_connection_creds_state {
3395         struct tevent_context *ev;
3396         const char *service;
3397         const char *service_type;
3398         struct cli_credentials *creds;
3399         int flags;
3400         struct cli_state *cli;
3401 };
3402
3403 static int cli_full_connection_creds_state_destructor(
3404         struct cli_full_connection_creds_state *s)
3405 {
3406         if (s->cli != NULL) {
3407                 cli_shutdown(s->cli);
3408                 s->cli = NULL;
3409         }
3410         return 0;
3411 }
3412
3413 static void cli_full_connection_creds_conn_done(struct tevent_req *subreq);
3414 static void cli_full_connection_creds_sess_done(struct tevent_req *subreq);
3415 static void cli_full_connection_creds_enc_start(struct tevent_req *req);
3416 static void cli_full_connection_creds_enc_tcon(struct tevent_req *subreq);
3417 static void cli_full_connection_creds_enc_ver(struct tevent_req *subreq);
3418 static void cli_full_connection_creds_enc_done(struct tevent_req *subreq);
3419 static void cli_full_connection_creds_enc_tdis(struct tevent_req *req);
3420 static void cli_full_connection_creds_enc_finished(struct tevent_req *subreq);
3421 static void cli_full_connection_creds_tcon_start(struct tevent_req *req);
3422 static void cli_full_connection_creds_tcon_done(struct tevent_req *subreq);
3423
3424 struct tevent_req *cli_full_connection_creds_send(
3425         TALLOC_CTX *mem_ctx, struct tevent_context *ev,
3426         const char *my_name, const char *dest_host,
3427         const struct sockaddr_storage *dest_ss, int port,
3428         const char *service, const char *service_type,
3429         struct cli_credentials *creds,
3430         int flags,
3431         struct smb2_negotiate_contexts *negotiate_contexts)
3432 {
3433         struct tevent_req *req, *subreq;
3434         struct cli_full_connection_creds_state *state;
3435         enum smb_signing_setting signing_state;
3436         enum smb_encryption_setting encryption_state =
3437                 cli_credentials_get_smb_encryption(creds);
3438
3439         req = tevent_req_create(mem_ctx, &state,
3440                                 struct cli_full_connection_creds_state);
3441         if (req == NULL) {
3442                 return NULL;
3443         }
3444         talloc_set_destructor(state, cli_full_connection_creds_state_destructor);
3445
3446         state->ev = ev;
3447         state->service = service;
3448         state->service_type = service_type;
3449         state->creds = creds;
3450         state->flags = flags;
3451
3452         if (flags & CLI_FULL_CONNECTION_IPC) {
3453                 signing_state = cli_credentials_get_smb_ipc_signing(creds);
3454         } else {
3455                 signing_state = cli_credentials_get_smb_signing(creds);
3456         }
3457
3458         if (encryption_state == SMB_ENCRYPTION_REQUIRED) {
3459                 if (flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK) {
3460                         encryption_state = SMB_ENCRYPTION_DESIRED;
3461                 }
3462         }
3463
3464         if (encryption_state >= SMB_ENCRYPTION_DESIRED) {
3465                 signing_state = SMB_SIGNING_REQUIRED;
3466         }
3467
3468         subreq = cli_start_connection_send(
3469                 state, ev, my_name, dest_host, dest_ss, port,
3470                 signing_state, flags,
3471                 negotiate_contexts);
3472         if (tevent_req_nomem(subreq, req)) {
3473                 return tevent_req_post(req, ev);
3474         }
3475         tevent_req_set_callback(subreq,
3476                                 cli_full_connection_creds_conn_done,
3477                                 req);
3478         return req;
3479 }
3480
3481 static void cli_full_connection_creds_conn_done(struct tevent_req *subreq)
3482 {
3483         struct tevent_req *req = tevent_req_callback_data(
3484                 subreq, struct tevent_req);
3485         struct cli_full_connection_creds_state *state = tevent_req_data(
3486                 req, struct cli_full_connection_creds_state);
3487         NTSTATUS status;
3488
3489         status = cli_start_connection_recv(subreq, &state->cli);
3490         TALLOC_FREE(subreq);
3491         if (tevent_req_nterror(req, status)) {
3492                 return;
3493         }
3494
3495         subreq = cli_session_setup_creds_send(
3496                 state, state->ev, state->cli, state->creds);
3497         if (tevent_req_nomem(subreq, req)) {
3498                 return;
3499         }
3500         tevent_req_set_callback(subreq,
3501                                 cli_full_connection_creds_sess_done,
3502                                 req);
3503 }
3504
3505 static void cli_full_connection_creds_sess_done(struct tevent_req *subreq)
3506 {
3507         struct tevent_req *req = tevent_req_callback_data(
3508                 subreq, struct tevent_req);
3509         struct cli_full_connection_creds_state *state = tevent_req_data(
3510                 req, struct cli_full_connection_creds_state);
3511         NTSTATUS status;
3512
3513         status = cli_session_setup_creds_recv(subreq);
3514         TALLOC_FREE(subreq);
3515
3516         if (!NT_STATUS_IS_OK(status) &&
3517             (state->flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)) {
3518
3519                 state->flags &= ~CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
3520
3521                 state->creds = cli_credentials_init_anon(state);
3522                 if (tevent_req_nomem(state->creds, req)) {
3523                         return;
3524                 }
3525
3526                 subreq = cli_session_setup_creds_send(
3527                         state, state->ev, state->cli, state->creds);
3528                 if (tevent_req_nomem(subreq, req)) {
3529                         return;
3530                 }
3531                 tevent_req_set_callback(subreq,
3532                                         cli_full_connection_creds_sess_done,
3533                                         req);
3534                 return;
3535         }
3536
3537         if (tevent_req_nterror(req, status)) {
3538                 return;
3539         }
3540
3541         cli_full_connection_creds_enc_start(req);
3542 }
3543
3544 static void cli_full_connection_creds_enc_start(struct tevent_req *req)
3545 {
3546         struct cli_full_connection_creds_state *state = tevent_req_data(
3547                 req, struct cli_full_connection_creds_state);
3548         enum smb_encryption_setting encryption_state =
3549                 cli_credentials_get_smb_encryption(state->creds);
3550         struct tevent_req *subreq = NULL;
3551         NTSTATUS status;
3552
3553         if (encryption_state < SMB_ENCRYPTION_DESIRED) {
3554                 cli_full_connection_creds_tcon_start(req);
3555                 return;
3556         }
3557
3558         if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
3559                 status = smb2cli_session_encryption_on(state->cli->smb2.session);
3560                 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
3561                         if (encryption_state < SMB_ENCRYPTION_REQUIRED) {
3562                                 cli_full_connection_creds_tcon_start(req);
3563                                 return;
3564                         }
3565                         d_printf("Encryption required and "
3566                                 "server doesn't support "
3567                                 "SMB3 encryption - failing connect\n");
3568                         tevent_req_nterror(req, status);
3569                         return;
3570                 } else if (!NT_STATUS_IS_OK(status)) {
3571                         d_printf("Encryption required and "
3572                                 "setup failed with error %s.\n",
3573                                 nt_errstr(status));
3574                         tevent_req_nterror(req, status);
3575                         return;
3576                 }
3577
3578                 cli_full_connection_creds_tcon_start(req);
3579                 return;
3580         }
3581
3582         if (!SERVER_HAS_UNIX_CIFS(state->cli)) {
3583                 if (encryption_state < SMB_ENCRYPTION_REQUIRED) {
3584                         cli_full_connection_creds_tcon_start(req);
3585                         return;
3586                 }
3587
3588                 status = NT_STATUS_NOT_SUPPORTED;
3589                 d_printf("Encryption required and "
3590                         "server doesn't support "
3591                         "SMB1 Unix Extensions - failing connect\n");
3592                 tevent_req_nterror(req, status);
3593                 return;
3594         }
3595
3596         /*
3597          * We do a tcon on IPC$ just to setup the encryption,
3598          * the real tcon will be encrypted then.
3599          */
3600         subreq = cli_tree_connect_send(state, state->ev, state->cli,
3601                                        "IPC$", "IPC", NULL);
3602         if (tevent_req_nomem(subreq, req)) {
3603                 return;
3604         }
3605         tevent_req_set_callback(subreq, cli_full_connection_creds_enc_tcon, req);
3606 }
3607
3608 static void cli_full_connection_creds_enc_tcon(struct tevent_req *subreq)
3609 {
3610         struct tevent_req *req = tevent_req_callback_data(
3611                 subreq, struct tevent_req);
3612         struct cli_full_connection_creds_state *state = tevent_req_data(
3613                 req, struct cli_full_connection_creds_state);
3614         NTSTATUS status;
3615
3616         status = cli_tree_connect_recv(subreq);
3617         TALLOC_FREE(subreq);
3618         if (tevent_req_nterror(req, status)) {
3619                 return;
3620         }
3621
3622         subreq = cli_unix_extensions_version_send(state, state->ev, state->cli);
3623         if (tevent_req_nomem(subreq, req)) {
3624                 return;
3625         }
3626         tevent_req_set_callback(subreq, cli_full_connection_creds_enc_ver, req);
3627 }
3628
3629 static void cli_full_connection_creds_enc_ver(struct tevent_req *subreq)
3630 {
3631         struct tevent_req *req = tevent_req_callback_data(
3632                 subreq, struct tevent_req);
3633         struct cli_full_connection_creds_state *state = tevent_req_data(
3634                 req, struct cli_full_connection_creds_state);
3635         enum smb_encryption_setting encryption_state =
3636                 cli_credentials_get_smb_encryption(state->creds);
3637         uint16_t major, minor;
3638         uint32_t caplow, caphigh;
3639         NTSTATUS status;
3640
3641         status = cli_unix_extensions_version_recv(subreq,
3642                                                   &major, &minor,
3643                                                   &caplow,
3644                                                   &caphigh);
3645         TALLOC_FREE(subreq);
3646         if (!NT_STATUS_IS_OK(status)) {
3647                 if (encryption_state < SMB_ENCRYPTION_REQUIRED) {
3648                         /* disconnect ipc$ followed by the real tree connect */
3649                         cli_full_connection_creds_enc_tdis(req);
3650                         return;
3651                 }
3652                 DEBUG(10, ("%s: cli_unix_extensions_version "
3653                            "returned %s\n", __func__, nt_errstr(status)));
3654                 tevent_req_nterror(req, NT_STATUS_UNKNOWN_REVISION);
3655                 return;
3656         }
3657
3658         if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
3659                 if (encryption_state < SMB_ENCRYPTION_REQUIRED) {
3660                         /* disconnect ipc$ followed by the real tree connect */
3661                         cli_full_connection_creds_enc_tdis(req);
3662                         return;
3663                 }
3664                 DEBUG(10, ("%s: CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP "
3665                            "not supported\n", __func__));
3666                 tevent_req_nterror(req, NT_STATUS_UNSUPPORTED_COMPRESSION);
3667                 return;
3668         }
3669
3670         subreq = cli_smb1_setup_encryption_send(state, state->ev,
3671                                                 state->cli,
3672                                                 state->creds);
3673         if (tevent_req_nomem(subreq, req)) {
3674                 return;
3675         }
3676         tevent_req_set_callback(subreq,
3677                                 cli_full_connection_creds_enc_done,
3678                                 req);
3679 }
3680
3681 static void cli_full_connection_creds_enc_done(struct tevent_req *subreq)
3682 {
3683         struct tevent_req *req = tevent_req_callback_data(
3684                 subreq, struct tevent_req);
3685         NTSTATUS status;
3686
3687         status = cli_smb1_setup_encryption_recv(subreq);
3688         TALLOC_FREE(subreq);
3689         if (tevent_req_nterror(req, status)) {
3690                 return;
3691         }
3692
3693         /* disconnect ipc$ followed by the real tree connect */
3694         cli_full_connection_creds_enc_tdis(req);
3695 }
3696
3697 static void cli_full_connection_creds_enc_tdis(struct tevent_req *req)
3698 {
3699         struct cli_full_connection_creds_state *state = tevent_req_data(
3700                 req, struct cli_full_connection_creds_state);
3701         struct tevent_req *subreq = NULL;
3702
3703         subreq = cli_tdis_send(state, state->ev, state->cli);
3704         if (tevent_req_nomem(subreq, req)) {
3705                 return;
3706         }
3707         tevent_req_set_callback(subreq,
3708                                 cli_full_connection_creds_enc_finished,
3709                                 req);
3710 }
3711
3712 static void cli_full_connection_creds_enc_finished(struct tevent_req *subreq)
3713 {
3714         struct tevent_req *req = tevent_req_callback_data(
3715                 subreq, struct tevent_req);
3716         NTSTATUS status;
3717
3718         status = cli_tdis_recv(subreq);
3719         TALLOC_FREE(subreq);
3720         if (tevent_req_nterror(req, status)) {
3721                 return;
3722         }
3723
3724         cli_full_connection_creds_tcon_start(req);
3725 }
3726
3727 static void cli_full_connection_creds_tcon_start(struct tevent_req *req)
3728 {
3729         struct cli_full_connection_creds_state *state = tevent_req_data(
3730                 req, struct cli_full_connection_creds_state);
3731         struct tevent_req *subreq = NULL;
3732         const char *password = NULL;
3733
3734         if (state->service == NULL) {
3735                 tevent_req_done(req);
3736                 return;
3737         }
3738
3739         password = cli_credentials_get_password(state->creds);
3740
3741         subreq = cli_tree_connect_send(state, state->ev,
3742                                        state->cli,
3743                                        state->service,
3744                                        state->service_type,
3745                                        password);
3746         if (tevent_req_nomem(subreq, req)) {
3747                 return;
3748         }
3749         tevent_req_set_callback(subreq,
3750                                 cli_full_connection_creds_tcon_done,
3751                                 req);
3752 }
3753
3754 static void cli_full_connection_creds_tcon_done(struct tevent_req *subreq)
3755 {
3756         struct tevent_req *req = tevent_req_callback_data(
3757                 subreq, struct tevent_req);
3758         NTSTATUS status;
3759
3760         status = cli_tree_connect_recv(subreq);
3761         TALLOC_FREE(subreq);
3762         if (tevent_req_nterror(req, status)) {
3763                 return;
3764         }
3765
3766         tevent_req_done(req);
3767 }
3768
3769 NTSTATUS cli_full_connection_creds_recv(struct tevent_req *req,
3770                                   struct cli_state **output_cli)
3771 {
3772         struct cli_full_connection_creds_state *state = tevent_req_data(
3773                 req, struct cli_full_connection_creds_state);
3774         NTSTATUS status;
3775
3776         if (tevent_req_is_nterror(req, &status)) {
3777                 return status;
3778         }
3779         *output_cli = state->cli;
3780         talloc_set_destructor(state, NULL);
3781         return NT_STATUS_OK;
3782 }
3783
3784 NTSTATUS cli_full_connection_creds(struct cli_state **output_cli,
3785                                    const char *my_name,
3786                                    const char *dest_host,
3787                                    const struct sockaddr_storage *dest_ss, int port,
3788                                    const char *service, const char *service_type,
3789                                    struct cli_credentials *creds,
3790                                    int flags)
3791 {
3792         struct tevent_context *ev;
3793         struct tevent_req *req;
3794         NTSTATUS status = NT_STATUS_NO_MEMORY;
3795
3796         ev = samba_tevent_context_init(talloc_tos());
3797         if (ev == NULL) {
3798                 goto fail;
3799         }
3800         req = cli_full_connection_creds_send(
3801                 ev, ev, my_name, dest_host, dest_ss, port, service,
3802                 service_type, creds, flags,
3803                 NULL);
3804         if (req == NULL) {
3805                 goto fail;
3806         }
3807         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
3808                 goto fail;
3809         }
3810         status = cli_full_connection_creds_recv(req, output_cli);
3811  fail:
3812         TALLOC_FREE(ev);
3813         return status;
3814 }
3815
3816 /****************************************************************************
3817  Send an old style tcon.
3818 ****************************************************************************/
3819 struct cli_raw_tcon_state {
3820         uint16_t *ret_vwv;
3821 };
3822
3823 static void cli_raw_tcon_done(struct tevent_req *subreq);
3824
3825 static struct tevent_req *cli_raw_tcon_send(
3826         TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
3827         const char *service, const char *pass, const char *dev)
3828 {
3829         struct tevent_req *req, *subreq;
3830         struct cli_raw_tcon_state *state;
3831         uint8_t *bytes;
3832
3833         req = tevent_req_create(mem_ctx, &state, struct cli_raw_tcon_state);
3834         if (req == NULL) {
3835                 return NULL;
3836         }
3837
3838         if (!lp_client_plaintext_auth() && (*pass)) {
3839                 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
3840                           " or 'client ntlmv2 auth = yes'\n"));
3841                 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
3842                 return tevent_req_post(req, ev);
3843         }
3844
3845         TALLOC_FREE(cli->smb1.tcon);
3846         cli->smb1.tcon = smbXcli_tcon_create(cli);
3847         if (tevent_req_nomem(cli->smb1.tcon, req)) {
3848                 return tevent_req_post(req, ev);
3849         }
3850         smb1cli_tcon_set_id(cli->smb1.tcon, UINT16_MAX);
3851
3852         bytes = talloc_array(state, uint8_t, 0);
3853         bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3854         bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3855                                    service, strlen(service)+1, NULL);
3856         bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3857         bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3858                                    pass, strlen(pass)+1, NULL);
3859         bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3860         bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3861                                    dev, strlen(dev)+1, NULL);
3862
3863         if (tevent_req_nomem(bytes, req)) {
3864                 return tevent_req_post(req, ev);
3865         }
3866
3867         subreq = cli_smb_send(state, ev, cli, SMBtcon, 0, 0, 0, NULL,
3868                               talloc_get_size(bytes), bytes);
3869         if (tevent_req_nomem(subreq, req)) {
3870                 return tevent_req_post(req, ev);
3871         }
3872         tevent_req_set_callback(subreq, cli_raw_tcon_done, req);
3873         return req;
3874 }
3875
3876 static void cli_raw_tcon_done(struct tevent_req *subreq)
3877 {
3878         struct tevent_req *req = tevent_req_callback_data(
3879                 subreq, struct tevent_req);
3880         struct cli_raw_tcon_state *state = tevent_req_data(
3881                 req, struct cli_raw_tcon_state);
3882         NTSTATUS status;
3883
3884         status = cli_smb_recv(subreq, state, NULL, 2, NULL, &state->ret_vwv,
3885                               NULL, NULL);
3886         TALLOC_FREE(subreq);
3887         if (tevent_req_nterror(req, status)) {
3888                 return;
3889         }
3890         tevent_req_done(req);
3891 }
3892
3893 static NTSTATUS cli_raw_tcon_recv(struct tevent_req *req,
3894                                   uint16_t *max_xmit, uint16_t *tid)
3895 {
3896         struct cli_raw_tcon_state *state = tevent_req_data(
3897                 req, struct cli_raw_tcon_state);
3898         NTSTATUS status;
3899
3900         if (tevent_req_is_nterror(req, &status)) {
3901                 return status;
3902         }
3903         *max_xmit = SVAL(state->ret_vwv + 0, 0);
3904         *tid = SVAL(state->ret_vwv + 1, 0);
3905         return NT_STATUS_OK;
3906 }
3907
3908 NTSTATUS cli_raw_tcon(struct cli_state *cli,
3909                       const char *service, const char *pass, const char *dev,
3910                       uint16_t *max_xmit, uint16_t *tid)
3911 {
3912         struct tevent_context *ev;
3913         struct tevent_req *req;
3914         NTSTATUS status = NT_STATUS_NO_MEMORY;
3915
3916         ev = samba_tevent_context_init(talloc_tos());
3917         if (ev == NULL) {
3918                 goto fail;
3919         }
3920         req = cli_raw_tcon_send(ev, ev, cli, service, pass, dev);
3921         if (req == NULL) {
3922                 goto fail;
3923         }
3924         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
3925                 goto fail;
3926         }
3927         status = cli_raw_tcon_recv(req, max_xmit, tid);
3928 fail:
3929         TALLOC_FREE(ev);
3930         return status;
3931 }
3932
3933 /* Return a cli_state pointing at the IPC$ share for the given server */
3934
3935 struct cli_state *get_ipc_connect(char *server,
3936                                 struct sockaddr_storage *server_ss,
3937                                 struct cli_credentials *creds)
3938 {
3939         struct cli_state *cli;
3940         NTSTATUS nt_status;
3941         uint32_t flags = CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
3942
3943         flags |= CLI_FULL_CONNECTION_FORCE_SMB1;
3944         flags |= CLI_FULL_CONNECTION_IPC;
3945
3946         nt_status = cli_full_connection_creds(&cli, NULL, server, server_ss, 0, "IPC$", "IPC",
3947                                               creds,
3948                                         flags);
3949
3950         if (NT_STATUS_IS_OK(nt_status)) {
3951                 return cli;
3952         }
3953         if (is_ipaddress(server)) {
3954             /* windows 9* needs a correct NMB name for connections */
3955             fstring remote_name;
3956
3957             if (name_status_find("*", 0, 0, server_ss, remote_name)) {
3958                 cli = get_ipc_connect(remote_name, server_ss, creds);
3959                 if (cli)
3960                     return cli;
3961             }
3962         }
3963         return NULL;
3964 }
3965
3966 /*
3967  * Given the IP address of a master browser on the network, return its
3968  * workgroup and connect to it.
3969  *
3970  * This function is provided to allow additional processing beyond what
3971  * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
3972  * browsers and obtain each master browsers' list of domains (in case the
3973  * first master browser is recently on the network and has not yet
3974  * synchronized with other master browsers and therefore does not yet have the
3975  * entire network browse list)
3976  */
3977
3978 struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx,
3979                                 struct sockaddr_storage *mb_ip,
3980                                 struct cli_credentials *creds,
3981                                 char **pp_workgroup_out)
3982 {
3983         char addr[INET6_ADDRSTRLEN];
3984         fstring name;
3985         struct cli_state *cli;
3986         struct sockaddr_storage server_ss;
3987
3988         *pp_workgroup_out = NULL;
3989
3990         print_sockaddr(addr, sizeof(addr), mb_ip);
3991         DEBUG(99, ("Looking up name of master browser %s\n",
3992                    addr));
3993
3994         /*
3995          * Do a name status query to find out the name of the master browser.
3996          * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
3997          * master browser will not respond to a wildcard query (or, at least,
3998          * an NT4 server acting as the domain master browser will not).
3999          *
4000          * We might be able to use ONLY the query on MSBROWSE, but that's not
4001          * yet been tested with all Windows versions, so until it is, leave
4002          * the original wildcard query as the first choice and fall back to
4003          * MSBROWSE if the wildcard query fails.
4004          */
4005         if (!name_status_find("*", 0, 0x1d, mb_ip, name) &&
4006             !name_status_find(MSBROWSE, 1, 0x1d, mb_ip, name)) {
4007
4008                 DEBUG(99, ("Could not retrieve name status for %s\n",
4009                            addr));
4010                 return NULL;
4011         }
4012
4013         if (!find_master_ip(name, &server_ss)) {
4014                 DEBUG(99, ("Could not find master ip for %s\n", name));
4015                 return NULL;
4016         }
4017
4018         *pp_workgroup_out = talloc_strdup(ctx, name);
4019
4020         DEBUG(4, ("found master browser %s, %s\n", name, addr));
4021
4022         print_sockaddr(addr, sizeof(addr), &server_ss);
4023         cli = get_ipc_connect(addr, &server_ss, creds);
4024
4025         return cli;
4026 }