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