s3:libsmb: also remember the optional server name from the negprot response
[obnox/samba/samba-obnox.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                 /*
1980                  * Ensure cli->server_domain,
1981                  * cli->server_os and cli->server_type
1982                  * are valid pointers.
1983                  */
1984                 cli->server_domain = talloc_strdup(cli, "");
1985                 cli->server_os = talloc_strdup(cli, "");
1986                 cli->server_type = talloc_strdup(cli, "");
1987                 if (cli->server_domain == NULL ||
1988                                 cli->server_os == NULL ||
1989                                 cli->server_type == NULL) {
1990                         return NT_STATUS_NO_MEMORY;
1991                 }
1992                 return NT_STATUS_OK;
1993         }
1994
1995         /* now work out what sort of session setup we are going to
1996            do. I have split this into separate functions to make the
1997            flow a bit easier to understand (tridge) */
1998
1999         /* if its an older server then we have to use the older request format */
2000
2001         if (cli_state_protocol(cli) < PROTOCOL_NT1) {
2002                 if (!lp_client_lanman_auth() && passlen != 24 && (*pass)) {
2003                         DEBUG(1, ("Server requested LM password but 'client lanman auth = no'"
2004                                   " or 'client ntlmv2 auth = yes'\n"));
2005                         return NT_STATUS_ACCESS_DENIED;
2006                 }
2007
2008                 if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0 &&
2009                     !lp_client_plaintext_auth() && (*pass)) {
2010                         DEBUG(1, ("Server requested LM password but 'client plaintext auth = no'"
2011                                   " or 'client ntlmv2 auth = yes'\n"));
2012                         return NT_STATUS_ACCESS_DENIED;
2013                 }
2014
2015                 return cli_session_setup_lanman2(cli, user, pass, passlen,
2016                                                  workgroup);
2017         }
2018
2019         /* if no user is supplied then we have to do an anonymous connection.
2020            passwords are ignored */
2021
2022         if (!user || !*user)
2023                 return cli_session_setup_guest(cli);
2024
2025         /* if the server is share level then send a plaintext null
2026            password at this point. The password is sent in the tree
2027            connect */
2028
2029         if ((sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0)
2030                 return cli_session_setup_plain(cli, user, "", workgroup);
2031
2032         /* if the server doesn't support encryption then we have to use 
2033            plaintext. The second password is ignored */
2034
2035         if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) {
2036                 if (!lp_client_plaintext_auth() && (*pass)) {
2037                         DEBUG(1, ("Server requested LM password but 'client plaintext auth = no'"
2038                                   " or 'client ntlmv2 auth = yes'\n"));
2039                         return NT_STATUS_ACCESS_DENIED;
2040                 }
2041                 return cli_session_setup_plain(cli, user, pass, workgroup);
2042         }
2043
2044         /* if the server supports extended security then use SPNEGO */
2045
2046         if (cli_state_capabilities(cli) & CAP_EXTENDED_SECURITY) {
2047                 const char *remote_realm = cli_state_remote_realm(cli);
2048                 ADS_STATUS status = cli_session_setup_spnego(cli, user, pass,
2049                                                              workgroup,
2050                                                              remote_realm);
2051                 if (!ADS_ERR_OK(status)) {
2052                         DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status)));
2053                         return ads_ntstatus(status);
2054                 }
2055         } else {
2056                 NTSTATUS status;
2057
2058                 /* otherwise do a NT1 style session setup */
2059                 status = cli_session_setup_nt1(cli, user, pass, passlen,
2060                                                ntpass, ntpasslen, workgroup);
2061                 if (!NT_STATUS_IS_OK(status)) {
2062                         DEBUG(3,("cli_session_setup: NT1 session setup "
2063                                  "failed: %s\n", nt_errstr(status)));
2064                         return status;
2065                 }
2066         }
2067
2068         return NT_STATUS_OK;
2069 }
2070
2071 /****************************************************************************
2072  Send a uloggoff.
2073 *****************************************************************************/
2074
2075 struct cli_ulogoff_state {
2076         struct cli_state *cli;
2077         uint16_t vwv[3];
2078 };
2079
2080 static void cli_ulogoff_done(struct tevent_req *subreq);
2081
2082 struct tevent_req *cli_ulogoff_send(TALLOC_CTX *mem_ctx,
2083                                     struct tevent_context *ev,
2084                                     struct cli_state *cli)
2085 {
2086         struct tevent_req *req, *subreq;
2087         struct cli_ulogoff_state *state;
2088
2089         req = tevent_req_create(mem_ctx, &state, struct cli_ulogoff_state);
2090         if (req == NULL) {
2091                 return NULL;
2092         }
2093         state->cli = cli;
2094
2095         SCVAL(state->vwv+0, 0, 0xFF);
2096         SCVAL(state->vwv+1, 0, 0);
2097         SSVAL(state->vwv+2, 0, 0);
2098
2099         subreq = cli_smb_send(state, ev, cli, SMBulogoffX, 0, 2, state->vwv,
2100                               0, NULL);
2101         if (tevent_req_nomem(subreq, req)) {
2102                 return tevent_req_post(req, ev);
2103         }
2104         tevent_req_set_callback(subreq, cli_ulogoff_done, req);
2105         return req;
2106 }
2107
2108 static void cli_ulogoff_done(struct tevent_req *subreq)
2109 {
2110         struct tevent_req *req = tevent_req_callback_data(
2111                 subreq, struct tevent_req);
2112         struct cli_ulogoff_state *state = tevent_req_data(
2113                 req, struct cli_ulogoff_state);
2114         NTSTATUS status;
2115
2116         status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
2117         if (!NT_STATUS_IS_OK(status)) {
2118                 tevent_req_nterror(req, status);
2119                 return;
2120         }
2121         cli_state_set_uid(state->cli, UID_FIELD_INVALID);
2122         tevent_req_done(req);
2123 }
2124
2125 NTSTATUS cli_ulogoff_recv(struct tevent_req *req)
2126 {
2127         return tevent_req_simple_recv_ntstatus(req);
2128 }
2129
2130 NTSTATUS cli_ulogoff(struct cli_state *cli)
2131 {
2132         struct tevent_context *ev;
2133         struct tevent_req *req;
2134         NTSTATUS status = NT_STATUS_NO_MEMORY;
2135
2136         if (cli_has_async_calls(cli)) {
2137                 return NT_STATUS_INVALID_PARAMETER;
2138         }
2139         ev = tevent_context_init(talloc_tos());
2140         if (ev == NULL) {
2141                 goto fail;
2142         }
2143         req = cli_ulogoff_send(ev, ev, cli);
2144         if (req == NULL) {
2145                 goto fail;
2146         }
2147         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2148                 goto fail;
2149         }
2150         status = cli_ulogoff_recv(req);
2151 fail:
2152         TALLOC_FREE(ev);
2153         return status;
2154 }
2155
2156 /****************************************************************************
2157  Send a tconX.
2158 ****************************************************************************/
2159
2160 struct cli_tcon_andx_state {
2161         struct cli_state *cli;
2162         uint16_t vwv[4];
2163         struct iovec bytes;
2164 };
2165
2166 static void cli_tcon_andx_done(struct tevent_req *subreq);
2167
2168 struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx,
2169                                         struct event_context *ev,
2170                                         struct cli_state *cli,
2171                                         const char *share, const char *dev,
2172                                         const char *pass, int passlen,
2173                                         struct tevent_req **psmbreq)
2174 {
2175         struct tevent_req *req, *subreq;
2176         struct cli_tcon_andx_state *state;
2177         uint8_t p24[24];
2178         uint16_t *vwv;
2179         char *tmp = NULL;
2180         uint8_t *bytes;
2181         uint16_t sec_mode = cli_state_security_mode(cli);
2182
2183         *psmbreq = NULL;
2184
2185         req = tevent_req_create(mem_ctx, &state, struct cli_tcon_andx_state);
2186         if (req == NULL) {
2187                 return NULL;
2188         }
2189         state->cli = cli;
2190         vwv = state->vwv;
2191
2192         cli->share = talloc_strdup(cli, share);
2193         if (!cli->share) {
2194                 return NULL;
2195         }
2196
2197         /* in user level security don't send a password now */
2198         if (sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {
2199                 passlen = 1;
2200                 pass = "";
2201         } else if (pass == NULL) {
2202                 DEBUG(1, ("Server not using user level security and no "
2203                           "password supplied.\n"));
2204                 goto access_denied;
2205         }
2206
2207         if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) &&
2208             *pass && passlen != 24) {
2209                 if (!lp_client_lanman_auth()) {
2210                         DEBUG(1, ("Server requested LANMAN password "
2211                                   "(share-level security) but "
2212                                   "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2213                         goto access_denied;
2214                 }
2215
2216                 /*
2217                  * Non-encrypted passwords - convert to DOS codepage before
2218                  * encryption.
2219                  */
2220                 SMBencrypt(pass, cli_state_server_challenge(cli), p24);
2221                 passlen = 24;
2222                 pass = (const char *)p24;
2223         } else {
2224                 if((sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL
2225                                      |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE))
2226                    == 0) {
2227                         uint8_t *tmp_pass;
2228
2229                         if (!lp_client_plaintext_auth() && (*pass)) {
2230                                 DEBUG(1, ("Server requested plaintext "
2231                                           "password but "
2232                                           "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2233                                 goto access_denied;
2234                         }
2235
2236                         /*
2237                          * Non-encrypted passwords - convert to DOS codepage
2238                          * before using.
2239                          */
2240                         tmp_pass = talloc_array(talloc_tos(), uint8, 0);
2241                         if (tevent_req_nomem(tmp_pass, req)) {
2242                                 return tevent_req_post(req, ev);
2243                         }
2244                         tmp_pass = trans2_bytes_push_str(tmp_pass,
2245                                                          false, /* always DOS */
2246                                                          pass,
2247                                                          passlen,
2248                                                          NULL);
2249                         if (tevent_req_nomem(tmp_pass, req)) {
2250                                 return tevent_req_post(req, ev);
2251                         }
2252                         pass = (const char *)tmp_pass;
2253                         passlen = talloc_get_size(tmp_pass);
2254                 }
2255         }
2256
2257         SCVAL(vwv+0, 0, 0xFF);
2258         SCVAL(vwv+0, 1, 0);
2259         SSVAL(vwv+1, 0, 0);
2260         SSVAL(vwv+2, 0, TCONX_FLAG_EXTENDED_RESPONSE);
2261         SSVAL(vwv+3, 0, passlen);
2262
2263         if (passlen && pass) {
2264                 bytes = (uint8_t *)talloc_memdup(state, pass, passlen);
2265         } else {
2266                 bytes = talloc_array(state, uint8_t, 0);
2267         }
2268
2269         /*
2270          * Add the sharename
2271          */
2272         tmp = talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
2273                                          cli_state_remote_name(cli), share);
2274         if (tmp == NULL) {
2275                 TALLOC_FREE(req);
2276                 return NULL;
2277         }
2278         bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), tmp, strlen(tmp)+1,
2279                                    NULL);
2280         TALLOC_FREE(tmp);
2281
2282         /*
2283          * Add the devicetype
2284          */
2285         tmp = talloc_strdup_upper(talloc_tos(), dev);
2286         if (tmp == NULL) {
2287                 TALLOC_FREE(req);
2288                 return NULL;
2289         }
2290         bytes = smb_bytes_push_str(bytes, false, tmp, strlen(tmp)+1, NULL);
2291         TALLOC_FREE(tmp);
2292
2293         if (bytes == NULL) {
2294                 TALLOC_FREE(req);
2295                 return NULL;
2296         }
2297
2298         state->bytes.iov_base = (void *)bytes;
2299         state->bytes.iov_len = talloc_get_size(bytes);
2300
2301         subreq = cli_smb_req_create(state, ev, cli, SMBtconX, 0, 4, vwv,
2302                                     1, &state->bytes);
2303         if (subreq == NULL) {
2304                 TALLOC_FREE(req);
2305                 return NULL;
2306         }
2307         tevent_req_set_callback(subreq, cli_tcon_andx_done, req);
2308         *psmbreq = subreq;
2309         return req;
2310
2311  access_denied:
2312         tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
2313         return tevent_req_post(req, ev);
2314 }
2315
2316 struct tevent_req *cli_tcon_andx_send(TALLOC_CTX *mem_ctx,
2317                                       struct event_context *ev,
2318                                       struct cli_state *cli,
2319                                       const char *share, const char *dev,
2320                                       const char *pass, int passlen)
2321 {
2322         struct tevent_req *req, *subreq;
2323         NTSTATUS status;
2324
2325         req = cli_tcon_andx_create(mem_ctx, ev, cli, share, dev, pass, passlen,
2326                                    &subreq);
2327         if (req == NULL) {
2328                 return NULL;
2329         }
2330         if (subreq == NULL) {
2331                 return req;
2332         }
2333         status = cli_smb_req_send(subreq);
2334         if (!NT_STATUS_IS_OK(status)) {
2335                 tevent_req_nterror(req, status);
2336                 return tevent_req_post(req, ev);
2337         }
2338         return req;
2339 }
2340
2341 static void cli_tcon_andx_done(struct tevent_req *subreq)
2342 {
2343         struct tevent_req *req = tevent_req_callback_data(
2344                 subreq, struct tevent_req);
2345         struct cli_tcon_andx_state *state = tevent_req_data(
2346                 req, struct cli_tcon_andx_state);
2347         struct cli_state *cli = state->cli;
2348         uint8_t *in;
2349         char *inbuf;
2350         uint8_t wct;
2351         uint16_t *vwv;
2352         uint32_t num_bytes;
2353         uint8_t *bytes;
2354         NTSTATUS status;
2355
2356         status = cli_smb_recv(subreq, state, &in, 0, &wct, &vwv,
2357                               &num_bytes, &bytes);
2358         TALLOC_FREE(subreq);
2359         if (!NT_STATUS_IS_OK(status)) {
2360                 tevent_req_nterror(req, status);
2361                 return;
2362         }
2363
2364         inbuf = (char *)in;
2365
2366         if (num_bytes) {
2367                 if (clistr_pull_talloc(cli,
2368                                 inbuf,
2369                                 SVAL(inbuf, smb_flg2),
2370                                 &cli->dev,
2371                                 bytes,
2372                                 num_bytes,
2373                                 STR_TERMINATE|STR_ASCII) == -1) {
2374                         tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2375                         return;
2376                 }
2377         } else {
2378                 cli->dev = talloc_strdup(cli, "");
2379                 if (cli->dev == NULL) {
2380                         tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2381                         return;
2382                 }
2383         }
2384
2385         if ((cli_state_protocol(cli) >= PROTOCOL_NT1) && (num_bytes == 3)) {
2386                 /* almost certainly win95 - enable bug fixes */
2387                 cli->win95 = True;
2388         }
2389
2390         /*
2391          * Make sure that we have the optional support 16-bit field. WCT > 2.
2392          * Avoids issues when connecting to Win9x boxes sharing files
2393          */
2394
2395         cli->dfsroot = false;
2396
2397         if ((wct > 2) && (cli_state_protocol(cli) >= PROTOCOL_LANMAN2)) {
2398                 cli->dfsroot = ((SVAL(vwv+2, 0) & SMB_SHARE_IN_DFS) != 0);
2399         }
2400
2401         cli->smb1.tid = SVAL(inbuf,smb_tid);
2402         tevent_req_done(req);
2403 }
2404
2405 NTSTATUS cli_tcon_andx_recv(struct tevent_req *req)
2406 {
2407         return tevent_req_simple_recv_ntstatus(req);
2408 }
2409
2410 NTSTATUS cli_tcon_andx(struct cli_state *cli, const char *share,
2411                        const char *dev, const char *pass, int passlen)
2412 {
2413         TALLOC_CTX *frame = talloc_stackframe();
2414         struct event_context *ev;
2415         struct tevent_req *req;
2416         NTSTATUS status = NT_STATUS_OK;
2417
2418         if (cli_has_async_calls(cli)) {
2419                 /*
2420                  * Can't use sync call while an async call is in flight
2421                  */
2422                 status = NT_STATUS_INVALID_PARAMETER;
2423                 goto fail;
2424         }
2425
2426         ev = event_context_init(frame);
2427         if (ev == NULL) {
2428                 status = NT_STATUS_NO_MEMORY;
2429                 goto fail;
2430         }
2431
2432         req = cli_tcon_andx_send(frame, ev, cli, share, dev, pass, passlen);
2433         if (req == NULL) {
2434                 status = NT_STATUS_NO_MEMORY;
2435                 goto fail;
2436         }
2437
2438         if (!tevent_req_poll(req, ev)) {
2439                 status = map_nt_error_from_unix(errno);
2440                 goto fail;
2441         }
2442
2443         status = cli_tcon_andx_recv(req);
2444  fail:
2445         TALLOC_FREE(frame);
2446         return status;
2447 }
2448
2449 /****************************************************************************
2450  Send a tree disconnect.
2451 ****************************************************************************/
2452
2453 struct cli_tdis_state {
2454         struct cli_state *cli;
2455 };
2456
2457 static void cli_tdis_done(struct tevent_req *subreq);
2458
2459 struct tevent_req *cli_tdis_send(TALLOC_CTX *mem_ctx,
2460                                  struct tevent_context *ev,
2461                                  struct cli_state *cli)
2462 {
2463         struct tevent_req *req, *subreq;
2464         struct cli_tdis_state *state;
2465
2466         req = tevent_req_create(mem_ctx, &state, struct cli_tdis_state);
2467         if (req == NULL) {
2468                 return NULL;
2469         }
2470         state->cli = cli;
2471
2472         subreq = cli_smb_send(state, ev, cli, SMBtdis, 0, 0, NULL, 0, NULL);
2473         if (tevent_req_nomem(subreq, req)) {
2474                 return tevent_req_post(req, ev);
2475         }
2476         tevent_req_set_callback(subreq, cli_tdis_done, req);
2477         return req;
2478 }
2479
2480 static void cli_tdis_done(struct tevent_req *subreq)
2481 {
2482         struct tevent_req *req = tevent_req_callback_data(
2483                 subreq, struct tevent_req);
2484         struct cli_tdis_state *state = tevent_req_data(
2485                 req, struct cli_tdis_state);
2486         NTSTATUS status;
2487
2488         status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
2489         TALLOC_FREE(subreq);
2490         if (!NT_STATUS_IS_OK(status)) {
2491                 tevent_req_nterror(req, status);
2492                 return;
2493         }
2494         state->cli->smb1.tid = UINT16_MAX;
2495         tevent_req_done(req);
2496 }
2497
2498 NTSTATUS cli_tdis_recv(struct tevent_req *req)
2499 {
2500         return tevent_req_simple_recv_ntstatus(req);
2501 }
2502
2503 NTSTATUS cli_tdis(struct cli_state *cli)
2504 {
2505         struct tevent_context *ev;
2506         struct tevent_req *req;
2507         NTSTATUS status = NT_STATUS_NO_MEMORY;
2508
2509         if (cli_has_async_calls(cli)) {
2510                 return NT_STATUS_INVALID_PARAMETER;
2511         }
2512         ev = tevent_context_init(talloc_tos());
2513         if (ev == NULL) {
2514                 goto fail;
2515         }
2516         req = cli_tdis_send(ev, ev, cli);
2517         if (req == NULL) {
2518                 goto fail;
2519         }
2520         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2521                 goto fail;
2522         }
2523         status = cli_tdis_recv(req);
2524 fail:
2525         TALLOC_FREE(ev);
2526         return status;
2527 }
2528
2529 /****************************************************************************
2530  Send a negprot command.
2531 ****************************************************************************/
2532
2533 struct cli_negprot_state {
2534         struct cli_state *cli;
2535         enum protocol_types max_protocol;
2536 };
2537
2538 static void cli_negprot_done(struct tevent_req *subreq);
2539
2540 struct tevent_req *cli_negprot_send(TALLOC_CTX *mem_ctx,
2541                                     struct event_context *ev,
2542                                     struct cli_state *cli,
2543                                     enum protocol_types max_protocol)
2544 {
2545         struct tevent_req *req, *subreq;
2546         struct cli_negprot_state *state;
2547         uint8_t *bytes = NULL;
2548         int numprots;
2549         enum protocol_types tmp_protocol;
2550
2551         req = tevent_req_create(mem_ctx, &state, struct cli_negprot_state);
2552         if (req == NULL) {
2553                 return NULL;
2554         }
2555         state->cli = cli;
2556         state->max_protocol = max_protocol;
2557
2558         /* setup the protocol strings */
2559         for (numprots=0; numprots < ARRAY_SIZE(prots); numprots++) {
2560                 uint8_t c = 2;
2561                 if (prots[numprots].prot > state->max_protocol) {
2562                         break;
2563                 }
2564                 bytes = (uint8_t *)talloc_append_blob(
2565                         state, bytes, data_blob_const(&c, sizeof(c)));
2566                 if (tevent_req_nomem(bytes, req)) {
2567                         return tevent_req_post(req, ev);
2568                 }
2569                 bytes = smb_bytes_push_str(bytes, false,
2570                                            prots[numprots].name,
2571                                            strlen(prots[numprots].name)+1,
2572                                            NULL);
2573                 if (tevent_req_nomem(bytes, req)) {
2574                         return tevent_req_post(req, ev);
2575                 }
2576         }
2577
2578         tmp_protocol = cli->conn.protocol;
2579         cli->conn.protocol = state->max_protocol;
2580         subreq = cli_smb_send(state, ev, cli, SMBnegprot, 0, 0, NULL,
2581                               talloc_get_size(bytes), bytes);
2582         cli->conn.protocol = tmp_protocol;
2583         if (tevent_req_nomem(subreq, req)) {
2584                 return tevent_req_post(req, ev);
2585         }
2586         tevent_req_set_callback(subreq, cli_negprot_done, req);
2587         return req;
2588 }
2589
2590 static void cli_negprot_done(struct tevent_req *subreq)
2591 {
2592         struct tevent_req *req = tevent_req_callback_data(
2593                 subreq, struct tevent_req);
2594         struct cli_negprot_state *state = tevent_req_data(
2595                 req, struct cli_negprot_state);
2596         struct cli_state *cli = state->cli;
2597         uint8_t flags;
2598         uint8_t wct;
2599         uint16_t *vwv;
2600         uint32_t num_bytes;
2601         uint8_t *bytes;
2602         NTSTATUS status;
2603         uint16_t protnum;
2604         uint8_t *inbuf;
2605         uint32_t client_capabilities = cli->conn.smb1.client.capabilities;
2606         uint32_t both_capabilities;
2607         uint32_t server_capabilities = 0;
2608         uint32_t capabilities;
2609         uint32_t client_max_xmit = cli->conn.smb1.client.max_xmit;
2610         uint32_t server_max_xmit = 0;
2611         uint32_t max_xmit;
2612         uint32_t server_max_mux = 0;
2613         uint16_t server_security_mode = 0;
2614         uint32_t server_session_key = 0;
2615         bool server_readbraw = false;
2616         bool server_writebraw = false;
2617         bool server_lockread = false;
2618         bool server_writeunlock = false;
2619         struct GUID server_guid = GUID_zero();
2620         DATA_BLOB server_gss_blob = data_blob_null;
2621         uint8_t server_challenge[8];
2622         char *server_workgroup = NULL;
2623         char *server_name = NULL;
2624         int server_time_zone = 0;
2625         time_t server_system_time = 0;
2626         enum protocol_types protocol;
2627
2628         ZERO_STRUCT(server_challenge);
2629
2630         status = cli_smb_recv(subreq, state, &inbuf, 1, &wct, &vwv,
2631                               &num_bytes, &bytes);
2632         TALLOC_FREE(subreq);
2633         if (!NT_STATUS_IS_OK(status)) {
2634                 tevent_req_nterror(req, status);
2635                 return;
2636         }
2637
2638         flags = CVAL(inbuf, smb_flg);
2639
2640         protnum = SVAL(vwv, 0);
2641
2642         if ((protnum >= ARRAY_SIZE(prots))
2643             || (prots[protnum].prot > state->max_protocol)) {
2644                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2645                 return;
2646         }
2647
2648         protocol = prots[protnum].prot;
2649
2650         if ((protocol < PROTOCOL_NT1) &&
2651             client_is_signing_mandatory(cli)) {
2652                 DEBUG(0,("cli_negprot: SMB signing is mandatory and the selected protocol level doesn't support it.\n"));
2653                 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
2654                 return;
2655         }
2656
2657         if (flags & FLAG_SUPPORT_LOCKREAD) {
2658                 server_lockread = true;
2659                 server_writeunlock = true;
2660         }
2661
2662         if (protocol >= PROTOCOL_NT1) {
2663                 struct timespec ts;
2664                 const char *client_signing = NULL;
2665                 bool server_mandatory;
2666                 bool server_allowed;
2667                 const char *server_signing = NULL;
2668                 bool ok;
2669                 uint16_t key_len;
2670
2671                 if (wct != 0x11) {
2672                         tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2673                         return;
2674                 }
2675
2676                 /* NT protocol */
2677                 server_security_mode = CVAL(vwv + 1, 0);
2678                 server_max_mux = SVAL(vwv + 1, 1);
2679                 server_max_xmit = IVAL(vwv + 3, 1);
2680                 server_session_key = IVAL(vwv + 7, 1);
2681                 server_time_zone = SVALS(vwv + 15, 1);
2682                 server_time_zone *= 60;
2683                 /* this time arrives in real GMT */
2684                 ts = interpret_long_date(((char *)(vwv+11))+1);
2685                 server_system_time = ts.tv_sec;
2686                 server_capabilities = IVAL(vwv + 9, 1);
2687
2688                 key_len = CVAL(vwv + 16, 1);
2689
2690                 if (server_capabilities & CAP_RAW_MODE) {
2691                         server_readbraw = true;
2692                         server_writebraw = true;
2693                 }
2694                 if (server_capabilities & CAP_LOCK_AND_READ) {
2695                         server_lockread = true;
2696                 }
2697
2698                 if (server_capabilities & CAP_EXTENDED_SECURITY) {
2699                         DATA_BLOB blob1, blob2;
2700
2701                         if (num_bytes < 16) {
2702                                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2703                                 return;
2704                         }
2705
2706                         blob1 = data_blob_const(bytes, 16);
2707                         GUID_from_data_blob(&blob1, &server_guid);
2708
2709                         blob1 = data_blob_const(bytes+16, num_bytes-16);
2710                         blob2 = data_blob_dup_talloc(state, blob1);
2711                         if (blob1.length > 0 &&
2712                             tevent_req_nomem(blob2.data, req)) {
2713                                 return;
2714                         }
2715                         server_gss_blob = blob2;
2716                 } else {
2717                         DATA_BLOB blob1, blob2;
2718                         ssize_t ret = 0;
2719
2720                         if (num_bytes < key_len) {
2721                                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2722                                 return;
2723                         }
2724
2725                         if (key_len != 0 && key_len != 8) {
2726                                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2727                                 return;
2728                         }
2729
2730                         if (key_len == 8) {
2731                                 memcpy(server_challenge, bytes, 8);
2732                         }
2733
2734                         blob1 = data_blob_const(bytes+key_len, num_bytes-key_len);
2735                         blob2 = data_blob_const(bytes+key_len, num_bytes-key_len);
2736                         if (blob1.length > 0) {
2737                                 ret = pull_string_talloc(state,
2738                                                          (char *)inbuf,
2739                                                          SVAL(inbuf, smb_flg2),
2740                                                          &server_workgroup,
2741                                                          blob1.data,
2742                                                          blob1.length,
2743                                                          STR_TERMINATE|
2744                                                          STR_UNICODE|
2745                                                          STR_NOALIGN);
2746                                 if (ret == -1) {
2747                                         tevent_req_oom(req);
2748                                         return;
2749                                 }
2750                         }
2751
2752                         blob2.data += ret;
2753                         blob2.length -= ret;
2754                         if (blob2.length > 0) {
2755                                 ret = pull_string_talloc(state,
2756                                                          (char *)inbuf,
2757                                                          SVAL(inbuf, smb_flg2),
2758                                                          &server_name,
2759                                                          blob2.data,
2760                                                          blob2.length,
2761                                                          STR_TERMINATE|
2762                                                          STR_UNICODE|
2763                                                          STR_NOALIGN);
2764                                 if (ret == -1) {
2765                                         tevent_req_oom(req);
2766                                         return;
2767                                 }
2768                         }
2769                 }
2770
2771                 client_signing = "disabled";
2772                 if (client_is_signing_allowed(cli)) {
2773                         client_signing = "allowed";
2774                 }
2775                 if (client_is_signing_mandatory(cli)) {
2776                         client_signing = "required";
2777                 }
2778
2779                 server_signing = "not supported";
2780
2781                 server_allowed = false;
2782                 if (server_security_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) {
2783                         server_signing = "supported";
2784                         server_allowed = true;
2785                 }
2786
2787                 server_mandatory = false;
2788                 if (server_security_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) {
2789                         server_signing = "required";
2790                         server_mandatory = true;
2791                 }
2792
2793                 ok = cli_set_signing_negotiated(cli,
2794                                                 server_allowed,
2795                                                 server_mandatory);
2796                 if (!ok) {
2797                         DEBUG(1,("cli_negprot: SMB signing is required, "
2798                                  "but client[%s] and server[%s] mismatch\n",
2799                                  client_signing, server_signing));
2800                         tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
2801                         return;
2802                 }
2803
2804         } else if (protocol >= PROTOCOL_LANMAN1) {
2805                 if (wct != 0x0D) {
2806                         tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2807                         return;
2808                 }
2809
2810                 server_security_mode = SVAL(vwv + 1, 0);
2811                 server_max_xmit = SVAL(vwv + 2, 0);
2812                 server_max_mux = SVAL(vwv + 3, 0);
2813                 server_session_key = IVAL(vwv + 6, 0);
2814                 server_time_zone = SVALS(vwv + 10, 0);
2815                 server_time_zone *= 60;
2816                 /* this time is converted to GMT by make_unix_date */
2817                 server_system_time = make_unix_date(
2818                         (char *)(vwv + 8), server_time_zone);
2819                 server_readbraw = ((SVAL(vwv + 5, 0) & 0x1) != 0);
2820                 server_writebraw = ((SVAL(vwv + 5, 0) & 0x2) != 0);
2821
2822                 if (num_bytes != 0 && num_bytes != 8) {
2823                         tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2824                         return;
2825                 }
2826
2827                 if (num_bytes == 8) {
2828                         memcpy(server_challenge, bytes, 8);
2829                 }
2830         } else {
2831                 /* the old core protocol */
2832                 server_time_zone = get_time_zone(time(NULL));
2833                 server_system_time = 0;
2834                 server_max_xmit = 1024;
2835                 server_max_mux = 1;
2836                 server_security_mode = 0;
2837         }
2838
2839         if (server_max_xmit < 1024) {
2840                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2841                 return;
2842         }
2843
2844         if (server_max_mux < 1) {
2845                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2846                 return;
2847         }
2848
2849         /*
2850          * Now calculate the negotiated capabilities
2851          * based on the mask for:
2852          * - client only flags
2853          * - flags used in both directions
2854          * - server only flags
2855          */
2856         both_capabilities = client_capabilities & server_capabilities;
2857         capabilities = client_capabilities & SMB_CAP_CLIENT_MASK;
2858         capabilities |= both_capabilities & SMB_CAP_BOTH_MASK;
2859         capabilities |= server_capabilities & SMB_CAP_SERVER_MASK;
2860
2861         max_xmit = MIN(client_max_xmit, server_max_xmit);
2862
2863         if (server_workgroup) {
2864                 cli->server_domain = talloc_strdup(cli, server_workgroup);
2865                 if (tevent_req_nomem(cli->server_domain, req)) {
2866                         return;
2867                 }
2868         }
2869
2870         cli->conn.protocol = protocol;
2871
2872         cli->conn.smb1.server.capabilities = server_capabilities;
2873         cli->conn.smb1.capabilities = capabilities;
2874
2875         cli->conn.smb1.server.max_xmit = server_max_xmit;
2876         cli->conn.smb1.max_xmit = max_xmit;
2877
2878         cli->conn.smb1.server.max_mux = server_max_mux;
2879
2880         cli->conn.smb1.server.security_mode = server_security_mode;
2881
2882         cli->conn.smb1.server.readbraw = server_readbraw;
2883         cli->conn.smb1.server.writebraw = server_writebraw;
2884         cli->conn.smb1.server.lockread = server_lockread;
2885         cli->conn.smb1.server.writeunlock = server_writeunlock;
2886
2887         cli->conn.smb1.server.session_key = server_session_key;
2888
2889         talloc_steal(cli, server_gss_blob.data);
2890         cli->conn.smb1.server.gss_blob = server_gss_blob;
2891         cli->conn.smb1.server.guid = server_guid;
2892         memcpy(cli->conn.smb1.server.challenge, server_challenge, 8);
2893         cli->conn.smb1.server.workgroup = talloc_move(cli, &server_workgroup);
2894         cli->conn.smb1.server.name = talloc_move(cli, &server_name);
2895
2896         cli->conn.smb1.server.time_zone = server_time_zone;
2897         cli->conn.smb1.server.system_time = server_system_time;
2898
2899         tevent_req_done(req);
2900 }
2901
2902 NTSTATUS cli_negprot_recv(struct tevent_req *req)
2903 {
2904         return tevent_req_simple_recv_ntstatus(req);
2905 }
2906
2907 NTSTATUS cli_negprot(struct cli_state *cli, enum protocol_types max_protocol)
2908 {
2909         TALLOC_CTX *frame = talloc_stackframe();
2910         struct event_context *ev;
2911         struct tevent_req *req;
2912         NTSTATUS status = NT_STATUS_OK;
2913
2914         if (cli_has_async_calls(cli)) {
2915                 /*
2916                  * Can't use sync call while an async call is in flight
2917                  */
2918                 status = NT_STATUS_INVALID_PARAMETER;
2919                 goto fail;
2920         }
2921
2922         ev = event_context_init(frame);
2923         if (ev == NULL) {
2924                 status = NT_STATUS_NO_MEMORY;
2925                 goto fail;
2926         }
2927
2928         req = cli_negprot_send(frame, ev, cli, max_protocol);
2929         if (req == NULL) {
2930                 status = NT_STATUS_NO_MEMORY;
2931                 goto fail;
2932         }
2933
2934         if (!tevent_req_poll(req, ev)) {
2935                 status = map_nt_error_from_unix(errno);
2936                 goto fail;
2937         }
2938
2939         status = cli_negprot_recv(req);
2940  fail:
2941         TALLOC_FREE(frame);
2942         return status;
2943 }
2944
2945 static NTSTATUS cli_connect_sock(const char *host, int name_type,
2946                                  const struct sockaddr_storage *pss,
2947                                  const char *myname, uint16_t port,
2948                                  int sec_timeout, int *pfd, uint16_t *pport)
2949 {
2950         TALLOC_CTX *frame = talloc_stackframe();
2951         const char *prog;
2952         unsigned int i, num_addrs;
2953         const char **called_names;
2954         const char **calling_names;
2955         int *called_types;
2956         NTSTATUS status;
2957         int fd;
2958
2959         prog = getenv("LIBSMB_PROG");
2960         if (prog != NULL) {
2961                 fd = sock_exec(prog);
2962                 if (fd == -1) {
2963                         return map_nt_error_from_unix(errno);
2964                 }
2965                 port = 0;
2966                 goto done;
2967         }
2968
2969         if ((pss == NULL) || is_zero_addr(pss)) {
2970                 struct sockaddr_storage *addrs;
2971                 status = resolve_name_list(talloc_tos(), host, name_type,
2972                                            &addrs, &num_addrs);
2973                 if (!NT_STATUS_IS_OK(status)) {
2974                         goto fail;
2975                 }
2976                 pss = addrs;
2977         } else {
2978                 num_addrs = 1;
2979         }
2980
2981         called_names = talloc_array(talloc_tos(), const char *, num_addrs);
2982         if (called_names == NULL) {
2983                 status = NT_STATUS_NO_MEMORY;
2984                 goto fail;
2985         }
2986         called_types = talloc_array(talloc_tos(), int, num_addrs);
2987         if (called_types == NULL) {
2988                 status = NT_STATUS_NO_MEMORY;
2989                 goto fail;
2990         }
2991         calling_names = talloc_array(talloc_tos(), const char *, num_addrs);
2992         if (calling_names == NULL) {
2993                 status = NT_STATUS_NO_MEMORY;
2994                 goto fail;
2995         }
2996         for (i=0; i<num_addrs; i++) {
2997                 called_names[i] = host;
2998                 called_types[i] = name_type;
2999                 calling_names[i] = myname;
3000         }
3001         status = smbsock_any_connect(pss, called_names, called_types,
3002                                      calling_names, NULL, num_addrs, port,
3003                                      sec_timeout, &fd, NULL, &port);
3004         if (!NT_STATUS_IS_OK(status)) {
3005                 goto fail;
3006         }
3007         set_socket_options(fd, lp_socket_options());
3008 done:
3009         *pfd = fd;
3010         *pport = port;
3011         status = NT_STATUS_OK;
3012 fail:
3013         TALLOC_FREE(frame);
3014         return status;
3015 }
3016
3017 NTSTATUS cli_connect_nb(const char *host, const struct sockaddr_storage *dest_ss,
3018                         uint16_t port, int name_type, const char *myname,
3019                         int signing_state, int flags, struct cli_state **pcli)
3020 {
3021         TALLOC_CTX *frame = talloc_stackframe();
3022         struct cli_state *cli;
3023         NTSTATUS status = NT_STATUS_NO_MEMORY;
3024         int fd = -1;
3025         char *desthost;
3026         char *p;
3027
3028         desthost = talloc_strdup(talloc_tos(), host);
3029         if (desthost == NULL) {
3030                 goto fail;
3031         }
3032
3033         p = strchr(host, '#');
3034         if (p != NULL) {
3035                 name_type = strtol(p+1, NULL, 16);
3036                 host = talloc_strndup(talloc_tos(), host, p - host);
3037                 if (host == NULL) {
3038                         goto fail;
3039                 }
3040         }
3041
3042         status = cli_connect_sock(host, name_type, dest_ss, myname, port,
3043                                   20, &fd, &port);
3044         if (!NT_STATUS_IS_OK(status)) {
3045                 goto fail;
3046         }
3047
3048         cli = cli_state_create(NULL, fd, desthost, NULL, signing_state, flags);
3049         if (cli == NULL) {
3050                 goto fail;
3051         }
3052
3053         *pcli = cli;
3054         status = NT_STATUS_OK;
3055 fail:
3056         TALLOC_FREE(frame);
3057         return status;
3058 }
3059
3060 /**
3061    establishes a connection to after the negprot. 
3062    @param output_cli A fully initialised cli structure, non-null only on success
3063    @param dest_host The netbios name of the remote host
3064    @param dest_ss (optional) The the destination IP, NULL for name based lookup
3065    @param port (optional) The destination port (0 for default)
3066 */
3067 NTSTATUS cli_start_connection(struct cli_state **output_cli, 
3068                               const char *my_name, 
3069                               const char *dest_host, 
3070                               const struct sockaddr_storage *dest_ss, int port,
3071                               int signing_state, int flags)
3072 {
3073         NTSTATUS nt_status;
3074         struct cli_state *cli;
3075
3076         nt_status = cli_connect_nb(dest_host, dest_ss, port, 0x20, my_name,
3077                                    signing_state, flags, &cli);
3078         if (!NT_STATUS_IS_OK(nt_status)) {
3079                 DEBUG(10, ("cli_connect_nb failed: %s\n",
3080                            nt_errstr(nt_status)));
3081                 return nt_status;
3082         }
3083
3084         nt_status = cli_negprot(cli, PROTOCOL_NT1);
3085         if (!NT_STATUS_IS_OK(nt_status)) {
3086                 DEBUG(1, ("failed negprot: %s\n", nt_errstr(nt_status)));
3087                 cli_shutdown(cli);
3088                 return nt_status;
3089         }
3090
3091         *output_cli = cli;
3092         return NT_STATUS_OK;
3093 }
3094
3095
3096 /**
3097    establishes a connection right up to doing tconX, password specified.
3098    @param output_cli A fully initialised cli structure, non-null only on success
3099    @param dest_host The netbios name of the remote host
3100    @param dest_ip (optional) The the destination IP, NULL for name based lookup
3101    @param port (optional) The destination port (0 for default)
3102    @param service (optional) The share to make the connection to.  Should be 'unqualified' in any way.
3103    @param service_type The 'type' of serivice. 
3104    @param user Username, unix string
3105    @param domain User's domain
3106    @param password User's password, unencrypted unix string.
3107 */
3108
3109 NTSTATUS cli_full_connection(struct cli_state **output_cli, 
3110                              const char *my_name, 
3111                              const char *dest_host, 
3112                              const struct sockaddr_storage *dest_ss, int port,
3113                              const char *service, const char *service_type,
3114                              const char *user, const char *domain, 
3115                              const char *password, int flags,
3116                              int signing_state)
3117 {
3118         NTSTATUS nt_status;
3119         struct cli_state *cli = NULL;
3120         int pw_len = password ? strlen(password)+1 : 0;
3121
3122         *output_cli = NULL;
3123
3124         if (password == NULL) {
3125                 password = "";
3126         }
3127
3128         nt_status = cli_start_connection(&cli, my_name, dest_host,
3129                                          dest_ss, port, signing_state,
3130                                          flags);
3131
3132         if (!NT_STATUS_IS_OK(nt_status)) {
3133                 return nt_status;
3134         }
3135
3136         nt_status = cli_session_setup(cli, user, password, pw_len, password,
3137                                       pw_len, domain);
3138         if (!NT_STATUS_IS_OK(nt_status)) {
3139
3140                 if (!(flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)) {
3141                         DEBUG(1,("failed session setup with %s\n",
3142                                  nt_errstr(nt_status)));
3143                         cli_shutdown(cli);
3144                         return nt_status;
3145                 }
3146
3147                 nt_status = cli_session_setup(cli, "", "", 0, "", 0, domain);
3148                 if (!NT_STATUS_IS_OK(nt_status)) {
3149                         DEBUG(1,("anonymous failed session setup with %s\n",
3150                                  nt_errstr(nt_status)));
3151                         cli_shutdown(cli);
3152                         return nt_status;
3153                 }
3154         }
3155
3156         if (service) {
3157                 nt_status = cli_tcon_andx(cli, service, service_type, password,
3158                                           pw_len);
3159                 if (!NT_STATUS_IS_OK(nt_status)) {
3160                         DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status)));
3161                         cli_shutdown(cli);
3162                         if (NT_STATUS_IS_OK(nt_status)) {
3163                                 nt_status = NT_STATUS_UNSUCCESSFUL;
3164                         }
3165                         return nt_status;
3166                 }
3167         }
3168
3169         nt_status = cli_init_creds(cli, user, domain, password);
3170         if (!NT_STATUS_IS_OK(nt_status)) {
3171                 cli_shutdown(cli);
3172                 return nt_status;
3173         }
3174
3175         *output_cli = cli;
3176         return NT_STATUS_OK;
3177 }
3178
3179 /****************************************************************************
3180  Send an old style tcon.
3181 ****************************************************************************/
3182 NTSTATUS cli_raw_tcon(struct cli_state *cli, 
3183                       const char *service, const char *pass, const char *dev,
3184                       uint16 *max_xmit, uint16 *tid)
3185 {
3186         struct tevent_req *req;
3187         uint16_t *ret_vwv;
3188         uint8_t *bytes;
3189         NTSTATUS status;
3190
3191         if (!lp_client_plaintext_auth() && (*pass)) {
3192                 DEBUG(1, ("Server requested plaintext password but 'client "
3193                           "plaintext auth' is disabled\n"));
3194                 return NT_STATUS_ACCESS_DENIED;
3195         }
3196
3197         bytes = talloc_array(talloc_tos(), uint8_t, 0);
3198         bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3199         bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
3200                                    service, strlen(service)+1, NULL);
3201         bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3202         bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
3203                                    pass, strlen(pass)+1, NULL);
3204         bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3205         bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
3206                                    dev, strlen(dev)+1, NULL);
3207
3208         status = cli_smb(talloc_tos(), cli, SMBtcon, 0, 0, NULL,
3209                          talloc_get_size(bytes), bytes, &req,
3210                          2, NULL, &ret_vwv, NULL, NULL);
3211         if (!NT_STATUS_IS_OK(status)) {
3212                 return status;
3213         }
3214
3215         *max_xmit = SVAL(ret_vwv + 0, 0);
3216         *tid = SVAL(ret_vwv + 1, 0);
3217
3218         return NT_STATUS_OK;
3219 }
3220
3221 /* Return a cli_state pointing at the IPC$ share for the given server */
3222
3223 struct cli_state *get_ipc_connect(char *server,
3224                                 struct sockaddr_storage *server_ss,
3225                                 const struct user_auth_info *user_info)
3226 {
3227         struct cli_state *cli;
3228         NTSTATUS nt_status;
3229         uint32_t flags = CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
3230
3231         if (user_info->use_kerberos) {
3232                 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
3233         }
3234
3235         nt_status = cli_full_connection(&cli, NULL, server, server_ss, 0, "IPC$", "IPC", 
3236                                         user_info->username ? user_info->username : "",
3237                                         lp_workgroup(),
3238                                         user_info->password ? user_info->password : "",
3239                                         flags,
3240                                         SMB_SIGNING_DEFAULT);
3241
3242         if (NT_STATUS_IS_OK(nt_status)) {
3243                 return cli;
3244         } else if (is_ipaddress(server)) {
3245             /* windows 9* needs a correct NMB name for connections */
3246             fstring remote_name;
3247
3248             if (name_status_find("*", 0, 0, server_ss, remote_name)) {
3249                 cli = get_ipc_connect(remote_name, server_ss, user_info);
3250                 if (cli)
3251                     return cli;
3252             }
3253         }
3254         return NULL;
3255 }
3256
3257 /*
3258  * Given the IP address of a master browser on the network, return its
3259  * workgroup and connect to it.
3260  *
3261  * This function is provided to allow additional processing beyond what
3262  * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
3263  * browsers and obtain each master browsers' list of domains (in case the
3264  * first master browser is recently on the network and has not yet
3265  * synchronized with other master browsers and therefore does not yet have the
3266  * entire network browse list)
3267  */
3268
3269 struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx,
3270                                 struct sockaddr_storage *mb_ip,
3271                                 const struct user_auth_info *user_info,
3272                                 char **pp_workgroup_out)
3273 {
3274         char addr[INET6_ADDRSTRLEN];
3275         fstring name;
3276         struct cli_state *cli;
3277         struct sockaddr_storage server_ss;
3278
3279         *pp_workgroup_out = NULL;
3280
3281         print_sockaddr(addr, sizeof(addr), mb_ip);
3282         DEBUG(99, ("Looking up name of master browser %s\n",
3283                    addr));
3284
3285         /*
3286          * Do a name status query to find out the name of the master browser.
3287          * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
3288          * master browser will not respond to a wildcard query (or, at least,
3289          * an NT4 server acting as the domain master browser will not).
3290          *
3291          * We might be able to use ONLY the query on MSBROWSE, but that's not
3292          * yet been tested with all Windows versions, so until it is, leave
3293          * the original wildcard query as the first choice and fall back to
3294          * MSBROWSE if the wildcard query fails.
3295          */
3296         if (!name_status_find("*", 0, 0x1d, mb_ip, name) &&
3297             !name_status_find(MSBROWSE, 1, 0x1d, mb_ip, name)) {
3298
3299                 DEBUG(99, ("Could not retrieve name status for %s\n",
3300                            addr));
3301                 return NULL;
3302         }
3303
3304         if (!find_master_ip(name, &server_ss)) {
3305                 DEBUG(99, ("Could not find master ip for %s\n", name));
3306                 return NULL;
3307         }
3308
3309         *pp_workgroup_out = talloc_strdup(ctx, name);
3310
3311         DEBUG(4, ("found master browser %s, %s\n", name, addr));
3312
3313         print_sockaddr(addr, sizeof(addr), &server_ss);
3314         cli = get_ipc_connect(addr, &server_ss, user_info);
3315
3316         return cli;
3317 }
3318
3319 /*
3320  * Return the IP address and workgroup of a master browser on the network, and
3321  * connect to it.
3322  */
3323
3324 struct cli_state *get_ipc_connect_master_ip_bcast(TALLOC_CTX *ctx,
3325                                         const struct user_auth_info *user_info,
3326                                         char **pp_workgroup_out)
3327 {
3328         struct sockaddr_storage *ip_list;
3329         struct cli_state *cli;
3330         int i, count;
3331         NTSTATUS status;
3332
3333         *pp_workgroup_out = NULL;
3334
3335         DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
3336
3337         /* Go looking for workgroups by broadcasting on the local network */
3338
3339         status = name_resolve_bcast(MSBROWSE, 1, talloc_tos(),
3340                                     &ip_list, &count);
3341         if (!NT_STATUS_IS_OK(status)) {
3342                 DEBUG(99, ("No master browsers responded: %s\n",
3343                            nt_errstr(status)));
3344                 return False;
3345         }
3346
3347         for (i = 0; i < count; i++) {
3348                 char addr[INET6_ADDRSTRLEN];
3349                 print_sockaddr(addr, sizeof(addr), &ip_list[i]);
3350                 DEBUG(99, ("Found master browser %s\n", addr));
3351
3352                 cli = get_ipc_connect_master_ip(ctx, &ip_list[i],
3353                                 user_info, pp_workgroup_out);
3354                 if (cli)
3355                         return(cli);
3356         }
3357
3358         return NULL;
3359 }