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