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