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