source3: remove sock_exec
[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         struct sockaddr_storage *addrs;
2509         unsigned i, num_addrs;
2510         NTSTATUS status;
2511
2512         req = tevent_req_create(mem_ctx, &state,
2513                                 struct cli_connect_sock_state);
2514         if (req == NULL) {
2515                 return NULL;
2516         }
2517
2518         if ((pss == NULL) || is_zero_addr(pss)) {
2519
2520                 /*
2521                  * Here we cheat. resolve_name_list is not async at all. So
2522                  * this call will only be really async if the name lookup has
2523                  * been done externally.
2524                  */
2525
2526                 status = resolve_name_list(state, host, name_type,
2527                                            &addrs, &num_addrs);
2528                 if (!NT_STATUS_IS_OK(status)) {
2529                         tevent_req_nterror(req, status);
2530                         return tevent_req_post(req, ev);
2531                 }
2532         } else {
2533                 addrs = talloc_array(state, struct sockaddr_storage, 1);
2534                 if (tevent_req_nomem(addrs, req)) {
2535                         return tevent_req_post(req, ev);
2536                 }
2537                 addrs[0] = *pss;
2538                 num_addrs = 1;
2539         }
2540
2541         state->called_names = talloc_array(state, const char *, num_addrs);
2542         if (tevent_req_nomem(state->called_names, req)) {
2543                 return tevent_req_post(req, ev);
2544         }
2545         state->called_types = talloc_array(state, int, num_addrs);
2546         if (tevent_req_nomem(state->called_types, req)) {
2547                 return tevent_req_post(req, ev);
2548         }
2549         state->calling_names = talloc_array(state, const char *, num_addrs);
2550         if (tevent_req_nomem(state->calling_names, req)) {
2551                 return tevent_req_post(req, ev);
2552         }
2553         for (i=0; i<num_addrs; i++) {
2554                 state->called_names[i] = host;
2555                 state->called_types[i] = name_type;
2556                 state->calling_names[i] = myname;
2557         }
2558
2559         subreq = smbsock_any_connect_send(
2560                 state, ev, addrs, state->called_names, state->called_types,
2561                 state->calling_names, NULL, num_addrs, port);
2562         if (tevent_req_nomem(subreq, req)) {
2563                 return tevent_req_post(req, ev);
2564         }
2565         tevent_req_set_callback(subreq, cli_connect_sock_done, req);
2566         return req;
2567 }
2568
2569 static void cli_connect_sock_done(struct tevent_req *subreq)
2570 {
2571         struct tevent_req *req = tevent_req_callback_data(
2572                 subreq, struct tevent_req);
2573         struct cli_connect_sock_state *state = tevent_req_data(
2574                 req, struct cli_connect_sock_state);
2575         NTSTATUS status;
2576
2577         status = smbsock_any_connect_recv(subreq, &state->fd, NULL,
2578                                           &state->port);
2579         TALLOC_FREE(subreq);
2580         if (tevent_req_nterror(req, status)) {
2581                 return;
2582         }
2583         set_socket_options(state->fd, lp_socket_options());
2584         tevent_req_done(req);
2585 }
2586
2587 static NTSTATUS cli_connect_sock_recv(struct tevent_req *req,
2588                                       int *pfd, uint16_t *pport)
2589 {
2590         struct cli_connect_sock_state *state = tevent_req_data(
2591                 req, struct cli_connect_sock_state);
2592         NTSTATUS status;
2593
2594         if (tevent_req_is_nterror(req, &status)) {
2595                 return status;
2596         }
2597         *pfd = state->fd;
2598         *pport = state->port;
2599         return NT_STATUS_OK;
2600 }
2601
2602 struct cli_connect_nb_state {
2603         const char *desthost;
2604         int signing_state;
2605         int flags;
2606         struct cli_state *cli;
2607 };
2608
2609 static void cli_connect_nb_done(struct tevent_req *subreq);
2610
2611 static struct tevent_req *cli_connect_nb_send(
2612         TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2613         const char *host, const struct sockaddr_storage *dest_ss,
2614         uint16_t port, int name_type, const char *myname,
2615         int signing_state, int flags)
2616 {
2617         struct tevent_req *req, *subreq;
2618         struct cli_connect_nb_state *state;
2619
2620         req = tevent_req_create(mem_ctx, &state, struct cli_connect_nb_state);
2621         if (req == NULL) {
2622                 return NULL;
2623         }
2624         state->signing_state = signing_state;
2625         state->flags = flags;
2626
2627         if (host != NULL) {
2628                 char *p = strchr(host, '#');
2629
2630                 if (p != NULL) {
2631                         name_type = strtol(p+1, NULL, 16);
2632                         host = talloc_strndup(state, host, p - host);
2633                         if (tevent_req_nomem(host, req)) {
2634                                 return tevent_req_post(req, ev);
2635                         }
2636                 }
2637
2638                 state->desthost = host;
2639         } else if (dest_ss != NULL) {
2640                 state->desthost = print_canonical_sockaddr(state, dest_ss);
2641                 if (tevent_req_nomem(state->desthost, req)) {
2642                         return tevent_req_post(req, ev);
2643                 }
2644         } else {
2645                 /* No host or dest_ss given. Error out. */
2646                 tevent_req_error(req, EINVAL);
2647                 return tevent_req_post(req, ev);
2648         }
2649
2650         subreq = cli_connect_sock_send(state, ev, host, name_type, dest_ss,
2651                                        myname, port);
2652         if (tevent_req_nomem(subreq, req)) {
2653                 return tevent_req_post(req, ev);
2654         }
2655         tevent_req_set_callback(subreq, cli_connect_nb_done, req);
2656         return req;
2657 }
2658
2659 static void cli_connect_nb_done(struct tevent_req *subreq)
2660 {
2661         struct tevent_req *req = tevent_req_callback_data(
2662                 subreq, struct tevent_req);
2663         struct cli_connect_nb_state *state = tevent_req_data(
2664                 req, struct cli_connect_nb_state);
2665         NTSTATUS status;
2666         int fd = 0;
2667         uint16_t port;
2668
2669         status = cli_connect_sock_recv(subreq, &fd, &port);
2670         TALLOC_FREE(subreq);
2671         if (tevent_req_nterror(req, status)) {
2672                 return;
2673         }
2674
2675         state->cli = cli_state_create(state, fd, state->desthost,
2676                                       state->signing_state, state->flags);
2677         if (tevent_req_nomem(state->cli, req)) {
2678                 close(fd);
2679                 return;
2680         }
2681         tevent_req_done(req);
2682 }
2683
2684 static NTSTATUS cli_connect_nb_recv(struct tevent_req *req,
2685                                     struct cli_state **pcli)
2686 {
2687         struct cli_connect_nb_state *state = tevent_req_data(
2688                 req, struct cli_connect_nb_state);
2689         NTSTATUS status;
2690
2691         if (tevent_req_is_nterror(req, &status)) {
2692                 return status;
2693         }
2694         *pcli = talloc_move(NULL, &state->cli);
2695         return NT_STATUS_OK;
2696 }
2697
2698 NTSTATUS cli_connect_nb(const char *host, const struct sockaddr_storage *dest_ss,
2699                         uint16_t port, int name_type, const char *myname,
2700                         int signing_state, int flags, struct cli_state **pcli)
2701 {
2702         struct tevent_context *ev;
2703         struct tevent_req *req;
2704         NTSTATUS status = NT_STATUS_NO_MEMORY;
2705
2706         ev = samba_tevent_context_init(talloc_tos());
2707         if (ev == NULL) {
2708                 goto fail;
2709         }
2710         req = cli_connect_nb_send(ev, ev, host, dest_ss, port, name_type,
2711                                   myname, signing_state, flags);
2712         if (req == NULL) {
2713                 goto fail;
2714         }
2715         if (!tevent_req_set_endtime(req, ev, timeval_current_ofs(20, 0))) {
2716                 goto fail;
2717         }
2718         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2719                 goto fail;
2720         }
2721         status = cli_connect_nb_recv(req, pcli);
2722 fail:
2723         TALLOC_FREE(ev);
2724         return status;
2725 }
2726
2727 struct cli_start_connection_state {
2728         struct tevent_context *ev;
2729         struct cli_state *cli;
2730         int min_protocol;
2731         int max_protocol;
2732 };
2733
2734 static void cli_start_connection_connected(struct tevent_req *subreq);
2735 static void cli_start_connection_done(struct tevent_req *subreq);
2736
2737 /**
2738    establishes a connection to after the negprot. 
2739    @param output_cli A fully initialised cli structure, non-null only on success
2740    @param dest_host The netbios name of the remote host
2741    @param dest_ss (optional) The the destination IP, NULL for name based lookup
2742    @param port (optional) The destination port (0 for default)
2743 */
2744
2745 static struct tevent_req *cli_start_connection_send(
2746         TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2747         const char *my_name, const char *dest_host,
2748         const struct sockaddr_storage *dest_ss, int port,
2749         int signing_state, int flags)
2750 {
2751         struct tevent_req *req, *subreq;
2752         struct cli_start_connection_state *state;
2753
2754         req = tevent_req_create(mem_ctx, &state,
2755                                 struct cli_start_connection_state);
2756         if (req == NULL) {
2757                 return NULL;
2758         }
2759         state->ev = ev;
2760
2761         if (signing_state == SMB_SIGNING_IPC_DEFAULT) {
2762                 state->min_protocol = lp_client_ipc_min_protocol();
2763                 state->max_protocol = lp_client_ipc_max_protocol();
2764         } else {
2765                 state->min_protocol = lp_client_min_protocol();
2766                 state->max_protocol = lp_client_max_protocol();
2767         }
2768
2769         if (flags & CLI_FULL_CONNECTION_FORCE_SMB1) {
2770                 state->max_protocol = MIN(state->max_protocol, PROTOCOL_NT1);
2771         }
2772
2773         if (flags & CLI_FULL_CONNECTION_DISABLE_SMB1) {
2774                 state->min_protocol = MAX(state->max_protocol, PROTOCOL_SMB2_02);
2775                 state->max_protocol = MAX(state->max_protocol, PROTOCOL_LATEST);
2776         }
2777
2778         subreq = cli_connect_nb_send(state, ev, dest_host, dest_ss, port,
2779                                      0x20, my_name, signing_state, flags);
2780         if (tevent_req_nomem(subreq, req)) {
2781                 return tevent_req_post(req, ev);
2782         }
2783         tevent_req_set_callback(subreq, cli_start_connection_connected, req);
2784         return req;
2785 }
2786
2787 static void cli_start_connection_connected(struct tevent_req *subreq)
2788 {
2789         struct tevent_req *req = tevent_req_callback_data(
2790                 subreq, struct tevent_req);
2791         struct cli_start_connection_state *state = tevent_req_data(
2792                 req, struct cli_start_connection_state);
2793         NTSTATUS status;
2794
2795         status = cli_connect_nb_recv(subreq, &state->cli);
2796         TALLOC_FREE(subreq);
2797         if (tevent_req_nterror(req, status)) {
2798                 return;
2799         }
2800
2801         subreq = smbXcli_negprot_send(state, state->ev, state->cli->conn,
2802                                       state->cli->timeout,
2803                                       state->min_protocol,
2804                                       state->max_protocol,
2805                                       WINDOWS_CLIENT_PURE_SMB2_NEGPROT_INITIAL_CREDIT_ASK);
2806         if (tevent_req_nomem(subreq, req)) {
2807                 return;
2808         }
2809         tevent_req_set_callback(subreq, cli_start_connection_done, req);
2810 }
2811
2812 static void cli_start_connection_done(struct tevent_req *subreq)
2813 {
2814         struct tevent_req *req = tevent_req_callback_data(
2815                 subreq, struct tevent_req);
2816         struct cli_start_connection_state *state = tevent_req_data(
2817                 req, struct cli_start_connection_state);
2818         NTSTATUS status;
2819
2820         status = smbXcli_negprot_recv(subreq);
2821         TALLOC_FREE(subreq);
2822         if (tevent_req_nterror(req, status)) {
2823                 return;
2824         }
2825
2826         if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
2827                 /* Ensure we ask for some initial credits. */
2828                 smb2cli_conn_set_max_credits(state->cli->conn,
2829                                              DEFAULT_SMB2_MAX_CREDITS);
2830         }
2831
2832         tevent_req_done(req);
2833 }
2834
2835 static NTSTATUS cli_start_connection_recv(struct tevent_req *req,
2836                                           struct cli_state **output_cli)
2837 {
2838         struct cli_start_connection_state *state = tevent_req_data(
2839                 req, struct cli_start_connection_state);
2840         NTSTATUS status;
2841
2842         if (tevent_req_is_nterror(req, &status)) {
2843                 return status;
2844         }
2845         *output_cli = state->cli;
2846
2847         return NT_STATUS_OK;
2848 }
2849
2850 NTSTATUS cli_start_connection(struct cli_state **output_cli, 
2851                               const char *my_name, 
2852                               const char *dest_host, 
2853                               const struct sockaddr_storage *dest_ss, int port,
2854                               int signing_state, int flags)
2855 {
2856         struct tevent_context *ev;
2857         struct tevent_req *req;
2858         NTSTATUS status = NT_STATUS_NO_MEMORY;
2859
2860         ev = samba_tevent_context_init(talloc_tos());
2861         if (ev == NULL) {
2862                 goto fail;
2863         }
2864         req = cli_start_connection_send(ev, ev, my_name, dest_host, dest_ss,
2865                                         port, signing_state, flags);
2866         if (req == NULL) {
2867                 goto fail;
2868         }
2869         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2870                 goto fail;
2871         }
2872         status = cli_start_connection_recv(req, output_cli);
2873 fail:
2874         TALLOC_FREE(ev);
2875         return status;
2876 }
2877
2878 struct cli_smb1_setup_encryption_blob_state {
2879         uint16_t setup[1];
2880         uint8_t param[4];
2881         NTSTATUS status;
2882         DATA_BLOB out;
2883         uint16_t enc_ctx_id;
2884 };
2885
2886 static void cli_smb1_setup_encryption_blob_done(struct tevent_req *subreq);
2887
2888 static struct tevent_req *cli_smb1_setup_encryption_blob_send(TALLOC_CTX *mem_ctx,
2889                                                         struct tevent_context *ev,
2890                                                         struct cli_state *cli,
2891                                                         const DATA_BLOB in)
2892 {
2893         struct tevent_req *req = NULL;
2894         struct cli_smb1_setup_encryption_blob_state *state = NULL;
2895         struct tevent_req *subreq = NULL;
2896
2897         req = tevent_req_create(mem_ctx, &state,
2898                                 struct cli_smb1_setup_encryption_blob_state);
2899         if (req == NULL) {
2900                 return NULL;
2901         }
2902
2903         if (in.length > CLI_BUFFER_SIZE) {
2904                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
2905                 return tevent_req_post(req, ev);
2906         }
2907
2908         SSVAL(state->setup+0,  0, TRANSACT2_SETFSINFO);
2909         SSVAL(state->param, 0, 0);
2910         SSVAL(state->param, 2, SMB_REQUEST_TRANSPORT_ENCRYPTION);
2911
2912         subreq = smb1cli_trans_send(state, ev, cli->conn,
2913                                     SMBtrans2,
2914                                     0, 0, /* _flags */
2915                                     0, 0, /* _flags2 */
2916                                     cli->timeout,
2917                                     cli->smb1.pid,
2918                                     cli->smb1.tcon,
2919                                     cli->smb1.session,
2920                                     NULL, /* pipe_name */
2921                                     0, /* fid */
2922                                     0, /* function */
2923                                     0, /* flags */
2924                                     state->setup, 1, 0,
2925                                     state->param, 4, 2,
2926                                     in.data, in.length, CLI_BUFFER_SIZE);
2927         if (tevent_req_nomem(subreq, req)) {
2928                 return tevent_req_post(req, ev);
2929         }
2930         tevent_req_set_callback(subreq,
2931                                 cli_smb1_setup_encryption_blob_done,
2932                                 req);
2933
2934         return req;
2935 }
2936
2937 static void cli_smb1_setup_encryption_blob_done(struct tevent_req *subreq)
2938 {
2939         struct tevent_req *req =
2940                 tevent_req_callback_data(subreq,
2941                                 struct tevent_req);
2942         struct cli_smb1_setup_encryption_blob_state *state =
2943                 tevent_req_data(req,
2944                 struct cli_smb1_setup_encryption_blob_state);
2945         uint8_t *rparam=NULL, *rdata=NULL;
2946         uint32_t num_rparam, num_rdata;
2947         NTSTATUS status;
2948
2949         status = smb1cli_trans_recv(subreq, state,
2950                                     NULL, /* recv_flags */
2951                                     NULL, 0, NULL, /* rsetup */
2952                                     &rparam, 0, &num_rparam,
2953                                     &rdata, 0, &num_rdata);
2954         TALLOC_FREE(subreq);
2955         state->status = status;
2956         if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
2957                 status = NT_STATUS_OK;
2958         }
2959         if (tevent_req_nterror(req, status)) {
2960                 return;
2961         }
2962
2963         if (num_rparam == 2) {
2964                 state->enc_ctx_id = SVAL(rparam, 0);
2965         }
2966         TALLOC_FREE(rparam);
2967
2968         state->out = data_blob_const(rdata, num_rdata);
2969
2970         tevent_req_done(req);
2971 }
2972
2973 static NTSTATUS cli_smb1_setup_encryption_blob_recv(struct tevent_req *req,
2974                                                     TALLOC_CTX *mem_ctx,
2975                                                     DATA_BLOB *out,
2976                                                     uint16_t *enc_ctx_id)
2977 {
2978         struct cli_smb1_setup_encryption_blob_state *state =
2979                 tevent_req_data(req,
2980                 struct cli_smb1_setup_encryption_blob_state);
2981         NTSTATUS status;
2982
2983         if (tevent_req_is_nterror(req, &status)) {
2984                 tevent_req_received(req);
2985                 return status;
2986         }
2987
2988         status = state->status;
2989
2990         *out = state->out;
2991         talloc_steal(mem_ctx, out->data);
2992
2993         *enc_ctx_id = state->enc_ctx_id;
2994
2995         tevent_req_received(req);
2996         return status;
2997 }
2998
2999 struct cli_smb1_setup_encryption_state {
3000         struct tevent_context *ev;
3001         struct cli_state *cli;
3002         struct smb_trans_enc_state *es;
3003         DATA_BLOB blob_in;
3004         DATA_BLOB blob_out;
3005         bool local_ready;
3006         bool remote_ready;
3007 };
3008
3009 static void cli_smb1_setup_encryption_local_next(struct tevent_req *req);
3010 static void cli_smb1_setup_encryption_local_done(struct tevent_req *subreq);
3011 static void cli_smb1_setup_encryption_remote_next(struct tevent_req *req);
3012 static void cli_smb1_setup_encryption_remote_done(struct tevent_req *subreq);
3013 static void cli_smb1_setup_encryption_ready(struct tevent_req *req);
3014
3015 static struct tevent_req *cli_smb1_setup_encryption_send(TALLOC_CTX *mem_ctx,
3016                                                 struct tevent_context *ev,
3017                                                 struct cli_state *cli,
3018                                                 struct cli_credentials *creds)
3019 {
3020         struct tevent_req *req = NULL;
3021         struct cli_smb1_setup_encryption_state *state = NULL;
3022         struct auth_generic_state *ags = NULL;
3023         const DATA_BLOB *b = NULL;
3024         bool auth_requested = false;
3025         const char *target_service = NULL;
3026         const char *target_hostname = NULL;
3027         NTSTATUS status;
3028
3029         req = tevent_req_create(mem_ctx, &state,
3030                                 struct cli_smb1_setup_encryption_state);
3031         if (req == NULL) {
3032                 return NULL;
3033         }
3034         state->ev = ev;
3035         state->cli = cli;
3036
3037         auth_requested = cli_credentials_authentication_requested(creds);
3038         if (!auth_requested) {
3039                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
3040                 return tevent_req_post(req, ev);
3041         }
3042
3043         target_service = "cifs";
3044         target_hostname = smbXcli_conn_remote_name(cli->conn);
3045
3046         status = cli_session_creds_prepare_krb5(cli, creds);
3047         if (tevent_req_nterror(req, status)) {
3048                 return tevent_req_post(req, ev);
3049         }
3050
3051         state->es = talloc_zero(state, struct smb_trans_enc_state);
3052         if (tevent_req_nomem(state->es, req)) {
3053                 return tevent_req_post(req, ev);
3054         }
3055
3056         status = auth_generic_client_prepare(state->es, &ags);
3057         if (tevent_req_nterror(req, status)) {
3058                 return tevent_req_post(req, ev);
3059         }
3060
3061         gensec_want_feature(ags->gensec_security,
3062                             GENSEC_FEATURE_SIGN);
3063         gensec_want_feature(ags->gensec_security,
3064                             GENSEC_FEATURE_SEAL);
3065
3066         status = auth_generic_set_creds(ags, creds);
3067         if (tevent_req_nterror(req, status)) {
3068                 return tevent_req_post(req, ev);
3069         }
3070
3071         if (target_service != NULL) {
3072                 status = gensec_set_target_service(ags->gensec_security,
3073                                                    target_service);
3074                 if (tevent_req_nterror(req, status)) {
3075                         return tevent_req_post(req, ev);
3076                 }
3077         }
3078
3079         if (target_hostname != NULL) {
3080                 status = gensec_set_target_hostname(ags->gensec_security,
3081                                                     target_hostname);
3082                 if (tevent_req_nterror(req, status)) {
3083                         return tevent_req_post(req, ev);
3084                 }
3085         }
3086
3087         gensec_set_max_update_size(ags->gensec_security,
3088                                    CLI_BUFFER_SIZE);
3089
3090         b = smbXcli_conn_server_gss_blob(state->cli->conn);
3091         if (b != NULL) {
3092                 state->blob_in = *b;
3093         }
3094
3095         status = auth_generic_client_start(ags, GENSEC_OID_SPNEGO);
3096         if (tevent_req_nterror(req, status)) {
3097                 return tevent_req_post(req, ev);
3098         }
3099
3100         /*
3101          * We only need the gensec_security part from here.
3102          */
3103         state->es->gensec_security = talloc_move(state->es,
3104                                                  &ags->gensec_security);
3105         TALLOC_FREE(ags);
3106
3107         cli_smb1_setup_encryption_local_next(req);
3108         if (!tevent_req_is_in_progress(req)) {
3109                 return tevent_req_post(req, ev);
3110         }
3111
3112         return req;
3113 }
3114
3115 static void cli_smb1_setup_encryption_local_next(struct tevent_req *req)
3116 {
3117         struct cli_smb1_setup_encryption_state *state =
3118                 tevent_req_data(req,
3119                 struct cli_smb1_setup_encryption_state);
3120         struct tevent_req *subreq = NULL;
3121
3122         if (state->local_ready) {
3123                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3124                 return;
3125         }
3126
3127         subreq = gensec_update_send(state, state->ev,
3128                         state->es->gensec_security,
3129                         state->blob_in);
3130         if (tevent_req_nomem(subreq, req)) {
3131                 return;
3132         }
3133         tevent_req_set_callback(subreq, cli_smb1_setup_encryption_local_done, req);
3134 }
3135
3136 static void cli_smb1_setup_encryption_local_done(struct tevent_req *subreq)
3137 {
3138         struct tevent_req *req =
3139                 tevent_req_callback_data(subreq,
3140                 struct tevent_req);
3141         struct cli_smb1_setup_encryption_state *state =
3142                 tevent_req_data(req,
3143                 struct cli_smb1_setup_encryption_state);
3144         NTSTATUS status;
3145
3146         status = gensec_update_recv(subreq, state, &state->blob_out);
3147         TALLOC_FREE(subreq);
3148         state->blob_in = data_blob_null;
3149         if (!NT_STATUS_IS_OK(status) &&
3150             !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
3151         {
3152                 tevent_req_nterror(req, status);
3153                 return;
3154         }
3155
3156         if (NT_STATUS_IS_OK(status)) {
3157                 state->local_ready = true;
3158         }
3159
3160         /*
3161          * We always get NT_STATUS_OK from the server even if it is not ready.
3162          * So guess the server is ready when we are ready and already sent
3163          * our last blob to the server.
3164          */
3165         if (state->local_ready && state->blob_out.length == 0) {
3166                 state->remote_ready = true;
3167         }
3168
3169         if (state->local_ready && state->remote_ready) {
3170                 cli_smb1_setup_encryption_ready(req);
3171                 return;
3172         }
3173
3174         cli_smb1_setup_encryption_remote_next(req);
3175 }
3176
3177 static void cli_smb1_setup_encryption_remote_next(struct tevent_req *req)
3178 {
3179         struct cli_smb1_setup_encryption_state *state =
3180                 tevent_req_data(req,
3181                 struct cli_smb1_setup_encryption_state);
3182         struct tevent_req *subreq = NULL;
3183
3184         if (state->remote_ready) {
3185                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3186                 return;
3187         }
3188
3189         subreq = cli_smb1_setup_encryption_blob_send(state, state->ev,
3190                                                      state->cli, state->blob_out);
3191         if (tevent_req_nomem(subreq, req)) {
3192                 return;
3193         }
3194         tevent_req_set_callback(subreq,
3195                                 cli_smb1_setup_encryption_remote_done,
3196                                 req);
3197 }
3198
3199 static void cli_smb1_setup_encryption_remote_done(struct tevent_req *subreq)
3200 {
3201         struct tevent_req *req =
3202                 tevent_req_callback_data(subreq,
3203                 struct tevent_req);
3204         struct cli_smb1_setup_encryption_state *state =
3205                 tevent_req_data(req,
3206                 struct cli_smb1_setup_encryption_state);
3207         NTSTATUS status;
3208
3209         status = cli_smb1_setup_encryption_blob_recv(subreq, state,
3210                                                      &state->blob_in,
3211                                                      &state->es->enc_ctx_num);
3212         TALLOC_FREE(subreq);
3213         data_blob_free(&state->blob_out);
3214         if (!NT_STATUS_IS_OK(status) &&
3215             !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
3216         {
3217                 tevent_req_nterror(req, status);
3218                 return;
3219         }
3220
3221         /*
3222          * We always get NT_STATUS_OK even if the server is not ready.
3223          * So guess the server is ready when we are ready and sent
3224          * our last blob to the server.
3225          */
3226         if (state->local_ready) {
3227                 state->remote_ready = true;
3228         }
3229
3230         if (state->local_ready && state->remote_ready) {
3231                 cli_smb1_setup_encryption_ready(req);
3232                 return;
3233         }
3234
3235         cli_smb1_setup_encryption_local_next(req);
3236 }
3237
3238 static void cli_smb1_setup_encryption_ready(struct tevent_req *req)
3239 {
3240         struct cli_smb1_setup_encryption_state *state =
3241                 tevent_req_data(req,
3242                 struct cli_smb1_setup_encryption_state);
3243         struct smb_trans_enc_state *es = NULL;
3244
3245         if (state->blob_in.length != 0) {
3246                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3247                 return;
3248         }
3249
3250         if (state->blob_out.length != 0) {
3251                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3252                 return;
3253         }
3254
3255         es = talloc_move(state->cli->conn, &state->es);
3256         es->enc_on = true;
3257         smb1cli_conn_set_encryption(state->cli->conn, es);
3258         es = NULL;
3259
3260         tevent_req_done(req);
3261 }
3262
3263 static NTSTATUS cli_smb1_setup_encryption_recv(struct tevent_req *req)
3264 {
3265         return tevent_req_simple_recv_ntstatus(req);
3266 }
3267
3268 NTSTATUS cli_smb1_setup_encryption(struct cli_state *cli,
3269                                    struct cli_credentials *creds)
3270 {
3271         struct tevent_context *ev = NULL;
3272         struct tevent_req *req = NULL;
3273         NTSTATUS status = NT_STATUS_NO_MEMORY;
3274
3275         ev = samba_tevent_context_init(talloc_tos());
3276         if (ev == NULL) {
3277                 goto fail;
3278         }
3279         req = cli_smb1_setup_encryption_send(ev, ev, cli, creds);
3280         if (req == NULL) {
3281                 goto fail;
3282         }
3283         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
3284