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