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