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
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.
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.
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/>.
24 #include "libsmb/libsmb.h"
25 #include "popt_common.h"
26 #include "../libcli/auth/libcli_auth.h"
27 #include "../libcli/auth/spnego.h"
29 #include "../libcli/auth/ntlmssp.h"
30 #include "libads/kerberos_proto.h"
32 #include "../lib/util/tevent_ntstatus.h"
33 #include "async_smb.h"
34 #include "libsmb/nmblib.h"
41 {PROTOCOL_CORE, "PC NETWORK PROGRAM 1.0"},
42 {PROTOCOL_COREPLUS, "MICROSOFT NETWORKS 1.03"},
43 {PROTOCOL_LANMAN1, "MICROSOFT NETWORKS 3.0"},
44 {PROTOCOL_LANMAN1, "LANMAN1.0"},
45 {PROTOCOL_LANMAN2, "LM1.2X002"},
46 {PROTOCOL_LANMAN2, "DOS LANMAN2.1"},
47 {PROTOCOL_LANMAN2, "LANMAN2.1"},
48 {PROTOCOL_LANMAN2, "Samba"},
49 {PROTOCOL_NT1, "NT LANMAN 1.0"},
50 {PROTOCOL_NT1, "NT LM 0.12"},
53 #define STAR_SMBSERVER "*SMBSERVER"
55 /********************************************************
56 Utility function to ensure we always return at least
57 a valid char * pointer to an empty string for the
58 cli->server_os, cli->server_type and cli->server_domain
60 *******************************************************/
62 static NTSTATUS smb_bytes_talloc_string(struct cli_state *cli,
69 *destlen = clistr_pull_talloc(cli,
71 SVAL(inbuf, smb_flg2),
77 return NT_STATUS_NO_MEMORY;
81 *dest = talloc_strdup(cli, "");
83 return NT_STATUS_NO_MEMORY;
90 * Set the user session key for a connection
91 * @param cli The cli structure to add it too
92 * @param session_key The session key used. (A copy of this is taken for the cli struct)
96 static void cli_set_session_key (struct cli_state *cli, const DATA_BLOB session_key)
98 cli->user_session_key = data_blob(session_key.data, session_key.length);
101 /****************************************************************************
102 Do an old lanman2 style session setup.
103 ****************************************************************************/
105 struct cli_session_setup_lanman2_state {
106 struct cli_state *cli;
111 static void cli_session_setup_lanman2_done(struct tevent_req *subreq);
113 static struct tevent_req *cli_session_setup_lanman2_send(
114 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
115 struct cli_state *cli, const char *user,
116 const char *pass, size_t passlen,
117 const char *workgroup)
119 struct tevent_req *req, *subreq;
120 struct cli_session_setup_lanman2_state *state;
121 DATA_BLOB lm_response = data_blob_null;
126 req = tevent_req_create(mem_ctx, &state,
127 struct cli_session_setup_lanman2_state);
136 * LANMAN servers predate NT status codes and Unicode and
137 * ignore those smb flags so we must disable the corresponding
138 * default capabilities that would otherwise cause the Unicode
139 * and NT Status flags to be set (and even returned by the
143 cli->capabilities &= ~(CAP_UNICODE | CAP_STATUS32);
146 * if in share level security then don't send a password now
148 if (!(cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) {
153 && (cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)
156 * Encrypted mode needed, and non encrypted password
159 lm_response = data_blob(NULL, 24);
160 if (tevent_req_nomem(lm_response.data, req)) {
161 return tevent_req_post(req, ev);
164 if (!SMBencrypt(pass, cli->secblob.data,
165 (uint8_t *)lm_response.data)) {
166 DEBUG(1, ("Password is > 14 chars in length, and is "
167 "therefore incompatible with Lanman "
168 "authentication\n"));
169 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
170 return tevent_req_post(req, ev);
172 } else if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)
175 * Encrypted mode needed, and encrypted password
178 lm_response = data_blob(pass, passlen);
179 if (tevent_req_nomem(lm_response.data, req)) {
180 return tevent_req_post(req, ev);
182 } else if (passlen > 0) {
184 size_t converted_size;
186 * Plaintext mode needed, assume plaintext supplied.
188 buf = talloc_array(talloc_tos(), uint8_t, 0);
189 buf = smb_bytes_push_str(buf, cli_ucs2(cli), pass, passlen+1,
191 if (tevent_req_nomem(buf, req)) {
192 return tevent_req_post(req, ev);
194 lm_response = data_blob(pass, passlen);
196 if (tevent_req_nomem(lm_response.data, req)) {
197 return tevent_req_post(req, ev);
201 SCVAL(vwv+0, 0, 0xff);
204 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
207 SIVAL(vwv+5, 0, cli->sesskey);
208 SSVAL(vwv+7, 0, lm_response.length);
210 bytes = talloc_array(state, uint8_t, lm_response.length);
211 if (tevent_req_nomem(bytes, req)) {
212 return tevent_req_post(req, ev);
214 if (lm_response.length != 0) {
215 memcpy(bytes, lm_response.data, lm_response.length);
217 data_blob_free(&lm_response);
219 tmp = talloc_strdup_upper(talloc_tos(), user);
220 if (tevent_req_nomem(tmp, req)) {
221 return tevent_req_post(req, ev);
223 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), tmp, strlen(tmp)+1,
227 tmp = talloc_strdup_upper(talloc_tos(), workgroup);
228 if (tevent_req_nomem(tmp, req)) {
229 return tevent_req_post(req, ev);
231 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), tmp, strlen(tmp)+1,
233 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Unix", 5, NULL);
234 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Samba", 6, NULL);
236 if (tevent_req_nomem(bytes, req)) {
237 return tevent_req_post(req, ev);
240 subreq = cli_smb_send(state, ev, cli, SMBsesssetupX, 0, 10, vwv,
241 talloc_get_size(bytes), bytes);
242 if (tevent_req_nomem(subreq, req)) {
243 return tevent_req_post(req, ev);
245 tevent_req_set_callback(subreq, cli_session_setup_lanman2_done, req);
249 static void cli_session_setup_lanman2_done(struct tevent_req *subreq)
251 struct tevent_req *req = tevent_req_callback_data(
252 subreq, struct tevent_req);
253 struct cli_session_setup_lanman2_state *state = tevent_req_data(
254 req, struct cli_session_setup_lanman2_state);
255 struct cli_state *cli = state->cli;
264 status = cli_smb_recv(subreq, state, &in, 0, NULL, NULL,
267 if (!NT_STATUS_IS_OK(status)) {
268 tevent_req_nterror(req, status);
275 cli->vuid = SVAL(inbuf, smb_uid);
277 status = smb_bytes_talloc_string(cli,
284 if (!NT_STATUS_IS_OK(status)) {
285 tevent_req_nterror(req, status);
290 status = smb_bytes_talloc_string(cli,
297 if (!NT_STATUS_IS_OK(status)) {
298 tevent_req_nterror(req, status);
303 status = smb_bytes_talloc_string(cli,
310 if (!NT_STATUS_IS_OK(status)) {
311 tevent_req_nterror(req, status);
316 if (strstr(cli->server_type, "Samba")) {
317 cli->is_samba = True;
319 status = cli_set_username(cli, state->user);
320 if (tevent_req_nterror(req, status)) {
323 tevent_req_done(req);
326 static NTSTATUS cli_session_setup_lanman2_recv(struct tevent_req *req)
328 return tevent_req_simple_recv_ntstatus(req);
331 static NTSTATUS cli_session_setup_lanman2(struct cli_state *cli, const char *user,
332 const char *pass, size_t passlen,
333 const char *workgroup)
335 TALLOC_CTX *frame = talloc_stackframe();
336 struct event_context *ev;
337 struct tevent_req *req;
338 NTSTATUS status = NT_STATUS_NO_MEMORY;
340 if (cli_has_async_calls(cli)) {
342 * Can't use sync call while an async call is in flight
344 status = NT_STATUS_INVALID_PARAMETER;
347 ev = event_context_init(frame);
351 req = cli_session_setup_lanman2_send(frame, ev, cli, user, pass, passlen,
356 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
359 status = cli_session_setup_lanman2_recv(req);
365 /****************************************************************************
366 Work out suitable capabilities to offer the server.
367 ****************************************************************************/
369 static uint32 cli_session_setup_capabilities(struct cli_state *cli)
371 uint32 capabilities = CAP_NT_SMBS;
373 if (!cli->force_dos_errors)
374 capabilities |= CAP_STATUS32;
376 if (cli->use_level_II_oplocks)
377 capabilities |= CAP_LEVEL_II_OPLOCKS;
379 capabilities |= (cli->capabilities & (CAP_UNICODE|CAP_LARGE_FILES|CAP_LARGE_READX|CAP_LARGE_WRITEX|CAP_DFS));
383 /****************************************************************************
384 Do a NT1 guest session setup.
385 ****************************************************************************/
387 struct cli_session_setup_guest_state {
388 struct cli_state *cli;
393 static void cli_session_setup_guest_done(struct tevent_req *subreq);
395 struct tevent_req *cli_session_setup_guest_create(TALLOC_CTX *mem_ctx,
396 struct event_context *ev,
397 struct cli_state *cli,
398 struct tevent_req **psmbreq)
400 struct tevent_req *req, *subreq;
401 struct cli_session_setup_guest_state *state;
405 req = tevent_req_create(mem_ctx, &state,
406 struct cli_session_setup_guest_state);
413 SCVAL(vwv+0, 0, 0xFF);
416 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
418 SSVAL(vwv+4, 0, cli->pid);
419 SIVAL(vwv+5, 0, cli->sesskey);
424 SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli));
426 bytes = talloc_array(state, uint8_t, 0);
428 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "", 1, /* username */
430 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "", 1, /* workgroup */
432 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Unix", 5, NULL);
433 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Samba", 6, NULL);
440 state->bytes.iov_base = (void *)bytes;
441 state->bytes.iov_len = talloc_get_size(bytes);
443 subreq = cli_smb_req_create(state, ev, cli, SMBsesssetupX, 0, 13, vwv,
445 if (subreq == NULL) {
449 tevent_req_set_callback(subreq, cli_session_setup_guest_done, req);
454 struct tevent_req *cli_session_setup_guest_send(TALLOC_CTX *mem_ctx,
455 struct event_context *ev,
456 struct cli_state *cli)
458 struct tevent_req *req, *subreq;
461 req = cli_session_setup_guest_create(mem_ctx, ev, cli, &subreq);
466 status = cli_smb_req_send(subreq);
467 if (NT_STATUS_IS_OK(status)) {
468 tevent_req_nterror(req, status);
469 return tevent_req_post(req, ev);
474 static void cli_session_setup_guest_done(struct tevent_req *subreq)
476 struct tevent_req *req = tevent_req_callback_data(
477 subreq, struct tevent_req);
478 struct cli_session_setup_guest_state *state = tevent_req_data(
479 req, struct cli_session_setup_guest_state);
480 struct cli_state *cli = state->cli;
489 status = cli_smb_recv(subreq, state, &in, 0, NULL, NULL,
492 if (!NT_STATUS_IS_OK(status)) {
493 tevent_req_nterror(req, status);
500 cli->vuid = SVAL(inbuf, smb_uid);
502 status = smb_bytes_talloc_string(cli,
509 if (!NT_STATUS_IS_OK(status)) {
510 tevent_req_nterror(req, status);
515 status = smb_bytes_talloc_string(cli,
522 if (!NT_STATUS_IS_OK(status)) {
523 tevent_req_nterror(req, status);
528 status = smb_bytes_talloc_string(cli,
535 if (!NT_STATUS_IS_OK(status)) {
536 tevent_req_nterror(req, status);
541 if (strstr(cli->server_type, "Samba")) {
542 cli->is_samba = True;
545 status = cli_set_username(cli, "");
546 if (!NT_STATUS_IS_OK(status)) {
547 tevent_req_nterror(req, status);
550 tevent_req_done(req);
553 NTSTATUS cli_session_setup_guest_recv(struct tevent_req *req)
555 return tevent_req_simple_recv_ntstatus(req);
558 static NTSTATUS cli_session_setup_guest(struct cli_state *cli)
560 TALLOC_CTX *frame = talloc_stackframe();
561 struct event_context *ev;
562 struct tevent_req *req;
563 NTSTATUS status = NT_STATUS_OK;
565 if (cli_has_async_calls(cli)) {
567 * Can't use sync call while an async call is in flight
569 status = NT_STATUS_INVALID_PARAMETER;
573 ev = event_context_init(frame);
575 status = NT_STATUS_NO_MEMORY;
579 req = cli_session_setup_guest_send(frame, ev, cli);
581 status = NT_STATUS_NO_MEMORY;
585 if (!tevent_req_poll(req, ev)) {
586 status = map_nt_error_from_unix(errno);
590 status = cli_session_setup_guest_recv(req);
596 /****************************************************************************
597 Do a NT1 plaintext session setup.
598 ****************************************************************************/
600 struct cli_session_setup_plain_state {
601 struct cli_state *cli;
606 static void cli_session_setup_plain_done(struct tevent_req *subreq);
608 static struct tevent_req *cli_session_setup_plain_send(
609 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
610 struct cli_state *cli,
611 const char *user, const char *pass, const char *workgroup)
613 struct tevent_req *req, *subreq;
614 struct cli_session_setup_plain_state *state;
620 req = tevent_req_create(mem_ctx, &state,
621 struct cli_session_setup_plain_state);
629 SCVAL(vwv+0, 0, 0xff);
632 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
634 SSVAL(vwv+4, 0, cli->pid);
635 SIVAL(vwv+5, 0, cli->sesskey);
640 SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli));
642 bytes = talloc_array(state, uint8_t, 0);
643 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), pass, strlen(pass)+1,
645 if (tevent_req_nomem(bytes, req)) {
646 return tevent_req_post(req, ev);
648 SSVAL(vwv + (cli_ucs2(cli) ? 8 : 7), 0, passlen);
650 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
651 user, strlen(user)+1, NULL);
652 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
653 workgroup, strlen(workgroup)+1, NULL);
654 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
657 version = talloc_asprintf(talloc_tos(), "Samba %s",
658 samba_version_string());
659 if (tevent_req_nomem(version, req)){
660 return tevent_req_post(req, ev);
662 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
663 version, strlen(version)+1, NULL);
664 TALLOC_FREE(version);
666 if (tevent_req_nomem(bytes, req)) {
667 return tevent_req_post(req, ev);
670 subreq = cli_smb_send(state, ev, cli, SMBsesssetupX, 0, 13, vwv,
671 talloc_get_size(bytes), bytes);
672 if (tevent_req_nomem(subreq, req)) {
673 return tevent_req_post(req, ev);
675 tevent_req_set_callback(subreq, cli_session_setup_plain_done, req);
679 static void cli_session_setup_plain_done(struct tevent_req *subreq)
681 struct tevent_req *req = tevent_req_callback_data(
682 subreq, struct tevent_req);
683 struct cli_session_setup_plain_state *state = tevent_req_data(
684 req, struct cli_session_setup_plain_state);
685 struct cli_state *cli = state->cli;
694 status = cli_smb_recv(subreq, state, &in, 0, NULL, NULL,
697 if (tevent_req_nterror(req, status)) {
704 cli->vuid = SVAL(inbuf, smb_uid);
706 status = smb_bytes_talloc_string(cli,
713 if (!NT_STATUS_IS_OK(status)) {
714 tevent_req_nterror(req, status);
719 status = smb_bytes_talloc_string(cli,
726 if (!NT_STATUS_IS_OK(status)) {
727 tevent_req_nterror(req, status);
732 status = smb_bytes_talloc_string(cli,
739 if (!NT_STATUS_IS_OK(status)) {
740 tevent_req_nterror(req, status);
745 status = cli_set_username(cli, state->user);
746 if (tevent_req_nterror(req, status)) {
749 if (strstr(cli->server_type, "Samba")) {
750 cli->is_samba = True;
752 tevent_req_done(req);
755 static NTSTATUS cli_session_setup_plain_recv(struct tevent_req *req)
757 return tevent_req_simple_recv_ntstatus(req);
760 static NTSTATUS cli_session_setup_plain(struct cli_state *cli,
761 const char *user, const char *pass,
762 const char *workgroup)
764 TALLOC_CTX *frame = talloc_stackframe();
765 struct event_context *ev;
766 struct tevent_req *req;
767 NTSTATUS status = NT_STATUS_NO_MEMORY;
769 if (cli_has_async_calls(cli)) {
771 * Can't use sync call while an async call is in flight
773 status = NT_STATUS_INVALID_PARAMETER;
776 ev = event_context_init(frame);
780 req = cli_session_setup_plain_send(frame, ev, cli, user, pass,
785 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
788 status = cli_session_setup_plain_recv(req);
794 /****************************************************************************
795 do a NT1 NTLM/LM encrypted session setup - for when extended security
797 @param cli client state to create do session setup on
799 @param pass *either* cleartext password (passlen !=24) or LM response.
800 @param ntpass NT response, implies ntpasslen >=24, implies pass is not clear
801 @param workgroup The user's domain.
802 ****************************************************************************/
804 struct cli_session_setup_nt1_state {
805 struct cli_state *cli;
808 DATA_BLOB session_key;
812 static void cli_session_setup_nt1_done(struct tevent_req *subreq);
814 static struct tevent_req *cli_session_setup_nt1_send(
815 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
816 struct cli_state *cli, const char *user,
817 const char *pass, size_t passlen,
818 const char *ntpass, size_t ntpasslen,
819 const char *workgroup)
821 struct tevent_req *req, *subreq;
822 struct cli_session_setup_nt1_state *state;
823 DATA_BLOB lm_response = data_blob_null;
824 DATA_BLOB nt_response = data_blob_null;
825 DATA_BLOB session_key = data_blob_null;
828 char *workgroup_upper;
830 req = tevent_req_create(mem_ctx, &state,
831 struct cli_session_setup_nt1_state);
840 /* do nothing - guest login */
841 } else if (passlen != 24) {
842 if (lp_client_ntlmv2_auth()) {
843 DATA_BLOB server_chal;
844 DATA_BLOB names_blob;
846 server_chal = data_blob(cli->secblob.data,
847 MIN(cli->secblob.length, 8));
848 if (tevent_req_nomem(server_chal.data, req)) {
849 return tevent_req_post(req, ev);
853 * note that the 'workgroup' here is a best
854 * guess - we don't know the server's domain
855 * at this point. The 'server name' is also
858 names_blob = NTLMv2_generate_names_blob(
859 NULL, cli->called.name, workgroup);
861 if (tevent_req_nomem(names_blob.data, req)) {
862 return tevent_req_post(req, ev);
865 if (!SMBNTLMv2encrypt(NULL, user, workgroup, pass,
866 &server_chal, &names_blob,
867 &lm_response, &nt_response,
868 NULL, &session_key)) {
869 data_blob_free(&names_blob);
870 data_blob_free(&server_chal);
872 req, NT_STATUS_ACCESS_DENIED);
873 return tevent_req_post(req, ev);
875 data_blob_free(&names_blob);
876 data_blob_free(&server_chal);
880 E_md4hash(pass, nt_hash);
883 nt_response = data_blob_null;
885 nt_response = data_blob(NULL, 24);
886 if (tevent_req_nomem(nt_response.data, req)) {
887 return tevent_req_post(req, ev);
890 SMBNTencrypt(pass, cli->secblob.data,
893 /* non encrypted password supplied. Ignore ntpass. */
894 if (lp_client_lanman_auth()) {
896 lm_response = data_blob(NULL, 24);
897 if (tevent_req_nomem(lm_response.data, req)) {
898 return tevent_req_post(req, ev);
901 if (!SMBencrypt(pass,cli->secblob.data,
904 * Oops, the LM response is
905 * invalid, just put the NT
906 * response there instead
908 data_blob_free(&lm_response);
909 lm_response = data_blob(
915 * LM disabled, place NT# in LM field
918 lm_response = data_blob(
919 nt_response.data, nt_response.length);
922 if (tevent_req_nomem(lm_response.data, req)) {
923 return tevent_req_post(req, ev);
926 session_key = data_blob(NULL, 16);
927 if (tevent_req_nomem(session_key.data, req)) {
928 return tevent_req_post(req, ev);
931 E_deshash(pass, session_key.data);
932 memset(&session_key.data[8], '\0', 8);
934 SMBsesskeygen_ntv1(nt_hash, session_key.data);
937 cli_temp_set_signing(cli);
939 /* pre-encrypted password supplied. Only used for
940 security=server, can't do
941 signing because we don't have original key */
943 lm_response = data_blob(pass, passlen);
944 if (tevent_req_nomem(lm_response.data, req)) {
945 return tevent_req_post(req, ev);
948 nt_response = data_blob(ntpass, ntpasslen);
949 if (tevent_req_nomem(nt_response.data, req)) {
950 return tevent_req_post(req, ev);
955 state->response = data_blob_talloc(
956 state, lm_response.data, lm_response.length);
958 state->response = data_blob_talloc(
959 state, nt_response.data, nt_response.length);
961 if (tevent_req_nomem(state->response.data, req)) {
962 return tevent_req_post(req, ev);
965 if (session_key.data) {
966 state->session_key = data_blob_talloc(
967 state, session_key.data, session_key.length);
968 if (tevent_req_nomem(state->session_key.data, req)) {
969 return tevent_req_post(req, ev);
972 data_blob_free(&session_key);
974 SCVAL(vwv+0, 0, 0xff);
977 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
979 SSVAL(vwv+4, 0, cli->pid);
980 SIVAL(vwv+5, 0, cli->sesskey);
981 SSVAL(vwv+7, 0, lm_response.length);
982 SSVAL(vwv+8, 0, nt_response.length);
985 SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli));
987 bytes = talloc_array(state, uint8_t,
988 lm_response.length + nt_response.length);
989 if (tevent_req_nomem(bytes, req)) {
990 return tevent_req_post(req, ev);
992 if (lm_response.length != 0) {
993 memcpy(bytes, lm_response.data, lm_response.length);
995 if (nt_response.length != 0) {
996 memcpy(bytes + lm_response.length,
997 nt_response.data, nt_response.length);
999 data_blob_free(&lm_response);
1000 data_blob_free(&nt_response);
1002 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
1003 user, strlen(user)+1, NULL);
1006 * Upper case here might help some NTLMv2 implementations
1008 workgroup_upper = talloc_strdup_upper(talloc_tos(), workgroup);
1009 if (tevent_req_nomem(workgroup_upper, req)) {
1010 return tevent_req_post(req, ev);
1012 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
1013 workgroup_upper, strlen(workgroup_upper)+1,
1015 TALLOC_FREE(workgroup_upper);
1017 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Unix", 5, NULL);
1018 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Samba", 6, NULL);
1019 if (tevent_req_nomem(bytes, req)) {
1020 return tevent_req_post(req, ev);
1023 subreq = cli_smb_send(state, ev, cli, SMBsesssetupX, 0, 13, vwv,
1024 talloc_get_size(bytes), bytes);
1025 if (tevent_req_nomem(subreq, req)) {
1026 return tevent_req_post(req, ev);
1028 tevent_req_set_callback(subreq, cli_session_setup_nt1_done, req);
1032 static void cli_session_setup_nt1_done(struct tevent_req *subreq)
1034 struct tevent_req *req = tevent_req_callback_data(
1035 subreq, struct tevent_req);
1036 struct cli_session_setup_nt1_state *state = tevent_req_data(
1037 req, struct cli_session_setup_nt1_state);
1038 struct cli_state *cli = state->cli;
1047 status = cli_smb_recv(subreq, state, &in, 0, NULL, NULL,
1048 &num_bytes, &bytes);
1049 TALLOC_FREE(subreq);
1050 if (!NT_STATUS_IS_OK(status)) {
1051 tevent_req_nterror(req, status);
1058 cli->vuid = SVAL(inbuf, smb_uid);
1060 status = smb_bytes_talloc_string(cli,
1066 if (!NT_STATUS_IS_OK(status)) {
1067 tevent_req_nterror(req, status);
1072 status = smb_bytes_talloc_string(cli,
1078 if (!NT_STATUS_IS_OK(status)) {
1079 tevent_req_nterror(req, status);
1084 status = smb_bytes_talloc_string(cli,
1086 &cli->server_domain,
1090 if (!NT_STATUS_IS_OK(status)) {
1091 tevent_req_nterror(req, status);
1096 if (strstr(cli->server_type, "Samba")) {
1097 cli->is_samba = True;
1100 status = cli_set_username(cli, state->user);
1101 if (tevent_req_nterror(req, status)) {
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);
1109 if (state->session_key.data) {
1110 /* Have plaintext orginal */
1111 cli_set_session_key(cli, state->session_key);
1113 tevent_req_done(req);
1116 static NTSTATUS cli_session_setup_nt1_recv(struct tevent_req *req)
1118 return tevent_req_simple_recv_ntstatus(req);
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)
1126 TALLOC_CTX *frame = talloc_stackframe();
1127 struct event_context *ev;
1128 struct tevent_req *req;
1129 NTSTATUS status = NT_STATUS_NO_MEMORY;
1131 if (cli_has_async_calls(cli)) {
1133 * Can't use sync call while an async call is in flight
1135 status = NT_STATUS_INVALID_PARAMETER;
1138 ev = event_context_init(frame);
1142 req = cli_session_setup_nt1_send(frame, ev, cli, user, pass, passlen,
1143 ntpass, ntpasslen, workgroup);
1147 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1150 status = cli_session_setup_nt1_recv(req);
1156 /* The following is calculated from :
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
1163 #define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22)
1165 struct cli_sesssetup_blob_state {
1166 struct tevent_context *ev;
1167 struct cli_state *cli;
1169 uint16_t max_blob_size;
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);
1182 static struct tevent_req *cli_sesssetup_blob_send(TALLOC_CTX *mem_ctx,
1183 struct tevent_context *ev,
1184 struct cli_state *cli,
1187 struct tevent_req *req, *subreq;
1188 struct cli_sesssetup_blob_state *state;
1190 req = tevent_req_create(mem_ctx, &state,
1191 struct cli_sesssetup_blob_state);
1199 if (cli->max_xmit < BASE_SESSSETUP_BLOB_PACKET_SIZE + 1) {
1200 DEBUG(1, ("cli_session_setup_blob: cli->max_xmit too small "
1201 "(was %u, need minimum %u)\n",
1202 (unsigned int)cli->max_xmit,
1203 BASE_SESSSETUP_BLOB_PACKET_SIZE));
1204 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1205 return tevent_req_post(req, ev);
1207 state->max_blob_size =
1208 MIN(cli->max_xmit - BASE_SESSSETUP_BLOB_PACKET_SIZE, 0xFFFF);
1210 if (!cli_sesssetup_blob_next(state, &subreq)) {
1211 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1212 return tevent_req_post(req, ev);
1214 tevent_req_set_callback(subreq, cli_sesssetup_blob_done, req);
1218 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state *state,
1219 struct tevent_req **psubreq)
1221 struct tevent_req *subreq;
1224 SCVAL(state->vwv+0, 0, 0xFF);
1225 SCVAL(state->vwv+0, 1, 0);
1226 SSVAL(state->vwv+1, 0, 0);
1227 SSVAL(state->vwv+2, 0, CLI_BUFFER_SIZE);
1228 SSVAL(state->vwv+3, 0, 2);
1229 SSVAL(state->vwv+4, 0, 1);
1230 SIVAL(state->vwv+5, 0, 0);
1232 thistime = MIN(state->blob.length, state->max_blob_size);
1233 SSVAL(state->vwv+7, 0, thistime);
1235 SSVAL(state->vwv+8, 0, 0);
1236 SSVAL(state->vwv+9, 0, 0);
1237 SIVAL(state->vwv+10, 0,
1238 cli_session_setup_capabilities(state->cli)
1239 | CAP_EXTENDED_SECURITY);
1241 state->buf = (uint8_t *)talloc_memdup(state, state->blob.data,
1243 if (state->buf == NULL) {
1246 state->blob.data += thistime;
1247 state->blob.length -= thistime;
1249 state->buf = smb_bytes_push_str(state->buf, cli_ucs2(state->cli),
1251 state->buf = smb_bytes_push_str(state->buf, cli_ucs2(state->cli),
1253 if (state->buf == NULL) {
1256 subreq = cli_smb_send(state, state->ev, state->cli, SMBsesssetupX, 0,
1258 talloc_get_size(state->buf), state->buf);
1259 if (subreq == NULL) {
1266 static void cli_sesssetup_blob_done(struct tevent_req *subreq)
1268 struct tevent_req *req = tevent_req_callback_data(
1269 subreq, struct tevent_req);
1270 struct cli_sesssetup_blob_state *state = tevent_req_data(
1271 req, struct cli_sesssetup_blob_state);
1272 struct cli_state *cli = state->cli;
1279 uint16_t blob_length;
1283 status = cli_smb_recv(subreq, state, &inbuf, 1, &wct, &vwv,
1284 &num_bytes, &bytes);
1285 TALLOC_FREE(subreq);
1286 if (!NT_STATUS_IS_OK(status)
1287 && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1288 tevent_req_nterror(req, status);
1292 state->status = status;
1293 TALLOC_FREE(state->buf);
1295 state->inbuf = (char *)inbuf;
1296 cli->vuid = SVAL(state->inbuf, smb_uid);
1298 blob_length = SVAL(vwv+3, 0);
1299 if (blob_length > num_bytes) {
1300 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1303 state->ret_blob = data_blob_const(bytes, blob_length);
1305 p = bytes + blob_length;
1307 status = smb_bytes_talloc_string(cli,
1314 if (!NT_STATUS_IS_OK(status)) {
1315 tevent_req_nterror(req, status);
1320 status = smb_bytes_talloc_string(cli,
1327 if (!NT_STATUS_IS_OK(status)) {
1328 tevent_req_nterror(req, status);
1333 status = smb_bytes_talloc_string(cli,
1335 &cli->server_domain,
1340 if (!NT_STATUS_IS_OK(status)) {
1341 tevent_req_nterror(req, status);
1346 if (strstr(cli->server_type, "Samba")) {
1347 cli->is_samba = True;
1350 if (state->blob.length != 0) {
1354 if (!cli_sesssetup_blob_next(state, &subreq)) {
1355 tevent_req_nomem(NULL, req);
1358 tevent_req_set_callback(subreq, cli_sesssetup_blob_done, req);
1361 tevent_req_done(req);
1364 static NTSTATUS cli_sesssetup_blob_recv(struct tevent_req *req,
1365 TALLOC_CTX *mem_ctx,
1369 struct cli_sesssetup_blob_state *state = tevent_req_data(
1370 req, struct cli_sesssetup_blob_state);
1374 if (tevent_req_is_nterror(req, &status)) {
1375 state->cli->vuid = 0;
1379 inbuf = talloc_move(mem_ctx, &state->inbuf);
1380 if (pblob != NULL) {
1381 *pblob = state->ret_blob;
1383 if (pinbuf != NULL) {
1386 /* could be NT_STATUS_MORE_PROCESSING_REQUIRED */
1387 return state->status;
1392 /****************************************************************************
1393 Use in-memory credentials cache
1394 ****************************************************************************/
1396 static void use_in_memory_ccache(void) {
1397 setenv(KRB5_ENV_CCNAME, "MEMORY:cliconnect", 1);
1400 /****************************************************************************
1401 Do a spnego/kerberos encrypted session setup.
1402 ****************************************************************************/
1404 struct cli_session_setup_kerberos_state {
1405 struct cli_state *cli;
1406 DATA_BLOB negTokenTarg;
1407 DATA_BLOB session_key_krb5;
1408 ADS_STATUS ads_status;
1411 static void cli_session_setup_kerberos_done(struct tevent_req *subreq);
1413 static struct tevent_req *cli_session_setup_kerberos_send(
1414 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
1415 const char *principal)
1417 struct tevent_req *req, *subreq;
1418 struct cli_session_setup_kerberos_state *state;
1421 DEBUG(2,("Doing kerberos session setup\n"));
1423 req = tevent_req_create(mem_ctx, &state,
1424 struct cli_session_setup_kerberos_state);
1429 state->ads_status = ADS_SUCCESS;
1431 cli_temp_set_signing(cli);
1434 * Ok, this is cheating: spnego_gen_krb5_negTokenInit can block if
1435 * we have to acquire a ticket. To be fixed later :-)
1437 rc = spnego_gen_krb5_negTokenInit(state, principal, 0, &state->negTokenTarg,
1438 &state->session_key_krb5, 0, NULL);
1440 DEBUG(1, ("cli_session_setup_kerberos: "
1441 "spnego_gen_krb5_negTokenInit failed: %s\n",
1442 error_message(rc)));
1443 state->ads_status = ADS_ERROR_KRB5(rc);
1444 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
1445 return tevent_req_post(req, ev);
1449 file_save("negTokenTarg.dat", state->negTokenTarg.data,
1450 state->negTokenTarg.length);
1453 subreq = cli_sesssetup_blob_send(state, ev, cli, state->negTokenTarg);
1454 if (tevent_req_nomem(subreq, req)) {
1455 return tevent_req_post(req, ev);
1457 tevent_req_set_callback(subreq, cli_session_setup_kerberos_done, req);
1461 static void cli_session_setup_kerberos_done(struct tevent_req *subreq)
1463 struct tevent_req *req = tevent_req_callback_data(
1464 subreq, struct tevent_req);
1465 struct cli_session_setup_kerberos_state *state = tevent_req_data(
1466 req, struct cli_session_setup_kerberos_state);
1470 status = cli_sesssetup_blob_recv(subreq, talloc_tos(), NULL, &inbuf);
1471 if (!NT_STATUS_IS_OK(status)) {
1472 TALLOC_FREE(subreq);
1473 tevent_req_nterror(req, status);
1477 cli_set_session_key(state->cli, state->session_key_krb5);
1479 if (cli_simple_set_signing(state->cli, state->session_key_krb5,
1481 && !cli_check_sign_mac(state->cli, inbuf, 1)) {
1482 TALLOC_FREE(subreq);
1483 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1486 TALLOC_FREE(subreq);
1487 tevent_req_done(req);
1490 static ADS_STATUS cli_session_setup_kerberos_recv(struct tevent_req *req)
1492 struct cli_session_setup_kerberos_state *state = tevent_req_data(
1493 req, struct cli_session_setup_kerberos_state);
1496 if (tevent_req_is_nterror(req, &status)) {
1497 return ADS_ERROR_NT(status);
1499 return state->ads_status;
1502 static ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli,
1503 const char *principal)
1505 struct tevent_context *ev;
1506 struct tevent_req *req;
1507 ADS_STATUS status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1509 if (cli_has_async_calls(cli)) {
1510 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1512 ev = tevent_context_init(talloc_tos());
1516 req = cli_session_setup_kerberos_send(ev, ev, cli, principal);
1520 if (!tevent_req_poll(req, ev)) {
1521 status = ADS_ERROR_SYSTEM(errno);
1524 status = cli_session_setup_kerberos_recv(req);
1529 #endif /* HAVE_KRB5 */
1531 /****************************************************************************
1532 Do a spnego/NTLMSSP encrypted session setup.
1533 ****************************************************************************/
1535 struct cli_session_setup_ntlmssp_state {
1536 struct tevent_context *ev;
1537 struct cli_state *cli;
1538 struct ntlmssp_state *ntlmssp_state;
1543 static int cli_session_setup_ntlmssp_state_destructor(
1544 struct cli_session_setup_ntlmssp_state *state)
1546 if (state->ntlmssp_state != NULL) {
1547 TALLOC_FREE(state->ntlmssp_state);
1552 static void cli_session_setup_ntlmssp_done(struct tevent_req *req);
1554 static struct tevent_req *cli_session_setup_ntlmssp_send(
1555 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
1556 const char *user, const char *pass, const char *domain)
1558 struct tevent_req *req, *subreq;
1559 struct cli_session_setup_ntlmssp_state *state;
1562 const char *OIDs_ntlm[] = {OID_NTLMSSP, NULL};
1564 req = tevent_req_create(mem_ctx, &state,
1565 struct cli_session_setup_ntlmssp_state);
1573 state->ntlmssp_state = NULL;
1574 talloc_set_destructor(
1575 state, cli_session_setup_ntlmssp_state_destructor);
1577 cli_temp_set_signing(cli);
1579 status = ntlmssp_client_start(state,
1582 lp_client_ntlmv2_auth(),
1583 &state->ntlmssp_state);
1584 if (!NT_STATUS_IS_OK(status)) {
1587 ntlmssp_want_feature(state->ntlmssp_state,
1588 NTLMSSP_FEATURE_SESSION_KEY);
1589 if (cli->use_ccache) {
1590 ntlmssp_want_feature(state->ntlmssp_state,
1591 NTLMSSP_FEATURE_CCACHE);
1593 status = ntlmssp_set_username(state->ntlmssp_state, user);
1594 if (!NT_STATUS_IS_OK(status)) {
1597 status = ntlmssp_set_domain(state->ntlmssp_state, domain);
1598 if (!NT_STATUS_IS_OK(status)) {
1601 status = ntlmssp_set_password(state->ntlmssp_state, pass);
1602 if (!NT_STATUS_IS_OK(status)) {
1605 status = ntlmssp_update(state->ntlmssp_state, data_blob_null,
1607 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1611 state->blob_out = spnego_gen_negTokenInit(state, OIDs_ntlm, &blob_out, NULL);
1612 data_blob_free(&blob_out);
1614 subreq = cli_sesssetup_blob_send(state, ev, cli, state->blob_out);
1615 if (tevent_req_nomem(subreq, req)) {
1616 return tevent_req_post(req, ev);
1618 tevent_req_set_callback(subreq, cli_session_setup_ntlmssp_done, req);
1621 tevent_req_nterror(req, status);
1622 return tevent_req_post(req, ev);
1625 static void cli_session_setup_ntlmssp_done(struct tevent_req *subreq)
1627 struct tevent_req *req = tevent_req_callback_data(
1628 subreq, struct tevent_req);
1629 struct cli_session_setup_ntlmssp_state *state = tevent_req_data(
1630 req, struct cli_session_setup_ntlmssp_state);
1631 DATA_BLOB blob_in, msg_in, blob_out;
1636 status = cli_sesssetup_blob_recv(subreq, talloc_tos(), &blob_in,
1638 TALLOC_FREE(subreq);
1639 data_blob_free(&state->blob_out);
1641 if (NT_STATUS_IS_OK(status)) {
1642 if (state->cli->server_domain[0] == '\0') {
1643 TALLOC_FREE(state->cli->server_domain);
1644 state->cli->server_domain = talloc_strdup(state->cli,
1645 state->ntlmssp_state->server.netbios_domain);
1646 if (state->cli->server_domain == NULL) {
1647 TALLOC_FREE(subreq);
1648 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1652 cli_set_session_key(
1653 state->cli, state->ntlmssp_state->session_key);
1655 if (cli_simple_set_signing(
1656 state->cli, state->ntlmssp_state->session_key,
1658 && !cli_check_sign_mac(state->cli, inbuf, 1)) {
1659 TALLOC_FREE(subreq);
1660 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1663 TALLOC_FREE(subreq);
1664 TALLOC_FREE(state->ntlmssp_state);
1665 tevent_req_done(req);
1668 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1669 tevent_req_nterror(req, status);
1673 if (blob_in.length == 0) {
1674 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
1678 if ((state->turn == 1)
1679 && NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1680 DATA_BLOB tmp_blob = data_blob_null;
1681 /* the server might give us back two challenges */
1682 parse_ret = spnego_parse_challenge(state, blob_in, &msg_in,
1684 data_blob_free(&tmp_blob);
1686 parse_ret = spnego_parse_auth_response(state, blob_in, status,
1687 OID_NTLMSSP, &msg_in);
1692 DEBUG(3,("Failed to parse auth response\n"));
1693 if (NT_STATUS_IS_OK(status)
1694 || NT_STATUS_EQUAL(status,
1695 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1697 req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1702 status = ntlmssp_update(state->ntlmssp_state, msg_in, &blob_out);
1704 if (!NT_STATUS_IS_OK(status)
1705 && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1706 TALLOC_FREE(subreq);
1707 TALLOC_FREE(state->ntlmssp_state);
1708 tevent_req_nterror(req, status);
1712 state->blob_out = spnego_gen_auth(state, blob_out);
1713 TALLOC_FREE(subreq);
1714 if (tevent_req_nomem(state->blob_out.data, req)) {
1718 subreq = cli_sesssetup_blob_send(state, state->ev, state->cli,
1720 if (tevent_req_nomem(subreq, req)) {
1723 tevent_req_set_callback(subreq, cli_session_setup_ntlmssp_done, req);
1726 static NTSTATUS cli_session_setup_ntlmssp_recv(struct tevent_req *req)
1728 struct cli_session_setup_ntlmssp_state *state = tevent_req_data(
1729 req, struct cli_session_setup_ntlmssp_state);
1732 if (tevent_req_is_nterror(req, &status)) {
1733 state->cli->vuid = 0;
1736 return NT_STATUS_OK;
1739 static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli,
1744 struct tevent_context *ev;
1745 struct tevent_req *req;
1746 NTSTATUS status = NT_STATUS_NO_MEMORY;
1748 if (cli_has_async_calls(cli)) {
1749 return NT_STATUS_INVALID_PARAMETER;
1751 ev = tevent_context_init(talloc_tos());
1755 req = cli_session_setup_ntlmssp_send(ev, ev, cli, user, pass, domain);
1759 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1762 status = cli_session_setup_ntlmssp_recv(req);
1768 /****************************************************************************
1769 Do a spnego encrypted session setup.
1771 user_domain: The shortname of the domain the user/machine is a member of.
1772 dest_realm: The realm we're connecting to, if NULL we use our default realm.
1773 ****************************************************************************/
1775 ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user,
1776 const char *pass, const char *user_domain,
1777 const char * dest_realm)
1779 char *principal = NULL;
1780 char *OIDs[ASN1_MAX_OIDS];
1783 const char *p = NULL;
1784 char *account = NULL;
1787 DEBUG(3,("Doing spnego session setup (blob length=%lu)\n", (unsigned long)cli->secblob.length));
1789 /* the server might not even do spnego */
1790 if (cli->secblob.length <= 16) {
1791 DEBUG(3,("server didn't supply a full spnego negprot\n"));
1796 file_save("negprot.dat", cli->secblob.data, cli->secblob.length);
1799 /* there is 16 bytes of GUID before the real spnego packet starts */
1800 blob = data_blob(cli->secblob.data+16, cli->secblob.length-16);
1802 /* The server sent us the first part of the SPNEGO exchange in the
1803 * negprot reply. It is WRONG to depend on the principal sent in the
1804 * negprot reply, but right now we do it. If we don't receive one,
1805 * we try to best guess, then fall back to NTLM. */
1806 if (!spnego_parse_negTokenInit(talloc_tos(), blob, OIDs, &principal, NULL) ||
1808 data_blob_free(&blob);
1809 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1811 data_blob_free(&blob);
1813 /* make sure the server understands kerberos */
1814 for (i=0;OIDs[i];i++) {
1816 DEBUG(3,("got OID=%s\n", OIDs[i]));
1818 DEBUGADD(3,("got OID=%s\n", OIDs[i]));
1819 if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0 ||
1820 strcmp(OIDs[i], OID_KERBEROS5) == 0) {
1821 cli->got_kerberos_mechanism = True;
1823 talloc_free(OIDs[i]);
1826 DEBUG(3,("got principal=%s\n", principal ? principal : "<null>"));
1828 status = cli_set_username(cli, user);
1829 if (!NT_STATUS_IS_OK(status)) {
1830 TALLOC_FREE(principal);
1831 return ADS_ERROR_NT(status);
1835 /* If password is set we reauthenticate to kerberos server
1836 * and do not store results */
1838 if (cli->got_kerberos_mechanism && cli->use_kerberos) {
1841 if (pass && *pass) {
1844 use_in_memory_ccache();
1845 ret = kerberos_kinit_password(user, pass, 0 /* no time correction for now */, NULL);
1848 TALLOC_FREE(principal);
1849 DEBUG(0, ("Kinit failed: %s\n", error_message(ret)));
1850 if (cli->fallback_after_kerberos)
1852 return ADS_ERROR_KRB5(ret);
1856 /* We may not be allowed to use the server-supplied SPNEGO principal, or it may not have been supplied to us
1858 if (!lp_client_use_spnego_principal() || strequal(principal, ADS_IGNORE_PRINCIPAL)) {
1859 TALLOC_FREE(principal);
1862 if (principal == NULL &&
1863 !is_ipaddress(cli->desthost) &&
1864 !strequal(STAR_SMBSERVER,
1868 DEBUG(3,("cli_session_setup_spnego: using target "
1869 "hostname not SPNEGO principal\n"));
1871 host = strchr_m(cli->desthost, '.');
1873 realm = SMB_STRDUP(dest_realm);
1875 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1881 realm = kerberos_get_realm_from_hostname(cli->desthost);
1883 /* NetBIOS name - use our realm. */
1884 realm = kerberos_get_default_realm_from_ccache();
1888 if (realm == NULL || *realm == '\0') {
1889 realm = SMB_STRDUP(lp_realm());
1891 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1894 DEBUG(3,("cli_session_setup_spnego: cannot "
1895 "get realm from dest_realm %s, "
1896 "desthost %s. Using default "
1897 "smb.conf realm %s\n",
1898 dest_realm ? dest_realm : "<null>",
1903 principal = talloc_asprintf(talloc_tos(),
1909 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1911 DEBUG(3,("cli_session_setup_spnego: guessed "
1912 "server principal=%s\n",
1913 principal ? principal : "<null>"));
1919 rc = cli_session_setup_kerberos(cli, principal);
1920 if (ADS_ERR_OK(rc) || !cli->fallback_after_kerberos) {
1921 TALLOC_FREE(principal);
1928 TALLOC_FREE(principal);
1932 account = talloc_strdup(talloc_tos(), user);
1934 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1937 /* when falling back to ntlmssp while authenticating with a machine
1938 * account strip off the realm - gd */
1940 if ((p = strchr_m(user, '@')) != NULL) {
1941 account[PTR_DIFF(p,user)] = '\0';
1944 return ADS_ERROR_NT(cli_session_setup_ntlmssp(cli, account, pass, user_domain));
1947 /****************************************************************************
1948 Send a session setup. The username and workgroup is in UNIX character
1949 format and must be converted to DOS codepage format before sending. If the
1950 password is in plaintext, the same should be done.
1951 ****************************************************************************/
1953 NTSTATUS cli_session_setup(struct cli_state *cli,
1955 const char *pass, int passlen,
1956 const char *ntpass, int ntpasslen,
1957 const char *workgroup)
1963 user2 = talloc_strdup(talloc_tos(), user);
1965 user2 = talloc_strdup(talloc_tos(), "");
1967 if (user2 == NULL) {
1968 return NT_STATUS_NO_MEMORY;
1975 /* allow for workgroups as part of the username */
1976 if ((p=strchr_m(user2,'\\')) || (p=strchr_m(user2,'/')) ||
1977 (p=strchr_m(user2,*lp_winbind_separator()))) {
1984 if (cli->protocol < PROTOCOL_LANMAN1) {
1985 return NT_STATUS_OK;
1988 /* now work out what sort of session setup we are going to
1989 do. I have split this into separate functions to make the
1990 flow a bit easier to understand (tridge) */
1992 /* if its an older server then we have to use the older request format */
1994 if (cli->protocol < PROTOCOL_NT1) {
1995 if (!lp_client_lanman_auth() && passlen != 24 && (*pass)) {
1996 DEBUG(1, ("Server requested LM password but 'client lanman auth = no'"
1997 " or 'client ntlmv2 auth = yes'\n"));
1998 return NT_STATUS_ACCESS_DENIED;
2001 if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0 &&
2002 !lp_client_plaintext_auth() && (*pass)) {
2003 DEBUG(1, ("Server requested LM password but 'client plaintext auth = no'"
2004 " or 'client ntlmv2 auth = yes'\n"));
2005 return NT_STATUS_ACCESS_DENIED;
2008 return cli_session_setup_lanman2(cli, user, pass, passlen,
2012 /* if no user is supplied then we have to do an anonymous connection.
2013 passwords are ignored */
2015 if (!user || !*user)
2016 return cli_session_setup_guest(cli);
2018 /* if the server is share level then send a plaintext null
2019 password at this point. The password is sent in the tree
2022 if ((cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0)
2023 return cli_session_setup_plain(cli, user, "", workgroup);
2025 /* if the server doesn't support encryption then we have to use
2026 plaintext. The second password is ignored */
2028 if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) {
2029 if (!lp_client_plaintext_auth() && (*pass)) {
2030 DEBUG(1, ("Server requested LM password but 'client plaintext auth = no'"
2031 " or 'client ntlmv2 auth = yes'\n"));
2032 return NT_STATUS_ACCESS_DENIED;
2034 return cli_session_setup_plain(cli, user, pass, workgroup);
2037 /* if the server supports extended security then use SPNEGO */
2039 if (cli->capabilities & CAP_EXTENDED_SECURITY) {
2040 ADS_STATUS status = cli_session_setup_spnego(cli, user, pass,
2042 if (!ADS_ERR_OK(status)) {
2043 DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status)));
2044 return ads_ntstatus(status);
2049 /* otherwise do a NT1 style session setup */
2050 status = cli_session_setup_nt1(cli, user, pass, passlen,
2051 ntpass, ntpasslen, workgroup);
2052 if (!NT_STATUS_IS_OK(status)) {
2053 DEBUG(3,("cli_session_setup: NT1 session setup "
2054 "failed: %s\n", nt_errstr(status)));
2059 if (strstr(cli->server_type, "Samba")) {
2060 cli->is_samba = True;
2063 return NT_STATUS_OK;
2066 /****************************************************************************
2068 *****************************************************************************/
2070 struct cli_ulogoff_state {
2071 struct cli_state *cli;
2075 static void cli_ulogoff_done(struct tevent_req *subreq);
2077 struct tevent_req *cli_ulogoff_send(TALLOC_CTX *mem_ctx,
2078 struct tevent_context *ev,
2079 struct cli_state *cli)
2081 struct tevent_req *req, *subreq;
2082 struct cli_ulogoff_state *state;
2084 req = tevent_req_create(mem_ctx, &state, struct cli_ulogoff_state);
2090 SCVAL(state->vwv+0, 0, 0xFF);
2091 SCVAL(state->vwv+1, 0, 0);
2092 SSVAL(state->vwv+2, 0, 0);
2094 subreq = cli_smb_send(state, ev, cli, SMBulogoffX, 0, 2, state->vwv,
2096 if (tevent_req_nomem(subreq, req)) {
2097 return tevent_req_post(req, ev);
2099 tevent_req_set_callback(subreq, cli_ulogoff_done, req);
2103 static void cli_ulogoff_done(struct tevent_req *subreq)
2105 struct tevent_req *req = tevent_req_callback_data(
2106 subreq, struct tevent_req);
2107 struct cli_ulogoff_state *state = tevent_req_data(
2108 req, struct cli_ulogoff_state);
2111 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
2112 if (!NT_STATUS_IS_OK(status)) {
2113 tevent_req_nterror(req, status);
2116 state->cli->vuid = -1;
2117 tevent_req_done(req);
2120 NTSTATUS cli_ulogoff_recv(struct tevent_req *req)
2122 return tevent_req_simple_recv_ntstatus(req);
2125 NTSTATUS cli_ulogoff(struct cli_state *cli)
2127 struct tevent_context *ev;
2128 struct tevent_req *req;
2129 NTSTATUS status = NT_STATUS_NO_MEMORY;
2131 if (cli_has_async_calls(cli)) {
2132 return NT_STATUS_INVALID_PARAMETER;
2134 ev = tevent_context_init(talloc_tos());
2138 req = cli_ulogoff_send(ev, ev, cli);
2142 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2145 status = cli_ulogoff_recv(req);
2151 /****************************************************************************
2153 ****************************************************************************/
2155 struct cli_tcon_andx_state {
2156 struct cli_state *cli;
2161 static void cli_tcon_andx_done(struct tevent_req *subreq);
2163 struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx,
2164 struct event_context *ev,
2165 struct cli_state *cli,
2166 const char *share, const char *dev,
2167 const char *pass, int passlen,
2168 struct tevent_req **psmbreq)
2170 struct tevent_req *req, *subreq;
2171 struct cli_tcon_andx_state *state;
2179 req = tevent_req_create(mem_ctx, &state, struct cli_tcon_andx_state);
2186 cli->share = talloc_strdup(cli, share);
2191 /* in user level security don't send a password now */
2192 if (cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {
2195 } else if (pass == NULL) {
2196 DEBUG(1, ("Server not using user level security and no "
2197 "password supplied.\n"));
2201 if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) &&
2202 *pass && passlen != 24) {
2203 if (!lp_client_lanman_auth()) {
2204 DEBUG(1, ("Server requested LANMAN password "
2205 "(share-level security) but "
2206 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2211 * Non-encrypted passwords - convert to DOS codepage before
2214 SMBencrypt(pass, cli->secblob.data, p24);
2216 pass = (const char *)p24;
2218 if((cli->sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL
2219 |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE))
2223 if (!lp_client_plaintext_auth() && (*pass)) {
2224 DEBUG(1, ("Server requested plaintext "
2226 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2231 * Non-encrypted passwords - convert to DOS codepage
2234 tmp_pass = talloc_array(talloc_tos(), char, 128);
2235 if (tmp_pass == NULL) {
2236 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2237 return tevent_req_post(req, ev);
2239 passlen = clistr_push(cli,
2242 talloc_get_size(tmp_pass),
2244 if (passlen == -1) {
2245 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2246 return tevent_req_post(req, ev);
2252 SCVAL(vwv+0, 0, 0xFF);
2255 SSVAL(vwv+2, 0, TCONX_FLAG_EXTENDED_RESPONSE);
2256 SSVAL(vwv+3, 0, passlen);
2258 if (passlen && pass) {
2259 bytes = (uint8_t *)talloc_memdup(state, pass, passlen);
2261 bytes = talloc_array(state, uint8_t, 0);
2267 tmp = talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
2268 cli->desthost, share);
2273 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), tmp, strlen(tmp)+1,
2278 * Add the devicetype
2280 tmp = talloc_strdup_upper(talloc_tos(), dev);
2285 bytes = smb_bytes_push_str(bytes, false, tmp, strlen(tmp)+1, NULL);
2288 if (bytes == NULL) {
2293 state->bytes.iov_base = (void *)bytes;
2294 state->bytes.iov_len = talloc_get_size(bytes);
2296 subreq = cli_smb_req_create(state, ev, cli, SMBtconX, 0, 4, vwv,
2298 if (subreq == NULL) {
2302 tevent_req_set_callback(subreq, cli_tcon_andx_done, req);
2307 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
2308 return tevent_req_post(req, ev);
2311 struct tevent_req *cli_tcon_andx_send(TALLOC_CTX *mem_ctx,
2312 struct event_context *ev,
2313 struct cli_state *cli,
2314 const char *share, const char *dev,
2315 const char *pass, int passlen)
2317 struct tevent_req *req, *subreq;
2320 req = cli_tcon_andx_create(mem_ctx, ev, cli, share, dev, pass, passlen,
2325 if (subreq == NULL) {
2328 status = cli_smb_req_send(subreq);
2329 if (!NT_STATUS_IS_OK(status)) {
2330 tevent_req_nterror(req, status);
2331 return tevent_req_post(req, ev);
2336 static void cli_tcon_andx_done(struct tevent_req *subreq)
2338 struct tevent_req *req = tevent_req_callback_data(
2339 subreq, struct tevent_req);
2340 struct cli_tcon_andx_state *state = tevent_req_data(
2341 req, struct cli_tcon_andx_state);
2342 struct cli_state *cli = state->cli;
2351 status = cli_smb_recv(subreq, state, &in, 0, &wct, &vwv,
2352 &num_bytes, &bytes);
2353 TALLOC_FREE(subreq);
2354 if (!NT_STATUS_IS_OK(status)) {
2355 tevent_req_nterror(req, status);
2362 if (clistr_pull_talloc(cli,
2364 SVAL(inbuf, smb_flg2),
2368 STR_TERMINATE|STR_ASCII) == -1) {
2369 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2373 cli->dev = talloc_strdup(cli, "");
2374 if (cli->dev == NULL) {
2375 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2380 if ((cli->protocol >= PROTOCOL_NT1) && (num_bytes == 3)) {
2381 /* almost certainly win95 - enable bug fixes */
2386 * Make sure that we have the optional support 16-bit field. WCT > 2.
2387 * Avoids issues when connecting to Win9x boxes sharing files
2390 cli->dfsroot = false;
2392 if ((wct > 2) && (cli->protocol >= PROTOCOL_LANMAN2)) {
2393 cli->dfsroot = ((SVAL(vwv+2, 0) & SMB_SHARE_IN_DFS) != 0);
2396 cli->cnum = SVAL(inbuf,smb_tid);
2397 tevent_req_done(req);
2400 NTSTATUS cli_tcon_andx_recv(struct tevent_req *req)
2402 return tevent_req_simple_recv_ntstatus(req);
2405 NTSTATUS cli_tcon_andx(struct cli_state *cli, const char *share,
2406 const char *dev, const char *pass, int passlen)
2408 TALLOC_CTX *frame = talloc_stackframe();
2409 struct event_context *ev;
2410 struct tevent_req *req;
2411 NTSTATUS status = NT_STATUS_OK;
2413 if (cli_has_async_calls(cli)) {
2415 * Can't use sync call while an async call is in flight
2417 status = NT_STATUS_INVALID_PARAMETER;
2421 ev = event_context_init(frame);
2423 status = NT_STATUS_NO_MEMORY;
2427 req = cli_tcon_andx_send(frame, ev, cli, share, dev, pass, passlen);
2429 status = NT_STATUS_NO_MEMORY;
2433 if (!tevent_req_poll(req, ev)) {
2434 status = map_nt_error_from_unix(errno);
2438 status = cli_tcon_andx_recv(req);
2444 /****************************************************************************
2445 Send a tree disconnect.
2446 ****************************************************************************/
2448 struct cli_tdis_state {
2449 struct cli_state *cli;
2452 static void cli_tdis_done(struct tevent_req *subreq);
2454 struct tevent_req *cli_tdis_send(TALLOC_CTX *mem_ctx,
2455 struct tevent_context *ev,
2456 struct cli_state *cli)
2458 struct tevent_req *req, *subreq;
2459 struct cli_tdis_state *state;
2461 req = tevent_req_create(mem_ctx, &state, struct cli_tdis_state);
2467 subreq = cli_smb_send(state, ev, cli, SMBtdis, 0, 0, NULL, 0, NULL);
2468 if (tevent_req_nomem(subreq, req)) {
2469 return tevent_req_post(req, ev);
2471 tevent_req_set_callback(subreq, cli_tdis_done, req);
2475 static void cli_tdis_done(struct tevent_req *subreq)
2477 struct tevent_req *req = tevent_req_callback_data(
2478 subreq, struct tevent_req);
2479 struct cli_tdis_state *state = tevent_req_data(
2480 req, struct cli_tdis_state);
2483 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
2484 TALLOC_FREE(subreq);
2485 if (!NT_STATUS_IS_OK(status)) {
2486 tevent_req_nterror(req, status);
2489 state->cli->cnum = -1;
2490 tevent_req_done(req);
2493 NTSTATUS cli_tdis_recv(struct tevent_req *req)
2495 return tevent_req_simple_recv_ntstatus(req);
2498 NTSTATUS cli_tdis(struct cli_state *cli)
2500 struct tevent_context *ev;
2501 struct tevent_req *req;
2502 NTSTATUS status = NT_STATUS_NO_MEMORY;
2504 if (cli_has_async_calls(cli)) {
2505 return NT_STATUS_INVALID_PARAMETER;
2507 ev = tevent_context_init(talloc_tos());
2511 req = cli_tdis_send(ev, ev, cli);
2515 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2518 status = cli_tdis_recv(req);
2524 /****************************************************************************
2525 Send a negprot command.
2526 ****************************************************************************/
2528 struct cli_negprot_state {
2529 struct cli_state *cli;
2532 static void cli_negprot_done(struct tevent_req *subreq);
2534 struct tevent_req *cli_negprot_send(TALLOC_CTX *mem_ctx,
2535 struct event_context *ev,
2536 struct cli_state *cli)
2538 struct tevent_req *req, *subreq;
2539 struct cli_negprot_state *state;
2540 uint8_t *bytes = NULL;
2544 req = tevent_req_create(mem_ctx, &state, struct cli_negprot_state);
2550 if (cli->protocol < PROTOCOL_NT1)
2551 cli->use_spnego = False;
2553 /* setup the protocol strings */
2554 for (numprots=0; numprots < ARRAY_SIZE(prots); numprots++) {
2556 if (prots[numprots].prot > cli->protocol) {
2559 bytes = (uint8_t *)talloc_append_blob(
2560 state, bytes, data_blob_const(&c, sizeof(c)));
2561 if (tevent_req_nomem(bytes, req)) {
2562 return tevent_req_post(req, ev);
2564 bytes = smb_bytes_push_str(bytes, false,
2565 prots[numprots].name,
2566 strlen(prots[numprots].name)+1,
2568 if (tevent_req_nomem(bytes, req)) {
2569 return tevent_req_post(req, ev);
2576 subreq = cli_smb_send(state, ev, cli, SMBnegprot, 0, 0, NULL,
2577 talloc_get_size(bytes), bytes);
2580 if (tevent_req_nomem(subreq, req)) {
2581 return tevent_req_post(req, ev);
2583 tevent_req_set_callback(subreq, cli_negprot_done, req);
2587 static void cli_negprot_done(struct tevent_req *subreq)
2589 struct tevent_req *req = tevent_req_callback_data(
2590 subreq, struct tevent_req);
2591 struct cli_negprot_state *state = tevent_req_data(
2592 req, struct cli_negprot_state);
2593 struct cli_state *cli = state->cli;
2602 status = cli_smb_recv(subreq, state, &inbuf, 1, &wct, &vwv,
2603 &num_bytes, &bytes);
2604 TALLOC_FREE(subreq);
2605 if (!NT_STATUS_IS_OK(status)) {
2606 tevent_req_nterror(req, status);
2610 protnum = SVAL(vwv, 0);
2612 if ((protnum >= ARRAY_SIZE(prots))
2613 || (prots[protnum].prot > cli->protocol)) {
2614 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2618 cli->protocol = prots[protnum].prot;
2620 if ((cli->protocol < PROTOCOL_NT1) &&
2621 client_is_signing_mandatory(cli)) {
2622 DEBUG(0,("cli_negprot: SMB signing is mandatory and the selected protocol level doesn't support it.\n"));
2623 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
2627 if (cli->protocol >= PROTOCOL_NT1) {
2629 bool negotiated_smb_signing = false;
2632 cli->sec_mode = CVAL(vwv + 1, 0);
2633 cli->max_mux = SVAL(vwv + 1, 1);
2634 cli->max_xmit = IVAL(vwv + 3, 1);
2635 cli->sesskey = IVAL(vwv + 7, 1);
2636 cli->serverzone = SVALS(vwv + 15, 1);
2637 cli->serverzone *= 60;
2638 /* this time arrives in real GMT */
2639 ts = interpret_long_date(((char *)(vwv+11))+1);
2640 cli->servertime = ts.tv_sec;
2641 cli->secblob = data_blob(bytes, num_bytes);
2642 cli->capabilities = IVAL(vwv + 9, 1);
2643 if (cli->capabilities & CAP_RAW_MODE) {
2644 cli->readbraw_supported = True;
2645 cli->writebraw_supported = True;
2647 /* work out if they sent us a workgroup */
2648 if (!(cli->capabilities & CAP_EXTENDED_SECURITY) &&
2649 smb_buflen(inbuf) > 8) {
2651 status = smb_bytes_talloc_string(
2652 cli, (char *)inbuf, &cli->server_domain,
2653 bytes + 8, num_bytes - 8, &ret);
2654 if (tevent_req_nterror(req, status)) {
2660 * As signing is slow we only turn it on if either the client or
2661 * the server require it. JRA.
2664 if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) {
2665 /* Fail if server says signing is mandatory and we don't want to support it. */
2666 if (!client_is_signing_allowed(cli)) {
2667 DEBUG(0,("cli_negprot: SMB signing is mandatory and we have disabled it.\n"));
2668 tevent_req_nterror(req,
2669 NT_STATUS_ACCESS_DENIED);
2672 negotiated_smb_signing = true;
2673 } else if (client_is_signing_mandatory(cli) && client_is_signing_allowed(cli)) {
2674 /* Fail if client says signing is mandatory and the server doesn't support it. */
2675 if (!(cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) {
2676 DEBUG(1,("cli_negprot: SMB signing is mandatory and the server doesn't support it.\n"));
2677 tevent_req_nterror(req,
2678 NT_STATUS_ACCESS_DENIED);
2681 negotiated_smb_signing = true;
2682 } else if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) {
2683 negotiated_smb_signing = true;
2686 if (negotiated_smb_signing) {
2687 cli_set_signing_negotiated(cli);
2690 if (cli->capabilities & (CAP_LARGE_READX|CAP_LARGE_WRITEX)) {
2691 SAFE_FREE(cli->outbuf);
2692 SAFE_FREE(cli->inbuf);
2693 cli->outbuf = (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE+LARGE_WRITEX_HDR_SIZE+SAFETY_MARGIN);
2694 cli->inbuf = (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE+LARGE_WRITEX_HDR_SIZE+SAFETY_MARGIN);
2695 if (!cli->outbuf || !cli->inbuf) {
2696 tevent_req_nterror(req,
2697 NT_STATUS_NO_MEMORY);
2700 cli->bufsize = CLI_SAMBA_MAX_LARGE_READX_SIZE + LARGE_WRITEX_HDR_SIZE;
2703 } else if (cli->protocol >= PROTOCOL_LANMAN1) {
2704 cli->use_spnego = False;
2705 cli->sec_mode = SVAL(vwv + 1, 0);
2706 cli->max_xmit = SVAL(vwv + 2, 0);
2707 cli->max_mux = SVAL(vwv + 3, 0);
2708 cli->sesskey = IVAL(vwv + 6, 0);
2709 cli->serverzone = SVALS(vwv + 10, 0);
2710 cli->serverzone *= 60;
2711 /* this time is converted to GMT by make_unix_date */
2712 cli->servertime = make_unix_date(
2713 (char *)(vwv + 8), cli->serverzone);
2714 cli->readbraw_supported = ((SVAL(vwv + 5, 0) & 0x1) != 0);
2715 cli->writebraw_supported = ((SVAL(vwv + 5, 0) & 0x2) != 0);
2716 cli->secblob = data_blob(bytes, num_bytes);
2718 /* the old core protocol */
2719 cli->use_spnego = False;
2721 cli->serverzone = get_time_zone(time(NULL));
2724 cli->max_xmit = MIN(cli->max_xmit, CLI_BUFFER_SIZE);
2726 /* a way to force ascii SMB */
2727 if (getenv("CLI_FORCE_ASCII"))
2728 cli->capabilities &= ~CAP_UNICODE;
2730 tevent_req_done(req);
2733 NTSTATUS cli_negprot_recv(struct tevent_req *req)
2735 return tevent_req_simple_recv_ntstatus(req);
2738 NTSTATUS cli_negprot(struct cli_state *cli)
2740 TALLOC_CTX *frame = talloc_stackframe();
2741 struct event_context *ev;
2742 struct tevent_req *req;
2743 NTSTATUS status = NT_STATUS_OK;
2745 if (cli_has_async_calls(cli)) {
2747 * Can't use sync call while an async call is in flight
2749 status = NT_STATUS_INVALID_PARAMETER;
2753 ev = event_context_init(frame);
2755 status = NT_STATUS_NO_MEMORY;
2759 req = cli_negprot_send(frame, ev, cli);
2761 status = NT_STATUS_NO_MEMORY;
2765 if (!tevent_req_poll(req, ev)) {
2766 status = map_nt_error_from_unix(errno);
2770 status = cli_negprot_recv(req);
2776 /****************************************************************************
2777 Send a session request. See rfc1002.txt 4.3 and 4.3.2.
2778 ****************************************************************************/
2780 bool cli_session_request(struct cli_state *cli,
2781 struct nmb_name *calling, struct nmb_name *called)
2785 struct iovec iov[3];
2791 /* 445 doesn't have session request */
2792 if (cli->port == 445)
2795 memcpy(&(cli->calling), calling, sizeof(*calling));
2796 memcpy(&(cli->called ), called , sizeof(*called ));
2798 /* put in the destination name */
2800 frame = talloc_stackframe();
2802 iov[0].iov_base = len_buf;
2803 iov[0].iov_len = sizeof(len_buf);
2805 /* put in the destination name */
2807 iov[1].iov_base = name_mangle(talloc_tos(), called->name,
2809 if (iov[1].iov_base == NULL) {
2812 iov[1].iov_len = name_len((unsigned char *)iov[1].iov_base,
2813 talloc_get_size(iov[1].iov_base));
2817 iov[2].iov_base = name_mangle(talloc_tos(), calling->name,
2818 calling->name_type);
2819 if (iov[2].iov_base == NULL) {
2822 iov[2].iov_len = name_len((unsigned char *)iov[2].iov_base,
2823 talloc_get_size(iov[2].iov_base));
2825 /* send a session request (RFC 1002) */
2826 /* setup the packet length
2827 * Remove four bytes from the length count, since the length
2828 * field in the NBT Session Service header counts the number
2829 * of bytes which follow. The cli_send_smb() function knows
2830 * about this and accounts for those four bytes.
2834 _smb_setlen(len_buf, iov[1].iov_len + iov[2].iov_len);
2835 SCVAL(len_buf,0,0x81);
2837 len = write_data_iov(cli->fd, iov, 3);
2841 len = read_smb(cli->fd, talloc_tos(), &inbuf, &err);
2847 if (CVAL(inbuf,0) == 0x84) {
2848 /* C. Hoch 9/14/95 Start */
2849 /* For information, here is the response structure.
2850 * We do the byte-twiddling to for portability.
2851 struct RetargetResponse{
2853 unsigned char flags;
2859 uint16_t port = (CVAL(inbuf,8)<<8)+CVAL(inbuf,9);
2860 struct in_addr dest_ip;
2863 /* SESSION RETARGET */
2864 putip((char *)&dest_ip,inbuf+4);
2865 in_addr_to_sockaddr_storage(&cli->dest_ss, dest_ip);
2867 status = open_socket_out(&cli->dest_ss, port,
2868 LONG_CONNECT_TIMEOUT, &cli->fd);
2869 if (!NT_STATUS_IS_OK(status)) {
2873 DEBUG(3,("Retargeted\n"));
2875 set_socket_options(cli->fd, lp_socket_options());
2881 DEBUG(0,("Retarget recursion - failing\n"));
2885 ret = cli_session_request(cli, calling, called);
2889 } /* C. Hoch 9/14/95 End */
2891 if (CVAL(inbuf,0) != 0x82) {
2892 /* This is the wrong place to put the error... JRA. */
2893 cli->rap_error = CVAL(inbuf,4);
2909 static void smb_sock_connected(struct tevent_req *req)
2911 struct fd_struct *pfd = tevent_req_callback_data(
2912 req, struct fd_struct);
2916 status = open_socket_out_defer_recv(req, &fd);
2917 if (NT_STATUS_IS_OK(status)) {
2922 static NTSTATUS open_smb_socket(const struct sockaddr_storage *pss,
2923 uint16_t *port, int timeout, int *pfd)
2925 struct event_context *ev;
2926 struct tevent_req *r139, *r445;
2927 struct fd_struct *fd139, *fd445;
2928 NTSTATUS status = NT_STATUS_NO_MEMORY;
2931 return open_socket_out(pss, *port, timeout, pfd);
2934 ev = event_context_init(talloc_tos());
2936 return NT_STATUS_NO_MEMORY;
2939 fd139 = talloc(ev, struct fd_struct);
2940 if (fd139 == NULL) {
2945 fd445 = talloc(ev, struct fd_struct);
2946 if (fd445 == NULL) {
2951 r445 = open_socket_out_defer_send(ev, ev, timeval_set(0, 0),
2953 r139 = open_socket_out_defer_send(ev, ev, timeval_set(0, 3000),
2955 if ((r445 == NULL) || (r139 == NULL)) {
2958 tevent_req_set_callback(r445, smb_sock_connected, fd445);
2959 tevent_req_set_callback(r139, smb_sock_connected, fd139);
2961 while ((fd445->fd == -1) && (fd139->fd == -1)
2962 && (tevent_req_is_in_progress(r139)
2963 || tevent_req_is_in_progress(r445))) {
2964 event_loop_once(ev);
2967 if ((fd139->fd != -1) && (fd445->fd != -1)) {
2972 if (fd445->fd != -1) {
2975 status = NT_STATUS_OK;
2978 if (fd139->fd != -1) {
2981 status = NT_STATUS_OK;
2985 status = open_socket_out_defer_recv(r445, &fd445->fd);
2991 /****************************************************************************
2992 Open the client sockets.
2993 ****************************************************************************/
2995 NTSTATUS cli_connect(struct cli_state *cli,
2997 struct sockaddr_storage *dest_ss)
3000 int name_type = 0x20;
3001 TALLOC_CTX *frame = talloc_stackframe();
3002 unsigned int num_addrs = 0;
3004 struct sockaddr_storage *ss_arr = NULL;
3007 /* reasonable default hostname */
3009 host = STAR_SMBSERVER;
3012 cli->desthost = talloc_strdup(cli, host);
3013 if (cli->desthost == NULL) {
3014 return NT_STATUS_NO_MEMORY;
3017 /* allow hostnames of the form NAME#xx and do a netbios lookup */
3018 if ((p = strchr(cli->desthost, '#'))) {
3019 name_type = strtol(p+1, NULL, 16);
3023 if (!dest_ss || is_zero_addr(dest_ss)) {
3024 NTSTATUS status =resolve_name_list(frame,
3029 if (!NT_STATUS_IS_OK(status)) {
3031 return NT_STATUS_BAD_NETWORK_NAME;
3035 ss_arr = TALLOC_P(frame, struct sockaddr_storage);
3038 return NT_STATUS_NO_MEMORY;
3043 for (i = 0; i < num_addrs; i++) {
3044 cli->dest_ss = ss_arr[i];
3045 if (getenv("LIBSMB_PROG")) {
3046 cli->fd = sock_exec(getenv("LIBSMB_PROG"));
3048 uint16_t port = cli->port;
3050 status = open_smb_socket(&cli->dest_ss, &port,
3051 cli->timeout, &cli->fd);
3052 if (NT_STATUS_IS_OK(status)) {
3056 if (cli->fd == -1) {
3057 char addr[INET6_ADDRSTRLEN];
3058 print_sockaddr(addr, sizeof(addr), &ss_arr[i]);
3059 DEBUG(2,("Error connecting to %s (%s)\n",
3060 dest_ss?addr:host,strerror(errno)));
3062 /* Exit from loop on first connection. */
3067 if (cli->fd == -1) {
3069 return map_nt_error_from_unix(errno);
3073 *dest_ss = cli->dest_ss;
3076 set_socket_options(cli->fd, lp_socket_options());
3079 return NT_STATUS_OK;
3082 static NTSTATUS cli_connect_sock(const char *host, int name_type,
3083 const struct sockaddr_storage *pss,
3084 const char *myname, uint16_t port,
3085 int sec_timeout, int *pfd, uint16_t *pport)
3087 TALLOC_CTX *frame = talloc_stackframe();
3089 unsigned int i, num_addrs;
3090 const char **called_names;
3091 const char **calling_names;
3096 prog = getenv("LIBSMB_PROG");
3098 fd = sock_exec(prog);
3100 return map_nt_error_from_unix(errno);
3106 if ((pss == NULL) || is_zero_addr(pss)) {
3107 struct sockaddr_storage *addrs;
3108 status = resolve_name_list(talloc_tos(), host, name_type,
3109 &addrs, &num_addrs);
3110 if (!NT_STATUS_IS_OK(status)) {
3118 called_names = talloc_array(talloc_tos(), const char *, num_addrs);
3119 if (called_names == NULL) {
3120 status = NT_STATUS_NO_MEMORY;
3123 called_types = talloc_array(talloc_tos(), int, num_addrs);
3124 if (called_types == NULL) {
3125 status = NT_STATUS_NO_MEMORY;
3128 calling_names = talloc_array(talloc_tos(), const char *, num_addrs);
3129 if (calling_names == NULL) {
3130 status = NT_STATUS_NO_MEMORY;
3133 for (i=0; i<num_addrs; i++) {
3134 called_names[i] = host;
3135 called_types[i] = name_type;
3136 calling_names[i] = myname;
3138 status = smbsock_any_connect(pss, called_names, called_types,
3139 calling_names, NULL, num_addrs, port,
3140 sec_timeout, &fd, NULL, &port);
3141 if (!NT_STATUS_IS_OK(status)) {
3147 status = NT_STATUS_OK;
3153 NTSTATUS cli_connect_nb(const char *host, struct sockaddr_storage *pss,
3154 uint16_t port, const char *myname,
3155 int signing_state, struct cli_state **pcli)
3157 TALLOC_CTX *frame = talloc_stackframe();
3158 struct cli_state *cli;
3159 NTSTATUS status = NT_STATUS_NO_MEMORY;
3160 int name_type = 0x20;
3167 desthost = talloc_strdup(talloc_tos(), host);
3168 if (desthost == NULL) {
3172 p = strchr(host, '#');
3174 name_type = strtol(p+1, NULL, 16);
3175 host = talloc_strndup(talloc_tos(), host, p - host);
3181 cli = cli_initialise_ex(signing_state);
3185 cli->desthost = talloc_move(cli, &desthost);
3187 status = cli_connect_sock(host, name_type, pss, myname, port, 20, &fd,
3189 if (!NT_STATUS_IS_OK(status)) {
3196 length = sizeof(cli->dest_ss);
3197 ret = getpeername(fd, (struct sockaddr *)&cli->dest_ss, &length);
3199 status = map_nt_error_from_unix(errno);
3205 *pss = cli->dest_ss;
3209 status = NT_STATUS_OK;
3216 establishes a connection to after the negprot.
3217 @param output_cli A fully initialised cli structure, non-null only on success
3218 @param dest_host The netbios name of the remote host
3219 @param dest_ss (optional) The the destination IP, NULL for name based lookup
3220 @param port (optional) The destination port (0 for default)
3222 NTSTATUS cli_start_connection(struct cli_state **output_cli,
3223 const char *my_name,
3224 const char *dest_host,
3225 struct sockaddr_storage *dest_ss, int port,
3226 int signing_state, int flags)
3229 struct nmb_name calling;
3230 struct nmb_name called;
3231 struct cli_state *cli;
3232 struct sockaddr_storage ss;
3235 my_name = global_myname();
3237 if (!(cli = cli_initialise_ex(signing_state))) {
3238 return NT_STATUS_NO_MEMORY;
3241 make_nmb_name(&calling, my_name, 0x0);
3242 make_nmb_name(&called , dest_host, 0x20);
3244 cli_set_port(cli, port);
3245 cli_set_timeout(cli, 10000); /* 10 seconds. */
3255 DEBUG(3,("Connecting to host=%s\n", dest_host));
3257 nt_status = cli_connect(cli, dest_host, &ss);
3258 if (!NT_STATUS_IS_OK(nt_status)) {
3259 char addr[INET6_ADDRSTRLEN];
3260 print_sockaddr(addr, sizeof(addr), &ss);
3261 DEBUG(1,("cli_start_connection: failed to connect to %s (%s). Error %s\n",
3262 nmb_namestr(&called), addr, nt_errstr(nt_status) ));
3267 if (!cli_session_request(cli, &calling, &called)) {
3269 DEBUG(1,("session request to %s failed (%s)\n",
3270 called.name, cli_errstr(cli)));
3271 if ((p=strchr(called.name, '.')) && !is_ipaddress(called.name)) {
3275 if (strcmp(called.name, STAR_SMBSERVER)) {
3276 make_nmb_name(&called , STAR_SMBSERVER, 0x20);
3279 return NT_STATUS_BAD_NETWORK_NAME;
3282 if (flags & CLI_FULL_CONNECTION_DONT_SPNEGO)
3283 cli->use_spnego = False;
3284 else if (flags & CLI_FULL_CONNECTION_USE_KERBEROS)
3285 cli->use_kerberos = True;
3287 if ((flags & CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS) &&
3288 cli->use_kerberos) {
3289 cli->fallback_after_kerberos = true;
3291 if (flags & CLI_FULL_CONNECTION_USE_CCACHE) {
3292 cli->use_ccache = true;
3295 nt_status = cli_negprot(cli);
3296 if (!NT_STATUS_IS_OK(nt_status)) {
3297 DEBUG(1, ("failed negprot: %s\n", nt_errstr(nt_status)));
3303 return NT_STATUS_OK;
3308 establishes a connection right up to doing tconX, password specified.
3309 @param output_cli A fully initialised cli structure, non-null only on success
3310 @param dest_host The netbios name of the remote host
3311 @param dest_ip (optional) The the destination IP, NULL for name based lookup
3312 @param port (optional) The destination port (0 for default)
3313 @param service (optional) The share to make the connection to. Should be 'unqualified' in any way.
3314 @param service_type The 'type' of serivice.
3315 @param user Username, unix string
3316 @param domain User's domain
3317 @param password User's password, unencrypted unix string.
3320 NTSTATUS cli_full_connection(struct cli_state **output_cli,
3321 const char *my_name,
3322 const char *dest_host,
3323 struct sockaddr_storage *dest_ss, int port,
3324 const char *service, const char *service_type,
3325 const char *user, const char *domain,
3326 const char *password, int flags,
3330 struct cli_state *cli = NULL;
3331 int pw_len = password ? strlen(password)+1 : 0;
3335 if (password == NULL) {
3339 nt_status = cli_start_connection(&cli, my_name, dest_host,
3340 dest_ss, port, signing_state,
3343 if (!NT_STATUS_IS_OK(nt_status)) {
3347 cli->use_oplocks = ((flags & CLI_FULL_CONNECTION_OPLOCKS) != 0);
3348 cli->use_level_II_oplocks =
3349 ((flags & CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS) != 0);
3351 nt_status = cli_session_setup(cli, user, password, pw_len, password,
3353 if (!NT_STATUS_IS_OK(nt_status)) {
3355 if (!(flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)) {
3356 DEBUG(1,("failed session setup with %s\n",
3357 nt_errstr(nt_status)));
3362 nt_status = cli_session_setup(cli, "", "", 0, "", 0, domain);
3363 if (!NT_STATUS_IS_OK(nt_status)) {
3364 DEBUG(1,("anonymous failed session setup with %s\n",
3365 nt_errstr(nt_status)));
3372 nt_status = cli_tcon_andx(cli, service, service_type, password,
3374 if (!NT_STATUS_IS_OK(nt_status)) {
3375 DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status)));
3377 if (NT_STATUS_IS_OK(nt_status)) {
3378 nt_status = NT_STATUS_UNSUCCESSFUL;
3384 nt_status = cli_init_creds(cli, user, domain, password);
3385 if (!NT_STATUS_IS_OK(nt_status)) {
3391 return NT_STATUS_OK;
3394 /****************************************************************************
3395 Attempt a NetBIOS session request, falling back to *SMBSERVER if needed.
3396 ****************************************************************************/
3398 bool attempt_netbios_session_request(struct cli_state **ppcli, const char *srchost, const char *desthost,
3399 struct sockaddr_storage *pdest_ss)
3401 struct nmb_name calling, called;
3403 make_nmb_name(&calling, srchost, 0x0);
3406 * If the called name is an IP address
3407 * then use *SMBSERVER immediately.
3410 if(is_ipaddress(desthost)) {
3411 make_nmb_name(&called, STAR_SMBSERVER, 0x20);
3413 make_nmb_name(&called, desthost, 0x20);
3416 if (!cli_session_request(*ppcli, &calling, &called)) {
3418 struct nmb_name smbservername;
3420 make_nmb_name(&smbservername, STAR_SMBSERVER, 0x20);
3423 * If the name wasn't *SMBSERVER then
3424 * try with *SMBSERVER if the first name fails.
3427 if (nmb_name_equal(&called, &smbservername)) {
3430 * The name used was *SMBSERVER, don't bother with another name.
3433 DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER \
3434 with error %s.\n", desthost, cli_errstr(*ppcli) ));
3439 cli_shutdown(*ppcli);
3441 *ppcli = cli_initialise();
3443 /* Out of memory... */
3447 status = cli_connect(*ppcli, desthost, pdest_ss);
3448 if (!NT_STATUS_IS_OK(status) ||
3449 !cli_session_request(*ppcli, &calling, &smbservername)) {
3450 DEBUG(0,("attempt_netbios_session_request: %s rejected the session for \
3451 name *SMBSERVER with error %s\n", desthost, cli_errstr(*ppcli) ));
3459 /****************************************************************************
3460 Send an old style tcon.
3461 ****************************************************************************/
3462 NTSTATUS cli_raw_tcon(struct cli_state *cli,
3463 const char *service, const char *pass, const char *dev,
3464 uint16 *max_xmit, uint16 *tid)
3466 struct tevent_req *req;
3471 if (!lp_client_plaintext_auth() && (*pass)) {
3472 DEBUG(1, ("Server requested plaintext password but 'client "
3473 "plaintext auth' is disabled\n"));
3474 return NT_STATUS_ACCESS_DENIED;
3477 bytes = talloc_array(talloc_tos(), uint8_t, 0);
3478 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3479 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
3480 service, strlen(service)+1, NULL);
3481 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3482 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
3483 pass, strlen(pass)+1, NULL);
3484 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3485 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
3486 dev, strlen(dev)+1, NULL);
3488 status = cli_smb(talloc_tos(), cli, SMBtcon, 0, 0, NULL,
3489 talloc_get_size(bytes), bytes, &req,
3490 2, NULL, &ret_vwv, NULL, NULL);
3491 if (!NT_STATUS_IS_OK(status)) {
3495 *max_xmit = SVAL(ret_vwv + 0, 0);
3496 *tid = SVAL(ret_vwv + 1, 0);
3498 return NT_STATUS_OK;
3501 /* Return a cli_state pointing at the IPC$ share for the given server */
3503 struct cli_state *get_ipc_connect(char *server,
3504 struct sockaddr_storage *server_ss,
3505 const struct user_auth_info *user_info)
3507 struct cli_state *cli;
3509 uint32_t flags = CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
3511 if (user_info->use_kerberos) {
3512 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
3515 nt_status = cli_full_connection(&cli, NULL, server, server_ss, 0, "IPC$", "IPC",
3516 user_info->username ? user_info->username : "",
3518 user_info->password ? user_info->password : "",
3522 if (NT_STATUS_IS_OK(nt_status)) {
3524 } else if (is_ipaddress(server)) {
3525 /* windows 9* needs a correct NMB name for connections */
3526 fstring remote_name;
3528 if (name_status_find("*", 0, 0, server_ss, remote_name)) {
3529 cli = get_ipc_connect(remote_name, server_ss, user_info);
3538 * Given the IP address of a master browser on the network, return its
3539 * workgroup and connect to it.
3541 * This function is provided to allow additional processing beyond what
3542 * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
3543 * browsers and obtain each master browsers' list of domains (in case the
3544 * first master browser is recently on the network and has not yet
3545 * synchronized with other master browsers and therefore does not yet have the
3546 * entire network browse list)
3549 struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx,
3550 struct sockaddr_storage *mb_ip,
3551 const struct user_auth_info *user_info,
3552 char **pp_workgroup_out)
3554 char addr[INET6_ADDRSTRLEN];
3556 struct cli_state *cli;
3557 struct sockaddr_storage server_ss;
3559 *pp_workgroup_out = NULL;
3561 print_sockaddr(addr, sizeof(addr), mb_ip);
3562 DEBUG(99, ("Looking up name of master browser %s\n",
3566 * Do a name status query to find out the name of the master browser.
3567 * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
3568 * master browser will not respond to a wildcard query (or, at least,
3569 * an NT4 server acting as the domain master browser will not).
3571 * We might be able to use ONLY the query on MSBROWSE, but that's not
3572 * yet been tested with all Windows versions, so until it is, leave
3573 * the original wildcard query as the first choice and fall back to
3574 * MSBROWSE if the wildcard query fails.
3576 if (!name_status_find("*", 0, 0x1d, mb_ip, name) &&
3577 !name_status_find(MSBROWSE, 1, 0x1d, mb_ip, name)) {
3579 DEBUG(99, ("Could not retrieve name status for %s\n",
3584 if (!find_master_ip(name, &server_ss)) {
3585 DEBUG(99, ("Could not find master ip for %s\n", name));
3589 *pp_workgroup_out = talloc_strdup(ctx, name);
3591 DEBUG(4, ("found master browser %s, %s\n", name, addr));
3593 print_sockaddr(addr, sizeof(addr), &server_ss);
3594 cli = get_ipc_connect(addr, &server_ss, user_info);
3600 * Return the IP address and workgroup of a master browser on the network, and
3604 struct cli_state *get_ipc_connect_master_ip_bcast(TALLOC_CTX *ctx,
3605 const struct user_auth_info *user_info,
3606 char **pp_workgroup_out)
3608 struct sockaddr_storage *ip_list;
3609 struct cli_state *cli;
3613 *pp_workgroup_out = NULL;
3615 DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
3617 /* Go looking for workgroups by broadcasting on the local network */
3619 status = name_resolve_bcast(MSBROWSE, 1, talloc_tos(),
3621 if (!NT_STATUS_IS_OK(status)) {
3622 DEBUG(99, ("No master browsers responded: %s\n",
3623 nt_errstr(status)));
3627 for (i = 0; i < count; i++) {
3628 char addr[INET6_ADDRSTRLEN];
3629 print_sockaddr(addr, sizeof(addr), &ip_list[i]);
3630 DEBUG(99, ("Found master browser %s\n", addr));
3632 cli = get_ipc_connect_master_ip(ctx, &ip_list[i],
3633 user_info, pp_workgroup_out);