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