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