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