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