s3:libsmb: make use of smb1cli_session_set_session_key()
[kai/samba.git] / source3 / libsmb / cliconnect.c
1 /* 
2    Unix SMB/CIFS implementation.
3    client connect/disconnect routines
4    Copyright (C) Andrew Tridgell 1994-1998
5    Copyright (C) Andrew Bartlett 2001-2003
6    Copyright (C) Volker Lendecke 2011
7    Copyright (C) Jeremy Allison 2011
8
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3 of the License, or
12    (at your option) any later version.
13
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <http://www.gnu.org/licenses/>.
21 */
22
23 #include "includes.h"
24 #include "libsmb/libsmb.h"
25 #include "auth_info.h"
26 #include "../libcli/auth/libcli_auth.h"
27 #include "../libcli/auth/spnego.h"
28 #include "smb_krb5.h"
29 #include "../auth/ntlmssp/ntlmssp.h"
30 #include "libads/kerberos_proto.h"
31 #include "krb5_env.h"
32 #include "../lib/util/tevent_ntstatus.h"
33 #include "async_smb.h"
34 #include "libsmb/nmblib.h"
35 #include "librpc/ndr/libndr.h"
36 #include "../libcli/smb/smbXcli_base.h"
37 #include "smb2cli.h"
38
39 #define STAR_SMBSERVER "*SMBSERVER"
40
41 /********************************************************
42  Utility function to ensure we always return at least
43  a valid char * pointer to an empty string for the
44  cli->server_os, cli->server_type and cli->server_domain
45  strings.
46 *******************************************************/
47
48 static NTSTATUS smb_bytes_talloc_string(TALLOC_CTX *mem_ctx,
49                                         const uint8_t *hdr,
50                                         char **dest,
51                                         uint8_t *src,
52                                         size_t srclen,
53                                         ssize_t *destlen)
54 {
55         *destlen = clistr_pull_talloc(mem_ctx,
56                                 (const char *)hdr,
57                                 SVAL(hdr, HDR_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 = smb1cli_conn_server_security_mode(cli->conn);
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, smb1cli_conn_server_challenge(cli->conn),
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, smbXcli_conn_use_unicode(cli->conn), 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, smb1cli_conn_server_session_key(cli->conn));
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, smbXcli_conn_use_unicode(cli->conn), 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, smbXcli_conn_use_unicode(cli->conn), tmp, strlen(tmp)+1,
209                                    NULL);
210         bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "Unix", 5, NULL);
211         bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "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         uint8_t *inhdr;
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         inhdr = in + NBT_HDR_SIZE;
252         p = bytes;
253
254         cli_state_set_uid(state->cli, SVAL(inhdr, HDR_UID));
255         cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0);
256
257         status = smb_bytes_talloc_string(cli,
258                                         inhdr,
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                                         inhdr,
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                                         inhdr,
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 (smbXcli_conn_has_async_calls(cli->conn)) {
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 = smb1cli_conn_capabilities(cli->conn);
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, smb1cli_conn_server_session_key(cli->conn));
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, smbXcli_conn_use_unicode(cli->conn), "",  1, /* username */
419                                    NULL);
420         bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "", 1, /* workgroup */
421                                    NULL);
422         bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "Unix", 5, NULL);
423         bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "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 = smb1cli_req_chain_submit(&subreq, 1);
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         uint8_t *inhdr;
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         inhdr = in + NBT_HDR_SIZE;
490         p = bytes;
491
492         cli_state_set_uid(state->cli, SVAL(inhdr, HDR_UID));
493         cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0);
494
495         status = smb_bytes_talloc_string(cli,
496                                         inhdr,
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                                         inhdr,
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                                         inhdr,
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 (smbXcli_conn_has_async_calls(cli->conn)) {
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, smb1cli_conn_server_session_key(cli->conn));
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, smbXcli_conn_use_unicode(cli->conn), pass, strlen(pass)+1,
633                                    &passlen);
634         if (tevent_req_nomem(bytes, req)) {
635                 return tevent_req_post(req, ev);
636         }
637         SSVAL(vwv + (smbXcli_conn_use_unicode(cli->conn) ? 8 : 7), 0, passlen);
638
639         bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
640                                    user, strlen(user)+1, NULL);
641         bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
642                                    workgroup, strlen(workgroup)+1, NULL);
643         bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
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, smbXcli_conn_use_unicode(cli->conn),
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         uint8_t *inhdr;
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         inhdr = in + NBT_HDR_SIZE;
693         p = bytes;
694
695         cli_state_set_uid(state->cli, SVAL(inhdr, HDR_UID));
696         cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0);
697
698         status = smb_bytes_talloc_string(cli,
699                                         inhdr,
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                                         inhdr,
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                                         inhdr,
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 (smbXcli_conn_has_async_calls(cli->conn)) {
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(smb1cli_conn_server_challenge(cli->conn),
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, smb1cli_conn_server_challenge(cli->conn),
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                                                 smb1cli_conn_server_challenge(cli->conn),
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, smb1cli_conn_server_session_key(cli->conn));
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, smbXcli_conn_use_unicode(cli->conn),
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, smbXcli_conn_use_unicode(cli->conn),
999                                    workgroup_upper, strlen(workgroup_upper)+1,
1000                                    NULL);
1001         TALLOC_FREE(workgroup_upper);
1002
1003         bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "Unix", 5, NULL);
1004         bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "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         uint8_t *inhdr;
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         inhdr = in + NBT_HDR_SIZE;
1044         p = bytes;
1045
1046         cli_state_set_uid(state->cli, SVAL(inhdr, HDR_UID));
1047         cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0);
1048
1049         status = smb_bytes_talloc_string(cli,
1050                                         inhdr,
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                                         inhdr,
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                                         inhdr,
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 (smb1cli_conn_activate_signing(cli->conn, state->session_key, state->response)
1090             && !smb1cli_conn_check_signing(cli->conn, (uint8_t *)in, 1)) {
1091                 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1092                 return;
1093         }
1094         if (state->session_key.data) {
1095                 struct smbXcli_session *session = state->cli->smb1.session;
1096
1097                 /* Have plaintext orginal */
1098                 cli_set_session_key(cli, state->session_key);
1099
1100                 status = smb1cli_session_set_session_key(session,
1101                                 state->session_key);
1102                 if (tevent_req_nterror(req, status)) {
1103                         return;
1104                 }
1105         }
1106         tevent_req_done(req);
1107 }
1108
1109 static NTSTATUS cli_session_setup_nt1_recv(struct tevent_req *req)
1110 {
1111         return tevent_req_simple_recv_ntstatus(req);
1112 }
1113
1114 static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user,
1115                                       const char *pass, size_t passlen,
1116                                       const char *ntpass, size_t ntpasslen,
1117                                       const char *workgroup)
1118 {
1119         TALLOC_CTX *frame = talloc_stackframe();
1120         struct event_context *ev;
1121         struct tevent_req *req;
1122         NTSTATUS status = NT_STATUS_NO_MEMORY;
1123
1124         if (smbXcli_conn_has_async_calls(cli->conn)) {
1125                 /*
1126                  * Can't use sync call while an async call is in flight
1127                  */
1128                 status = NT_STATUS_INVALID_PARAMETER;
1129                 goto fail;
1130         }
1131         ev = event_context_init(frame);
1132         if (ev == NULL) {
1133                 goto fail;
1134         }
1135         req = cli_session_setup_nt1_send(frame, ev, cli, user, pass, passlen,
1136                                          ntpass, ntpasslen, workgroup);
1137         if (req == NULL) {
1138                 goto fail;
1139         }
1140         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1141                 goto fail;
1142         }
1143         status = cli_session_setup_nt1_recv(req);
1144  fail:
1145         TALLOC_FREE(frame);
1146         return status;
1147 }
1148
1149 /* The following is calculated from :
1150  * (smb_size-4) = 35
1151  * (smb_wcnt * 2) = 24 (smb_wcnt == 12 in cli_session_setup_blob_send() )
1152  * (strlen("Unix") + 1 + strlen("Samba") + 1) * 2 = 22 (unicode strings at
1153  * end of packet.
1154  */
1155
1156 #define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22)
1157
1158 struct cli_sesssetup_blob_state {
1159         struct tevent_context *ev;
1160         struct cli_state *cli;
1161         DATA_BLOB blob;
1162         uint16_t max_blob_size;
1163         uint16_t vwv[12];
1164         uint8_t *buf;
1165
1166         DATA_BLOB smb2_blob;
1167         struct iovec *recv_iov;
1168
1169         NTSTATUS status;
1170         uint8_t *inbuf;
1171         DATA_BLOB ret_blob;
1172 };
1173
1174 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state *state,
1175                                     struct tevent_req **psubreq);
1176 static void cli_sesssetup_blob_done(struct tevent_req *subreq);
1177
1178 static struct tevent_req *cli_sesssetup_blob_send(TALLOC_CTX *mem_ctx,
1179                                                   struct tevent_context *ev,
1180                                                   struct cli_state *cli,
1181                                                   DATA_BLOB blob)
1182 {
1183         struct tevent_req *req, *subreq;
1184         struct cli_sesssetup_blob_state *state;
1185         uint32_t usable_space;
1186
1187         req = tevent_req_create(mem_ctx, &state,
1188                                 struct cli_sesssetup_blob_state);
1189         if (req == NULL) {
1190                 return NULL;
1191         }
1192         state->ev = ev;
1193         state->blob = blob;
1194         state->cli = cli;
1195
1196         if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
1197                 usable_space = UINT16_MAX;
1198         } else {
1199                 usable_space = cli_state_available_size(cli,
1200                                 BASE_SESSSETUP_BLOB_PACKET_SIZE);
1201         }
1202
1203         if (usable_space == 0) {
1204                 DEBUG(1, ("cli_session_setup_blob: cli->max_xmit too small "
1205                           "(not possible to send %u bytes)\n",
1206                           BASE_SESSSETUP_BLOB_PACKET_SIZE + 1));
1207                 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1208                 return tevent_req_post(req, ev);
1209         }
1210         state->max_blob_size = MIN(usable_space, 0xFFFF);
1211
1212         if (!cli_sesssetup_blob_next(state, &subreq)) {
1213                 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1214                 return tevent_req_post(req, ev);
1215         }
1216         tevent_req_set_callback(subreq, cli_sesssetup_blob_done, req);
1217         return req;
1218 }
1219
1220 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state *state,
1221                                     struct tevent_req **psubreq)
1222 {
1223         struct tevent_req *subreq;
1224         uint16_t thistime;
1225
1226         thistime = MIN(state->blob.length, state->max_blob_size);
1227
1228         if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
1229
1230                 state->smb2_blob.data = state->blob.data;
1231                 state->smb2_blob.length = thistime;
1232
1233                 state->blob.data += thistime;
1234                 state->blob.length -= thistime;
1235
1236                 subreq = smb2cli_session_setup_send(state, state->ev,
1237                                                     state->cli->conn,
1238                                                     state->cli->timeout,
1239                                                     state->cli->smb2.session,
1240                                                     0, /* in_flags */
1241                                                     SMB2_CAP_DFS, /* in_capabilities */
1242                                                     0, /* in_channel */
1243                                                     0, /* in_previous_session_id */
1244                                                     &state->smb2_blob);
1245                 if (subreq == NULL) {
1246                         return false;
1247                 }
1248                 *psubreq = subreq;
1249                 return true;
1250         }
1251
1252         SCVAL(state->vwv+0, 0, 0xFF);
1253         SCVAL(state->vwv+0, 1, 0);
1254         SSVAL(state->vwv+1, 0, 0);
1255         SSVAL(state->vwv+2, 0, CLI_BUFFER_SIZE);
1256         SSVAL(state->vwv+3, 0, 2);
1257         SSVAL(state->vwv+4, 0, 1);
1258         SIVAL(state->vwv+5, 0, 0);
1259
1260         SSVAL(state->vwv+7, 0, thistime);
1261
1262         SSVAL(state->vwv+8, 0, 0);
1263         SSVAL(state->vwv+9, 0, 0);
1264         SIVAL(state->vwv+10, 0,
1265                 cli_session_setup_capabilities(state->cli, CAP_EXTENDED_SECURITY));
1266
1267         state->buf = (uint8_t *)talloc_memdup(state, state->blob.data,
1268                                               thistime);
1269         if (state->buf == NULL) {
1270                 return false;
1271         }
1272         state->blob.data += thistime;
1273         state->blob.length -= thistime;
1274
1275         state->buf = smb_bytes_push_str(state->buf, smbXcli_conn_use_unicode(state->cli->conn),
1276                                         "Unix", 5, NULL);
1277         state->buf = smb_bytes_push_str(state->buf, smbXcli_conn_use_unicode(state->cli->conn),
1278                                         "Samba", 6, NULL);
1279         if (state->buf == NULL) {
1280                 return false;
1281         }
1282         subreq = cli_smb_send(state, state->ev, state->cli, SMBsesssetupX, 0,
1283                               12, state->vwv,
1284                               talloc_get_size(state->buf), state->buf);
1285         if (subreq == NULL) {
1286                 return false;
1287         }
1288         *psubreq = subreq;
1289         return true;
1290 }
1291
1292 static void cli_sesssetup_blob_done(struct tevent_req *subreq)
1293 {
1294         struct tevent_req *req = tevent_req_callback_data(
1295                 subreq, struct tevent_req);
1296         struct cli_sesssetup_blob_state *state = tevent_req_data(
1297                 req, struct cli_sesssetup_blob_state);
1298         struct cli_state *cli = state->cli;
1299         uint8_t wct;
1300         uint16_t *vwv;
1301         uint32_t num_bytes;
1302         uint8_t *bytes;
1303         NTSTATUS status;
1304         uint8_t *p;
1305         uint16_t blob_length;
1306         uint8_t *in;
1307         uint8_t *inhdr;
1308         ssize_t ret;
1309
1310         if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
1311                 status = smb2cli_session_setup_recv(subreq, state,
1312                                                     &state->recv_iov,
1313                                                     &state->ret_blob);
1314         } else {
1315                 status = cli_smb_recv(subreq, state, &in, 4, &wct, &vwv,
1316                                       &num_bytes, &bytes);
1317                 TALLOC_FREE(state->buf);
1318         }
1319         TALLOC_FREE(subreq);
1320         if (!NT_STATUS_IS_OK(status)
1321             && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1322                 tevent_req_nterror(req, status);
1323                 return;
1324         }
1325
1326         state->status = status;
1327
1328         if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
1329                 goto next;
1330         }
1331
1332         state->inbuf = in;
1333         inhdr = in + NBT_HDR_SIZE;
1334         cli_state_set_uid(state->cli, SVAL(inhdr, HDR_UID));
1335         cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0);
1336
1337         blob_length = SVAL(vwv+3, 0);
1338         if (blob_length > num_bytes) {
1339                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1340                 return;
1341         }
1342         state->ret_blob = data_blob_const(bytes, blob_length);
1343
1344         p = bytes + blob_length;
1345
1346         status = smb_bytes_talloc_string(cli,
1347                                         inhdr,
1348                                         &cli->server_os,
1349                                         p,
1350                                         bytes+num_bytes-p,
1351                                         &ret);
1352
1353         if (!NT_STATUS_IS_OK(status)) {
1354                 tevent_req_nterror(req, status);
1355                 return;
1356         }
1357         p += ret;
1358
1359         status = smb_bytes_talloc_string(cli,
1360                                         inhdr,
1361                                         &cli->server_type,
1362                                         p,
1363                                         bytes+num_bytes-p,
1364                                         &ret);
1365
1366         if (!NT_STATUS_IS_OK(status)) {
1367                 tevent_req_nterror(req, status);
1368                 return;
1369         }
1370         p += ret;
1371
1372         status = smb_bytes_talloc_string(cli,
1373                                         inhdr,
1374                                         &cli->server_domain,
1375                                         p,
1376                                         bytes+num_bytes-p,
1377                                         &ret);
1378
1379         if (!NT_STATUS_IS_OK(status)) {
1380                 tevent_req_nterror(req, status);
1381                 return;
1382         }
1383         p += ret;
1384
1385 next:
1386         if (state->blob.length != 0) {
1387                 /*
1388                  * More to send
1389                  */
1390                 if (!cli_sesssetup_blob_next(state, &subreq)) {
1391                         tevent_req_oom(req);
1392                         return;
1393                 }
1394                 tevent_req_set_callback(subreq, cli_sesssetup_blob_done, req);
1395                 return;
1396         }
1397         tevent_req_done(req);
1398 }
1399
1400 static NTSTATUS cli_sesssetup_blob_recv(struct tevent_req *req,
1401                                         TALLOC_CTX *mem_ctx,
1402                                         DATA_BLOB *pblob,
1403                                         uint8_t **pinbuf,
1404                                         struct iovec **precv_iov)
1405 {
1406         struct cli_sesssetup_blob_state *state = tevent_req_data(
1407                 req, struct cli_sesssetup_blob_state);
1408         NTSTATUS status;
1409         uint8_t *inbuf;
1410         struct iovec *recv_iov;
1411
1412         if (tevent_req_is_nterror(req, &status)) {
1413                 TALLOC_FREE(state->cli->smb2.session);
1414                 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
1415                 return status;
1416         }
1417
1418         inbuf = talloc_move(mem_ctx, &state->inbuf);
1419         recv_iov = talloc_move(mem_ctx, &state->recv_iov);
1420         if (pblob != NULL) {
1421                 *pblob = state->ret_blob;
1422         }
1423         if (pinbuf != NULL) {
1424                 *pinbuf = inbuf;
1425         }
1426         if (precv_iov != NULL) {
1427                 *precv_iov = recv_iov;
1428         }
1429         /* could be NT_STATUS_MORE_PROCESSING_REQUIRED */
1430         return state->status;
1431 }
1432
1433 #ifdef HAVE_KRB5
1434
1435 /****************************************************************************
1436  Use in-memory credentials cache
1437 ****************************************************************************/
1438
1439 static void use_in_memory_ccache(void) {
1440         setenv(KRB5_ENV_CCNAME, "MEMORY:cliconnect", 1);
1441 }
1442
1443 /****************************************************************************
1444  Do a spnego/kerberos encrypted session setup.
1445 ****************************************************************************/
1446
1447 struct cli_session_setup_kerberos_state {
1448         struct cli_state *cli;
1449         DATA_BLOB negTokenTarg;
1450         DATA_BLOB session_key_krb5;
1451         ADS_STATUS ads_status;
1452 };
1453
1454 static void cli_session_setup_kerberos_done(struct tevent_req *subreq);
1455
1456 static struct tevent_req *cli_session_setup_kerberos_send(
1457         TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
1458         const char *principal)
1459 {
1460         struct tevent_req *req, *subreq;
1461         struct cli_session_setup_kerberos_state *state;
1462         int rc;
1463
1464         DEBUG(2,("Doing kerberos session setup\n"));
1465
1466         req = tevent_req_create(mem_ctx, &state,
1467                                 struct cli_session_setup_kerberos_state);
1468         if (req == NULL) {
1469                 return NULL;
1470         }
1471         state->cli = cli;
1472         state->ads_status = ADS_SUCCESS;
1473
1474         /*
1475          * Ok, this is cheating: spnego_gen_krb5_negTokenInit can block if
1476          * we have to acquire a ticket. To be fixed later :-)
1477          */
1478         rc = spnego_gen_krb5_negTokenInit(state, principal, 0, &state->negTokenTarg,
1479                                      &state->session_key_krb5, 0, NULL);
1480         if (rc) {
1481                 DEBUG(1, ("cli_session_setup_kerberos: "
1482                           "spnego_gen_krb5_negTokenInit failed: %s\n",
1483                           error_message(rc)));
1484                 state->ads_status = ADS_ERROR_KRB5(rc);
1485                 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
1486                 return tevent_req_post(req, ev);
1487         }
1488
1489 #if 0
1490         file_save("negTokenTarg.dat", state->negTokenTarg.data,
1491                   state->negTokenTarg.length);
1492 #endif
1493
1494         if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
1495                 state->cli->smb2.session = smbXcli_session_create(cli,
1496                                                                   cli->conn);
1497                 if (tevent_req_nomem(state->cli->smb2.session, req)) {
1498                         return tevent_req_post(req, ev);
1499                 }
1500         }
1501
1502         subreq = cli_sesssetup_blob_send(state, ev, cli, state->negTokenTarg);
1503         if (tevent_req_nomem(subreq, req)) {
1504                 return tevent_req_post(req, ev);
1505         }
1506         tevent_req_set_callback(subreq, cli_session_setup_kerberos_done, req);
1507         return req;
1508 }
1509
1510 static void cli_session_setup_kerberos_done(struct tevent_req *subreq)
1511 {
1512         struct tevent_req *req = tevent_req_callback_data(
1513                 subreq, struct tevent_req);
1514         struct cli_session_setup_kerberos_state *state = tevent_req_data(
1515                 req, struct cli_session_setup_kerberos_state);
1516         uint8_t *inbuf = NULL;
1517         struct iovec *recv_iov = NULL;
1518         NTSTATUS status;
1519
1520         status = cli_sesssetup_blob_recv(subreq, state,
1521                                          NULL, &inbuf, &recv_iov);
1522         TALLOC_FREE(subreq);
1523         if (!NT_STATUS_IS_OK(status)) {
1524                 tevent_req_nterror(req, status);
1525                 return;
1526         }
1527
1528         cli_set_session_key(state->cli, state->session_key_krb5);
1529
1530         if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
1531                 struct smbXcli_session *session = state->cli->smb2.session;
1532                 status = smb2cli_session_set_session_key(session,
1533                                                 state->session_key_krb5,
1534                                                 recv_iov);
1535                 if (tevent_req_nterror(req, status)) {
1536                         return;
1537                 }
1538         } else {
1539                 struct smbXcli_session *session = state->cli->smb1.session;
1540
1541                 status = smb1cli_session_set_session_key(session,
1542                                                          state->session_key_krb5);
1543                 if (tevent_req_nterror(req, status)) {
1544                         return;
1545                 }
1546
1547                 if (smb1cli_conn_activate_signing(state->cli->conn, state->session_key_krb5,
1548                                            data_blob_null)
1549                     && !smb1cli_conn_check_signing(state->cli->conn, inbuf, 1)) {
1550                         tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1551                         return;
1552                 }
1553         }
1554
1555         tevent_req_done(req);
1556 }
1557
1558 static ADS_STATUS cli_session_setup_kerberos_recv(struct tevent_req *req)
1559 {
1560         struct cli_session_setup_kerberos_state *state = tevent_req_data(
1561                 req, struct cli_session_setup_kerberos_state);
1562         NTSTATUS status;
1563
1564         if (tevent_req_is_nterror(req, &status)) {
1565                 return ADS_ERROR_NT(status);
1566         }
1567         return state->ads_status;
1568 }
1569
1570 static ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli,
1571                                              const char *principal)
1572 {
1573         struct tevent_context *ev;
1574         struct tevent_req *req;
1575         ADS_STATUS status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1576
1577         if (smbXcli_conn_has_async_calls(cli->conn)) {
1578                 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1579         }
1580         ev = tevent_context_init(talloc_tos());
1581         if (ev == NULL) {
1582                 goto fail;
1583         }
1584         req = cli_session_setup_kerberos_send(ev, ev, cli, principal);
1585         if (req == NULL) {
1586                 goto fail;
1587         }
1588         if (!tevent_req_poll(req, ev)) {
1589                 status = ADS_ERROR_SYSTEM(errno);
1590                 goto fail;
1591         }
1592         status = cli_session_setup_kerberos_recv(req);
1593 fail:
1594         TALLOC_FREE(ev);
1595         return status;
1596 }
1597 #endif  /* HAVE_KRB5 */
1598
1599 /****************************************************************************
1600  Do a spnego/NTLMSSP encrypted session setup.
1601 ****************************************************************************/
1602
1603 struct cli_session_setup_ntlmssp_state {
1604         struct tevent_context *ev;
1605         struct cli_state *cli;
1606         struct ntlmssp_state *ntlmssp_state;
1607         int turn;
1608         DATA_BLOB blob_out;
1609 };
1610
1611 static int cli_session_setup_ntlmssp_state_destructor(
1612         struct cli_session_setup_ntlmssp_state *state)
1613 {
1614         if (state->ntlmssp_state != NULL) {
1615                 TALLOC_FREE(state->ntlmssp_state);
1616         }
1617         return 0;
1618 }
1619
1620 static void cli_session_setup_ntlmssp_done(struct tevent_req *req);
1621
1622 static struct tevent_req *cli_session_setup_ntlmssp_send(
1623         TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
1624         const char *user, const char *pass, const char *domain)
1625 {
1626         struct tevent_req *req, *subreq;
1627         struct cli_session_setup_ntlmssp_state *state;
1628         NTSTATUS status;
1629         DATA_BLOB blob_out;
1630         const char *OIDs_ntlm[] = {OID_NTLMSSP, NULL};
1631
1632         req = tevent_req_create(mem_ctx, &state,
1633                                 struct cli_session_setup_ntlmssp_state);
1634         if (req == NULL) {
1635                 return NULL;
1636         }
1637         state->ev = ev;
1638         state->cli = cli;
1639         state->turn = 1;
1640
1641         state->ntlmssp_state = NULL;
1642         talloc_set_destructor(
1643                 state, cli_session_setup_ntlmssp_state_destructor);
1644
1645         status = ntlmssp_client_start(state,
1646                                       lp_netbios_name(),
1647                                       lp_workgroup(),
1648                                       lp_client_ntlmv2_auth(),
1649                                       &state->ntlmssp_state);
1650         if (!NT_STATUS_IS_OK(status)) {
1651                 goto fail;
1652         }
1653         ntlmssp_want_feature(state->ntlmssp_state,
1654                              NTLMSSP_FEATURE_SESSION_KEY);
1655         if (cli->use_ccache) {
1656                 ntlmssp_want_feature(state->ntlmssp_state,
1657                                      NTLMSSP_FEATURE_CCACHE);
1658         }
1659         status = ntlmssp_set_username(state->ntlmssp_state, user);
1660         if (!NT_STATUS_IS_OK(status)) {
1661                 goto fail;
1662         }
1663         status = ntlmssp_set_domain(state->ntlmssp_state, domain);
1664         if (!NT_STATUS_IS_OK(status)) {
1665                 goto fail;
1666         }
1667         if (cli->pw_nt_hash) {
1668                 status = ntlmssp_set_password_hash(state->ntlmssp_state, pass);
1669         } else {
1670                 status = ntlmssp_set_password(state->ntlmssp_state, pass);
1671         }
1672         if (!NT_STATUS_IS_OK(status)) {
1673                 goto fail;
1674         }
1675         status = ntlmssp_update(state->ntlmssp_state, data_blob_null,
1676                                 &blob_out);
1677         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1678                 goto fail;
1679         }
1680
1681         state->blob_out = spnego_gen_negTokenInit(state, OIDs_ntlm, &blob_out, NULL);
1682         data_blob_free(&blob_out);
1683
1684         if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
1685                 state->cli->smb2.session = smbXcli_session_create(cli,
1686                                                                   cli->conn);
1687                 if (tevent_req_nomem(state->cli->smb2.session, req)) {
1688                         return tevent_req_post(req, ev);
1689                 }
1690         }
1691
1692         subreq = cli_sesssetup_blob_send(state, ev, cli, state->blob_out);
1693         if (tevent_req_nomem(subreq, req)) {
1694                 return tevent_req_post(req, ev);
1695         }
1696         tevent_req_set_callback(subreq, cli_session_setup_ntlmssp_done, req);
1697         return req;
1698 fail:
1699         tevent_req_nterror(req, status);
1700         return tevent_req_post(req, ev);
1701 }
1702
1703 static void cli_session_setup_ntlmssp_done(struct tevent_req *subreq)
1704 {
1705         struct tevent_req *req = tevent_req_callback_data(
1706                 subreq, struct tevent_req);
1707         struct cli_session_setup_ntlmssp_state *state = tevent_req_data(
1708                 req, struct cli_session_setup_ntlmssp_state);
1709         DATA_BLOB blob_in, msg_in, blob_out;
1710         uint8_t *inbuf = NULL;
1711         struct iovec *recv_iov = NULL;
1712         bool parse_ret;
1713         NTSTATUS status;
1714
1715         status = cli_sesssetup_blob_recv(subreq, talloc_tos(), &blob_in,
1716                                          &inbuf, &recv_iov);
1717         TALLOC_FREE(subreq);
1718         data_blob_free(&state->blob_out);
1719
1720         if (NT_STATUS_IS_OK(status)) {
1721                 if (state->cli->server_domain[0] == '\0') {
1722                         TALLOC_FREE(state->cli->server_domain);
1723                         state->cli->server_domain = talloc_strdup(state->cli,
1724                                                 state->ntlmssp_state->server.netbios_domain);
1725                         if (state->cli->server_domain == NULL) {
1726                                 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1727                                 return;
1728                         }
1729                 }
1730                 cli_set_session_key(
1731                         state->cli, state->ntlmssp_state->session_key);
1732
1733                 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
1734                         struct smbXcli_session *session = state->cli->smb2.session;
1735
1736                         if (ntlmssp_is_anonymous(state->ntlmssp_state)) {
1737                                 /*
1738                                  * Windows server does not set the
1739                                  * SMB2_SESSION_FLAG_IS_GUEST nor
1740                                  * SMB2_SESSION_FLAG_IS_NULL flag.
1741                                  *
1742                                  * This fix makes sure we do not try
1743                                  * to verify a signature on the final
1744                                  * session setup response.
1745                                  */
1746                                 TALLOC_FREE(state->ntlmssp_state);
1747                                 tevent_req_done(req);
1748                                 return;
1749                         }
1750
1751                         status = smb2cli_session_set_session_key(session,
1752                                                 state->ntlmssp_state->session_key,
1753                                                 recv_iov);
1754                         if (tevent_req_nterror(req, status)) {
1755                                 return;
1756                         }
1757                 } else {
1758                         struct smbXcli_session *session = state->cli->smb1.session;
1759
1760                         status = smb1cli_session_set_session_key(session,
1761                                         state->ntlmssp_state->session_key);
1762                         if (tevent_req_nterror(req, status)) {
1763                                 return;
1764                         }
1765
1766                         if (smb1cli_conn_activate_signing(
1767                                     state->cli->conn, state->ntlmssp_state->session_key,
1768                                     data_blob_null)
1769                             && !smb1cli_conn_check_signing(state->cli->conn, inbuf, 1)) {
1770                                 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1771                                 return;
1772                         }
1773                 }
1774                 TALLOC_FREE(state->ntlmssp_state);
1775                 tevent_req_done(req);
1776                 return;
1777         }
1778         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1779                 tevent_req_nterror(req, status);
1780                 return;
1781         }
1782
1783         if (blob_in.length == 0) {
1784                 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
1785                 return;
1786         }
1787
1788         if ((state->turn == 1)
1789             && NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1790                 DATA_BLOB tmp_blob = data_blob_null;
1791                 /* the server might give us back two challenges */
1792                 parse_ret = spnego_parse_challenge(state, blob_in, &msg_in,
1793                                                    &tmp_blob);
1794                 data_blob_free(&tmp_blob);
1795         } else {
1796                 parse_ret = spnego_parse_auth_response(state, blob_in, status,
1797                                                        OID_NTLMSSP, &msg_in);
1798         }
1799         state->turn += 1;
1800
1801         if (!parse_ret) {
1802                 DEBUG(3,("Failed to parse auth response\n"));
1803                 if (NT_STATUS_IS_OK(status)
1804                     || NT_STATUS_EQUAL(status,
1805                                        NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1806                         tevent_req_nterror(
1807                                 req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1808                         return;
1809                 }
1810         }
1811
1812         status = ntlmssp_update(state->ntlmssp_state, msg_in, &blob_out);
1813
1814         if (!NT_STATUS_IS_OK(status)
1815             && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1816                 TALLOC_FREE(state->ntlmssp_state);
1817                 tevent_req_nterror(req, status);
1818                 return;
1819         }
1820
1821         state->blob_out = spnego_gen_auth(state, blob_out);
1822         if (tevent_req_nomem(state->blob_out.data, req)) {
1823                 return;
1824         }
1825
1826         subreq = cli_sesssetup_blob_send(state, state->ev, state->cli,
1827                                          state->blob_out);
1828         if (tevent_req_nomem(subreq, req)) {
1829                 return;
1830         }
1831         tevent_req_set_callback(subreq, cli_session_setup_ntlmssp_done, req);
1832 }
1833
1834 static NTSTATUS cli_session_setup_ntlmssp_recv(struct tevent_req *req)
1835 {
1836         struct cli_session_setup_ntlmssp_state *state = tevent_req_data(
1837                 req, struct cli_session_setup_ntlmssp_state);
1838         NTSTATUS status;
1839
1840         if (tevent_req_is_nterror(req, &status)) {
1841                 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
1842                 return status;
1843         }
1844         return NT_STATUS_OK;
1845 }
1846
1847 static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli,
1848                                           const char *user,
1849                                           const char *pass,
1850                                           const char *domain)
1851 {
1852         struct tevent_context *ev;
1853         struct tevent_req *req;
1854         NTSTATUS status = NT_STATUS_NO_MEMORY;
1855
1856         if (smbXcli_conn_has_async_calls(cli->conn)) {
1857                 return NT_STATUS_INVALID_PARAMETER;
1858         }
1859         ev = tevent_context_init(talloc_tos());
1860         if (ev == NULL) {
1861                 goto fail;
1862         }
1863         req = cli_session_setup_ntlmssp_send(ev, ev, cli, user, pass, domain);
1864         if (req == NULL) {
1865                 goto fail;
1866         }
1867         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1868                 goto fail;
1869         }
1870         status = cli_session_setup_ntlmssp_recv(req);
1871 fail:
1872         TALLOC_FREE(ev);
1873         return status;
1874 }
1875
1876 /****************************************************************************
1877  Do a spnego encrypted session setup.
1878
1879  user_domain: The shortname of the domain the user/machine is a member of.
1880  dest_realm: The realm we're connecting to, if NULL we use our default realm.
1881 ****************************************************************************/
1882
1883 static ADS_STATUS cli_session_setup_spnego(struct cli_state *cli,
1884                               const char *user,
1885                               const char *pass,
1886                               const char *user_domain,
1887                               const char * dest_realm)
1888 {
1889         char *principal = NULL;
1890         char *OIDs[ASN1_MAX_OIDS];
1891         int i;
1892         const DATA_BLOB *server_blob;
1893         DATA_BLOB blob = data_blob_null;
1894         const char *p = NULL;
1895         char *account = NULL;
1896         NTSTATUS status;
1897
1898         server_blob = smbXcli_conn_server_gss_blob(cli->conn);
1899         if (server_blob) {
1900                 blob = data_blob(server_blob->data, server_blob->length);
1901         }
1902
1903         DEBUG(3,("Doing spnego session setup (blob length=%lu)\n", (unsigned long)blob.length));
1904
1905         /* the server might not even do spnego */
1906         if (blob.length == 0) {
1907                 DEBUG(3,("server didn't supply a full spnego negprot\n"));
1908                 goto ntlmssp;
1909         }
1910
1911 #if 0
1912         file_save("negprot.dat", cli->secblob.data, cli->secblob.length);
1913 #endif
1914
1915         /* The server sent us the first part of the SPNEGO exchange in the
1916          * negprot reply. It is WRONG to depend on the principal sent in the
1917          * negprot reply, but right now we do it. If we don't receive one,
1918          * we try to best guess, then fall back to NTLM.  */
1919         if (!spnego_parse_negTokenInit(talloc_tos(), blob, OIDs, &principal, NULL) ||
1920                         OIDs[0] == NULL) {
1921                 data_blob_free(&blob);
1922                 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1923         }
1924         data_blob_free(&blob);
1925
1926         /* make sure the server understands kerberos */
1927         for (i=0;OIDs[i];i++) {
1928                 if (i == 0)
1929                         DEBUG(3,("got OID=%s\n", OIDs[i]));
1930                 else
1931                         DEBUGADD(3,("got OID=%s\n", OIDs[i]));
1932                 if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0 ||
1933                     strcmp(OIDs[i], OID_KERBEROS5) == 0) {
1934                         cli->got_kerberos_mechanism = True;
1935                 }
1936                 talloc_free(OIDs[i]);
1937         }
1938
1939         DEBUG(3,("got principal=%s\n", principal ? principal : "<null>"));
1940
1941         status = cli_set_username(cli, user);
1942         if (!NT_STATUS_IS_OK(status)) {
1943                 TALLOC_FREE(principal);
1944                 return ADS_ERROR_NT(status);
1945         }
1946
1947 #ifdef HAVE_KRB5
1948         /* If password is set we reauthenticate to kerberos server
1949          * and do not store results */
1950
1951         if (user && *user && cli->got_kerberos_mechanism && cli->use_kerberos) {
1952                 ADS_STATUS rc;
1953                 const char *remote_name = smbXcli_conn_remote_name(cli->conn);
1954
1955                 if (pass && *pass) {
1956                         int ret;
1957
1958                         use_in_memory_ccache();
1959                         ret = kerberos_kinit_password(user, pass, 0 /* no time correction for now */, NULL);
1960
1961                         if (ret){
1962                                 TALLOC_FREE(principal);
1963                                 DEBUG(0, ("Kinit failed: %s\n", error_message(ret)));
1964                                 if (cli->fallback_after_kerberos)
1965                                         goto ntlmssp;
1966                                 return ADS_ERROR_KRB5(ret);
1967                         }
1968                 }
1969
1970                 /* We may not be allowed to use the server-supplied SPNEGO principal, or it may not have been supplied to us
1971                  */
1972                 if (!lp_client_use_spnego_principal() || strequal(principal, ADS_IGNORE_PRINCIPAL)) {
1973                         TALLOC_FREE(principal);
1974                 }
1975
1976                 if (principal == NULL &&
1977                         !is_ipaddress(remote_name) &&
1978                         !strequal(STAR_SMBSERVER,
1979                                   remote_name)) {
1980                         DEBUG(3,("cli_session_setup_spnego: using target "
1981                                  "hostname not SPNEGO principal\n"));
1982
1983                         if (dest_realm) {
1984                                 char *realm = strupper_talloc(talloc_tos(), dest_realm);
1985                                 if (realm) {
1986                                         principal = talloc_asprintf(talloc_tos(),
1987                                                                     "cifs/%s@%s",
1988                                                                     remote_name,
1989                                                                     realm);
1990                                         TALLOC_FREE(realm);
1991                                 }
1992                         } else {
1993                                 principal = kerberos_get_principal_from_service_hostname(talloc_tos(),
1994                                                                                          "cifs",
1995                                                                                          remote_name,
1996                                                                                          lp_realm());
1997                         }
1998
1999                         if (!principal) {
2000                                 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
2001                         }
2002                         DEBUG(3,("cli_session_setup_spnego: guessed "
2003                                 "server principal=%s\n",
2004                                 principal ? principal : "<null>"));
2005                 }
2006
2007                 if (principal) {
2008                         rc = cli_session_setup_kerberos(cli, principal);
2009                         if (ADS_ERR_OK(rc) || !cli->fallback_after_kerberos) {
2010                                 TALLOC_FREE(principal);
2011                                 return rc;
2012                         }
2013                 }
2014         }
2015 #endif
2016
2017         TALLOC_FREE(principal);
2018
2019 ntlmssp:
2020
2021         account = talloc_strdup(talloc_tos(), user);
2022         if (!account) {
2023                 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
2024         }
2025
2026         /* when falling back to ntlmssp while authenticating with a machine
2027          * account strip off the realm - gd */
2028
2029         if ((p = strchr_m(user, '@')) != NULL) {
2030                 account[PTR_DIFF(p,user)] = '\0';
2031         }
2032
2033         return ADS_ERROR_NT(cli_session_setup_ntlmssp(cli, account, pass, user_domain));
2034 }
2035
2036 /****************************************************************************
2037  Send a session setup. The username and workgroup is in UNIX character
2038  format and must be converted to DOS codepage format before sending. If the
2039  password is in plaintext, the same should be done.
2040 ****************************************************************************/
2041
2042 NTSTATUS cli_session_setup(struct cli_state *cli,
2043                            const char *user,
2044                            const char *pass, int passlen,
2045                            const char *ntpass, int ntpasslen,
2046                            const char *workgroup)
2047 {
2048         char *p;
2049         char *user2;
2050         uint16_t sec_mode = smb1cli_conn_server_security_mode(cli->conn);
2051
2052         if (user) {
2053                 user2 = talloc_strdup(talloc_tos(), user);
2054         } else {
2055                 user2 = talloc_strdup(talloc_tos(), "");
2056         }
2057         if (user2 == NULL) {
2058                 return NT_STATUS_NO_MEMORY;
2059         }
2060
2061         if (!workgroup) {
2062                 workgroup = "";
2063         }
2064
2065         /* allow for workgroups as part of the username */
2066         if ((p=strchr_m(user2,'\\')) || (p=strchr_m(user2,'/')) ||
2067             (p=strchr_m(user2,*lp_winbind_separator()))) {
2068                 *p = 0;
2069                 user = p+1;
2070                 strupper_m(user2);
2071                 workgroup = user2;
2072         }
2073
2074         if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_LANMAN1) {
2075                 return NT_STATUS_OK;
2076         }
2077
2078         /* now work out what sort of session setup we are going to
2079            do. I have split this into separate functions to make the
2080            flow a bit easier to understand (tridge) */
2081
2082         /* if its an older server then we have to use the older request format */
2083
2084         if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_NT1) {
2085                 if (!lp_client_lanman_auth() && passlen != 24 && (*pass)) {
2086                         DEBUG(1, ("Server requested LM password but 'client lanman auth = no'"
2087                                   " or 'client ntlmv2 auth = yes'\n"));
2088                         return NT_STATUS_ACCESS_DENIED;
2089                 }
2090
2091                 if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0 &&
2092                     !lp_client_plaintext_auth() && (*pass)) {
2093                         DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
2094                                   " or 'client ntlmv2 auth = yes'\n"));
2095                         return NT_STATUS_ACCESS_DENIED;
2096                 }
2097
2098                 return cli_session_setup_lanman2(cli, user, pass, passlen,
2099                                                  workgroup);
2100         }
2101
2102         if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
2103                 const char *remote_realm = cli_state_remote_realm(cli);
2104                 ADS_STATUS status = cli_session_setup_spnego(cli, user, pass,
2105                                                              workgroup,
2106                                                              remote_realm);
2107                 if (!ADS_ERR_OK(status)) {
2108                         DEBUG(3, ("SMB2-SPNEGO login failed: %s\n", ads_errstr(status)));
2109                         return ads_ntstatus(status);
2110                 }
2111                 return NT_STATUS_OK;
2112         }
2113
2114         /* if no user is supplied then we have to do an anonymous connection.
2115            passwords are ignored */
2116
2117         if (!user || !*user)
2118                 return cli_session_setup_guest(cli);
2119
2120         /* if the server is share level then send a plaintext null
2121            password at this point. The password is sent in the tree
2122            connect */
2123
2124         if ((sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0)
2125                 return cli_session_setup_plain(cli, user, "", workgroup);
2126
2127         /* if the server doesn't support encryption then we have to use 
2128            plaintext. The second password is ignored */
2129
2130         if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) {
2131                 if (!lp_client_plaintext_auth() && (*pass)) {
2132                         DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
2133                                   " or 'client ntlmv2 auth = yes'\n"));
2134                         return NT_STATUS_ACCESS_DENIED;
2135                 }
2136                 return cli_session_setup_plain(cli, user, pass, workgroup);
2137         }
2138
2139         /* if the server supports extended security then use SPNEGO */
2140
2141         if (smb1cli_conn_capabilities(cli->conn) & CAP_EXTENDED_SECURITY) {
2142                 const char *remote_realm = cli_state_remote_realm(cli);
2143                 ADS_STATUS status = cli_session_setup_spnego(cli, user, pass,
2144                                                              workgroup,
2145                                                              remote_realm);
2146                 if (!ADS_ERR_OK(status)) {
2147                         DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status)));
2148                         return ads_ntstatus(status);
2149                 }
2150         } else {
2151                 NTSTATUS status;
2152
2153                 /* otherwise do a NT1 style session setup */
2154                 status = cli_session_setup_nt1(cli, user, pass, passlen,
2155                                                ntpass, ntpasslen, workgroup);
2156                 if (!NT_STATUS_IS_OK(status)) {
2157                         DEBUG(3,("cli_session_setup: NT1 session setup "
2158                                  "failed: %s\n", nt_errstr(status)));
2159                         return status;
2160                 }
2161         }
2162
2163         return NT_STATUS_OK;
2164 }
2165
2166 /****************************************************************************
2167  Send a uloggoff.
2168 *****************************************************************************/
2169
2170 struct cli_ulogoff_state {
2171         struct cli_state *cli;
2172         uint16_t vwv[3];
2173 };
2174
2175 static void cli_ulogoff_done(struct tevent_req *subreq);
2176
2177 struct tevent_req *cli_ulogoff_send(TALLOC_CTX *mem_ctx,
2178                                     struct tevent_context *ev,
2179                                     struct cli_state *cli)
2180 {
2181         struct tevent_req *req, *subreq;
2182         struct cli_ulogoff_state *state;
2183
2184         req = tevent_req_create(mem_ctx, &state, struct cli_ulogoff_state);
2185         if (req == NULL) {
2186                 return NULL;
2187         }
2188         state->cli = cli;
2189
2190         SCVAL(state->vwv+0, 0, 0xFF);
2191         SCVAL(state->vwv+1, 0, 0);
2192         SSVAL(state->vwv+2, 0, 0);
2193
2194         subreq = cli_smb_send(state, ev, cli, SMBulogoffX, 0, 2, state->vwv,
2195                               0, NULL);
2196         if (tevent_req_nomem(subreq, req)) {
2197                 return tevent_req_post(req, ev);
2198         }
2199         tevent_req_set_callback(subreq, cli_ulogoff_done, req);
2200         return req;
2201 }
2202
2203 static void cli_ulogoff_done(struct tevent_req *subreq)
2204 {
2205         struct tevent_req *req = tevent_req_callback_data(
2206                 subreq, struct tevent_req);
2207         struct cli_ulogoff_state *state = tevent_req_data(
2208                 req, struct cli_ulogoff_state);
2209         NTSTATUS status;
2210
2211         status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
2212         if (!NT_STATUS_IS_OK(status)) {
2213                 tevent_req_nterror(req, status);
2214                 return;
2215         }
2216         cli_state_set_uid(state->cli, UID_FIELD_INVALID);
2217         tevent_req_done(req);
2218 }
2219
2220 NTSTATUS cli_ulogoff_recv(struct tevent_req *req)
2221 {
2222         return tevent_req_simple_recv_ntstatus(req);
2223 }
2224
2225 NTSTATUS cli_ulogoff(struct cli_state *cli)
2226 {
2227         struct tevent_context *ev;
2228         struct tevent_req *req;
2229         NTSTATUS status = NT_STATUS_NO_MEMORY;
2230
2231         if (smbXcli_conn_has_async_calls(cli->conn)) {
2232                 return NT_STATUS_INVALID_PARAMETER;
2233         }
2234         ev = tevent_context_init(talloc_tos());
2235         if (ev == NULL) {
2236                 goto fail;
2237         }
2238         req = cli_ulogoff_send(ev, ev, cli);
2239         if (req == NULL) {
2240                 goto fail;
2241         }
2242         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2243                 goto fail;
2244         }
2245         status = cli_ulogoff_recv(req);
2246 fail:
2247         TALLOC_FREE(ev);
2248         return status;
2249 }
2250
2251 /****************************************************************************
2252  Send a tconX.
2253 ****************************************************************************/
2254
2255 struct cli_tcon_andx_state {
2256         struct cli_state *cli;
2257         uint16_t vwv[4];
2258         struct iovec bytes;
2259 };
2260
2261 static void cli_tcon_andx_done(struct tevent_req *subreq);
2262
2263 struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx,
2264                                         struct event_context *ev,
2265                                         struct cli_state *cli,
2266                                         const char *share, const char *dev,
2267                                         const char *pass, int passlen,
2268                                         struct tevent_req **psmbreq)
2269 {
2270         struct tevent_req *req, *subreq;
2271         struct cli_tcon_andx_state *state;
2272         uint8_t p24[24];
2273         uint16_t *vwv;
2274         char *tmp = NULL;
2275         uint8_t *bytes;
2276         uint16_t sec_mode = smb1cli_conn_server_security_mode(cli->conn);
2277
2278         *psmbreq = NULL;
2279
2280         req = tevent_req_create(mem_ctx, &state, struct cli_tcon_andx_state);
2281         if (req == NULL) {
2282                 return NULL;
2283         }
2284         state->cli = cli;
2285         vwv = state->vwv;
2286
2287         cli->share = talloc_strdup(cli, share);
2288         if (!cli->share) {
2289                 return NULL;
2290         }
2291
2292         /* in user level security don't send a password now */
2293         if (sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {
2294                 passlen = 1;
2295                 pass = "";
2296         } else if (pass == NULL) {
2297                 DEBUG(1, ("Server not using user level security and no "
2298                           "password supplied.\n"));
2299                 goto access_denied;
2300         }
2301
2302         if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) &&
2303             *pass && passlen != 24) {
2304                 if (!lp_client_lanman_auth()) {
2305                         DEBUG(1, ("Server requested LANMAN password "
2306                                   "(share-level security) but "
2307                                   "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2308                         goto access_denied;
2309                 }
2310
2311                 /*
2312                  * Non-encrypted passwords - convert to DOS codepage before
2313                  * encryption.
2314                  */
2315                 SMBencrypt(pass, smb1cli_conn_server_challenge(cli->conn), p24);
2316                 passlen = 24;
2317                 pass = (const char *)p24;
2318         } else {
2319                 if((sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL
2320                                      |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE))
2321                    == 0) {
2322                         uint8_t *tmp_pass;
2323
2324                         if (!lp_client_plaintext_auth() && (*pass)) {
2325                                 DEBUG(1, ("Server requested PLAINTEXT "
2326                                           "password but "
2327                                           "'client plaintext auth = no' or 'client ntlmv2 auth = yes'\n"));
2328                                 goto access_denied;
2329                         }
2330
2331                         /*
2332                          * Non-encrypted passwords - convert to DOS codepage
2333                          * before using.
2334                          */
2335                         tmp_pass = talloc_array(talloc_tos(), uint8, 0);
2336                         if (tevent_req_nomem(tmp_pass, req)) {
2337                                 return tevent_req_post(req, ev);
2338                         }
2339                         tmp_pass = trans2_bytes_push_str(tmp_pass,
2340                                                          false, /* always DOS */
2341                                                          pass,
2342                                                          passlen,
2343                                                          NULL);
2344                         if (tevent_req_nomem(tmp_pass, req)) {
2345                                 return tevent_req_post(req, ev);
2346                         }
2347                         pass = (const char *)tmp_pass;
2348                         passlen = talloc_get_size(tmp_pass);
2349                 }
2350         }
2351
2352         SCVAL(vwv+0, 0, 0xFF);
2353         SCVAL(vwv+0, 1, 0);
2354         SSVAL(vwv+1, 0, 0);
2355         SSVAL(vwv+2, 0, TCONX_FLAG_EXTENDED_RESPONSE);
2356         SSVAL(vwv+3, 0, passlen);
2357
2358         if (passlen && pass) {
2359                 bytes = (uint8_t *)talloc_memdup(state, pass, passlen);
2360         } else {
2361                 bytes = talloc_array(state, uint8_t, 0);
2362         }
2363
2364         /*
2365          * Add the sharename
2366          */
2367         tmp = talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
2368                                          smbXcli_conn_remote_name(cli->conn), share);
2369         if (tmp == NULL) {
2370                 TALLOC_FREE(req);
2371                 return NULL;
2372         }
2373         bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), tmp, strlen(tmp)+1,
2374                                    NULL);
2375         TALLOC_FREE(tmp);
2376
2377         /*
2378          * Add the devicetype
2379          */
2380         tmp = talloc_strdup_upper(talloc_tos(), dev);
2381         if (tmp == NULL) {
2382                 TALLOC_FREE(req);
2383                 return NULL;
2384         }
2385         bytes = smb_bytes_push_str(bytes, false, tmp, strlen(tmp)+1, NULL);
2386         TALLOC_FREE(tmp);
2387
2388         if (bytes == NULL) {
2389                 TALLOC_FREE(req);
2390                 return NULL;
2391         }
2392
2393         state->bytes.iov_base = (void *)bytes;
2394         state->bytes.iov_len = talloc_get_size(bytes);
2395
2396         subreq = cli_smb_req_create(state, ev, cli, SMBtconX, 0, 4, vwv,
2397                                     1, &state->bytes);
2398         if (subreq == NULL) {
2399                 TALLOC_FREE(req);
2400                 return NULL;
2401         }
2402         tevent_req_set_callback(subreq, cli_tcon_andx_done, req);
2403         *psmbreq = subreq;
2404         return req;
2405
2406  access_denied:
2407         tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
2408         return tevent_req_post(req, ev);
2409 }
2410
2411 struct tevent_req *cli_tcon_andx_send(TALLOC_CTX *mem_ctx,
2412                                       struct event_context *ev,
2413                                       struct cli_state *cli,
2414                                       const char *share, const char *dev,
2415                                       const char *pass, int passlen)
2416 {
2417         struct tevent_req *req, *subreq;
2418         NTSTATUS status;
2419
2420         req = cli_tcon_andx_create(mem_ctx, ev, cli, share, dev, pass, passlen,
2421                                    &subreq);
2422         if (req == NULL) {
2423                 return NULL;
2424         }
2425         if (subreq == NULL) {
2426                 return req;
2427         }
2428         status = smb1cli_req_chain_submit(&subreq, 1);
2429         if (!NT_STATUS_IS_OK(status)) {
2430                 tevent_req_nterror(req, status);
2431                 return tevent_req_post(req, ev);
2432         }
2433         return req;
2434 }
2435
2436 static void cli_tcon_andx_done(struct tevent_req *subreq)
2437 {
2438         struct tevent_req *req = tevent_req_callback_data(
2439                 subreq, struct tevent_req);
2440         struct cli_tcon_andx_state *state = tevent_req_data(
2441                 req, struct cli_tcon_andx_state);
2442         struct cli_state *cli = state->cli;
2443         uint8_t *in;
2444         uint8_t *inhdr;
2445         uint8_t wct;
2446         uint16_t *vwv;
2447         uint32_t num_bytes;
2448         uint8_t *bytes;
2449         NTSTATUS status;
2450
2451         status = cli_smb_recv(subreq, state, &in, 0, &wct, &vwv,
2452                               &num_bytes, &bytes);
2453         TALLOC_FREE(subreq);
2454         if (!NT_STATUS_IS_OK(status)) {
2455                 tevent_req_nterror(req, status);
2456                 return;
2457         }
2458
2459         inhdr = in + NBT_HDR_SIZE;
2460
2461         if (num_bytes) {
2462                 if (clistr_pull_talloc(cli,
2463                                 (const char *)inhdr,
2464                                 SVAL(inhdr, HDR_FLG2),
2465                                 &cli->dev,
2466                                 bytes,
2467                                 num_bytes,
2468                                 STR_TERMINATE|STR_ASCII) == -1) {
2469                         tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2470                         return;
2471                 }
2472         } else {
2473                 cli->dev = talloc_strdup(cli, "");
2474                 if (cli->dev == NULL) {
2475                         tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2476                         return;
2477                 }
2478         }
2479
2480         if ((smbXcli_conn_protocol(cli->conn) >= PROTOCOL_NT1) && (num_bytes == 3)) {
2481                 /* almost certainly win95 - enable bug fixes */
2482                 cli->win95 = True;
2483         }
2484
2485         /*
2486          * Make sure that we have the optional support 16-bit field. WCT > 2.
2487          * Avoids issues when connecting to Win9x boxes sharing files
2488          */
2489
2490         cli->dfsroot = false;
2491
2492         if ((wct > 2) && (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_LANMAN2)) {
2493                 cli->dfsroot = ((SVAL(vwv+2, 0) & SMB_SHARE_IN_DFS) != 0);
2494         }
2495
2496         cli_state_set_tid(cli, SVAL(inhdr, HDR_TID));
2497         tevent_req_done(req);
2498 }
2499
2500 NTSTATUS cli_tcon_andx_recv(struct tevent_req *req)
2501 {
2502         return tevent_req_simple_recv_ntstatus(req);
2503 }
2504
2505 NTSTATUS cli_tcon_andx(struct cli_state *cli, const char *share,
2506                        const char *dev, const char *pass, int passlen)
2507 {
2508         TALLOC_CTX *frame = talloc_stackframe();
2509         struct event_context *ev;
2510         struct tevent_req *req;
2511         NTSTATUS status = NT_STATUS_OK;
2512
2513         if (smbXcli_conn_has_async_calls(cli->conn)) {
2514                 /*
2515                  * Can't use sync call while an async call is in flight
2516                  */
2517                 status = NT_STATUS_INVALID_PARAMETER;
2518                 goto fail;
2519         }
2520
2521         ev = event_context_init(frame);
2522         if (ev == NULL) {
2523                 status = NT_STATUS_NO_MEMORY;
2524                 goto fail;
2525         }
2526
2527         req = cli_tcon_andx_send(frame, ev, cli, share, dev, pass, passlen);
2528         if (req == NULL) {
2529                 status = NT_STATUS_NO_MEMORY;
2530                 goto fail;
2531         }
2532
2533         if (!tevent_req_poll(req, ev)) {
2534                 status = map_nt_error_from_unix(errno);
2535                 goto fail;
2536         }
2537
2538         status = cli_tcon_andx_recv(req);
2539  fail:
2540         TALLOC_FREE(frame);
2541         return status;
2542 }
2543
2544 NTSTATUS cli_tree_connect(struct cli_state *cli, const char *share,
2545                           const char *dev, const char *pass, int passlen)
2546 {
2547         NTSTATUS status;
2548         uint16_t max_xmit = 0;
2549         uint16_t tid = 0;
2550
2551         cli->share = talloc_strdup(cli, share);
2552         if (!cli->share) {
2553                 return NT_STATUS_NO_MEMORY;
2554         }
2555
2556         if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
2557                 return smb2cli_tcon(cli, share);
2558         }
2559
2560         if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_LANMAN1) {
2561                 return cli_tcon_andx(cli, share, dev, pass, passlen);
2562         }
2563
2564         status = cli_raw_tcon(cli, share, pass, dev, &max_xmit, &tid);
2565         if (!NT_STATUS_IS_OK(status)) {
2566                 return status;
2567         }
2568
2569         cli_state_set_tid(cli, tid);
2570
2571         return NT_STATUS_OK;
2572 }
2573
2574 /****************************************************************************
2575  Send a tree disconnect.
2576 ****************************************************************************/
2577
2578 struct cli_tdis_state {
2579         struct cli_state *cli;
2580 };
2581
2582 static void cli_tdis_done(struct tevent_req *subreq);
2583
2584 struct tevent_req *cli_tdis_send(TALLOC_CTX *mem_ctx,
2585                                  struct tevent_context *ev,
2586                                  struct cli_state *cli)
2587 {
2588         struct tevent_req *req, *subreq;
2589         struct cli_tdis_state *state;
2590
2591         req = tevent_req_create(mem_ctx, &state, struct cli_tdis_state);
2592         if (req == NULL) {
2593                 return NULL;
2594         }
2595         state->cli = cli;
2596
2597         subreq = cli_smb_send(state, ev, cli, SMBtdis, 0, 0, NULL, 0, NULL);
2598         if (tevent_req_nomem(subreq, req)) {
2599                 return tevent_req_post(req, ev);
2600         }
2601         tevent_req_set_callback(subreq, cli_tdis_done, req);
2602         return req;
2603 }
2604
2605 static void cli_tdis_done(struct tevent_req *subreq)
2606 {
2607         struct tevent_req *req = tevent_req_callback_data(
2608                 subreq, struct tevent_req);
2609         struct cli_tdis_state *state = tevent_req_data(
2610                 req, struct cli_tdis_state);
2611         NTSTATUS status;
2612
2613         status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
2614         TALLOC_FREE(subreq);
2615         if (!NT_STATUS_IS_OK(status)) {
2616                 tevent_req_nterror(req, status);
2617                 return;
2618         }
2619         cli_state_set_tid(state->cli, UINT16_MAX);
2620         tevent_req_done(req);
2621 }
2622
2623 NTSTATUS cli_tdis_recv(struct tevent_req *req)
2624 {
2625         return tevent_req_simple_recv_ntstatus(req);
2626 }
2627
2628 NTSTATUS cli_tdis(struct cli_state *cli)
2629 {
2630         struct tevent_context *ev;
2631         struct tevent_req *req;
2632         NTSTATUS status = NT_STATUS_NO_MEMORY;
2633
2634         if (smbXcli_conn_has_async_calls(cli->conn)) {
2635                 return NT_STATUS_INVALID_PARAMETER;
2636         }
2637         ev = tevent_context_init(talloc_tos());
2638         if (ev == NULL) {
2639                 goto fail;
2640         }
2641         req = cli_tdis_send(ev, ev, cli);
2642         if (req == NULL) {
2643                 goto fail;
2644         }
2645         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2646                 goto fail;
2647         }
2648         status = cli_tdis_recv(req);
2649 fail:
2650         TALLOC_FREE(ev);
2651         return status;
2652 }
2653
2654 static NTSTATUS cli_connect_sock(const char *host, int name_type,
2655                                  const struct sockaddr_storage *pss,
2656                                  const char *myname, uint16_t port,
2657                                  int sec_timeout, int *pfd, uint16_t *pport)
2658 {
2659         TALLOC_CTX *frame = talloc_stackframe();
2660         const char *prog;
2661         unsigned int i, num_addrs;
2662         const char **called_names;
2663         const char **calling_names;
2664         int *called_types;
2665         NTSTATUS status;
2666         int fd;
2667
2668         prog = getenv("LIBSMB_PROG");
2669         if (prog != NULL) {
2670                 fd = sock_exec(prog);
2671                 if (fd == -1) {
2672                         return map_nt_error_from_unix(errno);
2673                 }
2674                 port = 0;
2675                 goto done;
2676         }
2677
2678         if ((pss == NULL) || is_zero_addr(pss)) {
2679                 struct sockaddr_storage *addrs;
2680                 status = resolve_name_list(talloc_tos(), host, name_type,
2681                                            &addrs, &num_addrs);
2682                 if (!NT_STATUS_IS_OK(status)) {
2683                         goto fail;
2684                 }
2685                 pss = addrs;
2686         } else {
2687                 num_addrs = 1;
2688         }
2689
2690         called_names = talloc_array(talloc_tos(), const char *, num_addrs);
2691         if (called_names == NULL) {
2692                 status = NT_STATUS_NO_MEMORY;
2693                 goto fail;
2694         }
2695         called_types = talloc_array(talloc_tos(), int, num_addrs);
2696         if (called_types == NULL) {
2697                 status = NT_STATUS_NO_MEMORY;
2698                 goto fail;
2699         }
2700         calling_names = talloc_array(talloc_tos(), const char *, num_addrs);
2701         if (calling_names == NULL) {
2702                 status = NT_STATUS_NO_MEMORY;
2703                 goto fail;
2704         }
2705         for (i=0; i<num_addrs; i++) {
2706                 called_names[i] = host;
2707                 called_types[i] = name_type;
2708                 calling_names[i] = myname;
2709         }
2710         status = smbsock_any_connect(pss, called_names, called_types,
2711                                      calling_names, NULL, num_addrs, port,
2712                                      sec_timeout, &fd, NULL, &port);
2713         if (!NT_STATUS_IS_OK(status)) {
2714                 goto fail;
2715         }
2716         set_socket_options(fd, lp_socket_options());
2717 done:
2718         *pfd = fd;
2719         *pport = port;
2720         status = NT_STATUS_OK;
2721 fail:
2722         TALLOC_FREE(frame);
2723         return status;
2724 }
2725
2726 NTSTATUS cli_connect_nb(const char *host, const struct sockaddr_storage *dest_ss,
2727                         uint16_t port, int name_type, const char *myname,
2728                         int signing_state, int flags, struct cli_state **pcli)
2729 {
2730         TALLOC_CTX *frame = talloc_stackframe();
2731         struct cli_state *cli;
2732         NTSTATUS status = NT_STATUS_NO_MEMORY;
2733         int fd = -1;
2734         char *desthost;
2735         char *p;
2736
2737         desthost = talloc_strdup(talloc_tos(), host);
2738         if (desthost == NULL) {
2739                 goto fail;
2740         }
2741
2742         p = strchr(host, '#');
2743         if (p != NULL) {
2744                 name_type = strtol(p+1, NULL, 16);
2745                 host = talloc_strndup(talloc_tos(), host, p - host);
2746                 if (host == NULL) {
2747                         goto fail;
2748                 }
2749         }
2750
2751         status = cli_connect_sock(host, name_type, dest_ss, myname, port,
2752                                   20, &fd, &port);
2753         if (!NT_STATUS_IS_OK(status)) {
2754                 goto fail;
2755         }
2756
2757         cli = cli_state_create(NULL, fd, desthost, NULL, signing_state, flags);
2758         if (cli == NULL) {
2759                 close(fd);
2760                 fd = -1;
2761                 goto fail;
2762         }
2763
2764         *pcli = cli;
2765         status = NT_STATUS_OK;
2766 fail:
2767         TALLOC_FREE(frame);
2768         return status;
2769 }
2770
2771 /**
2772    establishes a connection to after the negprot. 
2773    @param output_cli A fully initialised cli structure, non-null only on success
2774    @param dest_host The netbios name of the remote host
2775    @param dest_ss (optional) The the destination IP, NULL for name based lookup
2776    @param port (optional) The destination port (0 for default)
2777 */
2778 NTSTATUS cli_start_connection(struct cli_state **output_cli, 
2779                               const char *my_name, 
2780                               const char *dest_host, 
2781                               const struct sockaddr_storage *dest_ss, int port,
2782                               int signing_state, int flags)
2783 {
2784         NTSTATUS nt_status;
2785         struct cli_state *cli;
2786
2787         nt_status = cli_connect_nb(dest_host, dest_ss, port, 0x20, my_name,
2788                                    signing_state, flags, &cli);
2789         if (!NT_STATUS_IS_OK(nt_status)) {
2790                 DEBUG(10, ("cli_connect_nb failed: %s\n",
2791                            nt_errstr(nt_status)));
2792                 return nt_status;
2793         }
2794
2795         nt_status = smbXcli_negprot(cli->conn, cli->timeout, PROTOCOL_CORE,
2796                                     PROTOCOL_NT1);
2797         if (!NT_STATUS_IS_OK(nt_status)) {
2798                 DEBUG(1, ("failed negprot: %s\n", nt_errstr(nt_status)));
2799                 cli_shutdown(cli);
2800                 return nt_status;
2801         }
2802
2803         *output_cli = cli;
2804         return NT_STATUS_OK;
2805 }
2806
2807
2808 /**
2809    establishes a connection right up to doing tconX, password specified.
2810    @param output_cli A fully initialised cli structure, non-null only on success
2811    @param dest_host The netbios name of the remote host
2812    @param dest_ip (optional) The the destination IP, NULL for name based lookup
2813    @param port (optional) The destination port (0 for default)
2814    @param service (optional) The share to make the connection to.  Should be 'unqualified' in any way.
2815    @param service_type The 'type' of serivice. 
2816    @param user Username, unix string
2817    @param domain User's domain
2818    @param password User's password, unencrypted unix string.
2819 */
2820
2821 NTSTATUS cli_full_connection(struct cli_state **output_cli, 
2822                              const char *my_name, 
2823                              const char *dest_host, 
2824                              const struct sockaddr_storage *dest_ss, int port,
2825                              const char *service, const char *service_type,
2826                              const char *user, const char *domain, 
2827                              const char *password, int flags,
2828                              int signing_state)
2829 {
2830         NTSTATUS nt_status;
2831         struct cli_state *cli = NULL;
2832         int pw_len = password ? strlen(password)+1 : 0;
2833
2834         *output_cli = NULL;
2835
2836         if (password == NULL) {
2837                 password = "";
2838         }
2839
2840         nt_status = cli_start_connection(&cli, my_name, dest_host,
2841                                          dest_ss, port, signing_state,
2842                                          flags);
2843
2844         if (!NT_STATUS_IS_OK(nt_status)) {
2845                 return nt_status;
2846         }
2847
2848         nt_status = cli_session_setup(cli, user, password, pw_len, password,
2849                                       pw_len, domain);
2850         if (!NT_STATUS_IS_OK(nt_status)) {
2851
2852                 if (!(flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)) {
2853                         DEBUG(1,("failed session setup with %s\n",
2854                                  nt_errstr(nt_status)));
2855                         cli_shutdown(cli);
2856                         return nt_status;
2857                 }
2858
2859                 nt_status = cli_session_setup(cli, "", "", 0, "", 0, domain);
2860                 if (!NT_STATUS_IS_OK(nt_status)) {
2861                         DEBUG(1,("anonymous failed session setup with %s\n",
2862                                  nt_errstr(nt_status)));
2863                         cli_shutdown(cli);
2864                         return nt_status;
2865                 }
2866         }
2867
2868         if (service) {
2869                 nt_status = cli_tree_connect(cli, service, service_type,
2870                                              password, pw_len);
2871                 if (!NT_STATUS_IS_OK(nt_status)) {
2872                         DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status)));
2873                         cli_shutdown(cli);
2874                         if (NT_STATUS_IS_OK(nt_status)) {
2875                                 nt_status = NT_STATUS_UNSUCCESSFUL;
2876                         }
2877                         return nt_status;
2878                 }
2879         }
2880
2881         nt_status = cli_init_creds(cli, user, domain, password);
2882         if (!NT_STATUS_IS_OK(nt_status)) {
2883                 cli_shutdown(cli);
2884                 return nt_status;
2885         }
2886
2887         *output_cli = cli;
2888         return NT_STATUS_OK;
2889 }
2890
2891 /****************************************************************************
2892  Send an old style tcon.
2893 ****************************************************************************/
2894 NTSTATUS cli_raw_tcon(struct cli_state *cli, 
2895                       const char *service, const char *pass, const char *dev,
2896                       uint16 *max_xmit, uint16 *tid)
2897 {
2898         struct tevent_req *req;
2899         uint16_t *ret_vwv;
2900         uint8_t *bytes;
2901         NTSTATUS status;
2902
2903         if (!lp_client_plaintext_auth() && (*pass)) {
2904                 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
2905                           " or 'client ntlmv2 auth = yes'\n"));
2906                 return NT_STATUS_ACCESS_DENIED;
2907         }
2908
2909         bytes = talloc_array(talloc_tos(), uint8_t, 0);
2910         bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
2911         bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
2912                                    service, strlen(service)+1, NULL);
2913         bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
2914         bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
2915                                    pass, strlen(pass)+1, NULL);
2916         bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
2917         bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
2918                                    dev, strlen(dev)+1, NULL);
2919
2920         status = cli_smb(talloc_tos(), cli, SMBtcon, 0, 0, NULL,
2921                          talloc_get_size(bytes), bytes, &req,
2922                          2, NULL, &ret_vwv, NULL, NULL);
2923         if (!NT_STATUS_IS_OK(status)) {
2924                 return status;
2925         }
2926
2927         *max_xmit = SVAL(ret_vwv + 0, 0);
2928         *tid = SVAL(ret_vwv + 1, 0);
2929
2930         return NT_STATUS_OK;
2931 }
2932
2933 /* Return a cli_state pointing at the IPC$ share for the given server */
2934
2935 struct cli_state *get_ipc_connect(char *server,
2936                                 struct sockaddr_storage *server_ss,
2937                                 const struct user_auth_info *user_info)
2938 {
2939         struct cli_state *cli;
2940         NTSTATUS nt_status;
2941         uint32_t flags = CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
2942
2943         if (user_info->use_kerberos) {
2944                 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
2945         }
2946
2947         nt_status = cli_full_connection(&cli, NULL, server, server_ss, 0, "IPC$", "IPC", 
2948                                         user_info->username ? user_info->username : "",
2949                                         lp_workgroup(),
2950                                         user_info->password ? user_info->password : "",
2951                                         flags,
2952                                         SMB_SIGNING_DEFAULT);
2953
2954         if (NT_STATUS_IS_OK(nt_status)) {
2955                 return cli;
2956         } else if (is_ipaddress(server)) {
2957             /* windows 9* needs a correct NMB name for connections */
2958             fstring remote_name;
2959
2960             if (name_status_find("*", 0, 0, server_ss, remote_name)) {
2961                 cli = get_ipc_connect(remote_name, server_ss, user_info);
2962                 if (cli)
2963                     return cli;
2964             }
2965         }
2966         return NULL;
2967 }
2968
2969 /*
2970  * Given the IP address of a master browser on the network, return its
2971  * workgroup and connect to it.
2972  *
2973  * This function is provided to allow additional processing beyond what
2974  * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
2975  * browsers and obtain each master browsers' list of domains (in case the
2976  * first master browser is recently on the network and has not yet
2977  * synchronized with other master browsers and therefore does not yet have the
2978  * entire network browse list)
2979  */
2980
2981 struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx,
2982                                 struct sockaddr_storage *mb_ip,
2983                                 const struct user_auth_info *user_info,
2984                                 char **pp_workgroup_out)
2985 {
2986         char addr[INET6_ADDRSTRLEN];
2987         fstring name;
2988         struct cli_state *cli;
2989         struct sockaddr_storage server_ss;
2990
2991         *pp_workgroup_out = NULL;
2992
2993         print_sockaddr(addr, sizeof(addr), mb_ip);
2994         DEBUG(99, ("Looking up name of master browser %s\n",
2995                    addr));
2996
2997         /*
2998          * Do a name status query to find out the name of the master browser.
2999          * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
3000          * master browser will not respond to a wildcard query (or, at least,
3001          * an NT4 server acting as the domain master browser will not).
3002          *
3003          * We might be able to use ONLY the query on MSBROWSE, but that's not
3004          * yet been tested with all Windows versions, so until it is, leave
3005          * the original wildcard query as the first choice and fall back to
3006          * MSBROWSE if the wildcard query fails.
3007          */
3008         if (!name_status_find("*", 0, 0x1d, mb_ip, name) &&
3009             !name_status_find(MSBROWSE, 1, 0x1d, mb_ip, name)) {
3010
3011                 DEBUG(99, ("Could not retrieve name status for %s\n",
3012                            addr));
3013                 return NULL;
3014         }
3015
3016         if (!find_master_ip(name, &server_ss)) {
3017                 DEBUG(99, ("Could not find master ip for %s\n", name));
3018                 return NULL;
3019         }
3020
3021         *pp_workgroup_out = talloc_strdup(ctx, name);
3022
3023         DEBUG(4, ("found master browser %s, %s\n", name, addr));
3024
3025         print_sockaddr(addr, sizeof(addr), &server_ss);
3026         cli = get_ipc_connect(addr, &server_ss, user_info);
3027
3028         return cli;
3029 }
3030
3031 /*
3032  * Return the IP address and workgroup of a master browser on the network, and
3033  * connect to it.
3034  */
3035
3036 struct cli_state *get_ipc_connect_master_ip_bcast(TALLOC_CTX *ctx,
3037                                         const struct user_auth_info *user_info,
3038                                         char **pp_workgroup_out)
3039 {
3040         struct sockaddr_storage *ip_list;
3041         struct cli_state *cli;
3042         int i, count;
3043         NTSTATUS status;
3044
3045         *pp_workgroup_out = NULL;
3046
3047         DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
3048
3049         /* Go looking for workgroups by broadcasting on the local network */
3050
3051         status = name_resolve_bcast(MSBROWSE, 1, talloc_tos(),
3052                                     &ip_list, &count);
3053         if (!NT_STATUS_IS_OK(status)) {
3054                 DEBUG(99, ("No master browsers responded: %s\n",
3055                            nt_errstr(status)));
3056                 return NULL;
3057         }
3058
3059         for (i = 0; i < count; i++) {
3060                 char addr[INET6_ADDRSTRLEN];
3061                 print_sockaddr(addr, sizeof(addr), &ip_list[i]);
3062                 DEBUG(99, ("Found master browser %s\n", addr));
3063
3064                 cli = get_ipc_connect_master_ip(ctx, &ip_list[i],
3065                                 user_info, pp_workgroup_out);
3066                 if (cli)
3067                         return(cli);
3068         }
3069
3070         return NULL;
3071 }