s3: Fix some False/NULL hickups
[nivanova/samba-autobuild/.git] / source3 / libsmb / cliconnect.c
1 /* 
2    Unix SMB/CIFS implementation.
3    client connect/disconnect routines
4    Copyright (C) Andrew Tridgell 1994-1998
5    Copyright (C) Andrew Bartlett 2001-2003
6    Copyright (C) Volker Lendecke 2011
7    Copyright (C) Jeremy Allison 2011
8
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3 of the License, or
12    (at your option) any later version.
13
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <http://www.gnu.org/licenses/>.
21 */
22
23 #include "includes.h"
24 #include "libsmb/libsmb.h"
25 #include "popt_common.h"
26 #include "../libcli/auth/libcli_auth.h"
27 #include "../libcli/auth/spnego.h"
28 #include "smb_krb5.h"
29 #include "../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                                                     NULL, /* in_previous_session */
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_update_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                         status = smb2cli_session_update_session_key(session,
1714                                                 state->ntlmssp_state->session_key,
1715                                                 recv_iov);
1716                         if (tevent_req_nterror(req, status)) {
1717                                 return;
1718                         }
1719                 } else {
1720                         if (cli_simple_set_signing(
1721                                     state->cli, state->ntlmssp_state->session_key,
1722                                     data_blob_null)
1723                             && !cli_check_sign_mac(state->cli, inbuf, 1)) {
1724                                 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1725                                 return;
1726                         }
1727                 }
1728                 TALLOC_FREE(state->ntlmssp_state);
1729                 tevent_req_done(req);
1730                 return;
1731         }
1732         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1733                 tevent_req_nterror(req, status);
1734                 return;
1735         }
1736
1737         if (blob_in.length == 0) {
1738                 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
1739                 return;
1740         }
1741
1742         if ((state->turn == 1)
1743             && NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1744                 DATA_BLOB tmp_blob = data_blob_null;
1745                 /* the server might give us back two challenges */
1746                 parse_ret = spnego_parse_challenge(state, blob_in, &msg_in,
1747                                                    &tmp_blob);
1748                 data_blob_free(&tmp_blob);
1749         } else {
1750                 parse_ret = spnego_parse_auth_response(state, blob_in, status,
1751                                                        OID_NTLMSSP, &msg_in);
1752         }
1753         state->turn += 1;
1754
1755         if (!parse_ret) {
1756                 DEBUG(3,("Failed to parse auth response\n"));
1757                 if (NT_STATUS_IS_OK(status)
1758                     || NT_STATUS_EQUAL(status,
1759                                        NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1760                         tevent_req_nterror(
1761                                 req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1762                         return;
1763                 }
1764         }
1765
1766         status = ntlmssp_update(state->ntlmssp_state, msg_in, &blob_out);
1767
1768         if (!NT_STATUS_IS_OK(status)
1769             && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1770                 TALLOC_FREE(state->ntlmssp_state);
1771                 tevent_req_nterror(req, status);
1772                 return;
1773         }
1774
1775         state->blob_out = spnego_gen_auth(state, blob_out);
1776         if (tevent_req_nomem(state->blob_out.data, req)) {
1777                 return;
1778         }
1779
1780         subreq = cli_sesssetup_blob_send(state, state->ev, state->cli,
1781                                          state->blob_out);
1782         if (tevent_req_nomem(subreq, req)) {
1783                 return;
1784         }
1785         tevent_req_set_callback(subreq, cli_session_setup_ntlmssp_done, req);
1786 }
1787
1788 static NTSTATUS cli_session_setup_ntlmssp_recv(struct tevent_req *req)
1789 {
1790         struct cli_session_setup_ntlmssp_state *state = tevent_req_data(
1791                 req, struct cli_session_setup_ntlmssp_state);
1792         NTSTATUS status;
1793
1794         if (tevent_req_is_nterror(req, &status)) {
1795                 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
1796                 return status;
1797         }
1798         return NT_STATUS_OK;
1799 }
1800
1801 static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli,
1802                                           const char *user,
1803                                           const char *pass,
1804                                           const char *domain)
1805 {
1806         struct tevent_context *ev;
1807         struct tevent_req *req;
1808         NTSTATUS status = NT_STATUS_NO_MEMORY;
1809
1810         if (cli_has_async_calls(cli)) {
1811                 return NT_STATUS_INVALID_PARAMETER;
1812         }
1813         ev = tevent_context_init(talloc_tos());
1814         if (ev == NULL) {
1815                 goto fail;
1816         }
1817         req = cli_session_setup_ntlmssp_send(ev, ev, cli, user, pass, domain);
1818         if (req == NULL) {
1819                 goto fail;
1820         }
1821         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1822                 goto fail;
1823         }
1824         status = cli_session_setup_ntlmssp_recv(req);
1825 fail:
1826         TALLOC_FREE(ev);
1827         return status;
1828 }
1829
1830 /****************************************************************************
1831  Do a spnego encrypted session setup.
1832
1833  user_domain: The shortname of the domain the user/machine is a member of.
1834  dest_realm: The realm we're connecting to, if NULL we use our default realm.
1835 ****************************************************************************/
1836
1837 static ADS_STATUS cli_session_setup_spnego(struct cli_state *cli,
1838                               const char *user,
1839                               const char *pass,
1840                               const char *user_domain,
1841                               const char * dest_realm)
1842 {
1843         char *principal = NULL;
1844         char *OIDs[ASN1_MAX_OIDS];
1845         int i;
1846         const DATA_BLOB *server_blob;
1847         DATA_BLOB blob = data_blob_null;
1848         const char *p = NULL;
1849         char *account = NULL;
1850         NTSTATUS status;
1851
1852         server_blob = cli_state_server_gss_blob(cli);
1853         if (server_blob) {
1854                 blob = data_blob(server_blob->data, server_blob->length);
1855         }
1856
1857         DEBUG(3,("Doing spnego session setup (blob length=%lu)\n", (unsigned long)blob.length));
1858
1859         /* the server might not even do spnego */
1860         if (blob.length == 0) {
1861                 DEBUG(3,("server didn't supply a full spnego negprot\n"));
1862                 goto ntlmssp;
1863         }
1864
1865 #if 0
1866         file_save("negprot.dat", cli->secblob.data, cli->secblob.length);
1867 #endif
1868
1869         /* The server sent us the first part of the SPNEGO exchange in the
1870          * negprot reply. It is WRONG to depend on the principal sent in the
1871          * negprot reply, but right now we do it. If we don't receive one,
1872          * we try to best guess, then fall back to NTLM.  */
1873         if (!spnego_parse_negTokenInit(talloc_tos(), blob, OIDs, &principal, NULL) ||
1874                         OIDs[0] == NULL) {
1875                 data_blob_free(&blob);
1876                 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1877         }
1878         data_blob_free(&blob);
1879
1880         /* make sure the server understands kerberos */
1881         for (i=0;OIDs[i];i++) {
1882                 if (i == 0)
1883                         DEBUG(3,("got OID=%s\n", OIDs[i]));
1884                 else
1885                         DEBUGADD(3,("got OID=%s\n", OIDs[i]));
1886                 if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0 ||
1887                     strcmp(OIDs[i], OID_KERBEROS5) == 0) {
1888                         cli->got_kerberos_mechanism = True;
1889                 }
1890                 talloc_free(OIDs[i]);
1891         }
1892
1893         DEBUG(3,("got principal=%s\n", principal ? principal : "<null>"));
1894
1895         status = cli_set_username(cli, user);
1896         if (!NT_STATUS_IS_OK(status)) {
1897                 TALLOC_FREE(principal);
1898                 return ADS_ERROR_NT(status);
1899         }
1900
1901 #ifdef HAVE_KRB5
1902         /* If password is set we reauthenticate to kerberos server
1903          * and do not store results */
1904
1905         if (user && *user && cli->got_kerberos_mechanism && cli->use_kerberos) {
1906                 ADS_STATUS rc;
1907                 const char *remote_name = cli_state_remote_name(cli);
1908
1909                 if (pass && *pass) {
1910                         int ret;
1911
1912                         use_in_memory_ccache();
1913                         ret = kerberos_kinit_password(user, pass, 0 /* no time correction for now */, NULL);
1914
1915                         if (ret){
1916                                 TALLOC_FREE(principal);
1917                                 DEBUG(0, ("Kinit failed: %s\n", error_message(ret)));
1918                                 if (cli->fallback_after_kerberos)
1919                                         goto ntlmssp;
1920                                 return ADS_ERROR_KRB5(ret);
1921                         }
1922                 }
1923
1924                 /* We may not be allowed to use the server-supplied SPNEGO principal, or it may not have been supplied to us
1925                  */
1926                 if (!lp_client_use_spnego_principal() || strequal(principal, ADS_IGNORE_PRINCIPAL)) {
1927                         TALLOC_FREE(principal);
1928                 }
1929
1930                 if (principal == NULL &&
1931                         !is_ipaddress(remote_name) &&
1932                         !strequal(STAR_SMBSERVER,
1933                                   remote_name)) {
1934                         char *realm = NULL;
1935                         char *host = NULL;
1936                         DEBUG(3,("cli_session_setup_spnego: using target "
1937                                  "hostname not SPNEGO principal\n"));
1938
1939                         host = strchr_m(remote_name, '.');
1940                         if (dest_realm) {
1941                                 realm = SMB_STRDUP(dest_realm);
1942                                 if (!realm) {
1943                                         return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1944                                 }
1945                                 strupper_m(realm);
1946                         } else {
1947                                 if (host) {
1948                                         /* DNS name. */
1949                                         realm = kerberos_get_realm_from_hostname(remote_name);
1950                                 } else {
1951                                         /* NetBIOS name - use our realm. */
1952                                         realm = kerberos_get_default_realm_from_ccache();
1953                                 }
1954                         }
1955
1956                         if (realm == NULL || *realm == '\0') {
1957                                 realm = SMB_STRDUP(lp_realm());
1958                                 if (!realm) {
1959                                         return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1960                                 }
1961                                 strupper_m(realm);
1962                                 DEBUG(3,("cli_session_setup_spnego: cannot "
1963                                         "get realm from dest_realm %s, "
1964                                         "desthost %s. Using default "
1965                                         "smb.conf realm %s\n",
1966                                         dest_realm ? dest_realm : "<null>",
1967                                         remote_name,
1968                                         realm));
1969                         }
1970
1971                         principal = talloc_asprintf(talloc_tos(),
1972                                                     "cifs/%s@%s",
1973                                                     remote_name,
1974                                                     realm);
1975                         if (!principal) {
1976                                 SAFE_FREE(realm);
1977                                 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1978                         }
1979                         DEBUG(3,("cli_session_setup_spnego: guessed "
1980                                 "server principal=%s\n",
1981                                 principal ? principal : "<null>"));
1982
1983                         SAFE_FREE(realm);
1984                 }
1985
1986                 if (principal) {
1987                         rc = cli_session_setup_kerberos(cli, principal);
1988                         if (ADS_ERR_OK(rc) || !cli->fallback_after_kerberos) {
1989                                 TALLOC_FREE(principal);
1990                                 return rc;
1991                         }
1992                 }
1993         }
1994 #endif
1995
1996         TALLOC_FREE(principal);
1997
1998 ntlmssp:
1999
2000         account = talloc_strdup(talloc_tos(), user);
2001         if (!account) {
2002                 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
2003         }
2004
2005         /* when falling back to ntlmssp while authenticating with a machine
2006          * account strip off the realm - gd */
2007
2008         if ((p = strchr_m(user, '@')) != NULL) {
2009                 account[PTR_DIFF(p,user)] = '\0';
2010         }
2011
2012         return ADS_ERROR_NT(cli_session_setup_ntlmssp(cli, account, pass, user_domain));
2013 }
2014
2015 /****************************************************************************
2016  Send a session setup. The username and workgroup is in UNIX character
2017  format and must be converted to DOS codepage format before sending. If the
2018  password is in plaintext, the same should be done.
2019 ****************************************************************************/
2020
2021 NTSTATUS cli_session_setup(struct cli_state *cli,
2022                            const char *user,
2023                            const char *pass, int passlen,
2024                            const char *ntpass, int ntpasslen,
2025                            const char *workgroup)
2026 {
2027         char *p;
2028         char *user2;
2029         uint16_t sec_mode = cli_state_security_mode(cli);
2030
2031         if (user) {
2032                 user2 = talloc_strdup(talloc_tos(), user);
2033         } else {
2034                 user2 = talloc_strdup(talloc_tos(), "");
2035         }
2036         if (user2 == NULL) {
2037                 return NT_STATUS_NO_MEMORY;
2038         }
2039
2040         if (!workgroup) {
2041                 workgroup = "";
2042         }
2043
2044         /* allow for workgroups as part of the username */
2045         if ((p=strchr_m(user2,'\\')) || (p=strchr_m(user2,'/')) ||
2046             (p=strchr_m(user2,*lp_winbind_separator()))) {
2047                 *p = 0;
2048                 user = p+1;
2049                 strupper_m(user2);
2050                 workgroup = user2;
2051         }
2052
2053         if (cli_state_protocol(cli) < PROTOCOL_LANMAN1) {
2054                 return NT_STATUS_OK;
2055         }
2056
2057         /* now work out what sort of session setup we are going to
2058            do. I have split this into separate functions to make the
2059            flow a bit easier to understand (tridge) */
2060
2061         /* if its an older server then we have to use the older request format */
2062
2063         if (cli_state_protocol(cli) < PROTOCOL_NT1) {
2064                 if (!lp_client_lanman_auth() && passlen != 24 && (*pass)) {
2065                         DEBUG(1, ("Server requested LM password but 'client lanman auth = no'"
2066                                   " or 'client ntlmv2 auth = yes'\n"));
2067                         return NT_STATUS_ACCESS_DENIED;
2068                 }
2069
2070                 if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0 &&
2071                     !lp_client_plaintext_auth() && (*pass)) {
2072                         DEBUG(1, ("Server requested LM password but 'client plaintext auth = no'"
2073                                   " or 'client ntlmv2 auth = yes'\n"));
2074                         return NT_STATUS_ACCESS_DENIED;
2075                 }
2076
2077                 return cli_session_setup_lanman2(cli, user, pass, passlen,
2078                                                  workgroup);
2079         }
2080
2081         if (cli_state_protocol(cli) >= PROTOCOL_SMB2_02) {
2082                 const char *remote_realm = cli_state_remote_realm(cli);
2083                 ADS_STATUS status = cli_session_setup_spnego(cli, user, pass,
2084                                                              workgroup,
2085                                                              remote_realm);
2086                 if (!ADS_ERR_OK(status)) {
2087                         DEBUG(3, ("SMB2-SPNEGO login failed: %s\n", ads_errstr(status)));
2088                         return ads_ntstatus(status);
2089                 }
2090                 return NT_STATUS_OK;
2091         }
2092
2093         /* if no user is supplied then we have to do an anonymous connection.
2094            passwords are ignored */
2095
2096         if (!user || !*user)
2097                 return cli_session_setup_guest(cli);
2098
2099         /* if the server is share level then send a plaintext null
2100            password at this point. The password is sent in the tree
2101            connect */
2102
2103         if ((sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0)
2104                 return cli_session_setup_plain(cli, user, "", workgroup);
2105
2106         /* if the server doesn't support encryption then we have to use 
2107            plaintext. The second password is ignored */
2108
2109         if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) {
2110                 if (!lp_client_plaintext_auth() && (*pass)) {
2111                         DEBUG(1, ("Server requested LM password but 'client plaintext auth = no'"
2112                                   " or 'client ntlmv2 auth = yes'\n"));
2113                         return NT_STATUS_ACCESS_DENIED;
2114                 }
2115                 return cli_session_setup_plain(cli, user, pass, workgroup);
2116         }
2117
2118         /* if the server supports extended security then use SPNEGO */
2119
2120         if (cli_state_capabilities(cli) & CAP_EXTENDED_SECURITY) {
2121                 const char *remote_realm = cli_state_remote_realm(cli);
2122                 ADS_STATUS status = cli_session_setup_spnego(cli, user, pass,
2123                                                              workgroup,
2124                                                              remote_realm);
2125                 if (!ADS_ERR_OK(status)) {
2126                         DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status)));
2127                         return ads_ntstatus(status);
2128                 }
2129         } else {
2130                 NTSTATUS status;
2131
2132                 /* otherwise do a NT1 style session setup */
2133                 status = cli_session_setup_nt1(cli, user, pass, passlen,
2134                                                ntpass, ntpasslen, workgroup);
2135                 if (!NT_STATUS_IS_OK(status)) {
2136                         DEBUG(3,("cli_session_setup: NT1 session setup "
2137                                  "failed: %s\n", nt_errstr(status)));
2138                         return status;
2139                 }
2140         }
2141
2142         return NT_STATUS_OK;
2143 }
2144
2145 /****************************************************************************
2146  Send a uloggoff.
2147 *****************************************************************************/
2148
2149 struct cli_ulogoff_state {
2150         struct cli_state *cli;
2151         uint16_t vwv[3];
2152 };
2153
2154 static void cli_ulogoff_done(struct tevent_req *subreq);
2155
2156 struct tevent_req *cli_ulogoff_send(TALLOC_CTX *mem_ctx,
2157                                     struct tevent_context *ev,
2158                                     struct cli_state *cli)
2159 {
2160         struct tevent_req *req, *subreq;
2161         struct cli_ulogoff_state *state;
2162
2163         req = tevent_req_create(mem_ctx, &state, struct cli_ulogoff_state);
2164         if (req == NULL) {
2165                 return NULL;
2166         }
2167         state->cli = cli;
2168
2169         SCVAL(state->vwv+0, 0, 0xFF);
2170         SCVAL(state->vwv+1, 0, 0);
2171         SSVAL(state->vwv+2, 0, 0);
2172
2173         subreq = cli_smb_send(state, ev, cli, SMBulogoffX, 0, 2, state->vwv,
2174                               0, NULL);
2175         if (tevent_req_nomem(subreq, req)) {
2176                 return tevent_req_post(req, ev);
2177         }
2178         tevent_req_set_callback(subreq, cli_ulogoff_done, req);
2179         return req;
2180 }
2181
2182 static void cli_ulogoff_done(struct tevent_req *subreq)
2183 {
2184         struct tevent_req *req = tevent_req_callback_data(
2185                 subreq, struct tevent_req);
2186         struct cli_ulogoff_state *state = tevent_req_data(
2187                 req, struct cli_ulogoff_state);
2188         NTSTATUS status;
2189
2190         status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
2191         if (!NT_STATUS_IS_OK(status)) {
2192                 tevent_req_nterror(req, status);
2193                 return;
2194         }
2195         cli_state_set_uid(state->cli, UID_FIELD_INVALID);
2196         tevent_req_done(req);
2197 }
2198
2199 NTSTATUS cli_ulogoff_recv(struct tevent_req *req)
2200 {
2201         return tevent_req_simple_recv_ntstatus(req);
2202 }
2203
2204 NTSTATUS cli_ulogoff(struct cli_state *cli)
2205 {
2206         struct tevent_context *ev;
2207         struct tevent_req *req;
2208         NTSTATUS status = NT_STATUS_NO_MEMORY;
2209
2210         if (cli_has_async_calls(cli)) {
2211                 return NT_STATUS_INVALID_PARAMETER;
2212         }
2213         ev = tevent_context_init(talloc_tos());
2214         if (ev == NULL) {
2215                 goto fail;
2216         }
2217         req = cli_ulogoff_send(ev, ev, cli);
2218         if (req == NULL) {
2219                 goto fail;
2220         }
2221         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2222                 goto fail;
2223         }
2224         status = cli_ulogoff_recv(req);
2225 fail:
2226         TALLOC_FREE(ev);
2227         return status;
2228 }
2229
2230 /****************************************************************************
2231  Send a tconX.
2232 ****************************************************************************/
2233
2234 struct cli_tcon_andx_state {
2235         struct cli_state *cli;
2236         uint16_t vwv[4];
2237         struct iovec bytes;
2238 };
2239
2240 static void cli_tcon_andx_done(struct tevent_req *subreq);
2241
2242 struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx,
2243                                         struct event_context *ev,
2244                                         struct cli_state *cli,
2245                                         const char *share, const char *dev,
2246                                         const char *pass, int passlen,
2247                                         struct tevent_req **psmbreq)
2248 {
2249         struct tevent_req *req, *subreq;
2250         struct cli_tcon_andx_state *state;
2251         uint8_t p24[24];
2252         uint16_t *vwv;
2253         char *tmp = NULL;
2254         uint8_t *bytes;
2255         uint16_t sec_mode = cli_state_security_mode(cli);
2256
2257         *psmbreq = NULL;
2258
2259         req = tevent_req_create(mem_ctx, &state, struct cli_tcon_andx_state);
2260         if (req == NULL) {
2261                 return NULL;
2262         }
2263         state->cli = cli;
2264         vwv = state->vwv;
2265
2266         cli->share = talloc_strdup(cli, share);
2267         if (!cli->share) {
2268                 return NULL;
2269         }
2270
2271         /* in user level security don't send a password now */
2272         if (sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {
2273                 passlen = 1;
2274                 pass = "";
2275         } else if (pass == NULL) {
2276                 DEBUG(1, ("Server not using user level security and no "
2277                           "password supplied.\n"));
2278                 goto access_denied;
2279         }
2280
2281         if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) &&
2282             *pass && passlen != 24) {
2283                 if (!lp_client_lanman_auth()) {
2284                         DEBUG(1, ("Server requested LANMAN password "
2285                                   "(share-level security) but "
2286                                   "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2287                         goto access_denied;
2288                 }
2289
2290                 /*
2291                  * Non-encrypted passwords - convert to DOS codepage before
2292                  * encryption.
2293                  */
2294                 SMBencrypt(pass, cli_state_server_challenge(cli), p24);
2295                 passlen = 24;
2296                 pass = (const char *)p24;
2297         } else {
2298                 if((sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL
2299                                      |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE))
2300                    == 0) {
2301                         uint8_t *tmp_pass;
2302
2303                         if (!lp_client_plaintext_auth() && (*pass)) {
2304                                 DEBUG(1, ("Server requested plaintext "
2305                                           "password but "
2306                                           "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2307                                 goto access_denied;
2308                         }
2309
2310                         /*
2311                          * Non-encrypted passwords - convert to DOS codepage
2312                          * before using.
2313                          */
2314                         tmp_pass = talloc_array(talloc_tos(), uint8, 0);
2315                         if (tevent_req_nomem(tmp_pass, req)) {
2316                                 return tevent_req_post(req, ev);
2317                         }
2318                         tmp_pass = trans2_bytes_push_str(tmp_pass,
2319                                                          false, /* always DOS */
2320                                                          pass,
2321                                                          passlen,
2322                                                          NULL);
2323                         if (tevent_req_nomem(tmp_pass, req)) {
2324                                 return tevent_req_post(req, ev);
2325                         }
2326                         pass = (const char *)tmp_pass;
2327                         passlen = talloc_get_size(tmp_pass);
2328                 }
2329         }
2330
2331         SCVAL(vwv+0, 0, 0xFF);
2332         SCVAL(vwv+0, 1, 0);
2333         SSVAL(vwv+1, 0, 0);
2334         SSVAL(vwv+2, 0, TCONX_FLAG_EXTENDED_RESPONSE);
2335         SSVAL(vwv+3, 0, passlen);
2336
2337         if (passlen && pass) {
2338                 bytes = (uint8_t *)talloc_memdup(state, pass, passlen);
2339         } else {
2340                 bytes = talloc_array(state, uint8_t, 0);
2341         }
2342
2343         /*
2344          * Add the sharename
2345          */
2346         tmp = talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
2347                                          cli_state_remote_name(cli), share);
2348         if (tmp == NULL) {
2349                 TALLOC_FREE(req);
2350                 return NULL;
2351         }
2352         bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), tmp, strlen(tmp)+1,
2353                                    NULL);
2354         TALLOC_FREE(tmp);
2355
2356         /*
2357          * Add the devicetype
2358          */
2359         tmp = talloc_strdup_upper(talloc_tos(), dev);
2360         if (tmp == NULL) {
2361                 TALLOC_FREE(req);
2362                 return NULL;
2363         }
2364         bytes = smb_bytes_push_str(bytes, false, tmp, strlen(tmp)+1, NULL);
2365         TALLOC_FREE(tmp);
2366
2367         if (bytes == NULL) {
2368                 TALLOC_FREE(req);
2369                 return NULL;
2370         }
2371
2372         state->bytes.iov_base = (void *)bytes;
2373         state->bytes.iov_len = talloc_get_size(bytes);
2374
2375         subreq = cli_smb_req_create(state, ev, cli, SMBtconX, 0, 4, vwv,
2376                                     1, &state->bytes);
2377         if (subreq == NULL) {
2378                 TALLOC_FREE(req);
2379                 return NULL;
2380         }
2381         tevent_req_set_callback(subreq, cli_tcon_andx_done, req);
2382         *psmbreq = subreq;
2383         return req;
2384
2385  access_denied:
2386         tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
2387         return tevent_req_post(req, ev);
2388 }
2389
2390 struct tevent_req *cli_tcon_andx_send(TALLOC_CTX *mem_ctx,
2391                                       struct event_context *ev,
2392                                       struct cli_state *cli,
2393                                       const char *share, const char *dev,
2394                                       const char *pass, int passlen)
2395 {
2396         struct tevent_req *req, *subreq;
2397         NTSTATUS status;
2398
2399         req = cli_tcon_andx_create(mem_ctx, ev, cli, share, dev, pass, passlen,
2400                                    &subreq);
2401         if (req == NULL) {
2402                 return NULL;
2403         }
2404         if (subreq == NULL) {
2405                 return req;
2406         }
2407         status = cli_smb_req_send(subreq);
2408         if (!NT_STATUS_IS_OK(status)) {
2409                 tevent_req_nterror(req, status);
2410                 return tevent_req_post(req, ev);
2411         }
2412         return req;
2413 }
2414
2415 static void cli_tcon_andx_done(struct tevent_req *subreq)
2416 {
2417         struct tevent_req *req = tevent_req_callback_data(
2418                 subreq, struct tevent_req);
2419         struct cli_tcon_andx_state *state = tevent_req_data(
2420                 req, struct cli_tcon_andx_state);
2421         struct cli_state *cli = state->cli;
2422         uint8_t *in;
2423         char *inbuf;
2424         uint8_t wct;
2425         uint16_t *vwv;
2426         uint32_t num_bytes;
2427         uint8_t *bytes;
2428         NTSTATUS status;
2429
2430         status = cli_smb_recv(subreq, state, &in, 0, &wct, &vwv,
2431                               &num_bytes, &bytes);
2432         TALLOC_FREE(subreq);
2433         if (!NT_STATUS_IS_OK(status)) {
2434                 tevent_req_nterror(req, status);
2435                 return;
2436         }
2437
2438         inbuf = (char *)in;
2439
2440         if (num_bytes) {
2441                 if (clistr_pull_talloc(cli,
2442                                 inbuf,
2443                                 SVAL(inbuf, smb_flg2),
2444                                 &cli->dev,
2445                                 bytes,
2446                                 num_bytes,
2447                                 STR_TERMINATE|STR_ASCII) == -1) {
2448                         tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2449                         return;
2450                 }
2451         } else {
2452                 cli->dev = talloc_strdup(cli, "");
2453                 if (cli->dev == NULL) {
2454                         tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2455                         return;
2456                 }
2457         }
2458
2459         if ((cli_state_protocol(cli) >= PROTOCOL_NT1) && (num_bytes == 3)) {
2460                 /* almost certainly win95 - enable bug fixes */
2461                 cli->win95 = True;
2462         }
2463
2464         /*
2465          * Make sure that we have the optional support 16-bit field. WCT > 2.
2466          * Avoids issues when connecting to Win9x boxes sharing files
2467          */
2468
2469         cli->dfsroot = false;
2470
2471         if ((wct > 2) && (cli_state_protocol(cli) >= PROTOCOL_LANMAN2)) {
2472                 cli->dfsroot = ((SVAL(vwv+2, 0) & SMB_SHARE_IN_DFS) != 0);
2473         }
2474
2475         cli->smb1.tid = SVAL(inbuf,smb_tid);
2476         tevent_req_done(req);
2477 }
2478
2479 NTSTATUS cli_tcon_andx_recv(struct tevent_req *req)
2480 {
2481         return tevent_req_simple_recv_ntstatus(req);
2482 }
2483
2484 NTSTATUS cli_tcon_andx(struct cli_state *cli, const char *share,
2485                        const char *dev, const char *pass, int passlen)
2486 {
2487         TALLOC_CTX *frame = talloc_stackframe();
2488         struct event_context *ev;
2489         struct tevent_req *req;
2490         NTSTATUS status = NT_STATUS_OK;
2491
2492         if (cli_has_async_calls(cli)) {
2493                 /*
2494                  * Can't use sync call while an async call is in flight
2495                  */
2496                 status = NT_STATUS_INVALID_PARAMETER;
2497                 goto fail;
2498         }
2499
2500         ev = event_context_init(frame);
2501         if (ev == NULL) {
2502                 status = NT_STATUS_NO_MEMORY;
2503                 goto fail;
2504         }
2505
2506         req = cli_tcon_andx_send(frame, ev, cli, share, dev, pass, passlen);
2507         if (req == NULL) {
2508                 status = NT_STATUS_NO_MEMORY;
2509                 goto fail;
2510         }
2511
2512         if (!tevent_req_poll(req, ev)) {
2513                 status = map_nt_error_from_unix(errno);
2514                 goto fail;
2515         }
2516
2517         status = cli_tcon_andx_recv(req);
2518  fail:
2519         TALLOC_FREE(frame);
2520         return status;
2521 }
2522
2523 NTSTATUS cli_tree_connect(struct cli_state *cli, const char *share,
2524                           const char *dev, const char *pass, int passlen)
2525 {
2526         cli->share = talloc_strdup(cli, share);
2527         if (!cli->share) {
2528                 return NT_STATUS_NO_MEMORY;
2529         }
2530
2531         if (cli_state_protocol(cli) >= PROTOCOL_SMB2_02) {
2532                 return smb2cli_tcon(cli, share);
2533         }
2534
2535         return cli_tcon_andx(cli, share, dev, pass, passlen);
2536 }
2537
2538 /****************************************************************************
2539  Send a tree disconnect.
2540 ****************************************************************************/
2541
2542 struct cli_tdis_state {
2543         struct cli_state *cli;
2544 };
2545
2546 static void cli_tdis_done(struct tevent_req *subreq);
2547
2548 struct tevent_req *cli_tdis_send(TALLOC_CTX *mem_ctx,
2549                                  struct tevent_context *ev,
2550                                  struct cli_state *cli)
2551 {
2552         struct tevent_req *req, *subreq;
2553         struct cli_tdis_state *state;
2554
2555         req = tevent_req_create(mem_ctx, &state, struct cli_tdis_state);
2556         if (req == NULL) {
2557                 return NULL;
2558         }
2559         state->cli = cli;
2560
2561         subreq = cli_smb_send(state, ev, cli, SMBtdis, 0, 0, NULL, 0, NULL);
2562         if (tevent_req_nomem(subreq, req)) {
2563                 return tevent_req_post(req, ev);
2564         }
2565         tevent_req_set_callback(subreq, cli_tdis_done, req);
2566         return req;
2567 }
2568
2569 static void cli_tdis_done(struct tevent_req *subreq)
2570 {
2571         struct tevent_req *req = tevent_req_callback_data(
2572                 subreq, struct tevent_req);
2573         struct cli_tdis_state *state = tevent_req_data(
2574                 req, struct cli_tdis_state);
2575         NTSTATUS status;
2576
2577         status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
2578         TALLOC_FREE(subreq);
2579         if (!NT_STATUS_IS_OK(status)) {
2580                 tevent_req_nterror(req, status);
2581                 return;
2582         }
2583         state->cli->smb1.tid = UINT16_MAX;
2584         tevent_req_done(req);
2585 }
2586
2587 NTSTATUS cli_tdis_recv(struct tevent_req *req)
2588 {
2589         return tevent_req_simple_recv_ntstatus(req);
2590 }
2591
2592 NTSTATUS cli_tdis(struct cli_state *cli)
2593 {
2594         struct tevent_context *ev;
2595         struct tevent_req *req;
2596         NTSTATUS status = NT_STATUS_NO_MEMORY;
2597
2598         if (cli_has_async_calls(cli)) {
2599                 return NT_STATUS_INVALID_PARAMETER;
2600         }
2601         ev = tevent_context_init(talloc_tos());
2602         if (ev == NULL) {
2603                 goto fail;
2604         }
2605         req = cli_tdis_send(ev, ev, cli);
2606         if (req == NULL) {
2607                 goto fail;
2608         }
2609         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2610                 goto fail;
2611         }
2612         status = cli_tdis_recv(req);
2613 fail:
2614         TALLOC_FREE(ev);
2615         return status;
2616 }
2617
2618 struct tevent_req *cli_negprot_send(TALLOC_CTX *mem_ctx,
2619                                     struct event_context *ev,
2620                                     struct cli_state *cli,
2621                                     enum protocol_types max_protocol)
2622 {
2623         return smbXcli_negprot_send(mem_ctx, ev,
2624                                     cli->conn, cli->timeout,
2625                                     PROTOCOL_CORE, max_protocol);
2626 }
2627
2628 NTSTATUS cli_negprot_recv(struct tevent_req *req)
2629 {
2630         return smbXcli_negprot_recv(req);
2631 }
2632
2633 NTSTATUS cli_negprot(struct cli_state *cli, enum protocol_types max_protocol)
2634 {
2635         return smbXcli_negprot(cli->conn, cli->timeout,
2636                                PROTOCOL_CORE, max_protocol);
2637 }
2638
2639 static NTSTATUS cli_connect_sock(const char *host, int name_type,
2640                                  const struct sockaddr_storage *pss,
2641                                  const char *myname, uint16_t port,
2642                                  int sec_timeout, int *pfd, uint16_t *pport)
2643 {
2644         TALLOC_CTX *frame = talloc_stackframe();
2645         const char *prog;
2646         unsigned int i, num_addrs;
2647         const char **called_names;
2648         const char **calling_names;
2649         int *called_types;
2650         NTSTATUS status;
2651         int fd;
2652
2653         prog = getenv("LIBSMB_PROG");
2654         if (prog != NULL) {
2655                 fd = sock_exec(prog);
2656                 if (fd == -1) {
2657                         return map_nt_error_from_unix(errno);
2658                 }
2659                 port = 0;
2660                 goto done;
2661         }
2662
2663         if ((pss == NULL) || is_zero_addr(pss)) {
2664                 struct sockaddr_storage *addrs;
2665                 status = resolve_name_list(talloc_tos(), host, name_type,
2666                                            &addrs, &num_addrs);
2667                 if (!NT_STATUS_IS_OK(status)) {
2668                         goto fail;
2669                 }
2670                 pss = addrs;
2671         } else {
2672                 num_addrs = 1;
2673         }
2674
2675         called_names = talloc_array(talloc_tos(), const char *, num_addrs);
2676         if (called_names == NULL) {
2677                 status = NT_STATUS_NO_MEMORY;
2678                 goto fail;
2679         }
2680         called_types = talloc_array(talloc_tos(), int, num_addrs);
2681         if (called_types == NULL) {
2682                 status = NT_STATUS_NO_MEMORY;
2683                 goto fail;
2684         }
2685         calling_names = talloc_array(talloc_tos(), const char *, num_addrs);
2686         if (calling_names == NULL) {
2687                 status = NT_STATUS_NO_MEMORY;
2688                 goto fail;
2689         }
2690         for (i=0; i<num_addrs; i++) {
2691                 called_names[i] = host;
2692                 called_types[i] = name_type;
2693                 calling_names[i] = myname;
2694         }
2695         status = smbsock_any_connect(pss, called_names, called_types,
2696                                      calling_names, NULL, num_addrs, port,
2697                                      sec_timeout, &fd, NULL, &port);
2698         if (!NT_STATUS_IS_OK(status)) {
2699                 goto fail;
2700         }
2701         set_socket_options(fd, lp_socket_options());
2702 done:
2703         *pfd = fd;
2704         *pport = port;
2705         status = NT_STATUS_OK;
2706 fail:
2707         TALLOC_FREE(frame);
2708         return status;
2709 }
2710
2711 NTSTATUS cli_connect_nb(const char *host, const struct sockaddr_storage *dest_ss,
2712                         uint16_t port, int name_type, const char *myname,
2713                         int signing_state, int flags, struct cli_state **pcli)
2714 {
2715         TALLOC_CTX *frame = talloc_stackframe();
2716         struct cli_state *cli;
2717         NTSTATUS status = NT_STATUS_NO_MEMORY;
2718         int fd = -1;
2719         char *desthost;
2720         char *p;
2721
2722         desthost = talloc_strdup(talloc_tos(), host);
2723         if (desthost == NULL) {
2724                 goto fail;
2725         }
2726
2727         p = strchr(host, '#');
2728         if (p != NULL) {
2729                 name_type = strtol(p+1, NULL, 16);
2730                 host = talloc_strndup(talloc_tos(), host, p - host);
2731                 if (host == NULL) {
2732                         goto fail;
2733                 }
2734         }
2735
2736         status = cli_connect_sock(host, name_type, dest_ss, myname, port,
2737                                   20, &fd, &port);
2738         if (!NT_STATUS_IS_OK(status)) {
2739                 goto fail;
2740         }
2741
2742         cli = cli_state_create(NULL, fd, desthost, NULL, signing_state, flags);
2743         if (cli == NULL) {
2744                 close(fd);
2745                 fd = -1;
2746                 goto fail;
2747         }
2748
2749         *pcli = cli;
2750         status = NT_STATUS_OK;
2751 fail:
2752         TALLOC_FREE(frame);
2753         return status;
2754 }
2755
2756 /**
2757    establishes a connection to after the negprot. 
2758    @param output_cli A fully initialised cli structure, non-null only on success
2759    @param dest_host The netbios name of the remote host
2760    @param dest_ss (optional) The the destination IP, NULL for name based lookup
2761    @param port (optional) The destination port (0 for default)
2762 */
2763 NTSTATUS cli_start_connection(struct cli_state **output_cli, 
2764                               const char *my_name, 
2765                               const char *dest_host, 
2766                               const struct sockaddr_storage *dest_ss, int port,
2767                               int signing_state, int flags)
2768 {
2769         NTSTATUS nt_status;
2770         struct cli_state *cli;
2771
2772         nt_status = cli_connect_nb(dest_host, dest_ss, port, 0x20, my_name,
2773                                    signing_state, flags, &cli);
2774         if (!NT_STATUS_IS_OK(nt_status)) {
2775                 DEBUG(10, ("cli_connect_nb failed: %s\n",
2776                            nt_errstr(nt_status)));
2777                 return nt_status;
2778         }
2779
2780         nt_status = cli_negprot(cli, PROTOCOL_NT1);
2781         if (!NT_STATUS_IS_OK(nt_status)) {
2782                 DEBUG(1, ("failed negprot: %s\n", nt_errstr(nt_status)));
2783                 cli_shutdown(cli);
2784                 return nt_status;
2785         }
2786
2787         *output_cli = cli;
2788         return NT_STATUS_OK;
2789 }
2790
2791
2792 /**
2793    establishes a connection right up to doing tconX, password specified.
2794    @param output_cli A fully initialised cli structure, non-null only on success
2795    @param dest_host The netbios name of the remote host
2796    @param dest_ip (optional) The the destination IP, NULL for name based lookup
2797    @param port (optional) The destination port (0 for default)
2798    @param service (optional) The share to make the connection to.  Should be 'unqualified' in any way.
2799    @param service_type The 'type' of serivice. 
2800    @param user Username, unix string
2801    @param domain User's domain
2802    @param password User's password, unencrypted unix string.
2803 */
2804
2805 NTSTATUS cli_full_connection(struct cli_state **output_cli, 
2806                              const char *my_name, 
2807                              const char *dest_host, 
2808                              const struct sockaddr_storage *dest_ss, int port,
2809                              const char *service, const char *service_type,
2810                              const char *user, const char *domain, 
2811                              const char *password, int flags,
2812                              int signing_state)
2813 {
2814         NTSTATUS nt_status;
2815         struct cli_state *cli = NULL;
2816         int pw_len = password ? strlen(password)+1 : 0;
2817
2818         *output_cli = NULL;
2819
2820         if (password == NULL) {
2821                 password = "";
2822         }
2823
2824         nt_status = cli_start_connection(&cli, my_name, dest_host,
2825                                          dest_ss, port, signing_state,
2826                                          flags);
2827
2828         if (!NT_STATUS_IS_OK(nt_status)) {
2829                 return nt_status;
2830         }
2831
2832         nt_status = cli_session_setup(cli, user, password, pw_len, password,
2833                                       pw_len, domain);
2834         if (!NT_STATUS_IS_OK(nt_status)) {
2835
2836                 if (!(flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)) {
2837                         DEBUG(1,("failed session setup with %s\n",
2838                                  nt_errstr(nt_status)));
2839                         cli_shutdown(cli);
2840                         return nt_status;
2841                 }
2842
2843                 nt_status = cli_session_setup(cli, "", "", 0, "", 0, domain);
2844                 if (!NT_STATUS_IS_OK(nt_status)) {
2845                         DEBUG(1,("anonymous failed session setup with %s\n",
2846                                  nt_errstr(nt_status)));
2847                         cli_shutdown(cli);
2848                         return nt_status;
2849                 }
2850         }
2851
2852         if (service) {
2853                 nt_status = cli_tcon_andx(cli, service, service_type, password,
2854                                           pw_len);
2855                 if (!NT_STATUS_IS_OK(nt_status)) {
2856                         DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status)));
2857                         cli_shutdown(cli);
2858                         if (NT_STATUS_IS_OK(nt_status)) {
2859                                 nt_status = NT_STATUS_UNSUCCESSFUL;
2860                         }
2861                         return nt_status;
2862                 }
2863         }
2864
2865         nt_status = cli_init_creds(cli, user, domain, password);
2866         if (!NT_STATUS_IS_OK(nt_status)) {
2867                 cli_shutdown(cli);
2868                 return nt_status;
2869         }
2870
2871         *output_cli = cli;
2872         return NT_STATUS_OK;
2873 }
2874
2875 /****************************************************************************
2876  Send an old style tcon.
2877 ****************************************************************************/
2878 NTSTATUS cli_raw_tcon(struct cli_state *cli, 
2879                       const char *service, const char *pass, const char *dev,
2880                       uint16 *max_xmit, uint16 *tid)
2881 {
2882         struct tevent_req *req;
2883         uint16_t *ret_vwv;
2884         uint8_t *bytes;
2885         NTSTATUS status;
2886
2887         if (!lp_client_plaintext_auth() && (*pass)) {
2888                 DEBUG(1, ("Server requested plaintext password but 'client "
2889                           "plaintext auth' is disabled\n"));
2890                 return NT_STATUS_ACCESS_DENIED;
2891         }
2892
2893         bytes = talloc_array(talloc_tos(), uint8_t, 0);
2894         bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
2895         bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
2896                                    service, strlen(service)+1, NULL);
2897         bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
2898         bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
2899                                    pass, strlen(pass)+1, NULL);
2900         bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
2901         bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
2902                                    dev, strlen(dev)+1, NULL);
2903
2904         status = cli_smb(talloc_tos(), cli, SMBtcon, 0, 0, NULL,
2905                          talloc_get_size(bytes), bytes, &req,
2906                          2, NULL, &ret_vwv, NULL, NULL);
2907         if (!NT_STATUS_IS_OK(status)) {
2908                 return status;
2909         }
2910
2911         *max_xmit = SVAL(ret_vwv + 0, 0);
2912         *tid = SVAL(ret_vwv + 1, 0);
2913
2914         return NT_STATUS_OK;
2915 }
2916
2917 /* Return a cli_state pointing at the IPC$ share for the given server */
2918
2919 struct cli_state *get_ipc_connect(char *server,
2920                                 struct sockaddr_storage *server_ss,
2921                                 const struct user_auth_info *user_info)
2922 {
2923         struct cli_state *cli;
2924         NTSTATUS nt_status;
2925         uint32_t flags = CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
2926
2927         if (user_info->use_kerberos) {
2928                 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
2929         }
2930
2931         nt_status = cli_full_connection(&cli, NULL, server, server_ss, 0, "IPC$", "IPC", 
2932                                         user_info->username ? user_info->username : "",
2933                                         lp_workgroup(),
2934                                         user_info->password ? user_info->password : "",
2935                                         flags,
2936                                         SMB_SIGNING_DEFAULT);
2937
2938         if (NT_STATUS_IS_OK(nt_status)) {
2939                 return cli;
2940         } else if (is_ipaddress(server)) {
2941             /* windows 9* needs a correct NMB name for connections */
2942             fstring remote_name;
2943
2944             if (name_status_find("*", 0, 0, server_ss, remote_name)) {
2945                 cli = get_ipc_connect(remote_name, server_ss, user_info);
2946                 if (cli)
2947                     return cli;
2948             }
2949         }
2950         return NULL;
2951 }
2952
2953 /*
2954  * Given the IP address of a master browser on the network, return its
2955  * workgroup and connect to it.
2956  *
2957  * This function is provided to allow additional processing beyond what
2958  * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
2959  * browsers and obtain each master browsers' list of domains (in case the
2960  * first master browser is recently on the network and has not yet
2961  * synchronized with other master browsers and therefore does not yet have the
2962  * entire network browse list)
2963  */
2964
2965 struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx,
2966                                 struct sockaddr_storage *mb_ip,
2967                                 const struct user_auth_info *user_info,
2968                                 char **pp_workgroup_out)
2969 {
2970         char addr[INET6_ADDRSTRLEN];
2971         fstring name;
2972         struct cli_state *cli;
2973         struct sockaddr_storage server_ss;
2974
2975         *pp_workgroup_out = NULL;
2976
2977         print_sockaddr(addr, sizeof(addr), mb_ip);
2978         DEBUG(99, ("Looking up name of master browser %s\n",
2979                    addr));
2980
2981         /*
2982          * Do a name status query to find out the name of the master browser.
2983          * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
2984          * master browser will not respond to a wildcard query (or, at least,
2985          * an NT4 server acting as the domain master browser will not).
2986          *
2987          * We might be able to use ONLY the query on MSBROWSE, but that's not
2988          * yet been tested with all Windows versions, so until it is, leave
2989          * the original wildcard query as the first choice and fall back to
2990          * MSBROWSE if the wildcard query fails.
2991          */
2992         if (!name_status_find("*", 0, 0x1d, mb_ip, name) &&
2993             !name_status_find(MSBROWSE, 1, 0x1d, mb_ip, name)) {
2994
2995                 DEBUG(99, ("Could not retrieve name status for %s\n",
2996                            addr));
2997                 return NULL;
2998         }
2999
3000         if (!find_master_ip(name, &server_ss)) {
3001                 DEBUG(99, ("Could not find master ip for %s\n", name));
3002                 return NULL;
3003         }
3004
3005         *pp_workgroup_out = talloc_strdup(ctx, name);
3006
3007         DEBUG(4, ("found master browser %s, %s\n", name, addr));
3008
3009         print_sockaddr(addr, sizeof(addr), &server_ss);
3010         cli = get_ipc_connect(addr, &server_ss, user_info);
3011
3012         return cli;
3013 }
3014
3015 /*
3016  * Return the IP address and workgroup of a master browser on the network, and
3017  * connect to it.
3018  */
3019
3020 struct cli_state *get_ipc_connect_master_ip_bcast(TALLOC_CTX *ctx,
3021                                         const struct user_auth_info *user_info,
3022                                         char **pp_workgroup_out)
3023 {
3024         struct sockaddr_storage *ip_list;
3025         struct cli_state *cli;
3026         int i, count;
3027         NTSTATUS status;
3028
3029         *pp_workgroup_out = NULL;
3030
3031         DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
3032
3033         /* Go looking for workgroups by broadcasting on the local network */
3034
3035         status = name_resolve_bcast(MSBROWSE, 1, talloc_tos(),
3036                                     &ip_list, &count);
3037         if (!NT_STATUS_IS_OK(status)) {
3038                 DEBUG(99, ("No master browsers responded: %s\n",
3039                            nt_errstr(status)));
3040                 return NULL;
3041         }
3042
3043         for (i = 0; i < count; i++) {
3044                 char addr[INET6_ADDRSTRLEN];
3045                 print_sockaddr(addr, sizeof(addr), &ip_list[i]);
3046                 DEBUG(99, ("Found master browser %s\n", addr));
3047
3048                 cli = get_ipc_connect_master_ip(ctx, &ip_list[i],
3049                                 user_info, pp_workgroup_out);
3050                 if (cli)
3051                         return(cli);
3052         }
3053
3054         return NULL;
3055 }