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