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