s3:libsmb: s/Undefined/SMB_SIGNING_DEFAULT/
[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         int server_time_zone = 0;
2624         time_t server_system_time = 0;
2625         enum protocol_types protocol;
2626
2627         ZERO_STRUCT(server_challenge);
2628
2629         status = cli_smb_recv(subreq, state, &inbuf, 1, &wct, &vwv,
2630                               &num_bytes, &bytes);
2631         TALLOC_FREE(subreq);
2632         if (!NT_STATUS_IS_OK(status)) {
2633                 tevent_req_nterror(req, status);
2634                 return;
2635         }
2636
2637         flags = CVAL(inbuf, smb_flg);
2638
2639         protnum = SVAL(vwv, 0);
2640
2641         if ((protnum >= ARRAY_SIZE(prots))
2642             || (prots[protnum].prot > state->max_protocol)) {
2643                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2644                 return;
2645         }
2646
2647         protocol = prots[protnum].prot;
2648
2649         if ((protocol < PROTOCOL_NT1) &&
2650             client_is_signing_mandatory(cli)) {
2651                 DEBUG(0,("cli_negprot: SMB signing is mandatory and the selected protocol level doesn't support it.\n"));
2652                 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
2653                 return;
2654         }
2655
2656         if (flags & FLAG_SUPPORT_LOCKREAD) {
2657                 server_lockread = true;
2658                 server_writeunlock = true;
2659         }
2660
2661         if (protocol >= PROTOCOL_NT1) {
2662                 struct timespec ts;
2663                 const char *client_signing = NULL;
2664                 bool server_mandatory;
2665                 bool server_allowed;
2666                 const char *server_signing = NULL;
2667                 bool ok;
2668                 uint16_t key_len;
2669
2670                 if (wct != 0x11) {
2671                         tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2672                         return;
2673                 }
2674
2675                 /* NT protocol */
2676                 server_security_mode = CVAL(vwv + 1, 0);
2677                 server_max_mux = SVAL(vwv + 1, 1);
2678                 server_max_xmit = IVAL(vwv + 3, 1);
2679                 server_session_key = IVAL(vwv + 7, 1);
2680                 server_time_zone = SVALS(vwv + 15, 1);
2681                 server_time_zone *= 60;
2682                 /* this time arrives in real GMT */
2683                 ts = interpret_long_date(((char *)(vwv+11))+1);
2684                 server_system_time = ts.tv_sec;
2685                 server_capabilities = IVAL(vwv + 9, 1);
2686
2687                 key_len = CVAL(vwv + 16, 1);
2688
2689                 if (server_capabilities & CAP_RAW_MODE) {
2690                         server_readbraw = true;
2691                         server_writebraw = true;
2692                 }
2693                 if (server_capabilities & CAP_LOCK_AND_READ) {
2694                         server_lockread = true;
2695                 }
2696
2697                 if (server_capabilities & CAP_EXTENDED_SECURITY) {
2698                         DATA_BLOB blob1, blob2;
2699
2700                         if (num_bytes < 16) {
2701                                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2702                                 return;
2703                         }
2704
2705                         blob1 = data_blob_const(bytes, 16);
2706                         GUID_from_data_blob(&blob1, &server_guid);
2707
2708                         blob1 = data_blob_const(bytes+16, num_bytes-16);
2709                         blob2 = data_blob_dup_talloc(state, blob1);
2710                         if (blob1.length > 0 &&
2711                             tevent_req_nomem(blob2.data, req)) {
2712                                 return;
2713                         }
2714                         server_gss_blob = blob2;
2715                 } else {
2716                         DATA_BLOB blob1;
2717                         ssize_t ret;
2718
2719                         if (num_bytes < key_len) {
2720                                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2721                                 return;
2722                         }
2723
2724                         if (key_len != 0 && key_len != 8) {
2725                                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2726                                 return;
2727                         }
2728
2729                         if (key_len == 8) {
2730                                 memcpy(server_challenge, bytes, 8);
2731                         }
2732
2733                         blob1 = data_blob_const(bytes+key_len, num_bytes-key_len);
2734                         if (blob1.length > 0) {
2735                                 ret = pull_string_talloc(state,
2736                                                          (char *)inbuf,
2737                                                          SVAL(inbuf, smb_flg2),
2738                                                          &server_workgroup,
2739                                                          blob1.data, blob1.length,
2740                                                          STR_TERMINATE);
2741                                 if (ret == -1) {
2742                                         tevent_req_oom(req);
2743                                         return;
2744                                 }
2745                         }
2746                 }
2747
2748                 client_signing = "disabled";
2749                 if (client_is_signing_allowed(cli)) {
2750                         client_signing = "allowed";
2751                 }
2752                 if (client_is_signing_mandatory(cli)) {
2753                         client_signing = "required";
2754                 }
2755
2756                 server_signing = "not supported";
2757
2758                 server_allowed = false;
2759                 if (server_security_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) {
2760                         server_signing = "supported";
2761                         server_allowed = true;
2762                 }
2763
2764                 server_mandatory = false;
2765                 if (server_security_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) {
2766                         server_signing = "required";
2767                         server_mandatory = true;
2768                 }
2769
2770                 ok = cli_set_signing_negotiated(cli,
2771                                                 server_allowed,
2772                                                 server_mandatory);
2773                 if (!ok) {
2774                         DEBUG(1,("cli_negprot: SMB signing is required, "
2775                                  "but client[%s] and server[%s] mismatch\n",
2776                                  client_signing, server_signing));
2777                         tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
2778                         return;
2779                 }
2780
2781         } else if (protocol >= PROTOCOL_LANMAN1) {
2782                 if (wct != 0x0D) {
2783                         tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2784                         return;
2785                 }
2786
2787                 server_security_mode = SVAL(vwv + 1, 0);
2788                 server_max_xmit = SVAL(vwv + 2, 0);
2789                 server_max_mux = SVAL(vwv + 3, 0);
2790                 server_session_key = IVAL(vwv + 6, 0);
2791                 server_time_zone = SVALS(vwv + 10, 0);
2792                 server_time_zone *= 60;
2793                 /* this time is converted to GMT by make_unix_date */
2794                 server_system_time = make_unix_date(
2795                         (char *)(vwv + 8), server_time_zone);
2796                 server_readbraw = ((SVAL(vwv + 5, 0) & 0x1) != 0);
2797                 server_writebraw = ((SVAL(vwv + 5, 0) & 0x2) != 0);
2798
2799                 if (num_bytes != 0 && num_bytes != 8) {
2800                         tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2801                         return;
2802                 }
2803
2804                 if (num_bytes == 8) {
2805                         memcpy(server_challenge, bytes, 8);
2806                 }
2807         } else {
2808                 /* the old core protocol */
2809                 server_time_zone = get_time_zone(time(NULL));
2810                 server_system_time = 0;
2811                 server_max_xmit = 1024;
2812                 server_max_mux = 1;
2813                 server_security_mode = 0;
2814         }
2815
2816         if (server_max_xmit < 1024) {
2817                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2818                 return;
2819         }
2820
2821         if (server_max_mux < 1) {
2822                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2823                 return;
2824         }
2825
2826         /*
2827          * Now calculate the negotiated capabilities
2828          * based on the mask for:
2829          * - client only flags
2830          * - flags used in both directions
2831          * - server only flags
2832          */
2833         both_capabilities = client_capabilities & server_capabilities;
2834         capabilities = client_capabilities & SMB_CAP_CLIENT_MASK;
2835         capabilities |= both_capabilities & SMB_CAP_BOTH_MASK;
2836         capabilities |= server_capabilities & SMB_CAP_SERVER_MASK;
2837
2838         max_xmit = MIN(client_max_xmit, server_max_xmit);
2839
2840         if (server_workgroup) {
2841                 cli->server_domain = talloc_strdup(cli, server_workgroup);
2842                 if (tevent_req_nomem(cli->server_domain, req)) {
2843                         return;
2844                 }
2845         }
2846
2847         cli->conn.protocol = protocol;
2848
2849         cli->conn.smb1.server.capabilities = server_capabilities;
2850         cli->conn.smb1.capabilities = capabilities;
2851
2852         cli->conn.smb1.server.max_xmit = server_max_xmit;
2853         cli->conn.smb1.max_xmit = max_xmit;
2854
2855         cli->conn.smb1.server.max_mux = server_max_mux;
2856
2857         cli->conn.smb1.server.security_mode = server_security_mode;
2858
2859         cli->conn.smb1.server.readbraw = server_readbraw;
2860         cli->conn.smb1.server.writebraw = server_writebraw;
2861         cli->conn.smb1.server.lockread = server_lockread;
2862         cli->conn.smb1.server.writeunlock = server_writeunlock;
2863
2864         cli->conn.smb1.server.session_key = server_session_key;
2865
2866         talloc_steal(cli, server_gss_blob.data);
2867         cli->conn.smb1.server.gss_blob = server_gss_blob;
2868         cli->conn.smb1.server.guid = server_guid;
2869         memcpy(cli->conn.smb1.server.challenge, server_challenge, 8);
2870         cli->conn.smb1.server.workgroup = talloc_move(cli, &server_workgroup);
2871
2872         cli->conn.smb1.server.time_zone = server_time_zone;
2873         cli->conn.smb1.server.system_time = server_system_time;
2874
2875         tevent_req_done(req);
2876 }
2877
2878 NTSTATUS cli_negprot_recv(struct tevent_req *req)
2879 {
2880         return tevent_req_simple_recv_ntstatus(req);
2881 }
2882
2883 NTSTATUS cli_negprot(struct cli_state *cli, enum protocol_types max_protocol)
2884 {
2885         TALLOC_CTX *frame = talloc_stackframe();
2886         struct event_context *ev;
2887         struct tevent_req *req;
2888         NTSTATUS status = NT_STATUS_OK;
2889
2890         if (cli_has_async_calls(cli)) {
2891                 /*
2892                  * Can't use sync call while an async call is in flight
2893                  */
2894                 status = NT_STATUS_INVALID_PARAMETER;
2895                 goto fail;
2896         }
2897
2898         ev = event_context_init(frame);
2899         if (ev == NULL) {
2900                 status = NT_STATUS_NO_MEMORY;
2901                 goto fail;
2902         }
2903
2904         req = cli_negprot_send(frame, ev, cli, max_protocol);
2905         if (req == NULL) {
2906                 status = NT_STATUS_NO_MEMORY;
2907                 goto fail;
2908         }
2909
2910         if (!tevent_req_poll(req, ev)) {
2911                 status = map_nt_error_from_unix(errno);
2912                 goto fail;
2913         }
2914
2915         status = cli_negprot_recv(req);
2916  fail:
2917         TALLOC_FREE(frame);
2918         return status;
2919 }
2920
2921 static NTSTATUS cli_connect_sock(const char *host, int name_type,
2922                                  const struct sockaddr_storage *pss,
2923                                  const char *myname, uint16_t port,
2924                                  int sec_timeout, int *pfd, uint16_t *pport)
2925 {
2926         TALLOC_CTX *frame = talloc_stackframe();
2927         const char *prog;
2928         unsigned int i, num_addrs;
2929         const char **called_names;
2930         const char **calling_names;
2931         int *called_types;
2932         NTSTATUS status;
2933         int fd;
2934
2935         prog = getenv("LIBSMB_PROG");
2936         if (prog != NULL) {
2937                 fd = sock_exec(prog);
2938                 if (fd == -1) {
2939                         return map_nt_error_from_unix(errno);
2940                 }
2941                 port = 0;
2942                 goto done;
2943         }
2944
2945         if ((pss == NULL) || is_zero_addr(pss)) {
2946                 struct sockaddr_storage *addrs;
2947                 status = resolve_name_list(talloc_tos(), host, name_type,
2948                                            &addrs, &num_addrs);
2949                 if (!NT_STATUS_IS_OK(status)) {
2950                         goto fail;
2951                 }
2952                 pss = addrs;
2953         } else {
2954                 num_addrs = 1;
2955         }
2956
2957         called_names = talloc_array(talloc_tos(), const char *, num_addrs);
2958         if (called_names == NULL) {
2959                 status = NT_STATUS_NO_MEMORY;
2960                 goto fail;
2961         }
2962         called_types = talloc_array(talloc_tos(), int, num_addrs);
2963         if (called_types == NULL) {
2964                 status = NT_STATUS_NO_MEMORY;
2965                 goto fail;
2966         }
2967         calling_names = talloc_array(talloc_tos(), const char *, num_addrs);
2968         if (calling_names == NULL) {
2969                 status = NT_STATUS_NO_MEMORY;
2970                 goto fail;
2971         }
2972         for (i=0; i<num_addrs; i++) {
2973                 called_names[i] = host;
2974                 called_types[i] = name_type;
2975                 calling_names[i] = myname;
2976         }
2977         status = smbsock_any_connect(pss, called_names, called_types,
2978                                      calling_names, NULL, num_addrs, port,
2979                                      sec_timeout, &fd, NULL, &port);
2980         if (!NT_STATUS_IS_OK(status)) {
2981                 goto fail;
2982         }
2983         set_socket_options(fd, lp_socket_options());
2984 done:
2985         *pfd = fd;
2986         *pport = port;
2987         status = NT_STATUS_OK;
2988 fail:
2989         TALLOC_FREE(frame);
2990         return status;
2991 }
2992
2993 NTSTATUS cli_connect_nb(const char *host, const struct sockaddr_storage *dest_ss,
2994                         uint16_t port, int name_type, const char *myname,
2995                         int signing_state, int flags, struct cli_state **pcli)
2996 {
2997         TALLOC_CTX *frame = talloc_stackframe();
2998         struct cli_state *cli;
2999         NTSTATUS status = NT_STATUS_NO_MEMORY;
3000         int fd = -1;
3001         char *desthost;
3002         char *p;
3003
3004         desthost = talloc_strdup(talloc_tos(), host);
3005         if (desthost == NULL) {
3006                 goto fail;
3007         }
3008
3009         p = strchr(host, '#');
3010         if (p != NULL) {
3011                 name_type = strtol(p+1, NULL, 16);
3012                 host = talloc_strndup(talloc_tos(), host, p - host);
3013                 if (host == NULL) {
3014                         goto fail;
3015                 }
3016         }
3017
3018         status = cli_connect_sock(host, name_type, dest_ss, myname, port,
3019                                   20, &fd, &port);
3020         if (!NT_STATUS_IS_OK(status)) {
3021                 goto fail;
3022         }
3023
3024         cli = cli_state_create(NULL, fd, desthost, NULL, signing_state, flags);
3025         if (cli == NULL) {
3026                 goto fail;
3027         }
3028
3029         *pcli = cli;
3030         status = NT_STATUS_OK;
3031 fail:
3032         TALLOC_FREE(frame);
3033         return status;
3034 }
3035
3036 /**
3037    establishes a connection to after the negprot. 
3038    @param output_cli A fully initialised cli structure, non-null only on success
3039    @param dest_host The netbios name of the remote host
3040    @param dest_ss (optional) The the destination IP, NULL for name based lookup
3041    @param port (optional) The destination port (0 for default)
3042 */
3043 NTSTATUS cli_start_connection(struct cli_state **output_cli, 
3044                               const char *my_name, 
3045                               const char *dest_host, 
3046                               const struct sockaddr_storage *dest_ss, int port,
3047                               int signing_state, int flags)
3048 {
3049         NTSTATUS nt_status;
3050         struct cli_state *cli;
3051
3052         nt_status = cli_connect_nb(dest_host, dest_ss, port, 0x20, my_name,
3053                                    signing_state, flags, &cli);
3054         if (!NT_STATUS_IS_OK(nt_status)) {
3055                 DEBUG(10, ("cli_connect_nb failed: %s\n",
3056                            nt_errstr(nt_status)));
3057                 return nt_status;
3058         }
3059
3060         nt_status = cli_negprot(cli, PROTOCOL_NT1);
3061         if (!NT_STATUS_IS_OK(nt_status)) {
3062                 DEBUG(1, ("failed negprot: %s\n", nt_errstr(nt_status)));
3063                 cli_shutdown(cli);
3064                 return nt_status;
3065         }
3066
3067         *output_cli = cli;
3068         return NT_STATUS_OK;
3069 }
3070
3071
3072 /**
3073    establishes a connection right up to doing tconX, password specified.
3074    @param output_cli A fully initialised cli structure, non-null only on success
3075    @param dest_host The netbios name of the remote host
3076    @param dest_ip (optional) The the destination IP, NULL for name based lookup
3077    @param port (optional) The destination port (0 for default)
3078    @param service (optional) The share to make the connection to.  Should be 'unqualified' in any way.
3079    @param service_type The 'type' of serivice. 
3080    @param user Username, unix string
3081    @param domain User's domain
3082    @param password User's password, unencrypted unix string.
3083 */
3084
3085 NTSTATUS cli_full_connection(struct cli_state **output_cli, 
3086                              const char *my_name, 
3087                              const char *dest_host, 
3088                              const struct sockaddr_storage *dest_ss, int port,
3089                              const char *service, const char *service_type,
3090                              const char *user, const char *domain, 
3091                              const char *password, int flags,
3092                              int signing_state)
3093 {
3094         NTSTATUS nt_status;
3095         struct cli_state *cli = NULL;
3096         int pw_len = password ? strlen(password)+1 : 0;
3097
3098         *output_cli = NULL;
3099
3100         if (password == NULL) {
3101                 password = "";
3102         }
3103
3104         nt_status = cli_start_connection(&cli, my_name, dest_host,
3105                                          dest_ss, port, signing_state,
3106                                          flags);
3107
3108         if (!NT_STATUS_IS_OK(nt_status)) {
3109                 return nt_status;
3110         }
3111
3112         nt_status = cli_session_setup(cli, user, password, pw_len, password,
3113                                       pw_len, domain);
3114         if (!NT_STATUS_IS_OK(nt_status)) {
3115
3116                 if (!(flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)) {
3117                         DEBUG(1,("failed session setup with %s\n",
3118                                  nt_errstr(nt_status)));
3119                         cli_shutdown(cli);
3120                         return nt_status;
3121                 }
3122
3123                 nt_status = cli_session_setup(cli, "", "", 0, "", 0, domain);
3124                 if (!NT_STATUS_IS_OK(nt_status)) {
3125                         DEBUG(1,("anonymous failed session setup with %s\n",
3126                                  nt_errstr(nt_status)));
3127                         cli_shutdown(cli);
3128                         return nt_status;
3129                 }
3130         }
3131
3132         if (service) {
3133                 nt_status = cli_tcon_andx(cli, service, service_type, password,
3134                                           pw_len);
3135                 if (!NT_STATUS_IS_OK(nt_status)) {
3136                         DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status)));
3137                         cli_shutdown(cli);
3138                         if (NT_STATUS_IS_OK(nt_status)) {
3139                                 nt_status = NT_STATUS_UNSUCCESSFUL;
3140                         }
3141                         return nt_status;
3142                 }
3143         }
3144
3145         nt_status = cli_init_creds(cli, user, domain, password);
3146         if (!NT_STATUS_IS_OK(nt_status)) {
3147                 cli_shutdown(cli);
3148                 return nt_status;
3149         }
3150
3151         *output_cli = cli;
3152         return NT_STATUS_OK;
3153 }
3154
3155 /****************************************************************************
3156  Send an old style tcon.
3157 ****************************************************************************/
3158 NTSTATUS cli_raw_tcon(struct cli_state *cli, 
3159                       const char *service, const char *pass, const char *dev,
3160                       uint16 *max_xmit, uint16 *tid)
3161 {
3162         struct tevent_req *req;
3163         uint16_t *ret_vwv;
3164         uint8_t *bytes;
3165         NTSTATUS status;
3166
3167         if (!lp_client_plaintext_auth() && (*pass)) {
3168                 DEBUG(1, ("Server requested plaintext password but 'client "
3169                           "plaintext auth' is disabled\n"));
3170                 return NT_STATUS_ACCESS_DENIED;
3171         }
3172
3173         bytes = talloc_array(talloc_tos(), uint8_t, 0);
3174         bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3175         bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
3176                                    service, strlen(service)+1, NULL);
3177         bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3178         bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
3179                                    pass, strlen(pass)+1, NULL);
3180         bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3181         bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
3182                                    dev, strlen(dev)+1, NULL);
3183
3184         status = cli_smb(talloc_tos(), cli, SMBtcon, 0, 0, NULL,
3185                          talloc_get_size(bytes), bytes, &req,
3186                          2, NULL, &ret_vwv, NULL, NULL);
3187         if (!NT_STATUS_IS_OK(status)) {
3188                 return status;
3189         }
3190
3191         *max_xmit = SVAL(ret_vwv + 0, 0);
3192         *tid = SVAL(ret_vwv + 1, 0);
3193
3194         return NT_STATUS_OK;
3195 }
3196
3197 /* Return a cli_state pointing at the IPC$ share for the given server */
3198
3199 struct cli_state *get_ipc_connect(char *server,
3200                                 struct sockaddr_storage *server_ss,
3201                                 const struct user_auth_info *user_info)
3202 {
3203         struct cli_state *cli;
3204         NTSTATUS nt_status;
3205         uint32_t flags = CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
3206
3207         if (user_info->use_kerberos) {
3208                 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
3209         }
3210
3211         nt_status = cli_full_connection(&cli, NULL, server, server_ss, 0, "IPC$", "IPC", 
3212                                         user_info->username ? user_info->username : "",
3213                                         lp_workgroup(),
3214                                         user_info->password ? user_info->password : "",
3215                                         flags,
3216                                         SMB_SIGNING_DEFAULT);
3217
3218         if (NT_STATUS_IS_OK(nt_status)) {
3219                 return cli;
3220         } else if (is_ipaddress(server)) {
3221             /* windows 9* needs a correct NMB name for connections */
3222             fstring remote_name;
3223
3224             if (name_status_find("*", 0, 0, server_ss, remote_name)) {
3225                 cli = get_ipc_connect(remote_name, server_ss, user_info);
3226                 if (cli)
3227                     return cli;
3228             }
3229         }
3230         return NULL;
3231 }
3232
3233 /*
3234  * Given the IP address of a master browser on the network, return its
3235  * workgroup and connect to it.
3236  *
3237  * This function is provided to allow additional processing beyond what
3238  * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
3239  * browsers and obtain each master browsers' list of domains (in case the
3240  * first master browser is recently on the network and has not yet
3241  * synchronized with other master browsers and therefore does not yet have the
3242  * entire network browse list)
3243  */
3244
3245 struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx,
3246                                 struct sockaddr_storage *mb_ip,
3247                                 const struct user_auth_info *user_info,
3248                                 char **pp_workgroup_out)
3249 {
3250         char addr[INET6_ADDRSTRLEN];
3251         fstring name;
3252         struct cli_state *cli;
3253         struct sockaddr_storage server_ss;
3254
3255         *pp_workgroup_out = NULL;
3256
3257         print_sockaddr(addr, sizeof(addr), mb_ip);
3258         DEBUG(99, ("Looking up name of master browser %s\n",
3259                    addr));
3260
3261         /*
3262          * Do a name status query to find out the name of the master browser.
3263          * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
3264          * master browser will not respond to a wildcard query (or, at least,
3265          * an NT4 server acting as the domain master browser will not).
3266          *
3267          * We might be able to use ONLY the query on MSBROWSE, but that's not
3268          * yet been tested with all Windows versions, so until it is, leave
3269          * the original wildcard query as the first choice and fall back to
3270          * MSBROWSE if the wildcard query fails.
3271          */
3272         if (!name_status_find("*", 0, 0x1d, mb_ip, name) &&
3273             !name_status_find(MSBROWSE, 1, 0x1d, mb_ip, name)) {
3274
3275                 DEBUG(99, ("Could not retrieve name status for %s\n",
3276                            addr));
3277                 return NULL;
3278         }
3279
3280         if (!find_master_ip(name, &server_ss)) {
3281                 DEBUG(99, ("Could not find master ip for %s\n", name));
3282                 return NULL;
3283         }
3284
3285         *pp_workgroup_out = talloc_strdup(ctx, name);
3286
3287         DEBUG(4, ("found master browser %s, %s\n", name, addr));
3288
3289         print_sockaddr(addr, sizeof(addr), &server_ss);
3290         cli = get_ipc_connect(addr, &server_ss, user_info);
3291
3292         return cli;
3293 }
3294
3295 /*
3296  * Return the IP address and workgroup of a master browser on the network, and
3297  * connect to it.
3298  */
3299
3300 struct cli_state *get_ipc_connect_master_ip_bcast(TALLOC_CTX *ctx,
3301                                         const struct user_auth_info *user_info,
3302                                         char **pp_workgroup_out)
3303 {
3304         struct sockaddr_storage *ip_list;
3305         struct cli_state *cli;
3306         int i, count;
3307         NTSTATUS status;
3308
3309         *pp_workgroup_out = NULL;
3310
3311         DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
3312
3313         /* Go looking for workgroups by broadcasting on the local network */
3314
3315         status = name_resolve_bcast(MSBROWSE, 1, talloc_tos(),
3316                                     &ip_list, &count);
3317         if (!NT_STATUS_IS_OK(status)) {
3318                 DEBUG(99, ("No master browsers responded: %s\n",
3319                            nt_errstr(status)));
3320                 return False;
3321         }
3322
3323         for (i = 0; i < count; i++) {
3324                 char addr[INET6_ADDRSTRLEN];
3325                 print_sockaddr(addr, sizeof(addr), &ip_list[i]);
3326                 DEBUG(99, ("Found master browser %s\n", addr));
3327
3328                 cli = get_ipc_connect_master_ip(ctx, &ip_list[i],
3329                                 user_info, pp_workgroup_out);
3330                 if (cli)
3331                         return(cli);
3332         }
3333
3334         return NULL;
3335 }