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