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