s3:libsmb: move cli->capabilities to cli->conn.smb1.capabilities
[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 wct;
2604         uint16_t *vwv;
2605         uint32_t num_bytes;
2606         uint8_t *bytes;
2607         NTSTATUS status;
2608         uint16_t protnum;
2609         uint8_t *inbuf;
2610         uint32_t client_capabilities = cli->conn.smb1.client.capabilities;
2611         uint32_t both_capabilities;
2612         uint32_t server_capabilities = 0;
2613         uint32_t capabilities;
2614         enum protocol_types protocol;
2615
2616         status = cli_smb_recv(subreq, state, &inbuf, 1, &wct, &vwv,
2617                               &num_bytes, &bytes);
2618         TALLOC_FREE(subreq);
2619         if (!NT_STATUS_IS_OK(status)) {
2620                 tevent_req_nterror(req, status);
2621                 return;
2622         }
2623
2624         protnum = SVAL(vwv, 0);
2625
2626         if ((protnum >= ARRAY_SIZE(prots))
2627             || (prots[protnum].prot > state->max_protocol)) {
2628                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2629                 return;
2630         }
2631
2632         protocol = prots[protnum].prot;
2633
2634         if ((protocol < PROTOCOL_NT1) &&
2635             client_is_signing_mandatory(cli)) {
2636                 DEBUG(0,("cli_negprot: SMB signing is mandatory and the selected protocol level doesn't support it.\n"));
2637                 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
2638                 return;
2639         }
2640
2641         if (protocol >= PROTOCOL_NT1) {
2642                 struct timespec ts;
2643                 const char *client_signing = NULL;
2644                 bool server_mandatory;
2645                 bool server_allowed;
2646                 const char *server_signing = NULL;
2647                 bool ok;
2648
2649                 if (wct != 0x11) {
2650                         tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2651                         return;
2652                 }
2653
2654                 /* NT protocol */
2655                 cli->sec_mode = CVAL(vwv + 1, 0);
2656                 cli->max_mux = SVAL(vwv + 1, 1);
2657                 cli->max_xmit = IVAL(vwv + 3, 1);
2658                 cli->sesskey = IVAL(vwv + 7, 1);
2659                 cli->serverzone = SVALS(vwv + 15, 1);
2660                 cli->serverzone *= 60;
2661                 /* this time arrives in real GMT */
2662                 ts = interpret_long_date(((char *)(vwv+11))+1);
2663                 cli->servertime = ts.tv_sec;
2664                 cli->secblob = data_blob(bytes, num_bytes);
2665                 server_capabilities = IVAL(vwv + 9, 1);
2666                 if (server_capabilities & CAP_RAW_MODE) {
2667                         cli->readbraw_supported = True;
2668                         cli->writebraw_supported = True;      
2669                 }
2670                 /* work out if they sent us a workgroup */
2671                 if (!(server_capabilities & CAP_EXTENDED_SECURITY) &&
2672                     smb_buflen(inbuf) > 8) {
2673                         ssize_t ret;
2674                         status = smb_bytes_talloc_string(
2675                                 cli, (char *)inbuf, &cli->server_domain,
2676                                 bytes + 8, num_bytes - 8, &ret);
2677                         if (tevent_req_nterror(req, status)) {
2678                                 return;
2679                         }
2680                 }
2681
2682                 client_signing = "disabled";
2683                 if (client_is_signing_allowed(cli)) {
2684                         client_signing = "allowed";
2685                 }
2686                 if (client_is_signing_mandatory(cli)) {
2687                         client_signing = "required";
2688                 }
2689
2690                 server_signing = "not supported";
2691                 if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) {
2692                         server_signing = "supported";
2693                         server_allowed = true;
2694                 }
2695                 if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) {
2696                         server_signing = "required";
2697                         server_mandatory = true;
2698                 }
2699
2700                 ok = cli_set_signing_negotiated(cli,
2701                                                 server_allowed,
2702                                                 server_mandatory);
2703                 if (!ok) {
2704                         DEBUG(1,("cli_negprot: SMB signing is required, "
2705                                  "but client[%s] and server[%s] mismatch\n",
2706                                  client_signing, server_signing));
2707                         tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
2708                         return;
2709                 }
2710
2711         } else if (protocol >= PROTOCOL_LANMAN1) {
2712                 if (wct != 0x0D) {
2713                         tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2714                         return;
2715                 }
2716
2717                 cli->sec_mode = SVAL(vwv + 1, 0);
2718                 cli->max_xmit = SVAL(vwv + 2, 0);
2719                 cli->max_mux = SVAL(vwv + 3, 0);
2720                 cli->sesskey = IVAL(vwv + 6, 0);
2721                 cli->serverzone = SVALS(vwv + 10, 0);
2722                 cli->serverzone *= 60;
2723                 /* this time is converted to GMT by make_unix_date */
2724                 cli->servertime = make_unix_date(
2725                         (char *)(vwv + 8), cli->serverzone);
2726                 cli->readbraw_supported = ((SVAL(vwv + 5, 0) & 0x1) != 0);
2727                 cli->writebraw_supported = ((SVAL(vwv + 5, 0) & 0x2) != 0);
2728                 cli->secblob = data_blob(bytes, num_bytes);
2729         } else {
2730                 /* the old core protocol */
2731                 cli->sec_mode = 0;
2732                 cli->serverzone = get_time_zone(time(NULL));
2733                 cli->max_xmit = 1024;
2734                 cli->max_mux = 1;
2735         }
2736
2737         if (cli->max_xmit < 1024) {
2738                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2739                 return;
2740         }
2741
2742         if (cli->max_mux < 1) {
2743                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2744                 return;
2745         }
2746
2747         cli->max_xmit = MIN(cli->max_xmit, CLI_BUFFER_SIZE);
2748
2749         /*
2750          * Now calculate the negotiated capabilities
2751          * based on the mask for:
2752          * - client only flags
2753          * - flags used in both directions
2754          * - server only flags
2755          */
2756         both_capabilities = client_capabilities & server_capabilities;
2757         capabilities = client_capabilities & SMB_CAP_CLIENT_MASK;
2758         capabilities |= both_capabilities & SMB_CAP_BOTH_MASK;
2759         capabilities |= server_capabilities & SMB_CAP_SERVER_MASK;
2760
2761         cli->conn.protocol = protocol;
2762
2763         cli->conn.smb1.server.capabilities = server_capabilities;
2764         cli->conn.smb1.capabilities = capabilities;
2765
2766         tevent_req_done(req);
2767 }
2768
2769 NTSTATUS cli_negprot_recv(struct tevent_req *req)
2770 {
2771         return tevent_req_simple_recv_ntstatus(req);
2772 }
2773
2774 NTSTATUS cli_negprot(struct cli_state *cli, enum protocol_types max_protocol)
2775 {
2776         TALLOC_CTX *frame = talloc_stackframe();
2777         struct event_context *ev;
2778         struct tevent_req *req;
2779         NTSTATUS status = NT_STATUS_OK;
2780
2781         if (cli_has_async_calls(cli)) {
2782                 /*
2783                  * Can't use sync call while an async call is in flight
2784                  */
2785                 status = NT_STATUS_INVALID_PARAMETER;
2786                 goto fail;
2787         }
2788
2789         ev = event_context_init(frame);
2790         if (ev == NULL) {
2791                 status = NT_STATUS_NO_MEMORY;
2792                 goto fail;
2793         }
2794
2795         req = cli_negprot_send(frame, ev, cli, max_protocol);
2796         if (req == NULL) {
2797                 status = NT_STATUS_NO_MEMORY;
2798                 goto fail;
2799         }
2800
2801         if (!tevent_req_poll(req, ev)) {
2802                 status = map_nt_error_from_unix(errno);
2803                 goto fail;
2804         }
2805
2806         status = cli_negprot_recv(req);
2807  fail:
2808         TALLOC_FREE(frame);
2809         return status;
2810 }
2811
2812 static NTSTATUS cli_connect_sock(const char *host, int name_type,
2813                                  const struct sockaddr_storage *pss,
2814                                  const char *myname, uint16_t port,
2815                                  int sec_timeout, int *pfd, uint16_t *pport)
2816 {
2817         TALLOC_CTX *frame = talloc_stackframe();
2818         const char *prog;
2819         unsigned int i, num_addrs;
2820         const char **called_names;
2821         const char **calling_names;
2822         int *called_types;
2823         NTSTATUS status;
2824         int fd;
2825
2826         prog = getenv("LIBSMB_PROG");
2827         if (prog != NULL) {
2828                 fd = sock_exec(prog);
2829                 if (fd == -1) {
2830                         return map_nt_error_from_unix(errno);
2831                 }
2832                 port = 0;
2833                 goto done;
2834         }
2835
2836         if ((pss == NULL) || is_zero_addr(pss)) {
2837                 struct sockaddr_storage *addrs;
2838                 status = resolve_name_list(talloc_tos(), host, name_type,
2839                                            &addrs, &num_addrs);
2840                 if (!NT_STATUS_IS_OK(status)) {
2841                         goto fail;
2842                 }
2843                 pss = addrs;
2844         } else {
2845                 num_addrs = 1;
2846         }
2847
2848         called_names = talloc_array(talloc_tos(), const char *, num_addrs);
2849         if (called_names == NULL) {
2850                 status = NT_STATUS_NO_MEMORY;
2851                 goto fail;
2852         }
2853         called_types = talloc_array(talloc_tos(), int, num_addrs);
2854         if (called_types == NULL) {
2855                 status = NT_STATUS_NO_MEMORY;
2856                 goto fail;
2857         }
2858         calling_names = talloc_array(talloc_tos(), const char *, num_addrs);
2859         if (calling_names == NULL) {
2860                 status = NT_STATUS_NO_MEMORY;
2861                 goto fail;
2862         }
2863         for (i=0; i<num_addrs; i++) {
2864                 called_names[i] = host;
2865                 called_types[i] = name_type;
2866                 calling_names[i] = myname;
2867         }
2868         status = smbsock_any_connect(pss, called_names, called_types,
2869                                      calling_names, NULL, num_addrs, port,
2870                                      sec_timeout, &fd, NULL, &port);
2871         if (!NT_STATUS_IS_OK(status)) {
2872                 goto fail;
2873         }
2874         set_socket_options(fd, lp_socket_options());
2875 done:
2876         *pfd = fd;
2877         *pport = port;
2878         status = NT_STATUS_OK;
2879 fail:
2880         TALLOC_FREE(frame);
2881         return status;
2882 }
2883
2884 NTSTATUS cli_connect_nb(const char *host, const struct sockaddr_storage *dest_ss,
2885                         uint16_t port, int name_type, const char *myname,
2886                         int signing_state, int flags, struct cli_state **pcli)
2887 {
2888         TALLOC_CTX *frame = talloc_stackframe();
2889         struct cli_state *cli;
2890         NTSTATUS status = NT_STATUS_NO_MEMORY;
2891         int fd = -1;
2892         char *desthost;
2893         char *p;
2894
2895         desthost = talloc_strdup(talloc_tos(), host);
2896         if (desthost == NULL) {
2897                 goto fail;
2898         }
2899
2900         p = strchr(host, '#');
2901         if (p != NULL) {
2902                 name_type = strtol(p+1, NULL, 16);
2903                 host = talloc_strndup(talloc_tos(), host, p - host);
2904                 if (host == NULL) {
2905                         goto fail;
2906                 }
2907         }
2908
2909         status = cli_connect_sock(host, name_type, dest_ss, myname, port,
2910                                   20, &fd, &port);
2911         if (!NT_STATUS_IS_OK(status)) {
2912                 goto fail;
2913         }
2914
2915         cli = cli_state_create(NULL, fd, desthost, NULL, signing_state, flags);
2916         if (cli == NULL) {
2917                 goto fail;
2918         }
2919
2920         *pcli = cli;
2921         status = NT_STATUS_OK;
2922 fail:
2923         TALLOC_FREE(frame);
2924         return status;
2925 }
2926
2927 /**
2928    establishes a connection to after the negprot. 
2929    @param output_cli A fully initialised cli structure, non-null only on success
2930    @param dest_host The netbios name of the remote host
2931    @param dest_ss (optional) The the destination IP, NULL for name based lookup
2932    @param port (optional) The destination port (0 for default)
2933 */
2934 NTSTATUS cli_start_connection(struct cli_state **output_cli, 
2935                               const char *my_name, 
2936                               const char *dest_host, 
2937                               const struct sockaddr_storage *dest_ss, int port,
2938                               int signing_state, int flags)
2939 {
2940         NTSTATUS nt_status;
2941         struct cli_state *cli;
2942
2943         nt_status = cli_connect_nb(dest_host, dest_ss, port, 0x20, my_name,
2944                                    signing_state, flags, &cli);
2945         if (!NT_STATUS_IS_OK(nt_status)) {
2946                 DEBUG(10, ("cli_connect_nb failed: %s\n",
2947                            nt_errstr(nt_status)));
2948                 return nt_status;
2949         }
2950
2951         nt_status = cli_negprot(cli, PROTOCOL_NT1);
2952         if (!NT_STATUS_IS_OK(nt_status)) {
2953                 DEBUG(1, ("failed negprot: %s\n", nt_errstr(nt_status)));
2954                 cli_shutdown(cli);
2955                 return nt_status;
2956         }
2957
2958         *output_cli = cli;
2959         return NT_STATUS_OK;
2960 }
2961
2962
2963 /**
2964    establishes a connection right up to doing tconX, password specified.
2965    @param output_cli A fully initialised cli structure, non-null only on success
2966    @param dest_host The netbios name of the remote host
2967    @param dest_ip (optional) The the destination IP, NULL for name based lookup
2968    @param port (optional) The destination port (0 for default)
2969    @param service (optional) The share to make the connection to.  Should be 'unqualified' in any way.
2970    @param service_type The 'type' of serivice. 
2971    @param user Username, unix string
2972    @param domain User's domain
2973    @param password User's password, unencrypted unix string.
2974 */
2975
2976 NTSTATUS cli_full_connection(struct cli_state **output_cli, 
2977                              const char *my_name, 
2978                              const char *dest_host, 
2979                              const struct sockaddr_storage *dest_ss, int port,
2980                              const char *service, const char *service_type,
2981                              const char *user, const char *domain, 
2982                              const char *password, int flags,
2983                              int signing_state)
2984 {
2985         NTSTATUS nt_status;
2986         struct cli_state *cli = NULL;
2987         int pw_len = password ? strlen(password)+1 : 0;
2988
2989         *output_cli = NULL;
2990
2991         if (password == NULL) {
2992                 password = "";
2993         }
2994
2995         nt_status = cli_start_connection(&cli, my_name, dest_host,
2996                                          dest_ss, port, signing_state,
2997                                          flags);
2998
2999         if (!NT_STATUS_IS_OK(nt_status)) {
3000                 return nt_status;
3001         }
3002
3003         nt_status = cli_session_setup(cli, user, password, pw_len, password,
3004                                       pw_len, domain);
3005         if (!NT_STATUS_IS_OK(nt_status)) {
3006
3007                 if (!(flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)) {
3008                         DEBUG(1,("failed session setup with %s\n",
3009                                  nt_errstr(nt_status)));
3010                         cli_shutdown(cli);
3011                         return nt_status;
3012                 }
3013
3014                 nt_status = cli_session_setup(cli, "", "", 0, "", 0, domain);
3015                 if (!NT_STATUS_IS_OK(nt_status)) {
3016                         DEBUG(1,("anonymous failed session setup with %s\n",
3017                                  nt_errstr(nt_status)));
3018                         cli_shutdown(cli);
3019                         return nt_status;
3020                 }
3021         }
3022
3023         if (service) {
3024                 nt_status = cli_tcon_andx(cli, service, service_type, password,
3025                                           pw_len);
3026                 if (!NT_STATUS_IS_OK(nt_status)) {
3027                         DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status)));
3028                         cli_shutdown(cli);
3029                         if (NT_STATUS_IS_OK(nt_status)) {
3030                                 nt_status = NT_STATUS_UNSUCCESSFUL;
3031                         }
3032                         return nt_status;
3033                 }
3034         }
3035
3036         nt_status = cli_init_creds(cli, user, domain, password);
3037         if (!NT_STATUS_IS_OK(nt_status)) {
3038                 cli_shutdown(cli);
3039                 return nt_status;
3040         }
3041
3042         *output_cli = cli;
3043         return NT_STATUS_OK;
3044 }
3045
3046 /****************************************************************************
3047  Send an old style tcon.
3048 ****************************************************************************/
3049 NTSTATUS cli_raw_tcon(struct cli_state *cli, 
3050                       const char *service, const char *pass, const char *dev,
3051                       uint16 *max_xmit, uint16 *tid)
3052 {
3053         struct tevent_req *req;
3054         uint16_t *ret_vwv;
3055         uint8_t *bytes;
3056         NTSTATUS status;
3057
3058         if (!lp_client_plaintext_auth() && (*pass)) {
3059                 DEBUG(1, ("Server requested plaintext password but 'client "
3060                           "plaintext auth' is disabled\n"));
3061                 return NT_STATUS_ACCESS_DENIED;
3062         }
3063
3064         bytes = talloc_array(talloc_tos(), uint8_t, 0);
3065         bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3066         bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
3067                                    service, strlen(service)+1, NULL);
3068         bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3069         bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
3070                                    pass, strlen(pass)+1, NULL);
3071         bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3072         bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
3073                                    dev, strlen(dev)+1, NULL);
3074
3075         status = cli_smb(talloc_tos(), cli, SMBtcon, 0, 0, NULL,
3076                          talloc_get_size(bytes), bytes, &req,
3077                          2, NULL, &ret_vwv, NULL, NULL);
3078         if (!NT_STATUS_IS_OK(status)) {
3079                 return status;
3080         }
3081
3082         *max_xmit = SVAL(ret_vwv + 0, 0);
3083         *tid = SVAL(ret_vwv + 1, 0);
3084
3085         return NT_STATUS_OK;
3086 }
3087
3088 /* Return a cli_state pointing at the IPC$ share for the given server */
3089
3090 struct cli_state *get_ipc_connect(char *server,
3091                                 struct sockaddr_storage *server_ss,
3092                                 const struct user_auth_info *user_info)
3093 {
3094         struct cli_state *cli;
3095         NTSTATUS nt_status;
3096         uint32_t flags = CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
3097
3098         if (user_info->use_kerberos) {
3099                 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
3100         }
3101
3102         nt_status = cli_full_connection(&cli, NULL, server, server_ss, 0, "IPC$", "IPC", 
3103                                         user_info->username ? user_info->username : "",
3104                                         lp_workgroup(),
3105                                         user_info->password ? user_info->password : "",
3106                                         flags,
3107                                         Undefined);
3108
3109         if (NT_STATUS_IS_OK(nt_status)) {
3110                 return cli;
3111         } else if (is_ipaddress(server)) {
3112             /* windows 9* needs a correct NMB name for connections */
3113             fstring remote_name;
3114
3115             if (name_status_find("*", 0, 0, server_ss, remote_name)) {
3116                 cli = get_ipc_connect(remote_name, server_ss, user_info);
3117                 if (cli)
3118                     return cli;
3119             }
3120         }
3121         return NULL;
3122 }
3123
3124 /*
3125  * Given the IP address of a master browser on the network, return its
3126  * workgroup and connect to it.
3127  *
3128  * This function is provided to allow additional processing beyond what
3129  * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
3130  * browsers and obtain each master browsers' list of domains (in case the
3131  * first master browser is recently on the network and has not yet
3132  * synchronized with other master browsers and therefore does not yet have the
3133  * entire network browse list)
3134  */
3135
3136 struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx,
3137                                 struct sockaddr_storage *mb_ip,
3138                                 const struct user_auth_info *user_info,
3139                                 char **pp_workgroup_out)
3140 {
3141         char addr[INET6_ADDRSTRLEN];
3142         fstring name;
3143         struct cli_state *cli;
3144         struct sockaddr_storage server_ss;
3145
3146         *pp_workgroup_out = NULL;
3147
3148         print_sockaddr(addr, sizeof(addr), mb_ip);
3149         DEBUG(99, ("Looking up name of master browser %s\n",
3150                    addr));
3151
3152         /*
3153          * Do a name status query to find out the name of the master browser.
3154          * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
3155          * master browser will not respond to a wildcard query (or, at least,
3156          * an NT4 server acting as the domain master browser will not).
3157          *
3158          * We might be able to use ONLY the query on MSBROWSE, but that's not
3159          * yet been tested with all Windows versions, so until it is, leave
3160          * the original wildcard query as the first choice and fall back to
3161          * MSBROWSE if the wildcard query fails.
3162          */
3163         if (!name_status_find("*", 0, 0x1d, mb_ip, name) &&
3164             !name_status_find(MSBROWSE, 1, 0x1d, mb_ip, name)) {
3165
3166                 DEBUG(99, ("Could not retrieve name status for %s\n",
3167                            addr));
3168                 return NULL;
3169         }
3170
3171         if (!find_master_ip(name, &server_ss)) {
3172                 DEBUG(99, ("Could not find master ip for %s\n", name));
3173                 return NULL;
3174         }
3175
3176         *pp_workgroup_out = talloc_strdup(ctx, name);
3177
3178         DEBUG(4, ("found master browser %s, %s\n", name, addr));
3179
3180         print_sockaddr(addr, sizeof(addr), &server_ss);
3181         cli = get_ipc_connect(addr, &server_ss, user_info);
3182
3183         return cli;
3184 }
3185
3186 /*
3187  * Return the IP address and workgroup of a master browser on the network, and
3188  * connect to it.
3189  */
3190
3191 struct cli_state *get_ipc_connect_master_ip_bcast(TALLOC_CTX *ctx,
3192                                         const struct user_auth_info *user_info,
3193                                         char **pp_workgroup_out)
3194 {
3195         struct sockaddr_storage *ip_list;
3196         struct cli_state *cli;
3197         int i, count;
3198         NTSTATUS status;
3199
3200         *pp_workgroup_out = NULL;
3201
3202         DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
3203
3204         /* Go looking for workgroups by broadcasting on the local network */
3205
3206         status = name_resolve_bcast(MSBROWSE, 1, talloc_tos(),
3207                                     &ip_list, &count);
3208         if (!NT_STATUS_IS_OK(status)) {
3209                 DEBUG(99, ("No master browsers responded: %s\n",
3210                            nt_errstr(status)));
3211                 return False;
3212         }
3213
3214         for (i = 0; i < count; i++) {
3215                 char addr[INET6_ADDRSTRLEN];
3216                 print_sockaddr(addr, sizeof(addr), &ip_list[i]);
3217                 DEBUG(99, ("Found master browser %s\n", addr));
3218
3219                 cli = get_ipc_connect_master_ip(ctx, &ip_list[i],
3220                                 user_info, pp_workgroup_out);
3221                 if (cli)
3222                         return(cli);
3223         }
3224
3225         return NULL;
3226 }