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