s3:libsmb: no longer pass remote_realm to cli_state_create()
[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         subreq = cli_connect_nb_send(state, ev, dest_host, dest_ss, port,
2784                                      0x20, my_name, signing_state, flags);
2785         if (tevent_req_nomem(subreq, req)) {
2786                 return tevent_req_post(req, ev);
2787         }
2788         tevent_req_set_callback(subreq, cli_start_connection_connected, req);
2789         return req;
2790 }
2791
2792 static void cli_start_connection_connected(struct tevent_req *subreq)
2793 {
2794         struct tevent_req *req = tevent_req_callback_data(
2795                 subreq, struct tevent_req);
2796         struct cli_start_connection_state *state = tevent_req_data(
2797                 req, struct cli_start_connection_state);
2798         NTSTATUS status;
2799
2800         status = cli_connect_nb_recv(subreq, &state->cli);
2801         TALLOC_FREE(subreq);
2802         if (tevent_req_nterror(req, status)) {
2803                 return;
2804         }
2805
2806         subreq = smbXcli_negprot_send(state, state->ev, state->cli->conn,
2807                                       state->cli->timeout,
2808                                       state->min_protocol,
2809                                       state->max_protocol,
2810                                       WINDOWS_CLIENT_PURE_SMB2_NEGPROT_INITIAL_CREDIT_ASK);
2811         if (tevent_req_nomem(subreq, req)) {
2812                 return;
2813         }
2814         tevent_req_set_callback(subreq, cli_start_connection_done, req);
2815 }
2816
2817 static void cli_start_connection_done(struct tevent_req *subreq)
2818 {
2819         struct tevent_req *req = tevent_req_callback_data(
2820                 subreq, struct tevent_req);
2821         struct cli_start_connection_state *state = tevent_req_data(
2822                 req, struct cli_start_connection_state);
2823         NTSTATUS status;
2824
2825         status = smbXcli_negprot_recv(subreq);
2826         TALLOC_FREE(subreq);
2827         if (tevent_req_nterror(req, status)) {
2828                 return;
2829         }
2830
2831         if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
2832                 /* Ensure we ask for some initial credits. */
2833                 smb2cli_conn_set_max_credits(state->cli->conn,
2834                                              DEFAULT_SMB2_MAX_CREDITS);
2835         }
2836
2837         tevent_req_done(req);
2838 }
2839
2840 static NTSTATUS cli_start_connection_recv(struct tevent_req *req,
2841                                           struct cli_state **output_cli)
2842 {
2843         struct cli_start_connection_state *state = tevent_req_data(
2844                 req, struct cli_start_connection_state);
2845         NTSTATUS status;
2846
2847         if (tevent_req_is_nterror(req, &status)) {
2848                 return status;
2849         }
2850         *output_cli = state->cli;
2851
2852         return NT_STATUS_OK;
2853 }
2854
2855 NTSTATUS cli_start_connection(struct cli_state **output_cli, 
2856                               const char *my_name, 
2857                               const char *dest_host, 
2858                               const struct sockaddr_storage *dest_ss, int port,
2859                               int signing_state, int flags)
2860 {
2861         struct tevent_context *ev;
2862         struct tevent_req *req;
2863         NTSTATUS status = NT_STATUS_NO_MEMORY;
2864
2865         ev = samba_tevent_context_init(talloc_tos());
2866         if (ev == NULL) {
2867                 goto fail;
2868         }
2869         req = cli_start_connection_send(ev, ev, my_name, dest_host, dest_ss,
2870                                         port, signing_state, flags);
2871         if (req == NULL) {
2872                 goto fail;
2873         }
2874         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2875                 goto fail;
2876         }
2877         status = cli_start_connection_recv(req, output_cli);
2878 fail:
2879         TALLOC_FREE(ev);
2880         return status;
2881 }
2882
2883 struct cli_smb1_setup_encryption_blob_state {
2884         uint16_t setup[1];
2885         uint8_t param[4];
2886         NTSTATUS status;
2887         DATA_BLOB out;
2888         uint16_t enc_ctx_id;
2889 };
2890
2891 static void cli_smb1_setup_encryption_blob_done(struct tevent_req *subreq);
2892
2893 static struct tevent_req *cli_smb1_setup_encryption_blob_send(TALLOC_CTX *mem_ctx,
2894                                                         struct tevent_context *ev,
2895                                                         struct cli_state *cli,
2896                                                         const DATA_BLOB in)
2897 {
2898         struct tevent_req *req = NULL;
2899         struct cli_smb1_setup_encryption_blob_state *state = NULL;
2900         struct tevent_req *subreq = NULL;
2901
2902         req = tevent_req_create(mem_ctx, &state,
2903                                 struct cli_smb1_setup_encryption_blob_state);
2904         if (req == NULL) {
2905                 return NULL;
2906         }
2907
2908         if (in.length > CLI_BUFFER_SIZE) {
2909                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
2910                 return tevent_req_post(req, ev);
2911         }
2912
2913         SSVAL(state->setup+0,  0, TRANSACT2_SETFSINFO);
2914         SSVAL(state->param, 0, 0);
2915         SSVAL(state->param, 2, SMB_REQUEST_TRANSPORT_ENCRYPTION);
2916
2917         subreq = smb1cli_trans_send(state, ev, cli->conn,
2918                                     SMBtrans2,
2919                                     0, 0, /* _flags */
2920                                     0, 0, /* _flags2 */
2921                                     cli->timeout,
2922                                     cli->smb1.pid,
2923                                     cli->smb1.tcon,
2924                                     cli->smb1.session,
2925                                     NULL, /* pipe_name */
2926                                     0, /* fid */
2927                                     0, /* function */
2928                                     0, /* flags */
2929                                     state->setup, 1, 0,
2930                                     state->param, 4, 2,
2931                                     in.data, in.length, CLI_BUFFER_SIZE);
2932         if (tevent_req_nomem(subreq, req)) {
2933                 return tevent_req_post(req, ev);
2934         }
2935         tevent_req_set_callback(subreq,
2936                                 cli_smb1_setup_encryption_blob_done,
2937                                 req);
2938
2939         return req;
2940 }
2941
2942 static void cli_smb1_setup_encryption_blob_done(struct tevent_req *subreq)
2943 {
2944         struct tevent_req *req =
2945                 tevent_req_callback_data(subreq,
2946                                 struct tevent_req);
2947         struct cli_smb1_setup_encryption_blob_state *state =
2948                 tevent_req_data(req,
2949                 struct cli_smb1_setup_encryption_blob_state);
2950         uint8_t *rparam=NULL, *rdata=NULL;
2951         uint32_t num_rparam, num_rdata;
2952         NTSTATUS status;
2953
2954         status = smb1cli_trans_recv(subreq, state,
2955                                     NULL, /* recv_flags */
2956                                     NULL, 0, NULL, /* rsetup */
2957                                     &rparam, 0, &num_rparam,
2958                                     &rdata, 0, &num_rdata);
2959         TALLOC_FREE(subreq);
2960         state->status = status;
2961         if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
2962                 status = NT_STATUS_OK;
2963         }
2964         if (tevent_req_nterror(req, status)) {
2965                 return;
2966         }
2967
2968         if (num_rparam == 2) {
2969                 state->enc_ctx_id = SVAL(rparam, 0);
2970         }
2971         TALLOC_FREE(rparam);
2972
2973         state->out = data_blob_const(rdata, num_rdata);
2974
2975         tevent_req_done(req);
2976 }
2977
2978 static NTSTATUS cli_smb1_setup_encryption_blob_recv(struct tevent_req *req,
2979                                                     TALLOC_CTX *mem_ctx,
2980                                                     DATA_BLOB *out,
2981                                                     uint16_t *enc_ctx_id)
2982 {
2983         struct cli_smb1_setup_encryption_blob_state *state =
2984                 tevent_req_data(req,
2985                 struct cli_smb1_setup_encryption_blob_state);
2986         NTSTATUS status;
2987
2988         if (tevent_req_is_nterror(req, &status)) {
2989                 tevent_req_received(req);
2990                 return status;
2991         }
2992
2993         status = state->status;
2994
2995         *out = state->out;
2996         talloc_steal(mem_ctx, out->data);
2997
2998         *enc_ctx_id = state->enc_ctx_id;
2999
3000         tevent_req_received(req);
3001         return status;
3002 }
3003
3004 struct cli_smb1_setup_encryption_state {
3005         struct tevent_context *ev;
3006         struct cli_state *cli;
3007         struct smb_trans_enc_state *es;
3008         DATA_BLOB blob_in;
3009         DATA_BLOB blob_out;
3010         bool local_ready;
3011         bool remote_ready;
3012 };
3013
3014 static void cli_smb1_setup_encryption_local_next(struct tevent_req *req);
3015 static void cli_smb1_setup_encryption_local_done(struct tevent_req *subreq);
3016 static void cli_smb1_setup_encryption_remote_next(struct tevent_req *req);
3017 static void cli_smb1_setup_encryption_remote_done(struct tevent_req *subreq);
3018 static void cli_smb1_setup_encryption_ready(struct tevent_req *req);
3019
3020 static struct tevent_req *cli_smb1_setup_encryption_send(TALLOC_CTX *mem_ctx,
3021                                                 struct tevent_context *ev,
3022                                                 struct cli_state *cli,
3023                                                 struct cli_credentials *creds)
3024 {
3025         struct tevent_req *req = NULL;
3026         struct cli_smb1_setup_encryption_state *state = NULL;
3027         struct auth_generic_state *ags = NULL;
3028         const DATA_BLOB *b = NULL;
3029         bool auth_requested = false;
3030         const char *target_service = NULL;
3031         const char *target_hostname = NULL;
3032         NTSTATUS status;
3033
3034         req = tevent_req_create(mem_ctx, &state,
3035                                 struct cli_smb1_setup_encryption_state);
3036         if (req == NULL) {
3037                 return NULL;
3038         }
3039         state->ev = ev;
3040         state->cli = cli;
3041
3042         auth_requested = cli_credentials_authentication_requested(creds);
3043         if (!auth_requested) {
3044                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
3045                 return tevent_req_post(req, ev);
3046         }
3047
3048         target_service = "cifs";
3049         target_hostname = smbXcli_conn_remote_name(cli->conn);
3050
3051         status = cli_session_creds_prepare_krb5(cli, creds);
3052         if (tevent_req_nterror(req, status)) {
3053                 return tevent_req_post(req, ev);
3054         }
3055
3056         state->es = talloc_zero(state, struct smb_trans_enc_state);
3057         if (tevent_req_nomem(state->es, req)) {
3058                 return tevent_req_post(req, ev);
3059         }
3060
3061         status = auth_generic_client_prepare(state->es, &ags);
3062         if (tevent_req_nterror(req, status)) {
3063                 return tevent_req_post(req, ev);
3064         }
3065
3066         gensec_want_feature(ags->gensec_security,
3067                             GENSEC_FEATURE_SIGN);
3068         gensec_want_feature(ags->gensec_security,
3069                             GENSEC_FEATURE_SEAL);
3070
3071         status = auth_generic_set_creds(ags, creds);
3072         if (tevent_req_nterror(req, status)) {
3073                 return tevent_req_post(req, ev);
3074         }
3075
3076         if (target_service != NULL) {
3077                 status = gensec_set_target_service(ags->gensec_security,
3078                                                    target_service);
3079                 if (tevent_req_nterror(req, status)) {
3080                         return tevent_req_post(req, ev);
3081                 }
3082         }
3083
3084         if (target_hostname != NULL) {
3085                 status = gensec_set_target_hostname(ags->gensec_security,
3086                                                     target_hostname);
3087                 if (tevent_req_nterror(req, status)) {
3088                         return tevent_req_post(req, ev);
3089                 }
3090         }
3091
3092         gensec_set_max_update_size(ags->gensec_security,
3093                                    CLI_BUFFER_SIZE);
3094
3095         b = smbXcli_conn_server_gss_blob(state->cli->conn);
3096         if (b != NULL) {
3097                 state->blob_in = *b;
3098         }
3099
3100         status = auth_generic_client_start(ags, GENSEC_OID_SPNEGO);
3101         if (tevent_req_nterror(req, status)) {
3102                 return tevent_req_post(req, ev);
3103         }
3104
3105         /*
3106          * We only need the gensec_security part from here.
3107          */
3108         state->es->gensec_security = talloc_move(state->es,
3109                                                  &ags->gensec_security);
3110         TALLOC_FREE(ags);
3111
3112         cli_smb1_setup_encryption_local_next(req);
3113         if (!tevent_req_is_in_progress(req)) {
3114                 return tevent_req_post(req, ev);
3115         }
3116
3117         return req;
3118 }
3119
3120 static void cli_smb1_setup_encryption_local_next(struct tevent_req *req)
3121 {
3122         struct cli_smb1_setup_encryption_state *state =
3123                 tevent_req_data(req,
3124                 struct cli_smb1_setup_encryption_state);
3125         struct tevent_req *subreq = NULL;
3126
3127         if (state->local_ready) {
3128                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3129                 return;
3130         }
3131
3132         subreq = gensec_update_send(state, state->ev,
3133                         state->es->gensec_security,
3134                         state->blob_in);
3135         if (tevent_req_nomem(subreq, req)) {
3136                 return;
3137         }
3138         tevent_req_set_callback(subreq, cli_smb1_setup_encryption_local_done, req);
3139 }
3140
3141 static void cli_smb1_setup_encryption_local_done(struct tevent_req *subreq)
3142 {
3143         struct tevent_req *req =
3144                 tevent_req_callback_data(subreq,
3145                 struct tevent_req);
3146         struct cli_smb1_setup_encryption_state *state =
3147                 tevent_req_data(req,
3148                 struct cli_smb1_setup_encryption_state);
3149         NTSTATUS status;
3150
3151         status = gensec_update_recv(subreq, state, &state->blob_out);
3152         TALLOC_FREE(subreq);
3153         state->blob_in = data_blob_null;
3154         if (!NT_STATUS_IS_OK(status) &&
3155             !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
3156         {
3157                 tevent_req_nterror(req, status);
3158                 return;
3159         }
3160
3161         if (NT_STATUS_IS_OK(status)) {
3162                 state->local_ready = true;
3163         }
3164
3165         /*
3166          * We always get NT_STATUS_OK from the server even if it is not ready.
3167          * So guess the server is ready when we are ready and already sent
3168          * our last blob to the server.
3169          */
3170         if (state->local_ready && state->blob_out.length == 0) {
3171                 state->remote_ready = true;
3172         }
3173
3174         if (state->local_ready && state->remote_ready) {
3175                 cli_smb1_setup_encryption_ready(req);
3176                 return;
3177         }
3178
3179         cli_smb1_setup_encryption_remote_next(req);
3180 }
3181
3182 static void cli_smb1_setup_encryption_remote_next(struct tevent_req *req)
3183 {
3184         struct cli_smb1_setup_encryption_state *state =
3185                 tevent_req_data(req,
3186                 struct cli_smb1_setup_encryption_state);
3187         struct tevent_req *subreq = NULL;
3188
3189         if (state->remote_ready) {
3190                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3191                 return;
3192         }
3193
3194         subreq = cli_smb1_setup_encryption_blob_send(state, state->ev,
3195                                                      state->cli, state->blob_out);
3196         if (tevent_req_nomem(subreq, req)) {
3197                 return;
3198         }
3199         tevent_req_set_callback(subreq,
3200                                 cli_smb1_setup_encryption_remote_done,
3201                                 req);
3202 }
3203
3204 static void cli_smb1_setup_encryption_remote_done(struct tevent_req *subreq)
3205 {
3206         struct tevent_req *req =
3207                 tevent_req_callback_data(subreq,
3208                 struct tevent_req);
3209         struct cli_smb1_setup_encryption_state *state =
3210                 tevent_req_data(req,
3211                 struct cli_smb1_setup_encryption_state);
3212         NTSTATUS status;
3213
3214         status = cli_smb1_setup_encryption_blob_recv(subreq, state,
3215                                                      &state->blob_in,
3216                                                      &state->es->enc_ctx_num);
3217         TALLOC_FREE(subreq);
3218         data_blob_free(&state->blob_out);
3219         if (!NT_STATUS_IS_OK(status) &&
3220             !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
3221         {
3222                 tevent_req_nterror(req, status);
3223                 return;
3224         }
3225
3226         /*
3227          * We always get NT_STATUS_OK even if the server is not ready.
3228          * So guess the server is ready when we are ready and sent
3229          * our last blob to the server.
3230          */
3231         if (state->local_ready) {
3232                 state->remote_ready = true;
3233         }
3234
3235         if (state->local_ready && state->remote_ready) {
3236                 cli_smb1_setup_encryption_ready(req);
3237                 return;
3238         }
3239
3240         cli_smb1_setup_encryption_local_next(req);
3241 }
3242
3243 static void cli_smb1_setup_encryption_ready(struct tevent_req *req)
3244 {
3245         struct cli_smb1_setup_encryption_state *state =
3246                 tevent_req_data(req,
3247                 struct cli_smb1_setup_encryption_state);
3248         struct smb_trans_enc_state *es = NULL;
3249
3250         if (state->blob_in.length != 0) {
3251                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3252                 return;
3253         }
3254
3255         if (state->blob_out.length != 0) {
3256                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3257                 return;
3258         }
3259
3260         es = talloc_move(state->cli->conn, &state->es);
3261         es->enc_on = true;
3262         smb1cli_conn_set_encryption(state->cli->conn, es);
3263         es = NULL;
3264
3265         tevent_req_done(req);
3266 }
3267
3268 static NTSTATUS cli_smb1_setup_encryption_recv(struct tevent_req *req)
3269 {
3270         return tevent_req_simple_recv_ntstatus(req);
3271 }
3272
3273 NTSTATUS cli_smb1_setup_encryption(struct cli_state *cli,
3274                                    struct cli_credentials *creds)
3275 {
3276         struct tevent_context *ev = NULL;
3277         struct tevent_req *req = NULL;
3278         NTSTATUS status = NT_STATUS_NO_MEMORY;
3279
3280         ev = samba_tevent_context_init(talloc_tos());
3281         if (ev == NULL) {
3282                 goto fail;
3283         }
3284         req = cli_smb1_setup_encryption_send(ev, ev, cli, creds);
3285         if (req == NULL) {
3286                 goto fail;
3287         }
3288         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
3289                 goto fail;
3290         }
3291         status = cli_smb1_setup_encryption_recv(req);
3292  fail:
3293         TALLOC_FREE(ev);
3294         return status;
3295 }
3296
3297 /**
3298    establishes a connection right up to doing tconX, password specified.
3299    @param output_cli A fully initialised cli structure, non-null only on success
3300    @param dest_host The netbios name of the remote host
3301    @param dest_ip (optional) The the destination IP, NULL for name based lookup
3302    @param port (optional) The destination port (0 for default)
3303    @param service (optional) The share to make the connection to.  Should be 'unqualified' in any way.
3304    @param service_type The 'type' of serivice. 
3305    @param creds The used user credentials
3306 */
3307
3308 struct cli_full_connection_creds_state {
3309         struct tevent_context *ev;
3310         const char *service;
3311         const char *service_type;
3312         struct cli_credentials *creds;
3313         int flags;
3314         struct cli_state *cli;
3315 };
3316
3317 static int cli_full_connection_creds_state_destructor(
3318         struct cli_full_connection_creds_state *s)
3319 {
3320         if (s->cli != NULL) {
3321                 cli_shutdown(s->cli);
3322                 s->cli = NULL;
3323         }
3324         return 0;
3325 }
3326
3327 static void cli_full_connection_creds_conn_done(struct tevent_req *subreq);
3328 static void cli_full_connection_creds_sess_start(struct tevent_req *req);
3329 static void cli_full_connection_creds_sess_done(struct tevent_req *subreq);
3330 static void cli_full_connection_creds_tcon_start(struct tevent_req *req);
3331 static void cli_full_connection_creds_tcon_done(struct tevent_req *subreq);
3332
3333 struct tevent_req *cli_full_connection_creds_send(
3334         TALLOC_CTX *mem_ctx, struct tevent_context *ev,
3335         const char *my_name, const char *dest_host,
3336         const struct sockaddr_storage *dest_ss, int port,
3337         const char *service, const char *service_type,
3338         struct cli_credentials *creds,
3339         int flags, int signing_state)
3340 {
3341         struct tevent_req *req, *subreq;
3342         struct cli_full_connection_creds_state *state;
3343         enum credentials_use_kerberos krb5_state;
3344         uint32_t gensec_features = 0;
3345
3346         req = tevent_req_create(mem_ctx, &state,
3347                                 struct cli_full_connection_creds_state);
3348         if (req == NULL) {
3349                 return NULL;
3350         }
3351         talloc_set_destructor(state, cli_full_connection_creds_state_destructor);
3352
3353         flags &= ~CLI_FULL_CONNECTION_USE_KERBEROS;
3354         flags &= ~CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS;
3355         flags &= ~CLI_FULL_CONNECTION_USE_CCACHE;
3356         flags &= ~CLI_FULL_CONNECTION_USE_NT_HASH;
3357
3358         krb5_state = cli_credentials_get_kerberos_state(creds);
3359         switch (krb5_state) {
3360         case CRED_MUST_USE_KERBEROS:
3361                 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
3362                 flags &= ~CLI_FULL_CONNECTION_DONT_SPNEGO;
3363                 break;
3364         case CRED_AUTO_USE_KERBEROS:
3365                 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
3366                 flags |= CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS;
3367                 break;
3368         case CRED_DONT_USE_KERBEROS:
3369                 break;
3370         }
3371
3372         gensec_features = cli_credentials_get_gensec_features(creds);
3373         if (gensec_features & GENSEC_FEATURE_NTLM_CCACHE) {
3374                 flags |= CLI_FULL_CONNECTION_USE_CCACHE;
3375         }
3376
3377         state->ev = ev;
3378         state->service = service;
3379         state->service_type = service_type;
3380         state->creds = creds;
3381         state->flags = flags;
3382
3383         subreq = cli_start_connection_send(
3384                 state, ev, my_name, dest_host, dest_ss, port,
3385                 signing_state, flags);
3386         if (tevent_req_nomem(subreq, req)) {
3387                 return tevent_req_post(req, ev);
3388         }
3389         tevent_req_set_callback(subreq,
3390                                 cli_full_connection_creds_conn_done,
3391                                 req);
3392         return req;
3393 }
3394
3395 static void cli_full_connection_creds_conn_done(struct tevent_req *subreq)
3396 {
3397         struct tevent_req *req = tevent_req_callback_data(
3398                 subreq, struct tevent_req);
3399         struct cli_full_connection_creds_state *state = tevent_req_data(
3400                 req, struct cli_full_connection_creds_state);
3401         NTSTATUS status;
3402
3403         status = cli_start_connection_recv(subreq, &state->cli);
3404         TALLOC_FREE(subreq);
3405         if (tevent_req_nterror(req, status)) {
3406                 return;
3407         }
3408
3409         cli_full_connection_creds_sess_start(req);
3410 }
3411
3412 static void cli_full_connection_creds_sess_start(struct tevent_req *req)
3413 {
3414         struct cli_full_connection_creds_state *state = tevent_req_data(
3415                 req, struct cli_full_connection_creds_state);
3416         struct tevent_req *subreq = NULL;
3417
3418         subreq = cli_session_setup_creds_send(
3419                 state, state->ev, state->cli, state->creds);
3420         if (tevent_req_nomem(subreq, req)) {
3421                 return;
3422         }
3423         tevent_req_set_callback(subreq,
3424                                 cli_full_connection_creds_sess_done,
3425                                 req);
3426 }
3427
3428 static void cli_full_connection_creds_sess_done(struct tevent_req *subreq)
3429 {
3430         struct tevent_req *req = tevent_req_callback_data(
3431                 subreq, struct tevent_req);
3432         struct cli_full_connection_creds_state *state = tevent_req_data(
3433                 req, struct cli_full_connection_creds_state);
3434         NTSTATUS status;
3435
3436         status = cli_session_setup_creds_recv(subreq);
3437         TALLOC_FREE(subreq);
3438
3439         if (!NT_STATUS_IS_OK(status) &&
3440             (state->flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)) {
3441
3442                 state->flags &= ~CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
3443
3444                 state->creds = cli_credentials_init_anon(state);
3445                 if (tevent_req_nomem(state->creds, req)) {
3446                         return;
3447                 }
3448
3449                 cli_full_connection_creds_sess_start(req);
3450                 return;
3451         }
3452
3453         if (tevent_req_nterror(req, status)) {
3454                 return;
3455         }
3456
3457         cli_full_connection_creds_tcon_start(req);
3458 }
3459
3460 static void cli_full_connection_creds_tcon_start(struct tevent_req *req)
3461 {
3462         struct cli_full_connection_creds_state *state = tevent_req_data(
3463                 req, struct cli_full_connection_creds_state);
3464         struct tevent_req *subreq = NULL;
3465         const char *password = NULL;
3466
3467         if (state->service == NULL) {
3468                 tevent_req_done(req);
3469                 return;
3470         }
3471
3472         password = cli_credentials_get_password(state->creds);
3473
3474         subreq = cli_tree_connect_send(state, state->ev,
3475                                        state->cli,
3476                                        state->service,
3477                                        state->service_type,
3478                                        password);
3479         if (tevent_req_nomem(subreq, req)) {
3480                 return;
3481         }
3482         tevent_req_set_callback(subreq,
3483                                 cli_full_connection_creds_tcon_done,
3484                                 req);
3485 }
3486
3487 static void cli_full_connection_creds_tcon_done(struct tevent_req *subreq)
3488 {
3489         struct tevent_req *req = tevent_req_callback_data(
3490                 subreq, struct tevent_req);
3491         NTSTATUS status;
3492
3493         status = cli_tree_connect_recv(subreq);
3494         TALLOC_FREE(subreq);
3495         if (tevent_req_nterror(req, status)) {
3496                 return;
3497         }
3498
3499         tevent_req_done(req);
3500 }
3501
3502 NTSTATUS cli_full_connection_creds_recv(struct tevent_req *req,
3503                                   struct cli_state **output_cli)
3504 {
3505         struct cli_full_connection_creds_state *state = tevent_req_data(
3506                 req, struct cli_full_connection_creds_state);
3507         NTSTATUS status;
3508
3509         if (tevent_req_is_nterror(req, &status)) {
3510                 return status;
3511         }
3512         *output_cli = state->cli;
3513         talloc_set_destructor(state, NULL);
3514         return NT_STATUS_OK;
3515 }
3516
3517 NTSTATUS cli_full_connection_creds(struct cli_state **output_cli,
3518                                    const char *my_name,
3519                                    const char *dest_host,
3520                                    const struct sockaddr_storage *dest_ss, int port,
3521                                    const char *service, const char *service_type,
3522                                    struct cli_credentials *creds,
3523                                    int flags,
3524                                    int signing_state)
3525 {
3526         struct tevent_context *ev;
3527         struct tevent_req *req;
3528         NTSTATUS status = NT_STATUS_NO_MEMORY;
3529
3530         ev = samba_tevent_context_init(talloc_tos());
3531         if (ev == NULL) {
3532                 goto fail;
3533         }
3534         req = cli_full_connection_creds_send(
3535                 ev, ev, my_name, dest_host, dest_ss, port, service,
3536                 service_type, creds, flags, signing_state);
3537         if (req == NULL) {
3538                 goto fail;
3539         }
3540         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
3541                 goto fail;
3542         }
3543         status = cli_full_connection_creds_recv(req, output_cli);
3544  fail:
3545         TALLOC_FREE(ev);
3546         return status;
3547 }
3548
3549 NTSTATUS cli_full_connection(struct cli_state **output_cli,
3550                              const char *my_name,
3551                              const char *dest_host,
3552                              const struct sockaddr_storage *dest_ss, int port,
3553                              const char *service, const char *service_type,
3554                              const char *user, const char *domain,
3555                              const char *password, int flags,
3556                              int signing_state)
3557 {
3558         TALLOC_CTX *frame = talloc_stackframe();
3559         NTSTATUS status;
3560         bool use_kerberos = false;
3561         bool fallback_after_kerberos = false;
3562         bool use_ccache = false;
3563         bool pw_nt_hash = false;
3564         struct cli_credentials *creds = NULL;
3565
3566         if (flags & CLI_FULL_CONNECTION_USE_KERBEROS) {
3567                 use_kerberos = true;
3568         }
3569
3570         if (flags & CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS) {
3571                 fallback_after_kerberos = true;
3572         }
3573
3574         if (flags & CLI_FULL_CONNECTION_USE_CCACHE) {
3575                 use_ccache = true;
3576         }
3577
3578         if (flags & CLI_FULL_CONNECTION_USE_NT_HASH) {
3579                 pw_nt_hash = true;
3580         }
3581
3582         creds = cli_session_creds_init(frame,
3583                                        user,
3584                                        domain,
3585                                        NULL, /* realm (use default) */
3586                                        password,
3587                                        use_kerberos,
3588                                        fallback_after_kerberos,
3589                                        use_ccache,
3590                                        pw_nt_hash);
3591         if (creds == NULL) {
3592                 TALLOC_FREE(frame);
3593                 return NT_STATUS_NO_MEMORY;
3594         }
3595
3596         status = cli_full_connection_creds(output_cli, my_name,
3597                                            dest_host, dest_ss, port,
3598                                            service, service_type,
3599                                            creds, flags, signing_state);
3600         if (!NT_STATUS_IS_OK(status)) {
3601                 TALLOC_FREE(frame);
3602                 return status;
3603         }
3604
3605         TALLOC_FREE(frame);
3606         return NT_STATUS_OK;
3607 }
3608
3609 /****************************************************************************
3610  Send an old style tcon.
3611 ****************************************************************************/
3612 struct cli_raw_tcon_state {
3613         uint16_t *ret_vwv;
3614 };
3615
3616 static void cli_raw_tcon_done(struct tevent_req *subreq);
3617
3618 static struct tevent_req *cli_raw_tcon_send(
3619         TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
3620         const char *service, const char *pass, const char *dev)
3621 {
3622         struct tevent_req *req, *subreq;
3623         struct cli_raw_tcon_state *state;
3624         uint8_t *bytes;
3625
3626         req = tevent_req_create(mem_ctx, &state, struct cli_raw_tcon_state);
3627         if (req == NULL) {
3628                 return NULL;
3629         }
3630
3631         if (!lp_client_plaintext_auth() && (*pass)) {
3632                 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
3633                           " or 'client ntlmv2 auth = yes'\n"));
3634                 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
3635                 return tevent_req_post(req, ev);
3636         }
3637
3638         TALLOC_FREE(cli->smb1.tcon);
3639         cli->smb1.tcon = smbXcli_tcon_create(cli);
3640         if (tevent_req_nomem(cli->smb1.tcon, req)) {
3641                 return tevent_req_post(req, ev);
3642         }
3643         smb1cli_tcon_set_id(cli->smb1.tcon, UINT16_MAX);
3644
3645         bytes = talloc_array(state, uint8_t, 0);
3646         bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3647         bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3648                                    service, strlen(service)+1, NULL);
3649         bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3650         bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3651                                    pass, strlen(pass)+1, NULL);
3652         bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3653         bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3654                                    dev, strlen(dev)+1, NULL);
3655
3656         if (tevent_req_nomem(bytes, req)) {
3657                 return tevent_req_post(req, ev);
3658         }
3659
3660         subreq = cli_smb_send(state, ev, cli, SMBtcon, 0, 0, 0, NULL,
3661                               talloc_get_size(bytes), bytes);
3662         if (tevent_req_nomem(subreq, req)) {
3663                 return tevent_req_post(req, ev);
3664         }
3665         tevent_req_set_callback(subreq, cli_raw_tcon_done, req);
3666         return req;
3667 }
3668
3669 static void cli_raw_tcon_done(struct tevent_req *subreq)
3670 {
3671         struct tevent_req *req = tevent_req_callback_data(
3672                 subreq, struct tevent_req);
3673         struct cli_raw_tcon_state *state = tevent_req_data(
3674                 req, struct cli_raw_tcon_state);
3675         NTSTATUS status;
3676
3677         status = cli_smb_recv(subreq, state, NULL, 2, NULL, &state->ret_vwv,
3678                               NULL, NULL);
3679         TALLOC_FREE(subreq);
3680         if (tevent_req_nterror(req, status)) {
3681                 return;
3682         }
3683         tevent_req_done(req);
3684 }
3685
3686 static NTSTATUS cli_raw_tcon_recv(struct tevent_req *req,
3687                                   uint16_t *max_xmit, uint16_t *tid)
3688 {
3689         struct cli_raw_tcon_state *state = tevent_req_data(
3690                 req, struct cli_raw_tcon_state);
3691         NTSTATUS status;
3692
3693         if (tevent_req_is_nterror(req, &status)) {
3694                 return status;
3695         }
3696         *max_xmit = SVAL(state->ret_vwv + 0, 0);
3697         *tid = SVAL(state->ret_vwv + 1, 0);
3698         return NT_STATUS_OK;
3699 }
3700
3701 NTSTATUS cli_raw_tcon(struct cli_state *cli,
3702                       const char *service, const char *pass, const char *dev,
3703                       uint16_t *max_xmit, uint16_t *tid)
3704 {
3705         struct tevent_context *ev;
3706         struct tevent_req *req;
3707         NTSTATUS status = NT_STATUS_NO_MEMORY;
3708
3709         ev = samba_tevent_context_init(talloc_tos());
3710         if (ev == NULL) {
3711                 goto fail;
3712         }
3713         req = cli_raw_tcon_send(ev, ev, cli, service, pass, dev);
3714         if (req == NULL) {
3715                 goto fail;
3716         }
3717         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
3718                 goto fail;
3719         }
3720         status = cli_raw_tcon_recv(req, max_xmit, tid);
3721 fail:
3722         TALLOC_FREE(ev);
3723         return status;
3724 }
3725
3726 /* Return a cli_state pointing at the IPC$ share for the given server */
3727
3728 struct cli_state *get_ipc_connect(char *server,
3729                                 struct sockaddr_storage *server_ss,
3730                                 const struct user_auth_info *user_info)
3731 {
3732         struct cli_state *cli;
3733         NTSTATUS nt_status;
3734         uint32_t flags = CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
3735
3736         if (get_cmdline_auth_info_use_kerberos(user_info)) {
3737                 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
3738         }
3739
3740         nt_status = cli_full_connection(&cli, NULL, server, server_ss, 0, "IPC$", "IPC", 
3741                                         get_cmdline_auth_info_username(user_info),
3742                                         lp_workgroup(),
3743                                         get_cmdline_auth_info_password(user_info),
3744                                         flags,
3745                                         SMB_SIGNING_DEFAULT);
3746
3747         if (NT_STATUS_IS_OK(nt_status)) {
3748                 return cli;
3749         } else if (is_ipaddress(server)) {
3750             /* windows 9* needs a correct NMB name for connections */
3751             fstring remote_name;
3752
3753             if (name_status_find("*", 0, 0, server_ss, remote_name)) {
3754                 cli = get_ipc_connect(remote_name, server_ss, user_info);
3755                 if (cli)
3756                     return cli;
3757             }
3758         }
3759         return NULL;
3760 }
3761
3762 /*
3763  * Given the IP address of a master browser on the network, return its
3764  * workgroup and connect to it.
3765  *
3766  * This function is provided to allow additional processing beyond what
3767  * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
3768  * browsers and obtain each master browsers' list of domains (in case the
3769  * first master browser is recently on the network and has not yet
3770  * synchronized with other master browsers and therefore does not yet have the
3771  * entire network browse list)
3772  */
3773
3774 struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx,
3775                                 struct sockaddr_storage *mb_ip,
3776                                 const struct user_auth_info *user_info,
3777                                 char **pp_workgroup_out)
3778 {
3779         char addr[INET6_ADDRSTRLEN];
3780         fstring name;
3781         struct cli_state *cli;
3782         struct sockaddr_storage server_ss;
3783
3784         *pp_workgroup_out = NULL;
3785
3786         print_sockaddr(addr, sizeof(addr), mb_ip);
3787         DEBUG(99, ("Looking up name of master browser %s\n",
3788                    addr));
3789
3790         /*
3791          * Do a name status query to find out the name of the master browser.
3792          * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
3793          * master browser will not respond to a wildcard query (or, at least,
3794          * an NT4 server acting as the domain master browser will not).
3795          *
3796          * We might be able to use ONLY the query on MSBROWSE, but that's not
3797          * yet been tested with all Windows versions, so until it is, leave
3798          * the original wildcard query as the first choice and fall back to
3799          * MSBROWSE if the wildcard query fails.
3800          */
3801         if (!name_status_find("*", 0, 0x1d, mb_ip, name) &&
3802             !name_status_find(MSBROWSE, 1, 0x1d, mb_ip, name)) {
3803
3804                 DEBUG(99, ("Could not retrieve name status for %s\n",
3805                            addr));
3806                 return NULL;
3807         }
3808
3809         if (!find_master_ip(name, &server_ss)) {
3810                 DEBUG(99, ("Could not find master ip for %s\n", name));
3811                 return NULL;
3812         }
3813
3814         *pp_workgroup_out = talloc_strdup(ctx, name);
3815
3816         DEBUG(4, ("found master browser %s, %s\n", name, addr));
3817
3818         print_sockaddr(addr, sizeof(addr), &server_ss);
3819         cli = get_ipc_connect(addr, &server_ss, user_info);
3820
3821         return cli;
3822 }
3823
3824 /*
3825  * Return the IP address and workgroup of a master browser on the network, and
3826  * connect to it.
3827  */
3828
3829 struct cli_state *get_ipc_connect_master_ip_bcast(TALLOC_CTX *ctx,
3830                                         const struct user_auth_info *user_info,
3831                                         char **pp_workgroup_out)
3832 {
3833         struct sockaddr_storage *ip_list;
3834         struct cli_state *cli;
3835         int i, count;
3836         NTSTATUS status;
3837
3838         *pp_workgroup_out = NULL;
3839
3840         DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
3841
3842         /* Go looking for workgroups by broadcasting on the local network */
3843
3844         status = name_resolve_bcast(MSBROWSE, 1, talloc_tos(),
3845                                     &ip_list, &count);
3846         if (!NT_STATUS_IS_OK(status)) {
3847                 DEBUG(99, ("No master browsers responded: %s\n",
3848                            nt_errstr(status)));
3849                 return NULL;
3850         }
3851
3852         for (i = 0; i < count; i++) {
3853                 char addr[INET6_ADDRSTRLEN];
3854                 print_sockaddr(addr, sizeof(addr), &ip_list[i]);
3855                 DEBUG(99, ("Found master browser %s\n", addr));
3856
3857                 cli = get_ipc_connect_master_ip(ctx, &ip_list[i],
3858                                 user_info, pp_workgroup_out);
3859                 if (cli)
3860                         return(cli);
3861         }
3862
3863         return NULL;
3864 }