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