Fix const warning.
[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         TALLOC_FREE(subreq);
1468         if (!NT_STATUS_IS_OK(status)) {
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                 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1479                 return;
1480         }
1481
1482         tevent_req_done(req);
1483 }
1484
1485 static ADS_STATUS cli_session_setup_kerberos_recv(struct tevent_req *req)
1486 {
1487         struct cli_session_setup_kerberos_state *state = tevent_req_data(
1488                 req, struct cli_session_setup_kerberos_state);
1489         NTSTATUS status;
1490
1491         if (tevent_req_is_nterror(req, &status)) {
1492                 return ADS_ERROR_NT(status);
1493         }
1494         return state->ads_status;
1495 }
1496
1497 static ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli,
1498                                              const char *principal)
1499 {
1500         struct tevent_context *ev;
1501         struct tevent_req *req;
1502         ADS_STATUS status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1503
1504         if (cli_has_async_calls(cli)) {
1505                 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1506         }
1507         ev = tevent_context_init(talloc_tos());
1508         if (ev == NULL) {
1509                 goto fail;
1510         }
1511         req = cli_session_setup_kerberos_send(ev, ev, cli, principal);
1512         if (req == NULL) {
1513                 goto fail;
1514         }
1515         if (!tevent_req_poll(req, ev)) {
1516                 status = ADS_ERROR_SYSTEM(errno);
1517                 goto fail;
1518         }
1519         status = cli_session_setup_kerberos_recv(req);
1520 fail:
1521         TALLOC_FREE(ev);
1522         return status;
1523 }
1524 #endif  /* HAVE_KRB5 */
1525
1526 /****************************************************************************
1527  Do a spnego/NTLMSSP encrypted session setup.
1528 ****************************************************************************/
1529
1530 struct cli_session_setup_ntlmssp_state {
1531         struct tevent_context *ev;
1532         struct cli_state *cli;
1533         struct ntlmssp_state *ntlmssp_state;
1534         int turn;
1535         DATA_BLOB blob_out;
1536 };
1537
1538 static int cli_session_setup_ntlmssp_state_destructor(
1539         struct cli_session_setup_ntlmssp_state *state)
1540 {
1541         if (state->ntlmssp_state != NULL) {
1542                 TALLOC_FREE(state->ntlmssp_state);
1543         }
1544         return 0;
1545 }
1546
1547 static void cli_session_setup_ntlmssp_done(struct tevent_req *req);
1548
1549 static struct tevent_req *cli_session_setup_ntlmssp_send(
1550         TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
1551         const char *user, const char *pass, const char *domain)
1552 {
1553         struct tevent_req *req, *subreq;
1554         struct cli_session_setup_ntlmssp_state *state;
1555         NTSTATUS status;
1556         DATA_BLOB blob_out;
1557         const char *OIDs_ntlm[] = {OID_NTLMSSP, NULL};
1558
1559         req = tevent_req_create(mem_ctx, &state,
1560                                 struct cli_session_setup_ntlmssp_state);
1561         if (req == NULL) {
1562                 return NULL;
1563         }
1564         state->ev = ev;
1565         state->cli = cli;
1566         state->turn = 1;
1567
1568         state->ntlmssp_state = NULL;
1569         talloc_set_destructor(
1570                 state, cli_session_setup_ntlmssp_state_destructor);
1571
1572         status = ntlmssp_client_start(state,
1573                                       lp_netbios_name(),
1574                                       lp_workgroup(),
1575                                       lp_client_ntlmv2_auth(),
1576                                       &state->ntlmssp_state);
1577         if (!NT_STATUS_IS_OK(status)) {
1578                 goto fail;
1579         }
1580         ntlmssp_want_feature(state->ntlmssp_state,
1581                              NTLMSSP_FEATURE_SESSION_KEY);
1582         if (cli->use_ccache) {
1583                 ntlmssp_want_feature(state->ntlmssp_state,
1584                                      NTLMSSP_FEATURE_CCACHE);
1585         }
1586         status = ntlmssp_set_username(state->ntlmssp_state, user);
1587         if (!NT_STATUS_IS_OK(status)) {
1588                 goto fail;
1589         }
1590         status = ntlmssp_set_domain(state->ntlmssp_state, domain);
1591         if (!NT_STATUS_IS_OK(status)) {
1592                 goto fail;
1593         }
1594         status = ntlmssp_set_password(state->ntlmssp_state, pass);
1595         if (!NT_STATUS_IS_OK(status)) {
1596                 goto fail;
1597         }
1598         status = ntlmssp_update(state->ntlmssp_state, data_blob_null,
1599                                 &blob_out);
1600         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1601                 goto fail;
1602         }
1603
1604         state->blob_out = spnego_gen_negTokenInit(state, OIDs_ntlm, &blob_out, NULL);
1605         data_blob_free(&blob_out);
1606
1607         subreq = cli_sesssetup_blob_send(state, ev, cli, state->blob_out);
1608         if (tevent_req_nomem(subreq, req)) {
1609                 return tevent_req_post(req, ev);
1610         }
1611         tevent_req_set_callback(subreq, cli_session_setup_ntlmssp_done, req);
1612         return req;
1613 fail:
1614         tevent_req_nterror(req, status);
1615         return tevent_req_post(req, ev);
1616 }
1617
1618 static void cli_session_setup_ntlmssp_done(struct tevent_req *subreq)
1619 {
1620         struct tevent_req *req = tevent_req_callback_data(
1621                 subreq, struct tevent_req);
1622         struct cli_session_setup_ntlmssp_state *state = tevent_req_data(
1623                 req, struct cli_session_setup_ntlmssp_state);
1624         DATA_BLOB blob_in, msg_in, blob_out;
1625         char *inbuf = NULL;
1626         bool parse_ret;
1627         NTSTATUS status;
1628
1629         status = cli_sesssetup_blob_recv(subreq, talloc_tos(), &blob_in,
1630                                          &inbuf);
1631         TALLOC_FREE(subreq);
1632         data_blob_free(&state->blob_out);
1633
1634         if (NT_STATUS_IS_OK(status)) {
1635                 if (state->cli->server_domain[0] == '\0') {
1636                         TALLOC_FREE(state->cli->server_domain);
1637                         state->cli->server_domain = talloc_strdup(state->cli,
1638                                                 state->ntlmssp_state->server.netbios_domain);
1639                         if (state->cli->server_domain == NULL) {
1640                                 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1641                                 return;
1642                         }
1643                 }
1644                 cli_set_session_key(
1645                         state->cli, state->ntlmssp_state->session_key);
1646
1647                 if (cli_simple_set_signing(
1648                             state->cli, state->ntlmssp_state->session_key,
1649                             data_blob_null)
1650                     && !cli_check_sign_mac(state->cli, inbuf, 1)) {
1651                         tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1652                         return;
1653                 }
1654                 TALLOC_FREE(state->ntlmssp_state);
1655                 tevent_req_done(req);
1656                 return;
1657         }
1658         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1659                 tevent_req_nterror(req, status);
1660                 return;
1661         }
1662
1663         if (blob_in.length == 0) {
1664                 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
1665                 return;
1666         }
1667
1668         if ((state->turn == 1)
1669             && NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1670                 DATA_BLOB tmp_blob = data_blob_null;
1671                 /* the server might give us back two challenges */
1672                 parse_ret = spnego_parse_challenge(state, blob_in, &msg_in,
1673                                                    &tmp_blob);
1674                 data_blob_free(&tmp_blob);
1675         } else {
1676                 parse_ret = spnego_parse_auth_response(state, blob_in, status,
1677                                                        OID_NTLMSSP, &msg_in);
1678         }
1679         state->turn += 1;
1680
1681         if (!parse_ret) {
1682                 DEBUG(3,("Failed to parse auth response\n"));
1683                 if (NT_STATUS_IS_OK(status)
1684                     || NT_STATUS_EQUAL(status,
1685                                        NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1686                         tevent_req_nterror(
1687                                 req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1688                         return;
1689                 }
1690         }
1691
1692         status = ntlmssp_update(state->ntlmssp_state, msg_in, &blob_out);
1693
1694         if (!NT_STATUS_IS_OK(status)
1695             && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1696                 TALLOC_FREE(state->ntlmssp_state);
1697                 tevent_req_nterror(req, status);
1698                 return;
1699         }
1700
1701         state->blob_out = spnego_gen_auth(state, blob_out);
1702         if (tevent_req_nomem(state->blob_out.data, req)) {
1703                 return;
1704         }
1705
1706         subreq = cli_sesssetup_blob_send(state, state->ev, state->cli,
1707                                          state->blob_out);
1708         if (tevent_req_nomem(subreq, req)) {
1709                 return;
1710         }
1711         tevent_req_set_callback(subreq, cli_session_setup_ntlmssp_done, req);
1712 }
1713
1714 static NTSTATUS cli_session_setup_ntlmssp_recv(struct tevent_req *req)
1715 {
1716         struct cli_session_setup_ntlmssp_state *state = tevent_req_data(
1717                 req, struct cli_session_setup_ntlmssp_state);
1718         NTSTATUS status;
1719
1720         if (tevent_req_is_nterror(req, &status)) {
1721                 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
1722                 return status;
1723         }
1724         return NT_STATUS_OK;
1725 }
1726
1727 static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli,
1728                                           const char *user,
1729                                           const char *pass,
1730                                           const char *domain)
1731 {
1732         struct tevent_context *ev;
1733         struct tevent_req *req;
1734         NTSTATUS status = NT_STATUS_NO_MEMORY;
1735
1736         if (cli_has_async_calls(cli)) {
1737                 return NT_STATUS_INVALID_PARAMETER;
1738         }
1739         ev = tevent_context_init(talloc_tos());
1740         if (ev == NULL) {
1741                 goto fail;
1742         }
1743         req = cli_session_setup_ntlmssp_send(ev, ev, cli, user, pass, domain);
1744         if (req == NULL) {
1745                 goto fail;
1746         }
1747         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1748                 goto fail;
1749         }
1750         status = cli_session_setup_ntlmssp_recv(req);
1751 fail:
1752         TALLOC_FREE(ev);
1753         return status;
1754 }
1755
1756 /****************************************************************************
1757  Do a spnego encrypted session setup.
1758
1759  user_domain: The shortname of the domain the user/machine is a member of.
1760  dest_realm: The realm we're connecting to, if NULL we use our default realm.
1761 ****************************************************************************/
1762
1763 static ADS_STATUS cli_session_setup_spnego(struct cli_state *cli,
1764                               const char *user,
1765                               const char *pass,
1766                               const char *user_domain,
1767                               const char * dest_realm)
1768 {
1769         char *principal = NULL;
1770         char *OIDs[ASN1_MAX_OIDS];
1771         int i;
1772         const DATA_BLOB *server_blob;
1773         DATA_BLOB blob = data_blob_null;
1774         const char *p = NULL;
1775         char *account = NULL;
1776         NTSTATUS status;
1777
1778         server_blob = cli_state_server_gss_blob(cli);
1779         if (server_blob) {
1780                 blob = data_blob(server_blob->data, server_blob->length);
1781         }
1782
1783         DEBUG(3,("Doing spnego session setup (blob length=%lu)\n", (unsigned long)blob.length));
1784
1785         /* the server might not even do spnego */
1786         if (blob.length == 0) {
1787                 DEBUG(3,("server didn't supply a full spnego negprot\n"));
1788                 goto ntlmssp;
1789         }
1790
1791 #if 0
1792         file_save("negprot.dat", cli->secblob.data, cli->secblob.length);
1793 #endif
1794
1795         /* The server sent us the first part of the SPNEGO exchange in the
1796          * negprot reply. It is WRONG to depend on the principal sent in the
1797          * negprot reply, but right now we do it. If we don't receive one,
1798          * we try to best guess, then fall back to NTLM.  */
1799         if (!spnego_parse_negTokenInit(talloc_tos(), blob, OIDs, &principal, NULL) ||
1800                         OIDs[0] == NULL) {
1801                 data_blob_free(&blob);
1802                 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1803         }
1804         data_blob_free(&blob);
1805
1806         /* make sure the server understands kerberos */
1807         for (i=0;OIDs[i];i++) {
1808                 if (i == 0)
1809                         DEBUG(3,("got OID=%s\n", OIDs[i]));
1810                 else
1811                         DEBUGADD(3,("got OID=%s\n", OIDs[i]));
1812                 if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0 ||
1813                     strcmp(OIDs[i], OID_KERBEROS5) == 0) {
1814                         cli->got_kerberos_mechanism = True;
1815                 }
1816                 talloc_free(OIDs[i]);
1817         }
1818
1819         DEBUG(3,("got principal=%s\n", principal ? principal : "<null>"));
1820
1821         status = cli_set_username(cli, user);
1822         if (!NT_STATUS_IS_OK(status)) {
1823                 TALLOC_FREE(principal);
1824                 return ADS_ERROR_NT(status);
1825         }
1826
1827 #ifdef HAVE_KRB5
1828         /* If password is set we reauthenticate to kerberos server
1829          * and do not store results */
1830
1831         if (cli->got_kerberos_mechanism && cli->use_kerberos) {
1832                 ADS_STATUS rc;
1833                 const char *remote_name = cli_state_remote_name(cli);
1834
1835                 if (pass && *pass) {
1836                         int ret;
1837
1838                         use_in_memory_ccache();
1839                         ret = kerberos_kinit_password(user, pass, 0 /* no time correction for now */, NULL);
1840
1841                         if (ret){
1842                                 TALLOC_FREE(principal);
1843                                 DEBUG(0, ("Kinit failed: %s\n", error_message(ret)));
1844                                 if (cli->fallback_after_kerberos)
1845                                         goto ntlmssp;
1846                                 return ADS_ERROR_KRB5(ret);
1847                         }
1848                 }
1849
1850                 /* We may not be allowed to use the server-supplied SPNEGO principal, or it may not have been supplied to us
1851                  */
1852                 if (!lp_client_use_spnego_principal() || strequal(principal, ADS_IGNORE_PRINCIPAL)) {
1853                         TALLOC_FREE(principal);
1854                 }
1855
1856                 if (principal == NULL &&
1857                         !is_ipaddress(remote_name) &&
1858                         !strequal(STAR_SMBSERVER,
1859                                   remote_name)) {
1860                         char *realm = NULL;
1861                         char *host = NULL;
1862                         DEBUG(3,("cli_session_setup_spnego: using target "
1863                                  "hostname not SPNEGO principal\n"));
1864
1865                         host = strchr_m(remote_name, '.');
1866                         if (dest_realm) {
1867                                 realm = SMB_STRDUP(dest_realm);
1868                                 if (!realm) {
1869                                         return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1870                                 }
1871                                 strupper_m(realm);
1872                         } else {
1873                                 if (host) {
1874                                         /* DNS name. */
1875                                         realm = kerberos_get_realm_from_hostname(remote_name);
1876                                 } else {
1877                                         /* NetBIOS name - use our realm. */
1878                                         realm = kerberos_get_default_realm_from_ccache();
1879                                 }
1880                         }
1881
1882                         if (realm == NULL || *realm == '\0') {
1883                                 realm = SMB_STRDUP(lp_realm());
1884                                 if (!realm) {
1885                                         return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1886                                 }
1887                                 strupper_m(realm);
1888                                 DEBUG(3,("cli_session_setup_spnego: cannot "
1889                                         "get realm from dest_realm %s, "
1890                                         "desthost %s. Using default "
1891                                         "smb.conf realm %s\n",
1892                                         dest_realm ? dest_realm : "<null>",
1893                                         remote_name,
1894                                         realm));
1895                         }
1896
1897                         principal = talloc_asprintf(talloc_tos(),
1898                                                     "cifs/%s@%s",
1899                                                     remote_name,
1900                                                     realm);
1901                         if (!principal) {
1902                                 SAFE_FREE(realm);
1903                                 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1904                         }
1905                         DEBUG(3,("cli_session_setup_spnego: guessed "
1906                                 "server principal=%s\n",
1907                                 principal ? principal : "<null>"));
1908
1909                         SAFE_FREE(realm);
1910                 }
1911
1912                 if (principal) {
1913                         rc = cli_session_setup_kerberos(cli, principal);
1914                         if (ADS_ERR_OK(rc) || !cli->fallback_after_kerberos) {
1915                                 TALLOC_FREE(principal);
1916                                 return rc;
1917                         }
1918                 }
1919         }
1920 #endif
1921
1922         TALLOC_FREE(principal);
1923
1924 ntlmssp:
1925
1926         account = talloc_strdup(talloc_tos(), user);
1927         if (!account) {
1928                 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1929         }
1930
1931         /* when falling back to ntlmssp while authenticating with a machine
1932          * account strip off the realm - gd */
1933
1934         if ((p = strchr_m(user, '@')) != NULL) {
1935                 account[PTR_DIFF(p,user)] = '\0';
1936         }
1937
1938         return ADS_ERROR_NT(cli_session_setup_ntlmssp(cli, account, pass, user_domain));
1939 }
1940
1941 /****************************************************************************
1942  Send a session setup. The username and workgroup is in UNIX character
1943  format and must be converted to DOS codepage format before sending. If the
1944  password is in plaintext, the same should be done.
1945 ****************************************************************************/
1946
1947 NTSTATUS cli_session_setup(struct cli_state *cli,
1948                            const char *user,
1949                            const char *pass, int passlen,
1950                            const char *ntpass, int ntpasslen,
1951                            const char *workgroup)
1952 {
1953         char *p;
1954         char *user2;
1955         uint16_t sec_mode = cli_state_security_mode(cli);
1956
1957         if (user) {
1958                 user2 = talloc_strdup(talloc_tos(), user);
1959         } else {
1960                 user2 = talloc_strdup(talloc_tos(), "");
1961         }
1962         if (user2 == NULL) {
1963                 return NT_STATUS_NO_MEMORY;
1964         }
1965
1966         if (!workgroup) {
1967                 workgroup = "";
1968         }
1969
1970         /* allow for workgroups as part of the username */
1971         if ((p=strchr_m(user2,'\\')) || (p=strchr_m(user2,'/')) ||
1972             (p=strchr_m(user2,*lp_winbind_separator()))) {
1973                 *p = 0;
1974                 user = p+1;
1975                 strupper_m(user2);
1976                 workgroup = user2;
1977         }
1978
1979         if (cli_state_protocol(cli) < PROTOCOL_LANMAN1) {
1980                 /*
1981                  * Ensure cli->server_domain,
1982                  * cli->server_os and cli->server_type
1983                  * are valid pointers.
1984                  */
1985                 cli->server_domain = talloc_strdup(cli, "");
1986                 cli->server_os = talloc_strdup(cli, "");
1987                 cli->server_type = talloc_strdup(cli, "");
1988                 if (cli->server_domain == NULL ||
1989                                 cli->server_os == NULL ||
1990                                 cli->server_type == NULL) {
1991                         return NT_STATUS_NO_MEMORY;
1992                 }
1993                 return NT_STATUS_OK;
1994         }
1995
1996         /* now work out what sort of session setup we are going to
1997            do. I have split this into separate functions to make the
1998            flow a bit easier to understand (tridge) */
1999
2000         /* if its an older server then we have to use the older request format */
2001
2002         if (cli_state_protocol(cli) < PROTOCOL_NT1) {
2003                 if (!lp_client_lanman_auth() && passlen != 24 && (*pass)) {
2004                         DEBUG(1, ("Server requested LM password but 'client lanman auth = no'"
2005                                   " or 'client ntlmv2 auth = yes'\n"));
2006                         return NT_STATUS_ACCESS_DENIED;
2007                 }
2008
2009                 if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0 &&
2010                     !lp_client_plaintext_auth() && (*pass)) {
2011                         DEBUG(1, ("Server requested LM password but 'client plaintext auth = no'"
2012                                   " or 'client ntlmv2 auth = yes'\n"));
2013                         return NT_STATUS_ACCESS_DENIED;
2014                 }
2015
2016                 return cli_session_setup_lanman2(cli, user, pass, passlen,
2017                                                  workgroup);
2018         }
2019
2020         /* if no user is supplied then we have to do an anonymous connection.
2021            passwords are ignored */
2022
2023         if (!user || !*user)
2024                 return cli_session_setup_guest(cli);
2025
2026         /* if the server is share level then send a plaintext null
2027            password at this point. The password is sent in the tree
2028            connect */
2029
2030         if ((sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0)
2031                 return cli_session_setup_plain(cli, user, "", workgroup);
2032
2033         /* if the server doesn't support encryption then we have to use 
2034            plaintext. The second password is ignored */
2035
2036         if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) {
2037                 if (!lp_client_plaintext_auth() && (*pass)) {
2038                         DEBUG(1, ("Server requested LM password but 'client plaintext auth = no'"
2039                                   " or 'client ntlmv2 auth = yes'\n"));
2040                         return NT_STATUS_ACCESS_DENIED;
2041                 }
2042                 return cli_session_setup_plain(cli, user, pass, workgroup);
2043         }
2044
2045         /* if the server supports extended security then use SPNEGO */
2046
2047         if (cli_state_capabilities(cli) & CAP_EXTENDED_SECURITY) {
2048                 const char *remote_realm = cli_state_remote_realm(cli);
2049                 ADS_STATUS status = cli_session_setup_spnego(cli, user, pass,
2050                                                              workgroup,
2051                                                              remote_realm);
2052                 if (!ADS_ERR_OK(status)) {
2053                         DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status)));
2054                         return ads_ntstatus(status);
2055                 }
2056         } else {
2057                 NTSTATUS status;
2058
2059                 /* otherwise do a NT1 style session setup */
2060                 status = cli_session_setup_nt1(cli, user, pass, passlen,
2061                                                ntpass, ntpasslen, workgroup);
2062                 if (!NT_STATUS_IS_OK(status)) {
2063                         DEBUG(3,("cli_session_setup: NT1 session setup "
2064                                  "failed: %s\n", nt_errstr(status)));
2065                         return status;
2066                 }
2067         }
2068
2069         return NT_STATUS_OK;
2070 }
2071
2072 /****************************************************************************
2073  Send a uloggoff.
2074 *****************************************************************************/
2075
2076 struct cli_ulogoff_state {
2077         struct cli_state *cli;
2078         uint16_t vwv[3];
2079 };
2080
2081 static void cli_ulogoff_done(struct tevent_req *subreq);
2082
2083 struct tevent_req *cli_ulogoff_send(TALLOC_CTX *mem_ctx,
2084                                     struct tevent_context *ev,
2085                                     struct cli_state *cli)
2086 {
2087         struct tevent_req *req, *subreq;
2088         struct cli_ulogoff_state *state;
2089
2090         req = tevent_req_create(mem_ctx, &state, struct cli_ulogoff_state);
2091         if (req == NULL) {
2092                 return NULL;
2093         }
2094         state->cli = cli;
2095
2096         SCVAL(state->vwv+0, 0, 0xFF);
2097         SCVAL(state->vwv+1, 0, 0);
2098         SSVAL(state->vwv+2, 0, 0);
2099
2100         subreq = cli_smb_send(state, ev, cli, SMBulogoffX, 0, 2, state->vwv,
2101                               0, NULL);
2102         if (tevent_req_nomem(subreq, req)) {
2103                 return tevent_req_post(req, ev);
2104         }
2105         tevent_req_set_callback(subreq, cli_ulogoff_done, req);
2106         return req;
2107 }
2108
2109 static void cli_ulogoff_done(struct tevent_req *subreq)
2110 {
2111         struct tevent_req *req = tevent_req_callback_data(
2112                 subreq, struct tevent_req);
2113         struct cli_ulogoff_state *state = tevent_req_data(
2114                 req, struct cli_ulogoff_state);
2115         NTSTATUS status;
2116
2117         status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
2118         if (!NT_STATUS_IS_OK(status)) {
2119                 tevent_req_nterror(req, status);
2120                 return;
2121         }
2122         cli_state_set_uid(state->cli, UID_FIELD_INVALID);
2123         tevent_req_done(req);
2124 }
2125
2126 NTSTATUS cli_ulogoff_recv(struct tevent_req *req)
2127 {
2128         return tevent_req_simple_recv_ntstatus(req);
2129 }
2130
2131 NTSTATUS cli_ulogoff(struct cli_state *cli)
2132 {
2133         struct tevent_context *ev;
2134         struct tevent_req *req;
2135         NTSTATUS status = NT_STATUS_NO_MEMORY;
2136
2137         if (cli_has_async_calls(cli)) {
2138                 return NT_STATUS_INVALID_PARAMETER;
2139         }
2140         ev = tevent_context_init(talloc_tos());
2141         if (ev == NULL) {
2142                 goto fail;
2143         }
2144         req = cli_ulogoff_send(ev, ev, cli);
2145         if (req == NULL) {
2146                 goto fail;
2147         }
2148         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2149                 goto fail;
2150         }
2151         status = cli_ulogoff_recv(req);
2152 fail:
2153         TALLOC_FREE(ev);
2154         return status;
2155 }
2156
2157 /****************************************************************************
2158  Send a tconX.
2159 ****************************************************************************/
2160
2161 struct cli_tcon_andx_state {
2162         struct cli_state *cli;
2163         uint16_t vwv[4];
2164         struct iovec bytes;
2165 };
2166
2167 static void cli_tcon_andx_done(struct tevent_req *subreq);
2168
2169 struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx,
2170                                         struct event_context *ev,
2171                                         struct cli_state *cli,
2172                                         const char *share, const char *dev,
2173                                         const char *pass, int passlen,
2174                                         struct tevent_req **psmbreq)
2175 {
2176         struct tevent_req *req, *subreq;
2177         struct cli_tcon_andx_state *state;
2178         uint8_t p24[24];
2179         uint16_t *vwv;
2180         char *tmp = NULL;
2181         uint8_t *bytes;
2182         uint16_t sec_mode = cli_state_security_mode(cli);
2183
2184         *psmbreq = NULL;
2185
2186         req = tevent_req_create(mem_ctx, &state, struct cli_tcon_andx_state);
2187         if (req == NULL) {
2188                 return NULL;
2189         }
2190         state->cli = cli;
2191         vwv = state->vwv;
2192
2193         cli->share = talloc_strdup(cli, share);
2194         if (!cli->share) {
2195                 return NULL;
2196         }
2197
2198         /* in user level security don't send a password now */
2199         if (sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {
2200                 passlen = 1;
2201                 pass = "";
2202         } else if (pass == NULL) {
2203                 DEBUG(1, ("Server not using user level security and no "
2204                           "password supplied.\n"));
2205                 goto access_denied;
2206         }
2207
2208         if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) &&
2209             *pass && passlen != 24) {
2210                 if (!lp_client_lanman_auth()) {
2211                         DEBUG(1, ("Server requested LANMAN password "
2212                                   "(share-level security) but "
2213                                   "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2214                         goto access_denied;
2215                 }
2216
2217                 /*
2218                  * Non-encrypted passwords - convert to DOS codepage before
2219                  * encryption.
2220                  */
2221                 SMBencrypt(pass, cli_state_server_challenge(cli), p24);
2222                 passlen = 24;
2223                 pass = (const char *)p24;
2224         } else {
2225                 if((sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL
2226                                      |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE))
2227                    == 0) {
2228                         uint8_t *tmp_pass;
2229
2230                         if (!lp_client_plaintext_auth() && (*pass)) {
2231                                 DEBUG(1, ("Server requested plaintext "
2232                                           "password but "
2233                                           "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2234                                 goto access_denied;
2235                         }
2236
2237                         /*
2238                          * Non-encrypted passwords - convert to DOS codepage
2239                          * before using.
2240                          */
2241                         tmp_pass = talloc_array(talloc_tos(), uint8, 0);
2242                         if (tevent_req_nomem(tmp_pass, req)) {
2243                                 return tevent_req_post(req, ev);
2244                         }
2245                         tmp_pass = trans2_bytes_push_str(tmp_pass,
2246                                                          false, /* always DOS */
2247                                                          pass,
2248                                                          passlen,
2249                                                          NULL);
2250                         if (tevent_req_nomem(tmp_pass, req)) {
2251                                 return tevent_req_post(req, ev);
2252                         }
2253                         pass = (const char *)tmp_pass;
2254                         passlen = talloc_get_size(tmp_pass);
2255                 }
2256         }
2257
2258         SCVAL(vwv+0, 0, 0xFF);
2259         SCVAL(vwv+0, 1, 0);
2260         SSVAL(vwv+1, 0, 0);
2261         SSVAL(vwv+2, 0, TCONX_FLAG_EXTENDED_RESPONSE);
2262         SSVAL(vwv+3, 0, passlen);
2263
2264         if (passlen && pass) {
2265                 bytes = (uint8_t *)talloc_memdup(state, pass, passlen);
2266         } else {
2267                 bytes = talloc_array(state, uint8_t, 0);
2268         }
2269
2270         /*
2271          * Add the sharename
2272          */
2273         tmp = talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
2274                                          cli_state_remote_name(cli), share);
2275         if (tmp == NULL) {
2276                 TALLOC_FREE(req);
2277                 return NULL;
2278         }
2279         bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), tmp, strlen(tmp)+1,
2280                                    NULL);
2281         TALLOC_FREE(tmp);
2282
2283         /*
2284          * Add the devicetype
2285          */
2286         tmp = talloc_strdup_upper(talloc_tos(), dev);
2287         if (tmp == NULL) {
2288                 TALLOC_FREE(req);
2289                 return NULL;
2290         }
2291         bytes = smb_bytes_push_str(bytes, false, tmp, strlen(tmp)+1, NULL);
2292         TALLOC_FREE(tmp);
2293
2294         if (bytes == NULL) {
2295                 TALLOC_FREE(req);
2296                 return NULL;
2297         }
2298
2299         state->bytes.iov_base = (void *)bytes;
2300         state->bytes.iov_len = talloc_get_size(bytes);
2301
2302         subreq = cli_smb_req_create(state, ev, cli, SMBtconX, 0, 4, vwv,
2303                                     1, &state->bytes);
2304         if (subreq == NULL) {
2305                 TALLOC_FREE(req);
2306                 return NULL;
2307         }
2308         tevent_req_set_callback(subreq, cli_tcon_andx_done, req);
2309         *psmbreq = subreq;
2310         return req;
2311
2312  access_denied:
2313         tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
2314         return tevent_req_post(req, ev);
2315 }
2316
2317 struct tevent_req *cli_tcon_andx_send(TALLOC_CTX *mem_ctx,
2318                                       struct event_context *ev,
2319                                       struct cli_state *cli,
2320                                       const char *share, const char *dev,
2321                                       const char *pass, int passlen)
2322 {
2323         struct tevent_req *req, *subreq;
2324         NTSTATUS status;
2325
2326         req = cli_tcon_andx_create(mem_ctx, ev, cli, share, dev, pass, passlen,
2327                                    &subreq);
2328         if (req == NULL) {
2329                 return NULL;
2330         }
2331         if (subreq == NULL) {
2332                 return req;
2333         }
2334         status = cli_smb_req_send(subreq);
2335         if (!NT_STATUS_IS_OK(status)) {
2336                 tevent_req_nterror(req, status);
2337                 return tevent_req_post(req, ev);
2338         }
2339         return req;
2340 }
2341
2342 static void cli_tcon_andx_done(struct tevent_req *subreq)
2343 {
2344         struct tevent_req *req = tevent_req_callback_data(
2345                 subreq, struct tevent_req);
2346         struct cli_tcon_andx_state *state = tevent_req_data(
2347                 req, struct cli_tcon_andx_state);
2348         struct cli_state *cli = state->cli;
2349         uint8_t *in;
2350         char *inbuf;
2351         uint8_t wct;
2352         uint16_t *vwv;
2353         uint32_t num_bytes;
2354         uint8_t *bytes;
2355         NTSTATUS status;
2356
2357         status = cli_smb_recv(subreq, state, &in, 0, &wct, &vwv,
2358                               &num_bytes, &bytes);
2359         TALLOC_FREE(subreq);
2360         if (!NT_STATUS_IS_OK(status)) {
2361                 tevent_req_nterror(req, status);
2362                 return;
2363         }
2364
2365         inbuf = (char *)in;
2366
2367         if (num_bytes) {
2368                 if (clistr_pull_talloc(cli,
2369                                 inbuf,
2370                                 SVAL(inbuf, smb_flg2),
2371                                 &cli->dev,
2372                                 bytes,
2373                                 num_bytes,
2374                                 STR_TERMINATE|STR_ASCII) == -1) {
2375                         tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2376                         return;
2377                 }
2378         } else {
2379                 cli->dev = talloc_strdup(cli, "");
2380                 if (cli->dev == NULL) {
2381                         tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2382                         return;
2383                 }
2384         }
2385
2386         if ((cli_state_protocol(cli) >= PROTOCOL_NT1) && (num_bytes == 3)) {
2387                 /* almost certainly win95 - enable bug fixes */
2388                 cli->win95 = True;
2389         }
2390
2391         /*
2392          * Make sure that we have the optional support 16-bit field. WCT > 2.
2393          * Avoids issues when connecting to Win9x boxes sharing files
2394          */
2395
2396         cli->dfsroot = false;
2397
2398         if ((wct > 2) && (cli_state_protocol(cli) >= PROTOCOL_LANMAN2)) {
2399                 cli->dfsroot = ((SVAL(vwv+2, 0) & SMB_SHARE_IN_DFS) != 0);
2400         }
2401
2402         cli->smb1.tid = SVAL(inbuf,smb_tid);
2403         tevent_req_done(req);
2404 }
2405
2406 NTSTATUS cli_tcon_andx_recv(struct tevent_req *req)
2407 {
2408         return tevent_req_simple_recv_ntstatus(req);
2409 }
2410
2411 NTSTATUS cli_tcon_andx(struct cli_state *cli, const char *share,
2412                        const char *dev, const char *pass, int passlen)
2413 {
2414         TALLOC_CTX *frame = talloc_stackframe();
2415         struct event_context *ev;
2416         struct tevent_req *req;
2417         NTSTATUS status = NT_STATUS_OK;
2418
2419         if (cli_has_async_calls(cli)) {
2420                 /*
2421                  * Can't use sync call while an async call is in flight
2422                  */
2423                 status = NT_STATUS_INVALID_PARAMETER;
2424                 goto fail;
2425         }
2426
2427         ev = event_context_init(frame);
2428         if (ev == NULL) {
2429                 status = NT_STATUS_NO_MEMORY;
2430                 goto fail;
2431         }
2432
2433         req = cli_tcon_andx_send(frame, ev, cli, share, dev, pass, passlen);
2434         if (req == NULL) {
2435                 status = NT_STATUS_NO_MEMORY;
2436                 goto fail;
2437         }
2438
2439         if (!tevent_req_poll(req, ev)) {
2440                 status = map_nt_error_from_unix(errno);
2441                 goto fail;
2442         }
2443
2444         status = cli_tcon_andx_recv(req);
2445  fail:
2446         TALLOC_FREE(frame);
2447         return status;
2448 }
2449
2450 /****************************************************************************
2451  Send a tree disconnect.
2452 ****************************************************************************/
2453
2454 struct cli_tdis_state {
2455         struct cli_state *cli;
2456 };
2457
2458 static void cli_tdis_done(struct tevent_req *subreq);
2459
2460 struct tevent_req *cli_tdis_send(TALLOC_CTX *mem_ctx,
2461                                  struct tevent_context *ev,
2462                                  struct cli_state *cli)
2463 {
2464         struct tevent_req *req, *subreq;
2465         struct cli_tdis_state *state;
2466
2467         req = tevent_req_create(mem_ctx, &state, struct cli_tdis_state);
2468         if (req == NULL) {
2469                 return NULL;
2470         }
2471         state->cli = cli;
2472
2473         subreq = cli_smb_send(state, ev, cli, SMBtdis, 0, 0, NULL, 0, NULL);
2474         if (tevent_req_nomem(subreq, req)) {
2475                 return tevent_req_post(req, ev);
2476         }
2477         tevent_req_set_callback(subreq, cli_tdis_done, req);
2478         return req;
2479 }
2480
2481 static void cli_tdis_done(struct tevent_req *subreq)
2482 {
2483         struct tevent_req *req = tevent_req_callback_data(
2484                 subreq, struct tevent_req);
2485         struct cli_tdis_state *state = tevent_req_data(
2486                 req, struct cli_tdis_state);
2487         NTSTATUS status;
2488
2489         status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
2490         TALLOC_FREE(subreq);
2491         if (!NT_STATUS_IS_OK(status)) {
2492                 tevent_req_nterror(req, status);
2493                 return;
2494         }
2495         state->cli->smb1.tid = UINT16_MAX;
2496         tevent_req_done(req);
2497 }
2498
2499 NTSTATUS cli_tdis_recv(struct tevent_req *req)
2500 {
2501         return tevent_req_simple_recv_ntstatus(req);
2502 }
2503
2504 NTSTATUS cli_tdis(struct cli_state *cli)
2505 {
2506         struct tevent_context *ev;
2507         struct tevent_req *req;
2508         NTSTATUS status = NT_STATUS_NO_MEMORY;
2509
2510         if (cli_has_async_calls(cli)) {
2511                 return NT_STATUS_INVALID_PARAMETER;
2512         }
2513         ev = tevent_context_init(talloc_tos());
2514         if (ev == NULL) {
2515                 goto fail;
2516         }
2517         req = cli_tdis_send(ev, ev, cli);
2518         if (req == NULL) {
2519                 goto fail;
2520         }
2521         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2522                 goto fail;
2523         }
2524         status = cli_tdis_recv(req);
2525 fail:
2526         TALLOC_FREE(ev);
2527         return status;
2528 }
2529
2530 /****************************************************************************
2531  Send a negprot command.
2532 ****************************************************************************/
2533
2534 struct cli_negprot_state {
2535         struct cli_state *cli;
2536         enum protocol_types max_protocol;
2537 };
2538
2539 static void cli_negprot_done(struct tevent_req *subreq);
2540
2541 struct tevent_req *cli_negprot_send(TALLOC_CTX *mem_ctx,
2542                                     struct event_context *ev,
2543                                     struct cli_state *cli,
2544                                     enum protocol_types max_protocol)
2545 {
2546         struct tevent_req *req, *subreq;
2547         struct cli_negprot_state *state;
2548         uint8_t *bytes = NULL;
2549         int numprots;
2550         enum protocol_types tmp_protocol;
2551
2552         req = tevent_req_create(mem_ctx, &state, struct cli_negprot_state);
2553         if (req == NULL) {
2554                 return NULL;
2555         }
2556         state->cli = cli;
2557         state->max_protocol = max_protocol;
2558
2559         /* setup the protocol strings */
2560         for (numprots=0; numprots < ARRAY_SIZE(prots); numprots++) {
2561                 uint8_t c = 2;
2562                 if (prots[numprots].prot > state->max_protocol) {
2563                         break;
2564                 }
2565                 bytes = (uint8_t *)talloc_append_blob(
2566                         state, bytes, data_blob_const(&c, sizeof(c)));
2567                 if (tevent_req_nomem(bytes, req)) {
2568                         return tevent_req_post(req, ev);
2569                 }
2570                 bytes = smb_bytes_push_str(bytes, false,
2571                                            prots[numprots].name,
2572                                            strlen(prots[numprots].name)+1,
2573                                            NULL);
2574                 if (tevent_req_nomem(bytes, req)) {
2575                         return tevent_req_post(req, ev);
2576                 }
2577         }
2578
2579         tmp_protocol = cli->conn.protocol;
2580         cli->conn.protocol = state->max_protocol;
2581         subreq = cli_smb_send(state, ev, cli, SMBnegprot, 0, 0, NULL,
2582                               talloc_get_size(bytes), bytes);
2583         cli->conn.protocol = tmp_protocol;
2584         if (tevent_req_nomem(subreq, req)) {
2585                 return tevent_req_post(req, ev);
2586         }
2587         tevent_req_set_callback(subreq, cli_negprot_done, req);
2588         return req;
2589 }
2590
2591 static void cli_negprot_done(struct tevent_req *subreq)
2592 {
2593         struct tevent_req *req = tevent_req_callback_data(
2594                 subreq, struct tevent_req);
2595         struct cli_negprot_state *state = tevent_req_data(
2596                 req, struct cli_negprot_state);
2597         struct cli_state *cli = state->cli;
2598         uint8_t flags;
2599         uint8_t wct;
2600         uint16_t *vwv;
2601         uint32_t num_bytes;
2602         uint8_t *bytes;
2603         NTSTATUS status;
2604         uint16_t protnum;
2605         uint8_t *inbuf;
2606         uint32_t client_capabilities = cli->conn.smb1.client.capabilities;
2607         uint32_t both_capabilities;
2608         uint32_t server_capabilities = 0;
2609         uint32_t capabilities;
2610         uint32_t client_max_xmit = cli->conn.smb1.client.max_xmit;
2611         uint32_t server_max_xmit = 0;
2612         uint32_t max_xmit;
2613         uint32_t server_max_mux = 0;
2614         uint16_t server_security_mode = 0;
2615         uint32_t server_session_key = 0;
2616         bool server_readbraw = false;
2617         bool server_writebraw = false;
2618         bool server_lockread = false;
2619         bool server_writeunlock = false;
2620         struct GUID server_guid = GUID_zero();
2621         DATA_BLOB server_gss_blob = data_blob_null;
2622         uint8_t server_challenge[8];
2623         char *server_workgroup = NULL;
2624         int server_time_zone = 0;
2625         time_t server_system_time = 0;
2626         enum protocol_types protocol;
2627
2628         ZERO_STRUCT(server_challenge);
2629
2630         status = cli_smb_recv(subreq, state, &inbuf, 1, &wct, &vwv,
2631                               &num_bytes, &bytes);
2632         TALLOC_FREE(subreq);
2633         if (!NT_STATUS_IS_OK(status)) {
2634                 tevent_req_nterror(req, status);
2635                 return;
2636         }
2637
2638         flags = CVAL(inbuf, smb_flg);
2639
2640         protnum = SVAL(vwv, 0);
2641
2642         if ((protnum >= ARRAY_SIZE(prots))
2643             || (prots[protnum].prot > state->max_protocol)) {
2644                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2645                 return;
2646         }
2647
2648         protocol = prots[protnum].prot;
2649
2650         if ((protocol < PROTOCOL_NT1) &&
2651             client_is_signing_mandatory(cli)) {
2652                 DEBUG(0,("cli_negprot: SMB signing is mandatory and the selected protocol level doesn't support it.\n"));
2653                 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
2654                 return;
2655         }
2656
2657         if (flags & FLAG_SUPPORT_LOCKREAD) {
2658                 server_lockread = true;
2659                 server_writeunlock = true;
2660         }
2661
2662         if (protocol >= PROTOCOL_NT1) {
2663                 struct timespec ts;
2664                 const char *client_signing = NULL;
2665                 bool server_mandatory;
2666                 bool server_allowed;
2667                 const char *server_signing = NULL;
2668                 bool ok;
2669                 uint16_t key_len;
2670
2671                 if (wct != 0x11) {
2672                         tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2673                         return;
2674                 }
2675
2676                 /* NT protocol */
2677                 server_security_mode = CVAL(vwv + 1, 0);
2678                 server_max_mux = SVAL(vwv + 1, 1);
2679                 server_max_xmit = IVAL(vwv + 3, 1);
2680                 server_session_key = IVAL(vwv + 7, 1);
2681                 server_time_zone = SVALS(vwv + 15, 1);
2682                 server_time_zone *= 60;
2683                 /* this time arrives in real GMT */
2684                 ts = interpret_long_date(((char *)(vwv+11))+1);
2685                 server_system_time = ts.tv_sec;
2686                 server_capabilities = IVAL(vwv + 9, 1);
2687
2688                 key_len = CVAL(vwv + 16, 1);
2689
2690                 if (server_capabilities & CAP_RAW_MODE) {
2691                         server_readbraw = true;
2692                         server_writebraw = true;
2693                 }
2694                 if (server_capabilities & CAP_LOCK_AND_READ) {
2695                         server_lockread = true;
2696                 }
2697
2698                 if (server_capabilities & CAP_EXTENDED_SECURITY) {
2699                         DATA_BLOB blob1, blob2;
2700
2701                         if (num_bytes < 16) {
2702                                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2703                                 return;
2704                         }
2705
2706                         blob1 = data_blob_const(bytes, 16);
2707                         GUID_from_data_blob(&blob1, &server_guid);
2708
2709                         blob1 = data_blob_const(bytes+16, num_bytes-16);
2710                         blob2 = data_blob_dup_talloc(state, blob1);
2711                         if (blob1.length > 0 &&
2712                             tevent_req_nomem(blob2.data, req)) {
2713                                 return;
2714                         }
2715                         server_gss_blob = blob2;
2716                 } else {
2717                         DATA_BLOB blob1;
2718                         ssize_t ret;
2719
2720                         if (num_bytes < key_len) {
2721                                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2722                                 return;
2723                         }
2724
2725                         if (key_len != 0 && key_len != 8) {
2726                                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2727                                 return;
2728                         }
2729
2730                         if (key_len == 8) {
2731                                 memcpy(server_challenge, bytes, 8);
2732                         }
2733
2734                         blob1 = data_blob_const(bytes+key_len, num_bytes-key_len);
2735                         if (blob1.length > 0) {
2736                                 ret = pull_string_talloc(state,
2737                                                          (char *)inbuf,
2738                                                          SVAL(inbuf, smb_flg2),
2739                                                          &server_workgroup,
2740                                                          blob1.data, blob1.length,
2741                                                          STR_TERMINATE);
2742                                 if (ret == -1) {
2743                                         tevent_req_oom(req);
2744                                         return;
2745                                 }
2746                         }
2747                 }
2748
2749                 client_signing = "disabled";
2750                 if (client_is_signing_allowed(cli)) {
2751                         client_signing = "allowed";
2752                 }
2753                 if (client_is_signing_mandatory(cli)) {
2754                         client_signing = "required";
2755                 }
2756
2757                 server_signing = "not supported";
2758
2759                 server_allowed = false;
2760                 if (server_security_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) {
2761                         server_signing = "supported";
2762                         server_allowed = true;
2763                 }
2764
2765                 server_mandatory = false;
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                 server_time_zone = SVALS(vwv + 10, 0);
2793                 server_time_zone *= 60;
2794                 /* this time is converted to GMT by make_unix_date */
2795                 server_system_time = make_unix_date(
2796                         (char *)(vwv + 8), server_time_zone);
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                 server_time_zone = get_time_zone(time(NULL));
2811                 server_system_time = 0;
2812                 server_max_xmit = 1024;
2813                 server_max_mux = 1;
2814                 server_security_mode = 0;
2815         }
2816
2817         if (server_max_xmit < 1024) {
2818                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2819                 return;
2820         }
2821
2822         if (server_max_mux < 1) {
2823                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2824                 return;
2825         }
2826
2827         /*
2828          * Now calculate the negotiated capabilities
2829          * based on the mask for:
2830          * - client only flags
2831          * - flags used in both directions
2832          * - server only flags
2833          */
2834         both_capabilities = client_capabilities & server_capabilities;
2835         capabilities = client_capabilities & SMB_CAP_CLIENT_MASK;
2836         capabilities |= both_capabilities & SMB_CAP_BOTH_MASK;
2837         capabilities |= server_capabilities & SMB_CAP_SERVER_MASK;
2838
2839         max_xmit = MIN(client_max_xmit, server_max_xmit);
2840
2841         if (server_workgroup) {
2842                 cli->server_domain = talloc_strdup(cli, server_workgroup);
2843                 if (tevent_req_nomem(cli->server_domain, req)) {
2844                         return;
2845                 }
2846         }
2847
2848         cli->conn.protocol = protocol;
2849
2850         cli->conn.smb1.server.capabilities = server_capabilities;
2851         cli->conn.smb1.capabilities = capabilities;
2852
2853         cli->conn.smb1.server.max_xmit = server_max_xmit;
2854         cli->conn.smb1.max_xmit = max_xmit;
2855
2856         cli->conn.smb1.server.max_mux = server_max_mux;
2857
2858         cli->conn.smb1.server.security_mode = server_security_mode;
2859
2860         cli->conn.smb1.server.readbraw = server_readbraw;
2861         cli->conn.smb1.server.writebraw = server_writebraw;
2862         cli->conn.smb1.server.lockread = server_lockread;
2863         cli->conn.smb1.server.writeunlock = server_writeunlock;
2864
2865         cli->conn.smb1.server.session_key = server_session_key;
2866
2867         talloc_steal(cli, server_gss_blob.data);
2868         cli->conn.smb1.server.gss_blob = server_gss_blob;
2869         cli->conn.smb1.server.guid = server_guid;
2870         memcpy(cli->conn.smb1.server.challenge, server_challenge, 8);
2871         cli->conn.smb1.server.workgroup = talloc_move(cli, &server_workgroup);
2872
2873         cli->conn.smb1.server.time_zone = server_time_zone;
2874         cli->conn.smb1.server.system_time = server_system_time;
2875
2876         tevent_req_done(req);
2877 }
2878
2879 NTSTATUS cli_negprot_recv(struct tevent_req *req)
2880 {
2881         return tevent_req_simple_recv_ntstatus(req);
2882 }
2883
2884 NTSTATUS cli_negprot(struct cli_state *cli, enum protocol_types max_protocol)
2885 {
2886         TALLOC_CTX *frame = talloc_stackframe();
2887         struct event_context *ev;
2888         struct tevent_req *req;
2889         NTSTATUS status = NT_STATUS_OK;
2890
2891         if (cli_has_async_calls(cli)) {
2892                 /*
2893                  * Can't use sync call while an async call is in flight
2894                  */
2895                 status = NT_STATUS_INVALID_PARAMETER;
2896                 goto fail;
2897         }
2898
2899         ev = event_context_init(frame);
2900         if (ev == NULL) {
2901                 status = NT_STATUS_NO_MEMORY;
2902                 goto fail;
2903         }
2904
2905         req = cli_negprot_send(frame, ev, cli, max_protocol);
2906         if (req == NULL) {
2907                 status = NT_STATUS_NO_MEMORY;
2908                 goto fail;
2909         }
2910
2911         if (!tevent_req_poll(req, ev)) {
2912                 status = map_nt_error_from_unix(errno);
2913                 goto fail;
2914         }
2915
2916         status = cli_negprot_recv(req);
2917  fail:
2918         TALLOC_FREE(frame);
2919         return status;
2920 }
2921
2922 static NTSTATUS cli_connect_sock(const char *host, int name_type,
2923                                  const struct sockaddr_storage *pss,
2924                                  const char *myname, uint16_t port,
2925                                  int sec_timeout, int *pfd, uint16_t *pport)
2926 {
2927         TALLOC_CTX *frame = talloc_stackframe();
2928         const char *prog;
2929         unsigned int i, num_addrs;
2930         const char **called_names;
2931         const char **calling_names;
2932         int *called_types;
2933         NTSTATUS status;
2934         int fd;
2935
2936         prog = getenv("LIBSMB_PROG");
2937         if (prog != NULL) {
2938                 fd = sock_exec(prog);
2939                 if (fd == -1) {
2940                         return map_nt_error_from_unix(errno);
2941                 }
2942                 port = 0;
2943                 goto done;
2944         }
2945
2946         if ((pss == NULL) || is_zero_addr(pss)) {
2947                 struct sockaddr_storage *addrs;
2948                 status = resolve_name_list(talloc_tos(), host, name_type,
2949                                            &addrs, &num_addrs);
2950                 if (!NT_STATUS_IS_OK(status)) {
2951                         goto fail;
2952                 }
2953                 pss = addrs;
2954         } else {
2955                 num_addrs = 1;
2956         }
2957
2958         called_names = talloc_array(talloc_tos(), const char *, num_addrs);
2959         if (called_names == NULL) {
2960                 status = NT_STATUS_NO_MEMORY;
2961                 goto fail;
2962         }
2963         called_types = talloc_array(talloc_tos(), int, num_addrs);
2964         if (called_types == NULL) {
2965                 status = NT_STATUS_NO_MEMORY;
2966                 goto fail;
2967         }
2968         calling_names = talloc_array(talloc_tos(), const char *, num_addrs);
2969         if (calling_names == NULL) {
2970                 status = NT_STATUS_NO_MEMORY;
2971                 goto fail;
2972         }
2973         for (i=0; i<num_addrs; i++) {
2974                 called_names[i] = host;
2975                 called_types[i] = name_type;
2976                 calling_names[i] = myname;
2977         }
2978         status = smbsock_any_connect(pss, called_names, called_types,
2979                                      calling_names, NULL, num_addrs, port,
2980                                      sec_timeout, &fd, NULL, &port);
2981         if (!NT_STATUS_IS_OK(status)) {
2982                 goto fail;
2983         }
2984         set_socket_options(fd, lp_socket_options());
2985 done:
2986         *pfd = fd;
2987         *pport = port;
2988         status = NT_STATUS_OK;
2989 fail:
2990         TALLOC_FREE(frame);
2991         return status;
2992 }
2993
2994 NTSTATUS cli_connect_nb(const char *host, const struct sockaddr_storage *dest_ss,
2995                         uint16_t port, int name_type, const char *myname,
2996                         int signing_state, int flags, struct cli_state **pcli)
2997 {
2998         TALLOC_CTX *frame = talloc_stackframe();
2999         struct cli_state *cli;
3000         NTSTATUS status = NT_STATUS_NO_MEMORY;
3001         int fd = -1;
3002         char *desthost;
3003         char *p;
3004
3005         desthost = talloc_strdup(talloc_tos(), host);
3006         if (desthost == NULL) {
3007                 goto fail;
3008         }
3009
3010         p = strchr(host, '#');
3011         if (p != NULL) {
3012                 name_type = strtol(p+1, NULL, 16);
3013                 host = talloc_strndup(talloc_tos(), host, p - host);
3014                 if (host == NULL) {
3015                         goto fail;
3016                 }
3017         }
3018
3019         status = cli_connect_sock(host, name_type, dest_ss, myname, port,
3020                                   20, &fd, &port);
3021         if (!NT_STATUS_IS_OK(status)) {
3022                 goto fail;
3023         }
3024
3025         cli = cli_state_create(NULL, fd, desthost, NULL, signing_state, flags);
3026         if (cli == NULL) {
3027                 goto fail;
3028         }
3029
3030         *pcli = cli;
3031         status = NT_STATUS_OK;
3032 fail:
3033         TALLOC_FREE(frame);
3034         return status;
3035 }
3036
3037 /**
3038    establishes a connection to after the negprot. 
3039    @param output_cli A fully initialised cli structure, non-null only on success
3040    @param dest_host The netbios name of the remote host
3041    @param dest_ss (optional) The the destination IP, NULL for name based lookup
3042    @param port (optional) The destination port (0 for default)
3043 */
3044 NTSTATUS cli_start_connection(struct cli_state **output_cli, 
3045                               const char *my_name, 
3046                               const char *dest_host, 
3047                               const struct sockaddr_storage *dest_ss, int port,
3048                               int signing_state, int flags)
3049 {
3050         NTSTATUS nt_status;
3051         struct cli_state *cli;
3052
3053         nt_status = cli_connect_nb(dest_host, dest_ss, port, 0x20, my_name,
3054                                    signing_state, flags, &cli);
3055         if (!NT_STATUS_IS_OK(nt_status)) {
3056                 DEBUG(10, ("cli_connect_nb failed: %s\n",
3057                            nt_errstr(nt_status)));
3058                 return nt_status;
3059         }
3060
3061         nt_status = cli_negprot(cli, PROTOCOL_NT1);
3062         if (!NT_STATUS_IS_OK(nt_status)) {
3063                 DEBUG(1, ("failed negprot: %s\n", nt_errstr(nt_status)));
3064                 cli_shutdown(cli);
3065                 return nt_status;
3066         }
3067
3068         *output_cli = cli;
3069         return NT_STATUS_OK;
3070 }
3071
3072
3073 /**
3074    establishes a connection right up to doing tconX, password specified.
3075    @param output_cli A fully initialised cli structure, non-null only on success
3076    @param dest_host The netbios name of the remote host
3077    @param dest_ip (optional) The the destination IP, NULL for name based lookup
3078    @param port (optional) The destination port (0 for default)
3079    @param service (optional) The share to make the connection to.  Should be 'unqualified' in any way.
3080    @param service_type The 'type' of serivice. 
3081    @param user Username, unix string
3082    @param domain User's domain
3083    @param password User's password, unencrypted unix string.
3084 */
3085
3086 NTSTATUS cli_full_connection(struct cli_state **output_cli, 
3087                              const char *my_name, 
3088                              const char *dest_host, 
3089                              const struct sockaddr_storage *dest_ss, int port,
3090                              const char *service, const char *service_type,
3091                              const char *user, const char *domain, 
3092                              const char *password, int flags,
3093                              int signing_state)
3094 {
3095         NTSTATUS nt_status;
3096         struct cli_state *cli = NULL;
3097         int pw_len = password ? strlen(password)+1 : 0;
3098
3099         *output_cli = NULL;
3100
3101         if (password == NULL) {
3102                 password = "";
3103         }
3104
3105         nt_status = cli_start_connection(&cli, my_name, dest_host,
3106                                          dest_ss, port, signing_state,
3107                                          flags);
3108
3109         if (!NT_STATUS_IS_OK(nt_status)) {
3110                 return nt_status;
3111         }
3112
3113         nt_status = cli_session_setup(cli, user, password, pw_len, password,
3114                                       pw_len, domain);
3115         if (!NT_STATUS_IS_OK(nt_status)) {
3116
3117                 if (!(flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)) {
3118                         DEBUG(1,("failed session setup with %s\n",
3119                                  nt_errstr(nt_status)));
3120                         cli_shutdown(cli);
3121                         return nt_status;
3122                 }
3123
3124                 nt_status = cli_session_setup(cli, "", "", 0, "", 0, domain);
3125                 if (!NT_STATUS_IS_OK(nt_status)) {
3126                         DEBUG(1,("anonymous failed session setup with %s\n",
3127                                  nt_errstr(nt_status)));
3128                         cli_shutdown(cli);
3129                         return nt_status;
3130                 }
3131         }
3132
3133         if (service) {
3134                 nt_status = cli_tcon_andx(cli, service, service_type, password,
3135                                           pw_len);
3136                 if (!NT_STATUS_IS_OK(nt_status)) {
3137                         DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status)));
3138                         cli_shutdown(cli);
3139                         if (NT_STATUS_IS_OK(nt_status)) {
3140                                 nt_status = NT_STATUS_UNSUCCESSFUL;
3141                         }
3142                         return nt_status;
3143                 }
3144         }
3145
3146         nt_status = cli_init_creds(cli, user, domain, password);
3147         if (!NT_STATUS_IS_OK(nt_status)) {
3148                 cli_shutdown(cli);
3149                 return nt_status;
3150         }
3151
3152         *output_cli = cli;
3153         return NT_STATUS_OK;
3154 }
3155
3156 /****************************************************************************
3157  Send an old style tcon.
3158 ****************************************************************************/
3159 NTSTATUS cli_raw_tcon(struct cli_state *cli, 
3160                       const char *service, const char *pass, const char *dev,
3161                       uint16 *max_xmit, uint16 *tid)
3162 {
3163         struct tevent_req *req;
3164         uint16_t *ret_vwv;
3165         uint8_t *bytes;
3166         NTSTATUS status;
3167
3168         if (!lp_client_plaintext_auth() && (*pass)) {
3169                 DEBUG(1, ("Server requested plaintext password but 'client "
3170                           "plaintext auth' is disabled\n"));
3171                 return NT_STATUS_ACCESS_DENIED;
3172         }
3173
3174         bytes = talloc_array(talloc_tos(), uint8_t, 0);
3175         bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3176         bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
3177                                    service, strlen(service)+1, NULL);
3178         bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3179         bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
3180                                    pass, strlen(pass)+1, NULL);
3181         bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3182         bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
3183                                    dev, strlen(dev)+1, NULL);
3184
3185         status = cli_smb(talloc_tos(), cli, SMBtcon, 0, 0, NULL,
3186                          talloc_get_size(bytes), bytes, &req,
3187                          2, NULL, &ret_vwv, NULL, NULL);
3188         if (!NT_STATUS_IS_OK(status)) {
3189                 return status;
3190         }
3191
3192         *max_xmit = SVAL(ret_vwv + 0, 0);
3193         *tid = SVAL(ret_vwv + 1, 0);
3194
3195         return NT_STATUS_OK;
3196 }
3197
3198 /* Return a cli_state pointing at the IPC$ share for the given server */
3199
3200 struct cli_state *get_ipc_connect(char *server,
3201                                 struct sockaddr_storage *server_ss,
3202                                 const struct user_auth_info *user_info)
3203 {
3204         struct cli_state *cli;
3205         NTSTATUS nt_status;
3206         uint32_t flags = CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
3207
3208         if (user_info->use_kerberos) {
3209                 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
3210         }
3211
3212         nt_status = cli_full_connection(&cli, NULL, server, server_ss, 0, "IPC$", "IPC", 
3213                                         user_info->username ? user_info->username : "",
3214                                         lp_workgroup(),
3215                                         user_info->password ? user_info->password : "",
3216                                         flags,
3217                                         Undefined);
3218
3219         if (NT_STATUS_IS_OK(nt_status)) {
3220                 return cli;
3221         } else if (is_ipaddress(server)) {
3222             /* windows 9* needs a correct NMB name for connections */
3223             fstring remote_name;
3224
3225             if (name_status_find("*", 0, 0, server_ss, remote_name)) {
3226                 cli = get_ipc_connect(remote_name, server_ss, user_info);
3227                 if (cli)
3228                     return cli;
3229             }
3230         }
3231         return NULL;
3232 }
3233
3234 /*
3235  * Given the IP address of a master browser on the network, return its
3236  * workgroup and connect to it.
3237  *
3238  * This function is provided to allow additional processing beyond what
3239  * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
3240  * browsers and obtain each master browsers' list of domains (in case the
3241  * first master browser is recently on the network and has not yet
3242  * synchronized with other master browsers and therefore does not yet have the
3243  * entire network browse list)
3244  */
3245
3246 struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx,
3247                                 struct sockaddr_storage *mb_ip,
3248                                 const struct user_auth_info *user_info,
3249                                 char **pp_workgroup_out)
3250 {
3251         char addr[INET6_ADDRSTRLEN];
3252         fstring name;
3253         struct cli_state *cli;
3254         struct sockaddr_storage server_ss;
3255
3256         *pp_workgroup_out = NULL;
3257
3258         print_sockaddr(addr, sizeof(addr), mb_ip);
3259         DEBUG(99, ("Looking up name of master browser %s\n",
3260                    addr));
3261
3262         /*
3263          * Do a name status query to find out the name of the master browser.
3264          * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
3265          * master browser will not respond to a wildcard query (or, at least,
3266          * an NT4 server acting as the domain master browser will not).
3267          *
3268          * We might be able to use ONLY the query on MSBROWSE, but that's not
3269          * yet been tested with all Windows versions, so until it is, leave
3270          * the original wildcard query as the first choice and fall back to
3271          * MSBROWSE if the wildcard query fails.
3272          */
3273         if (!name_status_find("*", 0, 0x1d, mb_ip, name) &&
3274             !name_status_find(MSBROWSE, 1, 0x1d, mb_ip, name)) {
3275
3276                 DEBUG(99, ("Could not retrieve name status for %s\n",
3277                            addr));
3278                 return NULL;
3279         }
3280
3281         if (!find_master_ip(name, &server_ss)) {
3282                 DEBUG(99, ("Could not find master ip for %s\n", name));
3283                 return NULL;
3284         }
3285
3286         *pp_workgroup_out = talloc_strdup(ctx, name);
3287
3288         DEBUG(4, ("found master browser %s, %s\n", name, addr));
3289
3290         print_sockaddr(addr, sizeof(addr), &server_ss);
3291         cli = get_ipc_connect(addr, &server_ss, user_info);
3292
3293         return cli;
3294 }
3295
3296 /*
3297  * Return the IP address and workgroup of a master browser on the network, and
3298  * connect to it.
3299  */
3300
3301 struct cli_state *get_ipc_connect_master_ip_bcast(TALLOC_CTX *ctx,
3302                                         const struct user_auth_info *user_info,
3303                                         char **pp_workgroup_out)
3304 {
3305         struct sockaddr_storage *ip_list;
3306         struct cli_state *cli;
3307         int i, count;
3308         NTSTATUS status;
3309
3310         *pp_workgroup_out = NULL;
3311
3312         DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
3313
3314         /* Go looking for workgroups by broadcasting on the local network */
3315
3316         status = name_resolve_bcast(MSBROWSE, 1, talloc_tos(),
3317                                     &ip_list, &count);
3318         if (!NT_STATUS_IS_OK(status)) {
3319                 DEBUG(99, ("No master browsers responded: %s\n",
3320                            nt_errstr(status)));
3321                 return False;
3322         }
3323
3324         for (i = 0; i < count; i++) {
3325                 char addr[INET6_ADDRSTRLEN];
3326                 print_sockaddr(addr, sizeof(addr), &ip_list[i]);
3327                 DEBUG(99, ("Found master browser %s\n", addr));
3328
3329                 cli = get_ipc_connect_master_ip(ctx, &ip_list[i],
3330                                 user_info, pp_workgroup_out);
3331                 if (cli)
3332                         return(cli);
3333         }
3334
3335         return NULL;
3336 }