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