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