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