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