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