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