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