libsmbclient: Remove unused cli_session_setup_ntlmssp()
[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 #ifdef HAVE_KRB5
1833
1834 static char *cli_session_setup_get_principal(
1835         TALLOC_CTX *mem_ctx, const char *spnego_principal,
1836         const char *remote_name, const char *dest_realm)
1837 {
1838         char *principal = NULL;
1839
1840         if (!lp_client_use_spnego_principal() ||
1841             strequal(principal, ADS_IGNORE_PRINCIPAL)) {
1842                 spnego_principal = NULL;
1843         }
1844         if (spnego_principal != NULL) {
1845                 DEBUG(3, ("cli_session_setup_spnego: using spnego provided "
1846                           "principal %s\n", spnego_principal));
1847                 return talloc_strdup(mem_ctx, spnego_principal);
1848         }
1849         if (is_ipaddress(remote_name) ||
1850             strequal(remote_name, STAR_SMBSERVER)) {
1851                 return NULL;
1852         }
1853
1854         DEBUG(3, ("cli_session_setup_spnego: using target "
1855                   "hostname not SPNEGO principal\n"));
1856
1857         if (dest_realm) {
1858                 char *realm = strupper_talloc(talloc_tos(), dest_realm);
1859                 if (realm == NULL) {
1860                         return NULL;
1861                 }
1862                 principal = talloc_asprintf(talloc_tos(), "cifs/%s@%s",
1863                                             remote_name, realm);
1864                 TALLOC_FREE(realm);
1865         } else {
1866                 principal = kerberos_get_principal_from_service_hostname(
1867                         talloc_tos(), "cifs", remote_name, lp_realm());
1868         }
1869         DEBUG(3, ("cli_session_setup_spnego: guessed server principal=%s\n",
1870                   principal ? principal : "<null>"));
1871
1872         return principal;
1873 }
1874 #endif
1875
1876 static char *cli_session_setup_get_account(TALLOC_CTX *mem_ctx,
1877                                            const char *principal)
1878 {
1879         char *account, *p;
1880
1881         account = talloc_strdup(mem_ctx, principal);
1882         if (account == NULL) {
1883                 return NULL;
1884         }
1885         p = strchr_m(account, '@');
1886         if (p != NULL) {
1887                 *p = '\0';
1888         }
1889         return account;
1890 }
1891
1892 /****************************************************************************
1893  Do a spnego encrypted session setup.
1894
1895  user_domain: The shortname of the domain the user/machine is a member of.
1896  dest_realm: The realm we're connecting to, if NULL we use our default realm.
1897 ****************************************************************************/
1898
1899 struct cli_session_setup_spnego_state {
1900         struct tevent_context *ev;
1901         struct cli_state *cli;
1902         const char *user;
1903         const char *account;
1904         const char *pass;
1905         const char *user_domain;
1906         const char *dest_realm;
1907         ADS_STATUS result;
1908 };
1909
1910 #ifdef HAVE_KRB5
1911 static void cli_session_setup_spnego_done_krb(struct tevent_req *subreq);
1912 #endif
1913
1914 static void cli_session_setup_spnego_done_ntlmssp(struct tevent_req *subreq);
1915
1916 static struct tevent_req *cli_session_setup_spnego_send(
1917         TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
1918         const char *user, const char *pass, const char *user_domain,
1919         const char *dest_realm)
1920 {
1921         struct tevent_req *req, *subreq;
1922         struct cli_session_setup_spnego_state *state;
1923         char *principal = NULL;
1924         char *OIDs[ASN1_MAX_OIDS];
1925         int i;
1926         const DATA_BLOB *server_blob;
1927         NTSTATUS status;
1928
1929         req = tevent_req_create(mem_ctx, &state,
1930                                 struct cli_session_setup_spnego_state);
1931         if (req == NULL) {
1932                 return NULL;
1933         }
1934         state->ev = ev;
1935         state->cli = cli;
1936         state->user = user;
1937         state->pass = pass;
1938         state->user_domain = user_domain;
1939         state->dest_realm = dest_realm;
1940
1941         state->account = cli_session_setup_get_account(state, user);
1942         if (tevent_req_nomem(state->account, req)) {
1943                 return tevent_req_post(req, ev);
1944         }
1945
1946         server_blob = smbXcli_conn_server_gss_blob(cli->conn);
1947
1948         DEBUG(3,("Doing spnego session setup (blob length=%lu)\n",
1949                  (unsigned long)server_blob->length));
1950
1951         /* the server might not even do spnego */
1952         if (server_blob->length == 0) {
1953                 DEBUG(3,("server didn't supply a full spnego negprot\n"));
1954                 goto ntlmssp;
1955         }
1956
1957 #if 0
1958         file_save("negprot.dat", cli->secblob.data, cli->secblob.length);
1959 #endif
1960
1961         /* The server sent us the first part of the SPNEGO exchange in the
1962          * negprot reply. It is WRONG to depend on the principal sent in the
1963          * negprot reply, but right now we do it. If we don't receive one,
1964          * we try to best guess, then fall back to NTLM.  */
1965         if (!spnego_parse_negTokenInit(state, *server_blob, OIDs,
1966                                        &principal, NULL) ||
1967                         OIDs[0] == NULL) {
1968                 state->result = ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1969                 tevent_req_done(req);
1970                 return tevent_req_post(req, ev);
1971         }
1972
1973         /* make sure the server understands kerberos */
1974         for (i=0;OIDs[i];i++) {
1975                 if (i == 0)
1976                         DEBUG(3,("got OID=%s\n", OIDs[i]));
1977                 else
1978                         DEBUGADD(3,("got OID=%s\n", OIDs[i]));
1979                 if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0 ||
1980                     strcmp(OIDs[i], OID_KERBEROS5) == 0) {
1981                         cli->got_kerberos_mechanism = True;
1982                 }
1983                 talloc_free(OIDs[i]);
1984         }
1985
1986         DEBUG(3,("got principal=%s\n", principal ? principal : "<null>"));
1987
1988         status = cli_set_username(cli, user);
1989         if (!NT_STATUS_IS_OK(status)) {
1990                 state->result = ADS_ERROR_NT(status);
1991                 tevent_req_done(req);
1992                 return tevent_req_post(req, ev);
1993         }
1994
1995 #ifdef HAVE_KRB5
1996         /* If password is set we reauthenticate to kerberos server
1997          * and do not store results */
1998
1999         if (user && *user && cli->got_kerberos_mechanism && cli->use_kerberos) {
2000                 const char *remote_name = smbXcli_conn_remote_name(cli->conn);
2001                 char *tmp;
2002
2003                 if (pass && *pass) {
2004                         int ret;
2005
2006                         use_in_memory_ccache();
2007                         ret = kerberos_kinit_password(user, pass, 0 /* no time correction for now */, NULL);
2008
2009                         if (ret){
2010                                 TALLOC_FREE(principal);
2011                                 DEBUG(0, ("Kinit failed: %s\n", error_message(ret)));
2012                                 if (cli->fallback_after_kerberos)
2013                                         goto ntlmssp;
2014                                 state->result = ADS_ERROR_KRB5(ret);
2015                                 tevent_req_done(req);
2016                                 return tevent_req_post(req, ev);
2017                         }
2018                 }
2019
2020                 tmp = cli_session_setup_get_principal(
2021                         talloc_tos(), principal, remote_name, dest_realm);
2022                 TALLOC_FREE(principal);
2023                 principal = tmp;
2024
2025                 if (principal) {
2026                         subreq = cli_session_setup_kerberos_send(
2027                                 state, ev, cli, principal);
2028                         if (tevent_req_nomem(subreq, req)) {
2029                                 return tevent_req_post(req, ev);
2030                         }
2031                         tevent_req_set_callback(
2032                                 subreq, cli_session_setup_spnego_done_krb,
2033                                 req);
2034                         return req;
2035                 }
2036         }
2037 #endif
2038
2039 ntlmssp:
2040         subreq = cli_session_setup_ntlmssp_send(
2041                 state, ev, cli, state->account, pass, user_domain);
2042         if (tevent_req_nomem(subreq, req)) {
2043                 return tevent_req_post(req, ev);
2044         }
2045         tevent_req_set_callback(
2046                 subreq, cli_session_setup_spnego_done_ntlmssp, req);
2047         return req;
2048 }
2049
2050 #ifdef HAVE_KRB5
2051 static void cli_session_setup_spnego_done_krb(struct tevent_req *subreq)
2052 {
2053         struct tevent_req *req = tevent_req_callback_data(
2054                 subreq, struct tevent_req);
2055         struct cli_session_setup_spnego_state *state = tevent_req_data(
2056                 req, struct cli_session_setup_spnego_state);
2057
2058         state->result = cli_session_setup_kerberos_recv(subreq);
2059         TALLOC_FREE(subreq);
2060
2061         if (ADS_ERR_OK(state->result) ||
2062             !state->cli->fallback_after_kerberos) {
2063                 tevent_req_done(req);
2064                 return;
2065         }
2066
2067         subreq = cli_session_setup_ntlmssp_send(
2068                 state, state->ev, state->cli, state->account, state->pass,
2069                 state->user_domain);
2070         if (tevent_req_nomem(subreq, req)) {
2071                 return;
2072         }
2073         tevent_req_set_callback(subreq, cli_session_setup_spnego_done_ntlmssp,
2074                                 req);
2075 }
2076 #endif
2077
2078 static void cli_session_setup_spnego_done_ntlmssp(struct tevent_req *subreq)
2079 {
2080         struct tevent_req *req = tevent_req_callback_data(
2081                 subreq, struct tevent_req);
2082         struct cli_session_setup_spnego_state *state = tevent_req_data(
2083                 req, struct cli_session_setup_spnego_state);
2084         NTSTATUS status;
2085
2086         status = cli_session_setup_ntlmssp_recv(subreq);
2087         TALLOC_FREE(subreq);
2088         state->result = ADS_ERROR_NT(status);
2089         tevent_req_done(req);
2090 }
2091
2092 static ADS_STATUS cli_session_setup_spnego_recv(struct tevent_req *req)
2093 {
2094         struct cli_session_setup_spnego_state *state = tevent_req_data(
2095                 req, struct cli_session_setup_spnego_state);
2096
2097         return state->result;
2098 }
2099
2100 static ADS_STATUS cli_session_setup_spnego(struct cli_state *cli,
2101                               const char *user,
2102                               const char *pass,
2103                               const char *user_domain,
2104                               const char * dest_realm)
2105 {
2106         struct tevent_context *ev;
2107         struct tevent_req *req;
2108         ADS_STATUS result = ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
2109         NTSTATUS status;
2110
2111         if (smbXcli_conn_has_async_calls(cli->conn)) {
2112                 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2113         }
2114         ev = samba_tevent_context_init(talloc_tos());
2115         if (ev == NULL) {
2116                 goto fail;
2117         }
2118         req = cli_session_setup_spnego_send(ev, ev, cli, user, pass,
2119                                             user_domain, dest_realm);
2120         if (req == NULL) {
2121                 goto fail;
2122         }
2123         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2124                 result = ADS_ERROR_NT(status);
2125                 goto fail;
2126         }
2127         result = cli_session_setup_spnego_recv(req);
2128 fail:
2129         TALLOC_FREE(ev);
2130         return result;
2131 }
2132
2133 /****************************************************************************
2134  Send a session setup. The username and workgroup is in UNIX character
2135  format and must be converted to DOS codepage format before sending. If the
2136  password is in plaintext, the same should be done.
2137 ****************************************************************************/
2138
2139 NTSTATUS cli_session_setup(struct cli_state *cli,
2140                            const char *user,
2141                            const char *pass, int passlen,
2142                            const char *ntpass, int ntpasslen,
2143                            const char *workgroup)
2144 {
2145         char *p;
2146         char *user2;
2147         uint16_t sec_mode = smb1cli_conn_server_security_mode(cli->conn);
2148
2149         if (user) {
2150                 user2 = talloc_strdup(talloc_tos(), user);
2151         } else {
2152                 user2 = talloc_strdup(talloc_tos(), "");
2153         }
2154         if (user2 == NULL) {
2155                 return NT_STATUS_NO_MEMORY;
2156         }
2157
2158         if (!workgroup) {
2159                 workgroup = "";
2160         }
2161
2162         /* allow for workgroups as part of the username */
2163         if ((p=strchr_m(user2,'\\')) || (p=strchr_m(user2,'/')) ||
2164             (p=strchr_m(user2,*lp_winbind_separator()))) {
2165                 *p = 0;
2166                 user = p+1;
2167                 if (!strupper_m(user2)) {
2168                         return NT_STATUS_INVALID_PARAMETER;
2169                 }
2170                 workgroup = user2;
2171         }
2172
2173         if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_LANMAN1) {
2174                 return NT_STATUS_OK;
2175         }
2176
2177         /* now work out what sort of session setup we are going to
2178            do. I have split this into separate functions to make the
2179            flow a bit easier to understand (tridge) */
2180
2181         /* if its an older server then we have to use the older request format */
2182
2183         if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_NT1) {
2184                 if (!lp_client_lanman_auth() && passlen != 24 && (*pass)) {
2185                         DEBUG(1, ("Server requested LM password but 'client lanman auth = no'"
2186                                   " or 'client ntlmv2 auth = yes'\n"));
2187                         return NT_STATUS_ACCESS_DENIED;
2188                 }
2189
2190                 if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0 &&
2191                     !lp_client_plaintext_auth() && (*pass)) {
2192                         DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
2193                                   " or 'client ntlmv2 auth = yes'\n"));
2194                         return NT_STATUS_ACCESS_DENIED;
2195                 }
2196
2197                 return cli_session_setup_lanman2(cli, user, pass, passlen,
2198                                                  workgroup);
2199         }
2200
2201         if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
2202                 const char *remote_realm = cli_state_remote_realm(cli);
2203                 ADS_STATUS status = cli_session_setup_spnego(cli, user, pass,
2204                                                              workgroup,
2205                                                              remote_realm);
2206                 if (!ADS_ERR_OK(status)) {
2207                         DEBUG(3, ("SMB2-SPNEGO login failed: %s\n", ads_errstr(status)));
2208                         return ads_ntstatus(status);
2209                 }
2210                 return NT_STATUS_OK;
2211         }
2212
2213         /* if no user is supplied then we have to do an anonymous connection.
2214            passwords are ignored */
2215
2216         if (!user || !*user)
2217                 return cli_session_setup_guest(cli);
2218
2219         /* if the server is share level then send a plaintext null
2220            password at this point. The password is sent in the tree
2221            connect */
2222
2223         if ((sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0)
2224                 return cli_session_setup_plain(cli, user, "", workgroup);
2225
2226         /* if the server doesn't support encryption then we have to use 
2227            plaintext. The second password is ignored */
2228
2229         if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) {
2230                 if (!lp_client_plaintext_auth() && (*pass)) {
2231                         DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
2232                                   " or 'client ntlmv2 auth = yes'\n"));
2233                         return NT_STATUS_ACCESS_DENIED;
2234                 }
2235                 return cli_session_setup_plain(cli, user, pass, workgroup);
2236         }
2237
2238         /* if the server supports extended security then use SPNEGO */
2239
2240         if (smb1cli_conn_capabilities(cli->conn) & CAP_EXTENDED_SECURITY) {
2241                 const char *remote_realm = cli_state_remote_realm(cli);
2242                 ADS_STATUS status = cli_session_setup_spnego(cli, user, pass,
2243                                                              workgroup,
2244                                                              remote_realm);
2245                 if (!ADS_ERR_OK(status)) {
2246                         DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status)));
2247                         return ads_ntstatus(status);
2248                 }
2249         } else {
2250                 NTSTATUS status;
2251
2252                 /* otherwise do a NT1 style session setup */
2253                 status = cli_session_setup_nt1(cli, user, pass, passlen,
2254                                                ntpass, ntpasslen, workgroup);
2255                 if (!NT_STATUS_IS_OK(status)) {
2256                         DEBUG(3,("cli_session_setup: NT1 session setup "
2257                                  "failed: %s\n", nt_errstr(status)));
2258                         return status;
2259                 }
2260         }
2261
2262         return NT_STATUS_OK;
2263 }
2264
2265 /****************************************************************************
2266  Send a uloggoff.
2267 *****************************************************************************/
2268
2269 struct cli_ulogoff_state {
2270         struct cli_state *cli;
2271         uint16_t vwv[3];
2272 };
2273
2274 static void cli_ulogoff_done(struct tevent_req *subreq);
2275
2276 struct tevent_req *cli_ulogoff_send(TALLOC_CTX *mem_ctx,
2277                                     struct tevent_context *ev,
2278                                     struct cli_state *cli)
2279 {
2280         struct tevent_req *req, *subreq;
2281         struct cli_ulogoff_state *state;
2282
2283         req = tevent_req_create(mem_ctx, &state, struct cli_ulogoff_state);
2284         if (req == NULL) {
2285                 return NULL;
2286         }
2287         state->cli = cli;
2288
2289         SCVAL(state->vwv+0, 0, 0xFF);
2290         SCVAL(state->vwv+1, 0, 0);
2291         SSVAL(state->vwv+2, 0, 0);
2292
2293         subreq = cli_smb_send(state, ev, cli, SMBulogoffX, 0, 2, state->vwv,
2294                               0, NULL);
2295         if (tevent_req_nomem(subreq, req)) {
2296                 return tevent_req_post(req, ev);
2297         }
2298         tevent_req_set_callback(subreq, cli_ulogoff_done, req);
2299         return req;
2300 }
2301
2302 static void cli_ulogoff_done(struct tevent_req *subreq)
2303 {
2304         struct tevent_req *req = tevent_req_callback_data(
2305                 subreq, struct tevent_req);
2306         struct cli_ulogoff_state *state = tevent_req_data(
2307                 req, struct cli_ulogoff_state);
2308         NTSTATUS status;
2309
2310         status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
2311         if (!NT_STATUS_IS_OK(status)) {
2312                 tevent_req_nterror(req, status);
2313                 return;
2314         }
2315         cli_state_set_uid(state->cli, UID_FIELD_INVALID);
2316         tevent_req_done(req);
2317 }
2318
2319 NTSTATUS cli_ulogoff_recv(struct tevent_req *req)
2320 {
2321         return tevent_req_simple_recv_ntstatus(req);
2322 }
2323
2324 NTSTATUS cli_ulogoff(struct cli_state *cli)
2325 {
2326         struct tevent_context *ev;
2327         struct tevent_req *req;
2328         NTSTATUS status = NT_STATUS_NO_MEMORY;
2329
2330         if (smbXcli_conn_has_async_calls(cli->conn)) {
2331                 return NT_STATUS_INVALID_PARAMETER;
2332         }
2333         ev = samba_tevent_context_init(talloc_tos());
2334         if (ev == NULL) {
2335                 goto fail;
2336         }
2337         req = cli_ulogoff_send(ev, ev, cli);
2338         if (req == NULL) {
2339                 goto fail;
2340         }
2341         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2342                 goto fail;
2343         }
2344         status = cli_ulogoff_recv(req);
2345 fail:
2346         TALLOC_FREE(ev);
2347         return status;
2348 }
2349
2350 /****************************************************************************
2351  Send a tconX.
2352 ****************************************************************************/
2353
2354 struct cli_tcon_andx_state {
2355         struct cli_state *cli;
2356         uint16_t vwv[4];
2357         struct iovec bytes;
2358 };
2359
2360 static void cli_tcon_andx_done(struct tevent_req *subreq);
2361
2362 struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx,
2363                                         struct tevent_context *ev,
2364                                         struct cli_state *cli,
2365                                         const char *share, const char *dev,
2366                                         const char *pass, int passlen,
2367                                         struct tevent_req **psmbreq)
2368 {
2369         struct tevent_req *req, *subreq;
2370         struct cli_tcon_andx_state *state;
2371         uint8_t p24[24];
2372         uint16_t *vwv;
2373         char *tmp = NULL;
2374         uint8_t *bytes;
2375         uint16_t sec_mode = smb1cli_conn_server_security_mode(cli->conn);
2376         uint16_t tcon_flags = 0;
2377
2378         *psmbreq = NULL;
2379
2380         req = tevent_req_create(mem_ctx, &state, struct cli_tcon_andx_state);
2381         if (req == NULL) {
2382                 return NULL;
2383         }
2384         state->cli = cli;
2385         vwv = state->vwv;
2386
2387         cli->share = talloc_strdup(cli, share);
2388         if (!cli->share) {
2389                 return NULL;
2390         }
2391
2392         /* in user level security don't send a password now */
2393         if (sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {
2394                 passlen = 1;
2395                 pass = "";
2396         } else if (pass == NULL) {
2397                 DEBUG(1, ("Server not using user level security and no "
2398                           "password supplied.\n"));
2399                 goto access_denied;
2400         }
2401
2402         if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) &&
2403             *pass && passlen != 24) {
2404                 if (!lp_client_lanman_auth()) {
2405                         DEBUG(1, ("Server requested LANMAN password "
2406                                   "(share-level security) but "
2407                                   "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2408                         goto access_denied;
2409                 }
2410
2411                 /*
2412                  * Non-encrypted passwords - convert to DOS codepage before
2413                  * encryption.
2414                  */
2415                 SMBencrypt(pass, smb1cli_conn_server_challenge(cli->conn), p24);
2416                 passlen = 24;
2417                 pass = (const char *)p24;
2418         } else {
2419                 if((sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL
2420                                      |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE))
2421                    == 0) {
2422                         uint8_t *tmp_pass;
2423
2424                         if (!lp_client_plaintext_auth() && (*pass)) {
2425                                 DEBUG(1, ("Server requested PLAINTEXT "
2426                                           "password but "
2427                                           "'client plaintext auth = no' or 'client ntlmv2 auth = yes'\n"));
2428                                 goto access_denied;
2429                         }
2430
2431                         /*
2432                          * Non-encrypted passwords - convert to DOS codepage
2433                          * before using.
2434                          */
2435                         tmp_pass = talloc_array(talloc_tos(), uint8, 0);
2436                         if (tevent_req_nomem(tmp_pass, req)) {
2437                                 return tevent_req_post(req, ev);
2438                         }
2439                         tmp_pass = trans2_bytes_push_str(tmp_pass,
2440                                                          false, /* always DOS */
2441                                                          pass,
2442                                                          passlen,
2443                                                          NULL);
2444                         if (tevent_req_nomem(tmp_pass, req)) {
2445                                 return tevent_req_post(req, ev);
2446                         }
2447                         pass = (const char *)tmp_pass;
2448                         passlen = talloc_get_size(tmp_pass);
2449                 }
2450         }
2451
2452         tcon_flags |= TCONX_FLAG_EXTENDED_RESPONSE;
2453         tcon_flags |= TCONX_FLAG_EXTENDED_SIGNATURES;
2454
2455         SCVAL(vwv+0, 0, 0xFF);
2456         SCVAL(vwv+0, 1, 0);
2457         SSVAL(vwv+1, 0, 0);
2458         SSVAL(vwv+2, 0, tcon_flags);
2459         SSVAL(vwv+3, 0, passlen);
2460
2461         if (passlen && pass) {
2462                 bytes = (uint8_t *)talloc_memdup(state, pass, passlen);
2463         } else {
2464                 bytes = talloc_array(state, uint8_t, 0);
2465         }
2466
2467         /*
2468          * Add the sharename
2469          */
2470         tmp = talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
2471                                          smbXcli_conn_remote_name(cli->conn), share);
2472         if (tmp == NULL) {
2473                 TALLOC_FREE(req);
2474                 return NULL;
2475         }
2476         bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), tmp, strlen(tmp)+1,
2477                                    NULL);
2478         TALLOC_FREE(tmp);
2479
2480         /*
2481          * Add the devicetype
2482          */
2483         tmp = talloc_strdup_upper(talloc_tos(), dev);
2484         if (tmp == NULL) {
2485                 TALLOC_FREE(req);
2486                 return NULL;
2487         }
2488         bytes = smb_bytes_push_str(bytes, false, tmp, strlen(tmp)+1, NULL);
2489         TALLOC_FREE(tmp);
2490
2491         if (bytes == NULL) {
2492                 TALLOC_FREE(req);
2493                 return NULL;
2494         }
2495
2496         state->bytes.iov_base = (void *)bytes;
2497         state->bytes.iov_len = talloc_get_size(bytes);
2498
2499         subreq = cli_smb_req_create(state, ev, cli, SMBtconX, 0, 4, vwv,
2500                                     1, &state->bytes);
2501         if (subreq == NULL) {
2502                 TALLOC_FREE(req);
2503                 return NULL;
2504         }
2505         tevent_req_set_callback(subreq, cli_tcon_andx_done, req);
2506         *psmbreq = subreq;
2507         return req;
2508
2509  access_denied:
2510         tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
2511         return tevent_req_post(req, ev);
2512 }
2513
2514 struct tevent_req *cli_tcon_andx_send(TALLOC_CTX *mem_ctx,
2515                                       struct tevent_context *ev,
2516                                       struct cli_state *cli,
2517                                       const char *share, const char *dev,
2518                                       const char *pass, int passlen)
2519 {
2520         struct tevent_req *req, *subreq;
2521         NTSTATUS status;
2522
2523         req = cli_tcon_andx_create(mem_ctx, ev, cli, share, dev, pass, passlen,
2524                                    &subreq);
2525         if (req == NULL) {
2526                 return NULL;
2527         }
2528         if (subreq == NULL) {
2529                 return req;
2530         }
2531         status = smb1cli_req_chain_submit(&subreq, 1);
2532         if (!NT_STATUS_IS_OK(status)) {
2533                 tevent_req_nterror(req, status);
2534                 return tevent_req_post(req, ev);
2535         }
2536         return req;
2537 }
2538
2539 static void cli_tcon_andx_done(struct tevent_req *subreq)
2540 {
2541         struct tevent_req *req = tevent_req_callback_data(
2542                 subreq, struct tevent_req);
2543         struct cli_tcon_andx_state *state = tevent_req_data(
2544                 req, struct cli_tcon_andx_state);
2545         struct cli_state *cli = state->cli;
2546         uint8_t *in;
2547         uint8_t *inhdr;
2548         uint8_t wct;
2549         uint16_t *vwv;
2550         uint32_t num_bytes;
2551         uint8_t *bytes;
2552         NTSTATUS status;
2553         uint16_t optional_support = 0;
2554
2555         status = cli_smb_recv(subreq, state, &in, 0, &wct, &vwv,
2556                               &num_bytes, &bytes);
2557         TALLOC_FREE(subreq);
2558         if (!NT_STATUS_IS_OK(status)) {
2559                 tevent_req_nterror(req, status);
2560                 return;
2561         }
2562
2563         inhdr = in + NBT_HDR_SIZE;
2564
2565         if (num_bytes) {
2566                 if (clistr_pull_talloc(cli,
2567                                 (const char *)inhdr,
2568                                 SVAL(inhdr, HDR_FLG2),
2569                                 &cli->dev,
2570                                 bytes,
2571                                 num_bytes,
2572                                 STR_TERMINATE|STR_ASCII) == -1) {
2573                         tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2574                         return;
2575                 }
2576         } else {
2577                 cli->dev = talloc_strdup(cli, "");
2578                 if (cli->dev == NULL) {
2579                         tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2580                         return;
2581                 }
2582         }
2583
2584         if ((smbXcli_conn_protocol(cli->conn) >= PROTOCOL_NT1) && (num_bytes == 3)) {
2585                 /* almost certainly win95 - enable bug fixes */
2586                 cli->win95 = True;
2587         }
2588
2589         /*
2590          * Make sure that we have the optional support 16-bit field. WCT > 2.
2591          * Avoids issues when connecting to Win9x boxes sharing files
2592          */
2593
2594         cli->dfsroot = false;
2595
2596         if ((wct > 2) && (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_LANMAN2)) {
2597                 optional_support = SVAL(vwv+2, 0);
2598         }
2599
2600         if (optional_support & SMB_SHARE_IN_DFS) {
2601                 cli->dfsroot = true;
2602         }
2603
2604         if (optional_support & SMB_EXTENDED_SIGNATURES) {
2605                 smb1cli_session_protect_session_key(cli->smb1.session);
2606         }
2607
2608         cli_state_set_tid(cli, SVAL(inhdr, HDR_TID));
2609         tevent_req_done(req);
2610 }
2611
2612 NTSTATUS cli_tcon_andx_recv(struct tevent_req *req)
2613 {
2614         return tevent_req_simple_recv_ntstatus(req);
2615 }
2616
2617 NTSTATUS cli_tcon_andx(struct cli_state *cli, const char *share,
2618                        const char *dev, const char *pass, int passlen)
2619 {
2620         TALLOC_CTX *frame = talloc_stackframe();
2621         struct tevent_context *ev;
2622         struct tevent_req *req;
2623         NTSTATUS status = NT_STATUS_OK;
2624
2625         if (smbXcli_conn_has_async_calls(cli->conn)) {
2626                 /*
2627                  * Can't use sync call while an async call is in flight
2628                  */
2629                 status = NT_STATUS_INVALID_PARAMETER;
2630                 goto fail;
2631         }
2632
2633         ev = samba_tevent_context_init(frame);
2634         if (ev == NULL) {
2635                 status = NT_STATUS_NO_MEMORY;
2636                 goto fail;
2637         }
2638
2639         req = cli_tcon_andx_send(frame, ev, cli, share, dev, pass, passlen);
2640         if (req == NULL) {
2641                 status = NT_STATUS_NO_MEMORY;
2642                 goto fail;
2643         }
2644
2645         if (!tevent_req_poll(req, ev)) {
2646                 status = map_nt_error_from_unix(errno);
2647                 goto fail;
2648         }
2649
2650         status = cli_tcon_andx_recv(req);
2651  fail:
2652         TALLOC_FREE(frame);
2653         return status;
2654 }
2655
2656 NTSTATUS cli_tree_connect(struct cli_state *cli, const char *share,
2657                           const char *dev, const char *pass, int passlen)
2658 {
2659         NTSTATUS status;
2660         uint16_t max_xmit = 0;
2661         uint16_t tid = 0;
2662
2663         cli->share = talloc_strdup(cli, share);
2664         if (!cli->share) {
2665                 return NT_STATUS_NO_MEMORY;
2666         }
2667
2668         if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
2669                 return smb2cli_tcon(cli, share);
2670         }
2671
2672         if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_LANMAN1) {
2673                 return cli_tcon_andx(cli, share, dev, pass, passlen);
2674         }
2675
2676         status = cli_raw_tcon(cli, share, pass, dev, &max_xmit, &tid);
2677         if (!NT_STATUS_IS_OK(status)) {
2678                 return status;
2679         }
2680
2681         cli_state_set_tid(cli, tid);
2682
2683         return NT_STATUS_OK;
2684 }
2685
2686 /****************************************************************************
2687  Send a tree disconnect.
2688 ****************************************************************************/
2689
2690 struct cli_tdis_state {
2691         struct cli_state *cli;
2692 };
2693
2694 static void cli_tdis_done(struct tevent_req *subreq);
2695
2696 struct tevent_req *cli_tdis_send(TALLOC_CTX *mem_ctx,
2697                                  struct tevent_context *ev,
2698                                  struct cli_state *cli)
2699 {
2700         struct tevent_req *req, *subreq;
2701         struct cli_tdis_state *state;
2702
2703         req = tevent_req_create(mem_ctx, &state, struct cli_tdis_state);
2704         if (req == NULL) {
2705                 return NULL;
2706         }
2707         state->cli = cli;
2708
2709         subreq = cli_smb_send(state, ev, cli, SMBtdis, 0, 0, NULL, 0, NULL);
2710         if (tevent_req_nomem(subreq, req)) {
2711                 return tevent_req_post(req, ev);
2712         }
2713         tevent_req_set_callback(subreq, cli_tdis_done, req);
2714         return req;
2715 }
2716
2717 static void cli_tdis_done(struct tevent_req *subreq)
2718 {
2719         struct tevent_req *req = tevent_req_callback_data(
2720                 subreq, struct tevent_req);
2721         struct cli_tdis_state *state = tevent_req_data(
2722                 req, struct cli_tdis_state);
2723         NTSTATUS status;
2724
2725         status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
2726         TALLOC_FREE(subreq);
2727         if (!NT_STATUS_IS_OK(status)) {
2728                 tevent_req_nterror(req, status);
2729                 return;
2730         }
2731         cli_state_set_tid(state->cli, UINT16_MAX);
2732         tevent_req_done(req);
2733 }
2734
2735 NTSTATUS cli_tdis_recv(struct tevent_req *req)
2736 {
2737         return tevent_req_simple_recv_ntstatus(req);
2738 }
2739
2740 NTSTATUS cli_tdis(struct cli_state *cli)
2741 {
2742         struct tevent_context *ev;
2743         struct tevent_req *req;
2744         NTSTATUS status = NT_STATUS_NO_MEMORY;
2745
2746         if (smbXcli_conn_has_async_calls(cli->conn)) {
2747                 return NT_STATUS_INVALID_PARAMETER;
2748         }
2749         ev = samba_tevent_context_init(talloc_tos());
2750         if (ev == NULL) {
2751                 goto fail;
2752         }
2753         req = cli_tdis_send(ev, ev, cli);
2754         if (req == NULL) {
2755                 goto fail;
2756         }
2757         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2758                 goto fail;
2759         }
2760         status = cli_tdis_recv(req);
2761 fail:
2762         TALLOC_FREE(ev);
2763         return status;
2764 }
2765
2766 static NTSTATUS cli_connect_sock(const char *host, int name_type,
2767                                  const struct sockaddr_storage *pss,
2768                                  const char *myname, uint16_t port,
2769                                  int sec_timeout, int *pfd, uint16_t *pport)
2770 {
2771         TALLOC_CTX *frame = talloc_stackframe();
2772         const char *prog;
2773         unsigned int i, num_addrs;
2774         const char **called_names;
2775         const char **calling_names;
2776         int *called_types;
2777         NTSTATUS status;
2778         int fd;
2779
2780         prog = getenv("LIBSMB_PROG");
2781         if (prog != NULL) {
2782                 fd = sock_exec(prog);
2783                 if (fd == -1) {
2784                         return map_nt_error_from_unix(errno);
2785                 }
2786                 port = 0;
2787                 goto done;
2788         }
2789
2790         if ((pss == NULL) || is_zero_addr(pss)) {
2791                 struct sockaddr_storage *addrs;
2792                 status = resolve_name_list(talloc_tos(), host, name_type,
2793                                            &addrs, &num_addrs);
2794                 if (!NT_STATUS_IS_OK(status)) {
2795                         goto fail;
2796                 }
2797                 pss = addrs;
2798         } else {
2799                 num_addrs = 1;
2800         }
2801
2802         called_names = talloc_array(talloc_tos(), const char *, num_addrs);
2803         if (called_names == NULL) {
2804                 status = NT_STATUS_NO_MEMORY;
2805                 goto fail;
2806         }
2807         called_types = talloc_array(talloc_tos(), int, num_addrs);
2808         if (called_types == NULL) {
2809                 status = NT_STATUS_NO_MEMORY;
2810                 goto fail;
2811         }
2812         calling_names = talloc_array(talloc_tos(), const char *, num_addrs);
2813         if (calling_names == NULL) {
2814                 status = NT_STATUS_NO_MEMORY;
2815                 goto fail;
2816         }
2817         for (i=0; i<num_addrs; i++) {
2818                 called_names[i] = host;
2819                 called_types[i] = name_type;
2820                 calling_names[i] = myname;
2821         }
2822         status = smbsock_any_connect(pss, called_names, called_types,
2823                                      calling_names, NULL, num_addrs, port,
2824                                      sec_timeout, &fd, NULL, &port);
2825         if (!NT_STATUS_IS_OK(status)) {
2826                 goto fail;
2827         }
2828         set_socket_options(fd, lp_socket_options());
2829 done:
2830         *pfd = fd;
2831         *pport = port;
2832         status = NT_STATUS_OK;
2833 fail:
2834         TALLOC_FREE(frame);
2835         return status;
2836 }
2837
2838 NTSTATUS cli_connect_nb(const char *host, const struct sockaddr_storage *dest_ss,
2839                         uint16_t port, int name_type, const char *myname,
2840                         int signing_state, int flags, struct cli_state **pcli)
2841 {
2842         TALLOC_CTX *frame = talloc_stackframe();
2843         struct cli_state *cli;
2844         NTSTATUS status = NT_STATUS_NO_MEMORY;
2845         int fd = -1;
2846         char *desthost;
2847         char *p;
2848
2849         desthost = talloc_strdup(talloc_tos(), host);
2850         if (desthost == NULL) {
2851                 goto fail;
2852         }
2853
2854         p = strchr(host, '#');
2855         if (p != NULL) {
2856                 name_type = strtol(p+1, NULL, 16);
2857                 host = talloc_strndup(talloc_tos(), host, p - host);
2858                 if (host == NULL) {
2859                         goto fail;
2860                 }
2861         }
2862
2863         status = cli_connect_sock(host, name_type, dest_ss, myname, port,
2864                                   20, &fd, &port);
2865         if (!NT_STATUS_IS_OK(status)) {
2866                 goto fail;
2867         }
2868
2869         cli = cli_state_create(NULL, fd, desthost, NULL, signing_state, flags);
2870         if (cli == NULL) {
2871                 close(fd);
2872                 fd = -1;
2873                 goto fail;
2874         }
2875
2876         *pcli = cli;
2877         status = NT_STATUS_OK;
2878 fail:
2879         TALLOC_FREE(frame);
2880         return status;
2881 }
2882
2883 /**
2884    establishes a connection to after the negprot. 
2885    @param output_cli A fully initialised cli structure, non-null only on success
2886    @param dest_host The netbios name of the remote host
2887    @param dest_ss (optional) The the destination IP, NULL for name based lookup
2888    @param port (optional) The destination port (0 for default)
2889 */
2890 NTSTATUS cli_start_connection(struct cli_state **output_cli, 
2891                               const char *my_name, 
2892                               const char *dest_host, 
2893                               const struct sockaddr_storage *dest_ss, int port,
2894                               int signing_state, int flags)
2895 {
2896         NTSTATUS nt_status;
2897         struct cli_state *cli;
2898
2899         nt_status = cli_connect_nb(dest_host, dest_ss, port, 0x20, my_name,
2900                                    signing_state, flags, &cli);
2901         if (!NT_STATUS_IS_OK(nt_status)) {
2902                 DEBUG(10, ("cli_connect_nb failed: %s\n",
2903                            nt_errstr(nt_status)));
2904                 return nt_status;
2905         }
2906
2907         nt_status = smbXcli_negprot(cli->conn, cli->timeout, PROTOCOL_CORE,
2908                                     PROTOCOL_NT1);
2909         if (!NT_STATUS_IS_OK(nt_status)) {
2910                 DEBUG(1, ("failed negprot: %s\n", nt_errstr(nt_status)));
2911                 cli_shutdown(cli);
2912                 return nt_status;
2913         }
2914
2915         *output_cli = cli;
2916         return NT_STATUS_OK;
2917 }
2918
2919
2920 /**
2921    establishes a connection right up to doing tconX, password specified.
2922    @param output_cli A fully initialised cli structure, non-null only on success
2923    @param dest_host The netbios name of the remote host
2924    @param dest_ip (optional) The the destination IP, NULL for name based lookup
2925    @param port (optional) The destination port (0 for default)
2926    @param service (optional) The share to make the connection to.  Should be 'unqualified' in any way.
2927    @param service_type The 'type' of serivice. 
2928    @param user Username, unix string
2929    @param domain User's domain
2930    @param password User's password, unencrypted unix string.
2931 */
2932
2933 NTSTATUS cli_full_connection(struct cli_state **output_cli, 
2934                              const char *my_name, 
2935                              const char *dest_host, 
2936                              const struct sockaddr_storage *dest_ss, int port,
2937                              const char *service, const char *service_type,
2938                              const char *user, const char *domain, 
2939                              const char *password, int flags,
2940                              int signing_state)
2941 {
2942         NTSTATUS nt_status;
2943         struct cli_state *cli = NULL;
2944         int pw_len = password ? strlen(password)+1 : 0;
2945
2946         *output_cli = NULL;
2947
2948         if (password == NULL) {
2949                 password = "";
2950         }
2951
2952         nt_status = cli_start_connection(&cli, my_name, dest_host,
2953                                          dest_ss, port, signing_state,
2954                                          flags);
2955
2956         if (!NT_STATUS_IS_OK(nt_status)) {
2957                 return nt_status;
2958         }
2959
2960         nt_status = cli_session_setup(cli, user, password, pw_len, password,
2961                                       pw_len, domain);
2962         if (!NT_STATUS_IS_OK(nt_status)) {
2963
2964                 if (!(flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)) {
2965                         DEBUG(1,("failed session setup with %s\n",
2966                                  nt_errstr(nt_status)));
2967                         cli_shutdown(cli);
2968                         return nt_status;
2969                 }
2970
2971                 nt_status = cli_session_setup(cli, "", "", 0, "", 0, domain);
2972                 if (!NT_STATUS_IS_OK(nt_status)) {
2973                         DEBUG(1,("anonymous failed session setup with %s\n",
2974                                  nt_errstr(nt_status)));
2975                         cli_shutdown(cli);
2976                         return nt_status;
2977                 }
2978         }
2979
2980         if (service) {
2981                 nt_status = cli_tree_connect(cli, service, service_type,
2982                                              password, pw_len);
2983                 if (!NT_STATUS_IS_OK(nt_status)) {
2984                         DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status)));
2985                         cli_shutdown(cli);
2986                         if (NT_STATUS_IS_OK(nt_status)) {
2987                                 nt_status = NT_STATUS_UNSUCCESSFUL;
2988                         }
2989                         return nt_status;
2990                 }
2991         }
2992
2993         nt_status = cli_init_creds(cli, user, domain, password);
2994         if (!NT_STATUS_IS_OK(nt_status)) {
2995                 cli_shutdown(cli);
2996                 return nt_status;
2997         }
2998
2999         *output_cli = cli;
3000         return NT_STATUS_OK;
3001 }
3002
3003 /****************************************************************************
3004  Send an old style tcon.
3005 ****************************************************************************/
3006 NTSTATUS cli_raw_tcon(struct cli_state *cli, 
3007                       const char *service, const char *pass, const char *dev,
3008                       uint16 *max_xmit, uint16 *tid)
3009 {
3010         struct tevent_req *req;
3011         uint16_t *ret_vwv;
3012         uint8_t *bytes;
3013         NTSTATUS status;
3014
3015         if (!lp_client_plaintext_auth() && (*pass)) {
3016                 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
3017                           " or 'client ntlmv2 auth = yes'\n"));
3018                 return NT_STATUS_ACCESS_DENIED;
3019         }
3020
3021         bytes = talloc_array(talloc_tos(), uint8_t, 0);
3022         bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3023         bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3024                                    service, strlen(service)+1, NULL);
3025         bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3026         bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3027                                    pass, strlen(pass)+1, NULL);
3028         bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3029         bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3030                                    dev, strlen(dev)+1, NULL);
3031
3032         status = cli_smb(talloc_tos(), cli, SMBtcon, 0, 0, NULL,
3033                          talloc_get_size(bytes), bytes, &req,
3034                          2, NULL, &ret_vwv, NULL, NULL);
3035         if (!NT_STATUS_IS_OK(status)) {
3036                 return status;
3037         }
3038
3039         *max_xmit = SVAL(ret_vwv + 0, 0);
3040         *tid = SVAL(ret_vwv + 1, 0);
3041
3042         return NT_STATUS_OK;
3043 }
3044
3045 /* Return a cli_state pointing at the IPC$ share for the given server */
3046
3047 struct cli_state *get_ipc_connect(char *server,
3048                                 struct sockaddr_storage *server_ss,
3049                                 const struct user_auth_info *user_info)
3050 {
3051         struct cli_state *cli;
3052         NTSTATUS nt_status;
3053         uint32_t flags = CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
3054
3055         if (user_info->use_kerberos) {
3056                 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
3057         }
3058
3059         nt_status = cli_full_connection(&cli, NULL, server, server_ss, 0, "IPC$", "IPC", 
3060                                         user_info->username ? user_info->username : "",
3061                                         lp_workgroup(),
3062                                         user_info->password ? user_info->password : "",
3063                                         flags,
3064                                         SMB_SIGNING_DEFAULT);
3065
3066         if (NT_STATUS_IS_OK(nt_status)) {
3067                 return cli;
3068         } else if (is_ipaddress(server)) {
3069             /* windows 9* needs a correct NMB name for connections */
3070             fstring remote_name;
3071
3072             if (name_status_find("*", 0, 0, server_ss, remote_name)) {
3073                 cli = get_ipc_connect(remote_name, server_ss, user_info);
3074                 if (cli)
3075                     return cli;
3076             }
3077         }
3078         return NULL;
3079 }
3080
3081 /*
3082  * Given the IP address of a master browser on the network, return its
3083  * workgroup and connect to it.
3084  *
3085  * This function is provided to allow additional processing beyond what
3086  * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
3087  * browsers and obtain each master browsers' list of domains (in case the
3088  * first master browser is recently on the network and has not yet
3089  * synchronized with other master browsers and therefore does not yet have the
3090  * entire network browse list)
3091  */
3092
3093 struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx,
3094                                 struct sockaddr_storage *mb_ip,
3095                                 const struct user_auth_info *user_info,
3096                                 char **pp_workgroup_out)
3097 {
3098         char addr[INET6_ADDRSTRLEN];
3099         fstring name;
3100         struct cli_state *cli;
3101         struct sockaddr_storage server_ss;
3102
3103         *pp_workgroup_out = NULL;
3104
3105         print_sockaddr(addr, sizeof(addr), mb_ip);
3106         DEBUG(99, ("Looking up name of master browser %s\n",
3107                    addr));
3108
3109         /*
3110          * Do a name status query to find out the name of the master browser.
3111          * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
3112          * master browser will not respond to a wildcard query (or, at least,
3113          * an NT4 server acting as the domain master browser will not).
3114          *
3115          * We might be able to use ONLY the query on MSBROWSE, but that's not
3116          * yet been tested with all Windows versions, so until it is, leave
3117          * the original wildcard query as the first choice and fall back to
3118          * MSBROWSE if the wildcard query fails.
3119          */
3120         if (!name_status_find("*", 0, 0x1d, mb_ip, name) &&
3121             !name_status_find(MSBROWSE, 1, 0x1d, mb_ip, name)) {
3122
3123                 DEBUG(99, ("Could not retrieve name status for %s\n",
3124                            addr));
3125                 return NULL;
3126         }
3127
3128         if (!find_master_ip(name, &server_ss)) {
3129                 DEBUG(99, ("Could not find master ip for %s\n", name));
3130                 return NULL;
3131         }
3132
3133         *pp_workgroup_out = talloc_strdup(ctx, name);
3134
3135         DEBUG(4, ("found master browser %s, %s\n", name, addr));
3136
3137         print_sockaddr(addr, sizeof(addr), &server_ss);
3138         cli = get_ipc_connect(addr, &server_ss, user_info);
3139
3140         return cli;
3141 }
3142
3143 /*
3144  * Return the IP address and workgroup of a master browser on the network, and
3145  * connect to it.
3146  */
3147
3148 struct cli_state *get_ipc_connect_master_ip_bcast(TALLOC_CTX *ctx,
3149                                         const struct user_auth_info *user_info,
3150                                         char **pp_workgroup_out)
3151 {
3152         struct sockaddr_storage *ip_list;
3153         struct cli_state *cli;
3154         int i, count;
3155         NTSTATUS status;
3156
3157         *pp_workgroup_out = NULL;
3158
3159         DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
3160
3161         /* Go looking for workgroups by broadcasting on the local network */
3162
3163         status = name_resolve_bcast(MSBROWSE, 1, talloc_tos(),
3164                                     &ip_list, &count);
3165         if (!NT_STATUS_IS_OK(status)) {
3166                 DEBUG(99, ("No master browsers responded: %s\n",
3167                            nt_errstr(status)));
3168                 return NULL;
3169         }
3170
3171         for (i = 0; i < count; i++) {
3172                 char addr[INET6_ADDRSTRLEN];
3173                 print_sockaddr(addr, sizeof(addr), &ip_list[i]);
3174                 DEBUG(99, ("Found master browser %s\n", addr));
3175
3176                 cli = get_ipc_connect_master_ip(ctx, &ip_list[i],
3177                                 user_info, pp_workgroup_out);
3178                 if (cli)
3179                         return(cli);
3180         }
3181
3182         return NULL;
3183 }