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 "../auth/ntlmssp/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"
35 #include "librpc/ndr/libndr.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(TALLOC_CTX
*mem_ctx
,
69 *destlen
= clistr_pull_talloc(mem_ctx
,
71 SVAL(inbuf
, smb_flg2
),
77 return NT_STATUS_NO_MEMORY
;
81 *dest
= talloc_strdup(mem_ctx
, "");
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
;
125 uint16_t sec_mode
= cli_state_security_mode(cli
);
127 req
= tevent_req_create(mem_ctx
, &state
,
128 struct cli_session_setup_lanman2_state
);
137 * if in share level security then don't send a password now
139 if (!(sec_mode
& NEGOTIATE_SECURITY_USER_LEVEL
)) {
144 && (sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
)
147 * Encrypted mode needed, and non encrypted password
150 lm_response
= data_blob(NULL
, 24);
151 if (tevent_req_nomem(lm_response
.data
, req
)) {
152 return tevent_req_post(req
, ev
);
155 if (!SMBencrypt(pass
, cli_state_server_challenge(cli
),
156 (uint8_t *)lm_response
.data
)) {
157 DEBUG(1, ("Password is > 14 chars in length, and is "
158 "therefore incompatible with Lanman "
159 "authentication\n"));
160 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
161 return tevent_req_post(req
, ev
);
163 } else if ((sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
)
166 * Encrypted mode needed, and encrypted password
169 lm_response
= data_blob(pass
, passlen
);
170 if (tevent_req_nomem(lm_response
.data
, req
)) {
171 return tevent_req_post(req
, ev
);
173 } else if (passlen
> 0) {
175 size_t converted_size
;
177 * Plaintext mode needed, assume plaintext supplied.
179 buf
= talloc_array(talloc_tos(), uint8_t, 0);
180 buf
= smb_bytes_push_str(buf
, cli_ucs2(cli
), pass
, passlen
+1,
182 if (tevent_req_nomem(buf
, req
)) {
183 return tevent_req_post(req
, ev
);
185 lm_response
= data_blob(pass
, passlen
);
187 if (tevent_req_nomem(lm_response
.data
, req
)) {
188 return tevent_req_post(req
, ev
);
192 SCVAL(vwv
+0, 0, 0xff);
195 SSVAL(vwv
+2, 0, CLI_BUFFER_SIZE
);
198 SIVAL(vwv
+5, 0, cli_state_server_session_key(cli
));
199 SSVAL(vwv
+7, 0, lm_response
.length
);
201 bytes
= talloc_array(state
, uint8_t, lm_response
.length
);
202 if (tevent_req_nomem(bytes
, req
)) {
203 return tevent_req_post(req
, ev
);
205 if (lm_response
.length
!= 0) {
206 memcpy(bytes
, lm_response
.data
, lm_response
.length
);
208 data_blob_free(&lm_response
);
210 tmp
= talloc_strdup_upper(talloc_tos(), user
);
211 if (tevent_req_nomem(tmp
, req
)) {
212 return tevent_req_post(req
, ev
);
214 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), tmp
, strlen(tmp
)+1,
218 tmp
= talloc_strdup_upper(talloc_tos(), workgroup
);
219 if (tevent_req_nomem(tmp
, req
)) {
220 return tevent_req_post(req
, ev
);
222 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), tmp
, strlen(tmp
)+1,
224 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), "Unix", 5, NULL
);
225 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), "Samba", 6, NULL
);
227 if (tevent_req_nomem(bytes
, req
)) {
228 return tevent_req_post(req
, ev
);
231 subreq
= cli_smb_send(state
, ev
, cli
, SMBsesssetupX
, 0, 10, vwv
,
232 talloc_get_size(bytes
), bytes
);
233 if (tevent_req_nomem(subreq
, req
)) {
234 return tevent_req_post(req
, ev
);
236 tevent_req_set_callback(subreq
, cli_session_setup_lanman2_done
, req
);
240 static void cli_session_setup_lanman2_done(struct tevent_req
*subreq
)
242 struct tevent_req
*req
= tevent_req_callback_data(
243 subreq
, struct tevent_req
);
244 struct cli_session_setup_lanman2_state
*state
= tevent_req_data(
245 req
, struct cli_session_setup_lanman2_state
);
246 struct cli_state
*cli
= state
->cli
;
257 status
= cli_smb_recv(subreq
, state
, &in
, 3, &wct
, &vwv
,
260 if (!NT_STATUS_IS_OK(status
)) {
261 tevent_req_nterror(req
, status
);
268 cli_state_set_uid(state
->cli
, SVAL(inbuf
, smb_uid
));
269 cli
->is_guestlogin
= ((SVAL(vwv
+2, 0) & 1) != 0);
271 status
= smb_bytes_talloc_string(cli
,
278 if (!NT_STATUS_IS_OK(status
)) {
279 tevent_req_nterror(req
, status
);
284 status
= smb_bytes_talloc_string(cli
,
291 if (!NT_STATUS_IS_OK(status
)) {
292 tevent_req_nterror(req
, status
);
297 status
= smb_bytes_talloc_string(cli
,
304 if (!NT_STATUS_IS_OK(status
)) {
305 tevent_req_nterror(req
, status
);
310 status
= cli_set_username(cli
, state
->user
);
311 if (tevent_req_nterror(req
, status
)) {
314 tevent_req_done(req
);
317 static NTSTATUS
cli_session_setup_lanman2_recv(struct tevent_req
*req
)
319 return tevent_req_simple_recv_ntstatus(req
);
322 static NTSTATUS
cli_session_setup_lanman2(struct cli_state
*cli
, const char *user
,
323 const char *pass
, size_t passlen
,
324 const char *workgroup
)
326 TALLOC_CTX
*frame
= talloc_stackframe();
327 struct event_context
*ev
;
328 struct tevent_req
*req
;
329 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
331 if (cli_has_async_calls(cli
)) {
333 * Can't use sync call while an async call is in flight
335 status
= NT_STATUS_INVALID_PARAMETER
;
338 ev
= event_context_init(frame
);
342 req
= cli_session_setup_lanman2_send(frame
, ev
, cli
, user
, pass
, passlen
,
347 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
350 status
= cli_session_setup_lanman2_recv(req
);
356 /****************************************************************************
357 Work out suitable capabilities to offer the server.
358 ****************************************************************************/
360 static uint32_t cli_session_setup_capabilities(struct cli_state
*cli
,
361 uint32_t sesssetup_capabilities
)
363 uint32_t client_capabilities
= cli_state_capabilities(cli
);
366 * We only send capabilities based on the mask for:
367 * - client only flags
368 * - flags used in both directions
370 * We do not echo the server only flags.
372 client_capabilities
&= (SMB_CAP_BOTH_MASK
| SMB_CAP_CLIENT_MASK
);
375 * Session Setup specific flags CAP_DYNAMIC_REAUTH
376 * and CAP_EXTENDED_SECURITY are passed by the caller.
377 * We need that in order to do guest logins even if
378 * CAP_EXTENDED_SECURITY is negotiated.
380 client_capabilities
&= ~(CAP_DYNAMIC_REAUTH
|CAP_EXTENDED_SECURITY
);
381 sesssetup_capabilities
&= (CAP_DYNAMIC_REAUTH
|CAP_EXTENDED_SECURITY
);
382 client_capabilities
|= sesssetup_capabilities
;
384 return client_capabilities
;
387 /****************************************************************************
388 Do a NT1 guest session setup.
389 ****************************************************************************/
391 struct cli_session_setup_guest_state
{
392 struct cli_state
*cli
;
397 static void cli_session_setup_guest_done(struct tevent_req
*subreq
);
399 struct tevent_req
*cli_session_setup_guest_create(TALLOC_CTX
*mem_ctx
,
400 struct event_context
*ev
,
401 struct cli_state
*cli
,
402 struct tevent_req
**psmbreq
)
404 struct tevent_req
*req
, *subreq
;
405 struct cli_session_setup_guest_state
*state
;
409 req
= tevent_req_create(mem_ctx
, &state
,
410 struct cli_session_setup_guest_state
);
417 SCVAL(vwv
+0, 0, 0xFF);
420 SSVAL(vwv
+2, 0, CLI_BUFFER_SIZE
);
422 SSVAL(vwv
+4, 0, cli_state_get_vc_num(cli
));
423 SIVAL(vwv
+5, 0, cli_state_server_session_key(cli
));
428 SIVAL(vwv
+11, 0, cli_session_setup_capabilities(cli
, 0));
430 bytes
= talloc_array(state
, uint8_t, 0);
432 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), "", 1, /* username */
434 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), "", 1, /* workgroup */
436 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), "Unix", 5, NULL
);
437 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), "Samba", 6, NULL
);
444 state
->bytes
.iov_base
= (void *)bytes
;
445 state
->bytes
.iov_len
= talloc_get_size(bytes
);
447 subreq
= cli_smb_req_create(state
, ev
, cli
, SMBsesssetupX
, 0, 13, vwv
,
449 if (subreq
== NULL
) {
453 tevent_req_set_callback(subreq
, cli_session_setup_guest_done
, req
);
458 struct tevent_req
*cli_session_setup_guest_send(TALLOC_CTX
*mem_ctx
,
459 struct event_context
*ev
,
460 struct cli_state
*cli
)
462 struct tevent_req
*req
, *subreq
;
465 req
= cli_session_setup_guest_create(mem_ctx
, ev
, cli
, &subreq
);
470 status
= cli_smb_req_send(subreq
);
471 if (NT_STATUS_IS_OK(status
)) {
472 tevent_req_nterror(req
, status
);
473 return tevent_req_post(req
, ev
);
478 static void cli_session_setup_guest_done(struct tevent_req
*subreq
)
480 struct tevent_req
*req
= tevent_req_callback_data(
481 subreq
, struct tevent_req
);
482 struct cli_session_setup_guest_state
*state
= tevent_req_data(
483 req
, struct cli_session_setup_guest_state
);
484 struct cli_state
*cli
= state
->cli
;
495 status
= cli_smb_recv(subreq
, state
, &in
, 3, &wct
, &vwv
,
498 if (!NT_STATUS_IS_OK(status
)) {
499 tevent_req_nterror(req
, status
);
506 cli_state_set_uid(state
->cli
, SVAL(inbuf
, smb_uid
));
507 cli
->is_guestlogin
= ((SVAL(vwv
+2, 0) & 1) != 0);
509 status
= smb_bytes_talloc_string(cli
,
516 if (!NT_STATUS_IS_OK(status
)) {
517 tevent_req_nterror(req
, status
);
522 status
= smb_bytes_talloc_string(cli
,
529 if (!NT_STATUS_IS_OK(status
)) {
530 tevent_req_nterror(req
, status
);
535 status
= smb_bytes_talloc_string(cli
,
542 if (!NT_STATUS_IS_OK(status
)) {
543 tevent_req_nterror(req
, status
);
548 status
= cli_set_username(cli
, "");
549 if (!NT_STATUS_IS_OK(status
)) {
550 tevent_req_nterror(req
, status
);
553 tevent_req_done(req
);
556 NTSTATUS
cli_session_setup_guest_recv(struct tevent_req
*req
)
558 return tevent_req_simple_recv_ntstatus(req
);
561 static NTSTATUS
cli_session_setup_guest(struct cli_state
*cli
)
563 TALLOC_CTX
*frame
= talloc_stackframe();
564 struct event_context
*ev
;
565 struct tevent_req
*req
;
566 NTSTATUS status
= NT_STATUS_OK
;
568 if (cli_has_async_calls(cli
)) {
570 * Can't use sync call while an async call is in flight
572 status
= NT_STATUS_INVALID_PARAMETER
;
576 ev
= event_context_init(frame
);
578 status
= NT_STATUS_NO_MEMORY
;
582 req
= cli_session_setup_guest_send(frame
, ev
, cli
);
584 status
= NT_STATUS_NO_MEMORY
;
588 if (!tevent_req_poll(req
, ev
)) {
589 status
= map_nt_error_from_unix(errno
);
593 status
= cli_session_setup_guest_recv(req
);
599 /****************************************************************************
600 Do a NT1 plaintext session setup.
601 ****************************************************************************/
603 struct cli_session_setup_plain_state
{
604 struct cli_state
*cli
;
609 static void cli_session_setup_plain_done(struct tevent_req
*subreq
);
611 static struct tevent_req
*cli_session_setup_plain_send(
612 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
613 struct cli_state
*cli
,
614 const char *user
, const char *pass
, const char *workgroup
)
616 struct tevent_req
*req
, *subreq
;
617 struct cli_session_setup_plain_state
*state
;
623 req
= tevent_req_create(mem_ctx
, &state
,
624 struct cli_session_setup_plain_state
);
632 SCVAL(vwv
+0, 0, 0xff);
635 SSVAL(vwv
+2, 0, CLI_BUFFER_SIZE
);
637 SSVAL(vwv
+4, 0, cli_state_get_vc_num(cli
));
638 SIVAL(vwv
+5, 0, cli_state_server_session_key(cli
));
643 SIVAL(vwv
+11, 0, cli_session_setup_capabilities(cli
, 0));
645 bytes
= talloc_array(state
, uint8_t, 0);
646 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), pass
, strlen(pass
)+1,
648 if (tevent_req_nomem(bytes
, req
)) {
649 return tevent_req_post(req
, ev
);
651 SSVAL(vwv
+ (cli_ucs2(cli
) ? 8 : 7), 0, passlen
);
653 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
),
654 user
, strlen(user
)+1, NULL
);
655 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
),
656 workgroup
, strlen(workgroup
)+1, NULL
);
657 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
),
660 version
= talloc_asprintf(talloc_tos(), "Samba %s",
661 samba_version_string());
662 if (tevent_req_nomem(version
, req
)){
663 return tevent_req_post(req
, ev
);
665 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
),
666 version
, strlen(version
)+1, NULL
);
667 TALLOC_FREE(version
);
669 if (tevent_req_nomem(bytes
, req
)) {
670 return tevent_req_post(req
, ev
);
673 subreq
= cli_smb_send(state
, ev
, cli
, SMBsesssetupX
, 0, 13, vwv
,
674 talloc_get_size(bytes
), bytes
);
675 if (tevent_req_nomem(subreq
, req
)) {
676 return tevent_req_post(req
, ev
);
678 tevent_req_set_callback(subreq
, cli_session_setup_plain_done
, req
);
682 static void cli_session_setup_plain_done(struct tevent_req
*subreq
)
684 struct tevent_req
*req
= tevent_req_callback_data(
685 subreq
, struct tevent_req
);
686 struct cli_session_setup_plain_state
*state
= tevent_req_data(
687 req
, struct cli_session_setup_plain_state
);
688 struct cli_state
*cli
= state
->cli
;
699 status
= cli_smb_recv(subreq
, state
, &in
, 3, &wct
, &vwv
,
702 if (tevent_req_nterror(req
, status
)) {
709 cli_state_set_uid(state
->cli
, SVAL(inbuf
, smb_uid
));
710 cli
->is_guestlogin
= ((SVAL(vwv
+2, 0) & 1) != 0);
712 status
= smb_bytes_talloc_string(cli
,
719 if (!NT_STATUS_IS_OK(status
)) {
720 tevent_req_nterror(req
, status
);
725 status
= smb_bytes_talloc_string(cli
,
732 if (!NT_STATUS_IS_OK(status
)) {
733 tevent_req_nterror(req
, status
);
738 status
= smb_bytes_talloc_string(cli
,
745 if (!NT_STATUS_IS_OK(status
)) {
746 tevent_req_nterror(req
, status
);
751 status
= cli_set_username(cli
, state
->user
);
752 if (tevent_req_nterror(req
, status
)) {
756 tevent_req_done(req
);
759 static NTSTATUS
cli_session_setup_plain_recv(struct tevent_req
*req
)
761 return tevent_req_simple_recv_ntstatus(req
);
764 static NTSTATUS
cli_session_setup_plain(struct cli_state
*cli
,
765 const char *user
, const char *pass
,
766 const char *workgroup
)
768 TALLOC_CTX
*frame
= talloc_stackframe();
769 struct event_context
*ev
;
770 struct tevent_req
*req
;
771 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
773 if (cli_has_async_calls(cli
)) {
775 * Can't use sync call while an async call is in flight
777 status
= NT_STATUS_INVALID_PARAMETER
;
780 ev
= event_context_init(frame
);
784 req
= cli_session_setup_plain_send(frame
, ev
, cli
, user
, pass
,
789 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
792 status
= cli_session_setup_plain_recv(req
);
798 /****************************************************************************
799 do a NT1 NTLM/LM encrypted session setup - for when extended security
801 @param cli client state to create do session setup on
803 @param pass *either* cleartext password (passlen !=24) or LM response.
804 @param ntpass NT response, implies ntpasslen >=24, implies pass is not clear
805 @param workgroup The user's domain.
806 ****************************************************************************/
808 struct cli_session_setup_nt1_state
{
809 struct cli_state
*cli
;
812 DATA_BLOB session_key
;
816 static void cli_session_setup_nt1_done(struct tevent_req
*subreq
);
818 static struct tevent_req
*cli_session_setup_nt1_send(
819 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
820 struct cli_state
*cli
, const char *user
,
821 const char *pass
, size_t passlen
,
822 const char *ntpass
, size_t ntpasslen
,
823 const char *workgroup
)
825 struct tevent_req
*req
, *subreq
;
826 struct cli_session_setup_nt1_state
*state
;
827 DATA_BLOB lm_response
= data_blob_null
;
828 DATA_BLOB nt_response
= data_blob_null
;
829 DATA_BLOB session_key
= data_blob_null
;
832 char *workgroup_upper
;
834 req
= tevent_req_create(mem_ctx
, &state
,
835 struct cli_session_setup_nt1_state
);
844 /* do nothing - guest login */
845 } else if (passlen
!= 24) {
846 if (lp_client_ntlmv2_auth()) {
847 DATA_BLOB server_chal
;
848 DATA_BLOB names_blob
;
851 data_blob_const(cli_state_server_challenge(cli
),
855 * note that the 'workgroup' here is a best
856 * guess - we don't know the server's domain
857 * at this point. Windows clients also don't
860 names_blob
= NTLMv2_generate_names_blob(
861 NULL
, NULL
, workgroup
);
863 if (tevent_req_nomem(names_blob
.data
, req
)) {
864 return tevent_req_post(req
, ev
);
867 if (!SMBNTLMv2encrypt(NULL
, user
, workgroup
, pass
,
868 &server_chal
, &names_blob
,
869 &lm_response
, &nt_response
,
870 NULL
, &session_key
)) {
871 data_blob_free(&names_blob
);
873 req
, NT_STATUS_ACCESS_DENIED
);
874 return tevent_req_post(req
, ev
);
876 data_blob_free(&names_blob
);
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_state_server_challenge(cli
),
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
,
902 cli_state_server_challenge(cli
),
905 * Oops, the LM response is
906 * invalid, just put the NT
907 * response there instead
909 data_blob_free(&lm_response
);
910 lm_response
= data_blob(
916 * LM disabled, place NT# in LM field
919 lm_response
= data_blob(
920 nt_response
.data
, nt_response
.length
);
923 if (tevent_req_nomem(lm_response
.data
, req
)) {
924 return tevent_req_post(req
, ev
);
927 session_key
= data_blob(NULL
, 16);
928 if (tevent_req_nomem(session_key
.data
, req
)) {
929 return tevent_req_post(req
, ev
);
932 E_deshash(pass
, session_key
.data
);
933 memset(&session_key
.data
[8], '\0', 8);
935 SMBsesskeygen_ntv1(nt_hash
, session_key
.data
);
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_state_get_vc_num(cli
));
980 SIVAL(vwv
+5, 0, cli_state_server_session_key(cli
));
981 SSVAL(vwv
+7, 0, lm_response
.length
);
982 SSVAL(vwv
+8, 0, nt_response
.length
);
985 SIVAL(vwv
+11, 0, cli_session_setup_capabilities(cli
, 0));
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
;
1049 status
= cli_smb_recv(subreq
, state
, &in
, 3, &wct
, &vwv
,
1050 &num_bytes
, &bytes
);
1051 TALLOC_FREE(subreq
);
1052 if (!NT_STATUS_IS_OK(status
)) {
1053 tevent_req_nterror(req
, status
);
1060 cli_state_set_uid(state
->cli
, SVAL(inbuf
, smb_uid
));
1061 cli
->is_guestlogin
= ((SVAL(vwv
+2, 0) & 1) != 0);
1063 status
= smb_bytes_talloc_string(cli
,
1069 if (!NT_STATUS_IS_OK(status
)) {
1070 tevent_req_nterror(req
, status
);
1075 status
= smb_bytes_talloc_string(cli
,
1081 if (!NT_STATUS_IS_OK(status
)) {
1082 tevent_req_nterror(req
, status
);
1087 status
= smb_bytes_talloc_string(cli
,
1089 &cli
->server_domain
,
1093 if (!NT_STATUS_IS_OK(status
)) {
1094 tevent_req_nterror(req
, status
);
1099 status
= cli_set_username(cli
, state
->user
);
1100 if (tevent_req_nterror(req
, status
)) {
1103 if (cli_simple_set_signing(cli
, state
->session_key
, state
->response
)
1104 && !cli_check_sign_mac(cli
, (char *)in
, 1)) {
1105 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1108 if (state
->session_key
.data
) {
1109 /* Have plaintext orginal */
1110 cli_set_session_key(cli
, state
->session_key
);
1112 tevent_req_done(req
);
1115 static NTSTATUS
cli_session_setup_nt1_recv(struct tevent_req
*req
)
1117 return tevent_req_simple_recv_ntstatus(req
);
1120 static NTSTATUS
cli_session_setup_nt1(struct cli_state
*cli
, const char *user
,
1121 const char *pass
, size_t passlen
,
1122 const char *ntpass
, size_t ntpasslen
,
1123 const char *workgroup
)
1125 TALLOC_CTX
*frame
= talloc_stackframe();
1126 struct event_context
*ev
;
1127 struct tevent_req
*req
;
1128 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
1130 if (cli_has_async_calls(cli
)) {
1132 * Can't use sync call while an async call is in flight
1134 status
= NT_STATUS_INVALID_PARAMETER
;
1137 ev
= event_context_init(frame
);
1141 req
= cli_session_setup_nt1_send(frame
, ev
, cli
, user
, pass
, passlen
,
1142 ntpass
, ntpasslen
, workgroup
);
1146 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
1149 status
= cli_session_setup_nt1_recv(req
);
1155 /* The following is calculated from :
1157 * (smb_wcnt * 2) = 24 (smb_wcnt == 12 in cli_session_setup_blob_send() )
1158 * (strlen("Unix") + 1 + strlen("Samba") + 1) * 2 = 22 (unicode strings at
1162 #define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22)
1164 struct cli_sesssetup_blob_state
{
1165 struct tevent_context
*ev
;
1166 struct cli_state
*cli
;
1168 uint16_t max_blob_size
;
1177 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state
*state
,
1178 struct tevent_req
**psubreq
);
1179 static void cli_sesssetup_blob_done(struct tevent_req
*subreq
);
1181 static struct tevent_req
*cli_sesssetup_blob_send(TALLOC_CTX
*mem_ctx
,
1182 struct tevent_context
*ev
,
1183 struct cli_state
*cli
,
1186 struct tevent_req
*req
, *subreq
;
1187 struct cli_sesssetup_blob_state
*state
;
1188 uint32_t usable_space
;
1190 req
= tevent_req_create(mem_ctx
, &state
,
1191 struct cli_sesssetup_blob_state
);
1199 usable_space
= cli_state_available_size(cli
,
1200 BASE_SESSSETUP_BLOB_PACKET_SIZE
);
1202 if (usable_space
== 0) {
1203 DEBUG(1, ("cli_session_setup_blob: cli->max_xmit too small "
1204 "(not possible to send %u bytes)\n",
1205 BASE_SESSSETUP_BLOB_PACKET_SIZE
+ 1));
1206 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1207 return tevent_req_post(req
, ev
);
1209 state
->max_blob_size
= MIN(usable_space
, 0xFFFF);
1211 if (!cli_sesssetup_blob_next(state
, &subreq
)) {
1212 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
1213 return tevent_req_post(req
, ev
);
1215 tevent_req_set_callback(subreq
, cli_sesssetup_blob_done
, req
);
1219 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state
*state
,
1220 struct tevent_req
**psubreq
)
1222 struct tevent_req
*subreq
;
1225 SCVAL(state
->vwv
+0, 0, 0xFF);
1226 SCVAL(state
->vwv
+0, 1, 0);
1227 SSVAL(state
->vwv
+1, 0, 0);
1228 SSVAL(state
->vwv
+2, 0, CLI_BUFFER_SIZE
);
1229 SSVAL(state
->vwv
+3, 0, 2);
1230 SSVAL(state
->vwv
+4, 0, 1);
1231 SIVAL(state
->vwv
+5, 0, 0);
1233 thistime
= MIN(state
->blob
.length
, state
->max_blob_size
);
1234 SSVAL(state
->vwv
+7, 0, thistime
);
1236 SSVAL(state
->vwv
+8, 0, 0);
1237 SSVAL(state
->vwv
+9, 0, 0);
1238 SIVAL(state
->vwv
+10, 0,
1239 cli_session_setup_capabilities(state
->cli
, CAP_EXTENDED_SECURITY
));
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
, 4, &wct
, &vwv
,
1284 &num_bytes
, &bytes
);
1285 TALLOC_FREE(subreq
);
1286 if (!NT_STATUS_IS_OK(status
)
1287 && !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1288 tevent_req_nterror(req
, status
);
1292 state
->status
= status
;
1293 TALLOC_FREE(state
->buf
);
1295 state
->inbuf
= (char *)inbuf
;
1296 cli_state_set_uid(state
->cli
, SVAL(inbuf
, smb_uid
));
1297 cli
->is_guestlogin
= ((SVAL(vwv
+2, 0) & 1) != 0);
1299 blob_length
= SVAL(vwv
+3, 0);
1300 if (blob_length
> num_bytes
) {
1301 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
1304 state
->ret_blob
= data_blob_const(bytes
, blob_length
);
1306 p
= bytes
+ blob_length
;
1308 status
= smb_bytes_talloc_string(cli
,
1315 if (!NT_STATUS_IS_OK(status
)) {
1316 tevent_req_nterror(req
, status
);
1321 status
= smb_bytes_talloc_string(cli
,
1328 if (!NT_STATUS_IS_OK(status
)) {
1329 tevent_req_nterror(req
, status
);
1334 status
= smb_bytes_talloc_string(cli
,
1336 &cli
->server_domain
,
1341 if (!NT_STATUS_IS_OK(status
)) {
1342 tevent_req_nterror(req
, status
);
1347 if (state
->blob
.length
!= 0) {
1351 if (!cli_sesssetup_blob_next(state
, &subreq
)) {
1352 tevent_req_oom(req
);
1355 tevent_req_set_callback(subreq
, cli_sesssetup_blob_done
, req
);
1358 tevent_req_done(req
);
1361 static NTSTATUS
cli_sesssetup_blob_recv(struct tevent_req
*req
,
1362 TALLOC_CTX
*mem_ctx
,
1366 struct cli_sesssetup_blob_state
*state
= tevent_req_data(
1367 req
, struct cli_sesssetup_blob_state
);
1371 if (tevent_req_is_nterror(req
, &status
)) {
1372 cli_state_set_uid(state
->cli
, UID_FIELD_INVALID
);
1376 inbuf
= talloc_move(mem_ctx
, &state
->inbuf
);
1377 if (pblob
!= NULL
) {
1378 *pblob
= state
->ret_blob
;
1380 if (pinbuf
!= NULL
) {
1383 /* could be NT_STATUS_MORE_PROCESSING_REQUIRED */
1384 return state
->status
;
1389 /****************************************************************************
1390 Use in-memory credentials cache
1391 ****************************************************************************/
1393 static void use_in_memory_ccache(void) {
1394 setenv(KRB5_ENV_CCNAME
, "MEMORY:cliconnect", 1);
1397 /****************************************************************************
1398 Do a spnego/kerberos encrypted session setup.
1399 ****************************************************************************/
1401 struct cli_session_setup_kerberos_state
{
1402 struct cli_state
*cli
;
1403 DATA_BLOB negTokenTarg
;
1404 DATA_BLOB session_key_krb5
;
1405 ADS_STATUS ads_status
;
1408 static void cli_session_setup_kerberos_done(struct tevent_req
*subreq
);
1410 static struct tevent_req
*cli_session_setup_kerberos_send(
1411 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
1412 const char *principal
)
1414 struct tevent_req
*req
, *subreq
;
1415 struct cli_session_setup_kerberos_state
*state
;
1418 DEBUG(2,("Doing kerberos session setup\n"));
1420 req
= tevent_req_create(mem_ctx
, &state
,
1421 struct cli_session_setup_kerberos_state
);
1426 state
->ads_status
= ADS_SUCCESS
;
1429 * Ok, this is cheating: spnego_gen_krb5_negTokenInit can block if
1430 * we have to acquire a ticket. To be fixed later :-)
1432 rc
= spnego_gen_krb5_negTokenInit(state
, principal
, 0, &state
->negTokenTarg
,
1433 &state
->session_key_krb5
, 0, NULL
);
1435 DEBUG(1, ("cli_session_setup_kerberos: "
1436 "spnego_gen_krb5_negTokenInit failed: %s\n",
1437 error_message(rc
)));
1438 state
->ads_status
= ADS_ERROR_KRB5(rc
);
1439 tevent_req_nterror(req
, NT_STATUS_UNSUCCESSFUL
);
1440 return tevent_req_post(req
, ev
);
1444 file_save("negTokenTarg.dat", state
->negTokenTarg
.data
,
1445 state
->negTokenTarg
.length
);
1448 subreq
= cli_sesssetup_blob_send(state
, ev
, cli
, state
->negTokenTarg
);
1449 if (tevent_req_nomem(subreq
, req
)) {
1450 return tevent_req_post(req
, ev
);
1452 tevent_req_set_callback(subreq
, cli_session_setup_kerberos_done
, req
);
1456 static void cli_session_setup_kerberos_done(struct tevent_req
*subreq
)
1458 struct tevent_req
*req
= tevent_req_callback_data(
1459 subreq
, struct tevent_req
);
1460 struct cli_session_setup_kerberos_state
*state
= tevent_req_data(
1461 req
, struct cli_session_setup_kerberos_state
);
1465 status
= cli_sesssetup_blob_recv(subreq
, talloc_tos(), NULL
, &inbuf
);
1466 TALLOC_FREE(subreq
);
1467 if (!NT_STATUS_IS_OK(status
)) {
1468 tevent_req_nterror(req
, status
);
1472 cli_set_session_key(state
->cli
, state
->session_key_krb5
);
1474 if (cli_simple_set_signing(state
->cli
, state
->session_key_krb5
,
1476 && !cli_check_sign_mac(state
->cli
, inbuf
, 1)) {
1477 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1481 tevent_req_done(req
);
1484 static ADS_STATUS
cli_session_setup_kerberos_recv(struct tevent_req
*req
)
1486 struct cli_session_setup_kerberos_state
*state
= tevent_req_data(
1487 req
, struct cli_session_setup_kerberos_state
);
1490 if (tevent_req_is_nterror(req
, &status
)) {
1491 return ADS_ERROR_NT(status
);
1493 return state
->ads_status
;
1496 static ADS_STATUS
cli_session_setup_kerberos(struct cli_state
*cli
,
1497 const char *principal
)
1499 struct tevent_context
*ev
;
1500 struct tevent_req
*req
;
1501 ADS_STATUS status
= ADS_ERROR_NT(NT_STATUS_NO_MEMORY
);
1503 if (cli_has_async_calls(cli
)) {
1504 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
1506 ev
= tevent_context_init(talloc_tos());
1510 req
= cli_session_setup_kerberos_send(ev
, ev
, cli
, principal
);
1514 if (!tevent_req_poll(req
, ev
)) {
1515 status
= ADS_ERROR_SYSTEM(errno
);
1518 status
= cli_session_setup_kerberos_recv(req
);
1523 #endif /* HAVE_KRB5 */
1525 /****************************************************************************
1526 Do a spnego/NTLMSSP encrypted session setup.
1527 ****************************************************************************/
1529 struct cli_session_setup_ntlmssp_state
{
1530 struct tevent_context
*ev
;
1531 struct cli_state
*cli
;
1532 struct ntlmssp_state
*ntlmssp_state
;
1537 static int cli_session_setup_ntlmssp_state_destructor(
1538 struct cli_session_setup_ntlmssp_state
*state
)
1540 if (state
->ntlmssp_state
!= NULL
) {
1541 TALLOC_FREE(state
->ntlmssp_state
);
1546 static void cli_session_setup_ntlmssp_done(struct tevent_req
*req
);
1548 static struct tevent_req
*cli_session_setup_ntlmssp_send(
1549 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
1550 const char *user
, const char *pass
, const char *domain
)
1552 struct tevent_req
*req
, *subreq
;
1553 struct cli_session_setup_ntlmssp_state
*state
;
1556 const char *OIDs_ntlm
[] = {OID_NTLMSSP
, NULL
};
1558 req
= tevent_req_create(mem_ctx
, &state
,
1559 struct cli_session_setup_ntlmssp_state
);
1567 state
->ntlmssp_state
= NULL
;
1568 talloc_set_destructor(
1569 state
, cli_session_setup_ntlmssp_state_destructor
);
1571 status
= ntlmssp_client_start(state
,
1574 lp_client_ntlmv2_auth(),
1575 &state
->ntlmssp_state
);
1576 if (!NT_STATUS_IS_OK(status
)) {
1579 ntlmssp_want_feature(state
->ntlmssp_state
,
1580 NTLMSSP_FEATURE_SESSION_KEY
);
1581 if (cli
->use_ccache
) {
1582 ntlmssp_want_feature(state
->ntlmssp_state
,
1583 NTLMSSP_FEATURE_CCACHE
);
1585 status
= ntlmssp_set_username(state
->ntlmssp_state
, user
);
1586 if (!NT_STATUS_IS_OK(status
)) {
1589 status
= ntlmssp_set_domain(state
->ntlmssp_state
, domain
);
1590 if (!NT_STATUS_IS_OK(status
)) {
1593 status
= ntlmssp_set_password(state
->ntlmssp_state
, pass
);
1594 if (!NT_STATUS_IS_OK(status
)) {
1597 status
= ntlmssp_update(state
->ntlmssp_state
, data_blob_null
,
1599 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1603 state
->blob_out
= spnego_gen_negTokenInit(state
, OIDs_ntlm
, &blob_out
, NULL
);
1604 data_blob_free(&blob_out
);
1606 subreq
= cli_sesssetup_blob_send(state
, ev
, cli
, state
->blob_out
);
1607 if (tevent_req_nomem(subreq
, req
)) {
1608 return tevent_req_post(req
, ev
);
1610 tevent_req_set_callback(subreq
, cli_session_setup_ntlmssp_done
, req
);
1613 tevent_req_nterror(req
, status
);
1614 return tevent_req_post(req
, ev
);
1617 static void cli_session_setup_ntlmssp_done(struct tevent_req
*subreq
)
1619 struct tevent_req
*req
= tevent_req_callback_data(
1620 subreq
, struct tevent_req
);
1621 struct cli_session_setup_ntlmssp_state
*state
= tevent_req_data(
1622 req
, struct cli_session_setup_ntlmssp_state
);
1623 DATA_BLOB blob_in
, msg_in
, blob_out
;
1628 status
= cli_sesssetup_blob_recv(subreq
, talloc_tos(), &blob_in
,
1630 TALLOC_FREE(subreq
);
1631 data_blob_free(&state
->blob_out
);
1633 if (NT_STATUS_IS_OK(status
)) {
1634 if (state
->cli
->server_domain
[0] == '\0') {
1635 TALLOC_FREE(state
->cli
->server_domain
);
1636 state
->cli
->server_domain
= talloc_strdup(state
->cli
,
1637 state
->ntlmssp_state
->server
.netbios_domain
);
1638 if (state
->cli
->server_domain
== NULL
) {
1639 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
1643 cli_set_session_key(
1644 state
->cli
, state
->ntlmssp_state
->session_key
);
1646 if (cli_simple_set_signing(
1647 state
->cli
, state
->ntlmssp_state
->session_key
,
1649 && !cli_check_sign_mac(state
->cli
, inbuf
, 1)) {
1650 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1653 TALLOC_FREE(state
->ntlmssp_state
);
1654 tevent_req_done(req
);
1657 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1658 tevent_req_nterror(req
, status
);
1662 if (blob_in
.length
== 0) {
1663 tevent_req_nterror(req
, NT_STATUS_UNSUCCESSFUL
);
1667 if ((state
->turn
== 1)
1668 && NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1669 DATA_BLOB tmp_blob
= data_blob_null
;
1670 /* the server might give us back two challenges */
1671 parse_ret
= spnego_parse_challenge(state
, blob_in
, &msg_in
,
1673 data_blob_free(&tmp_blob
);
1675 parse_ret
= spnego_parse_auth_response(state
, blob_in
, status
,
1676 OID_NTLMSSP
, &msg_in
);
1681 DEBUG(3,("Failed to parse auth response\n"));
1682 if (NT_STATUS_IS_OK(status
)
1683 || NT_STATUS_EQUAL(status
,
1684 NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1686 req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
1691 status
= ntlmssp_update(state
->ntlmssp_state
, msg_in
, &blob_out
);
1693 if (!NT_STATUS_IS_OK(status
)
1694 && !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1695 TALLOC_FREE(state
->ntlmssp_state
);
1696 tevent_req_nterror(req
, status
);
1700 state
->blob_out
= spnego_gen_auth(state
, blob_out
);
1701 if (tevent_req_nomem(state
->blob_out
.data
, req
)) {
1705 subreq
= cli_sesssetup_blob_send(state
, state
->ev
, state
->cli
,
1707 if (tevent_req_nomem(subreq
, req
)) {
1710 tevent_req_set_callback(subreq
, cli_session_setup_ntlmssp_done
, req
);
1713 static NTSTATUS
cli_session_setup_ntlmssp_recv(struct tevent_req
*req
)
1715 struct cli_session_setup_ntlmssp_state
*state
= tevent_req_data(
1716 req
, struct cli_session_setup_ntlmssp_state
);
1719 if (tevent_req_is_nterror(req
, &status
)) {
1720 cli_state_set_uid(state
->cli
, UID_FIELD_INVALID
);
1723 return NT_STATUS_OK
;
1726 static NTSTATUS
cli_session_setup_ntlmssp(struct cli_state
*cli
,
1731 struct tevent_context
*ev
;
1732 struct tevent_req
*req
;
1733 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
1735 if (cli_has_async_calls(cli
)) {
1736 return NT_STATUS_INVALID_PARAMETER
;
1738 ev
= tevent_context_init(talloc_tos());
1742 req
= cli_session_setup_ntlmssp_send(ev
, ev
, cli
, user
, pass
, domain
);
1746 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
1749 status
= cli_session_setup_ntlmssp_recv(req
);
1755 /****************************************************************************
1756 Do a spnego encrypted session setup.
1758 user_domain: The shortname of the domain the user/machine is a member of.
1759 dest_realm: The realm we're connecting to, if NULL we use our default realm.
1760 ****************************************************************************/
1762 static ADS_STATUS
cli_session_setup_spnego(struct cli_state
*cli
,
1765 const char *user_domain
,
1766 const char * dest_realm
)
1768 char *principal
= NULL
;
1769 char *OIDs
[ASN1_MAX_OIDS
];
1771 const DATA_BLOB
*server_blob
;
1772 DATA_BLOB blob
= data_blob_null
;
1773 const char *p
= NULL
;
1774 char *account
= NULL
;
1777 server_blob
= cli_state_server_gss_blob(cli
);
1779 blob
= data_blob(server_blob
->data
, server_blob
->length
);
1782 DEBUG(3,("Doing spnego session setup (blob length=%lu)\n", (unsigned long)blob
.length
));
1784 /* the server might not even do spnego */
1785 if (blob
.length
== 0) {
1786 DEBUG(3,("server didn't supply a full spnego negprot\n"));
1791 file_save("negprot.dat", cli
->secblob
.data
, cli
->secblob
.length
);
1794 /* The server sent us the first part of the SPNEGO exchange in the
1795 * negprot reply. It is WRONG to depend on the principal sent in the
1796 * negprot reply, but right now we do it. If we don't receive one,
1797 * we try to best guess, then fall back to NTLM. */
1798 if (!spnego_parse_negTokenInit(talloc_tos(), blob
, OIDs
, &principal
, NULL
) ||
1800 data_blob_free(&blob
);
1801 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
1803 data_blob_free(&blob
);
1805 /* make sure the server understands kerberos */
1806 for (i
=0;OIDs
[i
];i
++) {
1808 DEBUG(3,("got OID=%s\n", OIDs
[i
]));
1810 DEBUGADD(3,("got OID=%s\n", OIDs
[i
]));
1811 if (strcmp(OIDs
[i
], OID_KERBEROS5_OLD
) == 0 ||
1812 strcmp(OIDs
[i
], OID_KERBEROS5
) == 0) {
1813 cli
->got_kerberos_mechanism
= True
;
1815 talloc_free(OIDs
[i
]);
1818 DEBUG(3,("got principal=%s\n", principal
? principal
: "<null>"));
1820 status
= cli_set_username(cli
, user
);
1821 if (!NT_STATUS_IS_OK(status
)) {
1822 TALLOC_FREE(principal
);
1823 return ADS_ERROR_NT(status
);
1827 /* If password is set we reauthenticate to kerberos server
1828 * and do not store results */
1830 if (cli
->got_kerberos_mechanism
&& cli
->use_kerberos
) {
1832 const char *remote_name
= cli_state_remote_name(cli
);
1834 if (pass
&& *pass
) {
1837 use_in_memory_ccache();
1838 ret
= kerberos_kinit_password(user
, pass
, 0 /* no time correction for now */, NULL
);
1841 TALLOC_FREE(principal
);
1842 DEBUG(0, ("Kinit failed: %s\n", error_message(ret
)));
1843 if (cli
->fallback_after_kerberos
)
1845 return ADS_ERROR_KRB5(ret
);
1849 /* We may not be allowed to use the server-supplied SPNEGO principal, or it may not have been supplied to us
1851 if (!lp_client_use_spnego_principal() || strequal(principal
, ADS_IGNORE_PRINCIPAL
)) {
1852 TALLOC_FREE(principal
);
1855 if (principal
== NULL
&&
1856 !is_ipaddress(remote_name
) &&
1857 !strequal(STAR_SMBSERVER
,
1861 DEBUG(3,("cli_session_setup_spnego: using target "
1862 "hostname not SPNEGO principal\n"));
1864 host
= strchr_m(remote_name
, '.');
1866 realm
= SMB_STRDUP(dest_realm
);
1868 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY
);
1874 realm
= kerberos_get_realm_from_hostname(remote_name
);
1876 /* NetBIOS name - use our realm. */
1877 realm
= kerberos_get_default_realm_from_ccache();
1881 if (realm
== NULL
|| *realm
== '\0') {
1882 realm
= SMB_STRDUP(lp_realm());
1884 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY
);
1887 DEBUG(3,("cli_session_setup_spnego: cannot "
1888 "get realm from dest_realm %s, "
1889 "desthost %s. Using default "
1890 "smb.conf realm %s\n",
1891 dest_realm
? dest_realm
: "<null>",
1896 principal
= talloc_asprintf(talloc_tos(),
1902 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY
);
1904 DEBUG(3,("cli_session_setup_spnego: guessed "
1905 "server principal=%s\n",
1906 principal
? principal
: "<null>"));
1912 rc
= cli_session_setup_kerberos(cli
, principal
);
1913 if (ADS_ERR_OK(rc
) || !cli
->fallback_after_kerberos
) {
1914 TALLOC_FREE(principal
);
1921 TALLOC_FREE(principal
);
1925 account
= talloc_strdup(talloc_tos(), user
);
1927 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY
);
1930 /* when falling back to ntlmssp while authenticating with a machine
1931 * account strip off the realm - gd */
1933 if ((p
= strchr_m(user
, '@')) != NULL
) {
1934 account
[PTR_DIFF(p
,user
)] = '\0';
1937 return ADS_ERROR_NT(cli_session_setup_ntlmssp(cli
, account
, pass
, user_domain
));
1940 /****************************************************************************
1941 Send a session setup. The username and workgroup is in UNIX character
1942 format and must be converted to DOS codepage format before sending. If the
1943 password is in plaintext, the same should be done.
1944 ****************************************************************************/
1946 NTSTATUS
cli_session_setup(struct cli_state
*cli
,
1948 const char *pass
, int passlen
,
1949 const char *ntpass
, int ntpasslen
,
1950 const char *workgroup
)
1954 uint16_t sec_mode
= cli_state_security_mode(cli
);
1957 user2
= talloc_strdup(talloc_tos(), user
);
1959 user2
= talloc_strdup(talloc_tos(), "");
1961 if (user2
== NULL
) {
1962 return NT_STATUS_NO_MEMORY
;
1969 /* allow for workgroups as part of the username */
1970 if ((p
=strchr_m(user2
,'\\')) || (p
=strchr_m(user2
,'/')) ||
1971 (p
=strchr_m(user2
,*lp_winbind_separator()))) {
1978 if (cli_state_protocol(cli
) < PROTOCOL_LANMAN1
) {
1979 return NT_STATUS_OK
;
1982 /* now work out what sort of session setup we are going to
1983 do. I have split this into separate functions to make the
1984 flow a bit easier to understand (tridge) */
1986 /* if its an older server then we have to use the older request format */
1988 if (cli_state_protocol(cli
) < PROTOCOL_NT1
) {
1989 if (!lp_client_lanman_auth() && passlen
!= 24 && (*pass
)) {
1990 DEBUG(1, ("Server requested LM password but 'client lanman auth = no'"
1991 " or 'client ntlmv2 auth = yes'\n"));
1992 return NT_STATUS_ACCESS_DENIED
;
1995 if ((sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
) == 0 &&
1996 !lp_client_plaintext_auth() && (*pass
)) {
1997 DEBUG(1, ("Server requested LM password but 'client plaintext auth = no'"
1998 " or 'client ntlmv2 auth = yes'\n"));
1999 return NT_STATUS_ACCESS_DENIED
;
2002 return cli_session_setup_lanman2(cli
, user
, pass
, passlen
,
2006 /* if no user is supplied then we have to do an anonymous connection.
2007 passwords are ignored */
2009 if (!user
|| !*user
)
2010 return cli_session_setup_guest(cli
);
2012 /* if the server is share level then send a plaintext null
2013 password at this point. The password is sent in the tree
2016 if ((sec_mode
& NEGOTIATE_SECURITY_USER_LEVEL
) == 0)
2017 return cli_session_setup_plain(cli
, user
, "", workgroup
);
2019 /* if the server doesn't support encryption then we have to use
2020 plaintext. The second password is ignored */
2022 if ((sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
) == 0) {
2023 if (!lp_client_plaintext_auth() && (*pass
)) {
2024 DEBUG(1, ("Server requested LM password but 'client plaintext auth = no'"
2025 " or 'client ntlmv2 auth = yes'\n"));
2026 return NT_STATUS_ACCESS_DENIED
;
2028 return cli_session_setup_plain(cli
, user
, pass
, workgroup
);
2031 /* if the server supports extended security then use SPNEGO */
2033 if (cli_state_capabilities(cli
) & CAP_EXTENDED_SECURITY
) {
2034 const char *remote_realm
= cli_state_remote_realm(cli
);
2035 ADS_STATUS status
= cli_session_setup_spnego(cli
, user
, pass
,
2038 if (!ADS_ERR_OK(status
)) {
2039 DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status
)));
2040 return ads_ntstatus(status
);
2045 /* otherwise do a NT1 style session setup */
2046 status
= cli_session_setup_nt1(cli
, user
, pass
, passlen
,
2047 ntpass
, ntpasslen
, workgroup
);
2048 if (!NT_STATUS_IS_OK(status
)) {
2049 DEBUG(3,("cli_session_setup: NT1 session setup "
2050 "failed: %s\n", nt_errstr(status
)));
2055 return NT_STATUS_OK
;
2058 /****************************************************************************
2060 *****************************************************************************/
2062 struct cli_ulogoff_state
{
2063 struct cli_state
*cli
;
2067 static void cli_ulogoff_done(struct tevent_req
*subreq
);
2069 struct tevent_req
*cli_ulogoff_send(TALLOC_CTX
*mem_ctx
,
2070 struct tevent_context
*ev
,
2071 struct cli_state
*cli
)
2073 struct tevent_req
*req
, *subreq
;
2074 struct cli_ulogoff_state
*state
;
2076 req
= tevent_req_create(mem_ctx
, &state
, struct cli_ulogoff_state
);
2082 SCVAL(state
->vwv
+0, 0, 0xFF);
2083 SCVAL(state
->vwv
+1, 0, 0);
2084 SSVAL(state
->vwv
+2, 0, 0);
2086 subreq
= cli_smb_send(state
, ev
, cli
, SMBulogoffX
, 0, 2, state
->vwv
,
2088 if (tevent_req_nomem(subreq
, req
)) {
2089 return tevent_req_post(req
, ev
);
2091 tevent_req_set_callback(subreq
, cli_ulogoff_done
, req
);
2095 static void cli_ulogoff_done(struct tevent_req
*subreq
)
2097 struct tevent_req
*req
= tevent_req_callback_data(
2098 subreq
, struct tevent_req
);
2099 struct cli_ulogoff_state
*state
= tevent_req_data(
2100 req
, struct cli_ulogoff_state
);
2103 status
= cli_smb_recv(subreq
, NULL
, NULL
, 0, NULL
, NULL
, NULL
, NULL
);
2104 if (!NT_STATUS_IS_OK(status
)) {
2105 tevent_req_nterror(req
, status
);
2108 cli_state_set_uid(state
->cli
, UID_FIELD_INVALID
);
2109 tevent_req_done(req
);
2112 NTSTATUS
cli_ulogoff_recv(struct tevent_req
*req
)
2114 return tevent_req_simple_recv_ntstatus(req
);
2117 NTSTATUS
cli_ulogoff(struct cli_state
*cli
)
2119 struct tevent_context
*ev
;
2120 struct tevent_req
*req
;
2121 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2123 if (cli_has_async_calls(cli
)) {
2124 return NT_STATUS_INVALID_PARAMETER
;
2126 ev
= tevent_context_init(talloc_tos());
2130 req
= cli_ulogoff_send(ev
, ev
, cli
);
2134 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2137 status
= cli_ulogoff_recv(req
);
2143 /****************************************************************************
2145 ****************************************************************************/
2147 struct cli_tcon_andx_state
{
2148 struct cli_state
*cli
;
2153 static void cli_tcon_andx_done(struct tevent_req
*subreq
);
2155 struct tevent_req
*cli_tcon_andx_create(TALLOC_CTX
*mem_ctx
,
2156 struct event_context
*ev
,
2157 struct cli_state
*cli
,
2158 const char *share
, const char *dev
,
2159 const char *pass
, int passlen
,
2160 struct tevent_req
**psmbreq
)
2162 struct tevent_req
*req
, *subreq
;
2163 struct cli_tcon_andx_state
*state
;
2168 uint16_t sec_mode
= cli_state_security_mode(cli
);
2172 req
= tevent_req_create(mem_ctx
, &state
, struct cli_tcon_andx_state
);
2179 cli
->share
= talloc_strdup(cli
, share
);
2184 /* in user level security don't send a password now */
2185 if (sec_mode
& NEGOTIATE_SECURITY_USER_LEVEL
) {
2188 } else if (pass
== NULL
) {
2189 DEBUG(1, ("Server not using user level security and no "
2190 "password supplied.\n"));
2194 if ((sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
) &&
2195 *pass
&& passlen
!= 24) {
2196 if (!lp_client_lanman_auth()) {
2197 DEBUG(1, ("Server requested LANMAN password "
2198 "(share-level security) but "
2199 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2204 * Non-encrypted passwords - convert to DOS codepage before
2207 SMBencrypt(pass
, cli_state_server_challenge(cli
), p24
);
2209 pass
= (const char *)p24
;
2211 if((sec_mode
& (NEGOTIATE_SECURITY_USER_LEVEL
2212 |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
))
2216 if (!lp_client_plaintext_auth() && (*pass
)) {
2217 DEBUG(1, ("Server requested plaintext "
2219 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2224 * Non-encrypted passwords - convert to DOS codepage
2227 tmp_pass
= talloc_array(talloc_tos(), uint8
, 0);
2228 if (tevent_req_nomem(tmp_pass
, req
)) {
2229 return tevent_req_post(req
, ev
);
2231 tmp_pass
= trans2_bytes_push_str(tmp_pass
,
2232 false, /* always DOS */
2236 if (tevent_req_nomem(tmp_pass
, req
)) {
2237 return tevent_req_post(req
, ev
);
2239 pass
= (const char *)tmp_pass
;
2240 passlen
= talloc_get_size(tmp_pass
);
2244 SCVAL(vwv
+0, 0, 0xFF);
2247 SSVAL(vwv
+2, 0, TCONX_FLAG_EXTENDED_RESPONSE
);
2248 SSVAL(vwv
+3, 0, passlen
);
2250 if (passlen
&& pass
) {
2251 bytes
= (uint8_t *)talloc_memdup(state
, pass
, passlen
);
2253 bytes
= talloc_array(state
, uint8_t, 0);
2259 tmp
= talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
2260 cli_state_remote_name(cli
), share
);
2265 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), tmp
, strlen(tmp
)+1,
2270 * Add the devicetype
2272 tmp
= talloc_strdup_upper(talloc_tos(), dev
);
2277 bytes
= smb_bytes_push_str(bytes
, false, tmp
, strlen(tmp
)+1, NULL
);
2280 if (bytes
== NULL
) {
2285 state
->bytes
.iov_base
= (void *)bytes
;
2286 state
->bytes
.iov_len
= talloc_get_size(bytes
);
2288 subreq
= cli_smb_req_create(state
, ev
, cli
, SMBtconX
, 0, 4, vwv
,
2290 if (subreq
== NULL
) {
2294 tevent_req_set_callback(subreq
, cli_tcon_andx_done
, req
);
2299 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
2300 return tevent_req_post(req
, ev
);
2303 struct tevent_req
*cli_tcon_andx_send(TALLOC_CTX
*mem_ctx
,
2304 struct event_context
*ev
,
2305 struct cli_state
*cli
,
2306 const char *share
, const char *dev
,
2307 const char *pass
, int passlen
)
2309 struct tevent_req
*req
, *subreq
;
2312 req
= cli_tcon_andx_create(mem_ctx
, ev
, cli
, share
, dev
, pass
, passlen
,
2317 if (subreq
== NULL
) {
2320 status
= cli_smb_req_send(subreq
);
2321 if (!NT_STATUS_IS_OK(status
)) {
2322 tevent_req_nterror(req
, status
);
2323 return tevent_req_post(req
, ev
);
2328 static void cli_tcon_andx_done(struct tevent_req
*subreq
)
2330 struct tevent_req
*req
= tevent_req_callback_data(
2331 subreq
, struct tevent_req
);
2332 struct cli_tcon_andx_state
*state
= tevent_req_data(
2333 req
, struct cli_tcon_andx_state
);
2334 struct cli_state
*cli
= state
->cli
;
2343 status
= cli_smb_recv(subreq
, state
, &in
, 0, &wct
, &vwv
,
2344 &num_bytes
, &bytes
);
2345 TALLOC_FREE(subreq
);
2346 if (!NT_STATUS_IS_OK(status
)) {
2347 tevent_req_nterror(req
, status
);
2354 if (clistr_pull_talloc(cli
,
2356 SVAL(inbuf
, smb_flg2
),
2360 STR_TERMINATE
|STR_ASCII
) == -1) {
2361 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
2365 cli
->dev
= talloc_strdup(cli
, "");
2366 if (cli
->dev
== NULL
) {
2367 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
2372 if ((cli_state_protocol(cli
) >= PROTOCOL_NT1
) && (num_bytes
== 3)) {
2373 /* almost certainly win95 - enable bug fixes */
2378 * Make sure that we have the optional support 16-bit field. WCT > 2.
2379 * Avoids issues when connecting to Win9x boxes sharing files
2382 cli
->dfsroot
= false;
2384 if ((wct
> 2) && (cli_state_protocol(cli
) >= PROTOCOL_LANMAN2
)) {
2385 cli
->dfsroot
= ((SVAL(vwv
+2, 0) & SMB_SHARE_IN_DFS
) != 0);
2388 cli
->smb1
.tid
= SVAL(inbuf
,smb_tid
);
2389 tevent_req_done(req
);
2392 NTSTATUS
cli_tcon_andx_recv(struct tevent_req
*req
)
2394 return tevent_req_simple_recv_ntstatus(req
);
2397 NTSTATUS
cli_tcon_andx(struct cli_state
*cli
, const char *share
,
2398 const char *dev
, const char *pass
, int passlen
)
2400 TALLOC_CTX
*frame
= talloc_stackframe();
2401 struct event_context
*ev
;
2402 struct tevent_req
*req
;
2403 NTSTATUS status
= NT_STATUS_OK
;
2405 if (cli_has_async_calls(cli
)) {
2407 * Can't use sync call while an async call is in flight
2409 status
= NT_STATUS_INVALID_PARAMETER
;
2413 ev
= event_context_init(frame
);
2415 status
= NT_STATUS_NO_MEMORY
;
2419 req
= cli_tcon_andx_send(frame
, ev
, cli
, share
, dev
, pass
, passlen
);
2421 status
= NT_STATUS_NO_MEMORY
;
2425 if (!tevent_req_poll(req
, ev
)) {
2426 status
= map_nt_error_from_unix(errno
);
2430 status
= cli_tcon_andx_recv(req
);
2436 /****************************************************************************
2437 Send a tree disconnect.
2438 ****************************************************************************/
2440 struct cli_tdis_state
{
2441 struct cli_state
*cli
;
2444 static void cli_tdis_done(struct tevent_req
*subreq
);
2446 struct tevent_req
*cli_tdis_send(TALLOC_CTX
*mem_ctx
,
2447 struct tevent_context
*ev
,
2448 struct cli_state
*cli
)
2450 struct tevent_req
*req
, *subreq
;
2451 struct cli_tdis_state
*state
;
2453 req
= tevent_req_create(mem_ctx
, &state
, struct cli_tdis_state
);
2459 subreq
= cli_smb_send(state
, ev
, cli
, SMBtdis
, 0, 0, NULL
, 0, NULL
);
2460 if (tevent_req_nomem(subreq
, req
)) {
2461 return tevent_req_post(req
, ev
);
2463 tevent_req_set_callback(subreq
, cli_tdis_done
, req
);
2467 static void cli_tdis_done(struct tevent_req
*subreq
)
2469 struct tevent_req
*req
= tevent_req_callback_data(
2470 subreq
, struct tevent_req
);
2471 struct cli_tdis_state
*state
= tevent_req_data(
2472 req
, struct cli_tdis_state
);
2475 status
= cli_smb_recv(subreq
, NULL
, NULL
, 0, NULL
, NULL
, NULL
, NULL
);
2476 TALLOC_FREE(subreq
);
2477 if (!NT_STATUS_IS_OK(status
)) {
2478 tevent_req_nterror(req
, status
);
2481 state
->cli
->smb1
.tid
= UINT16_MAX
;
2482 tevent_req_done(req
);
2485 NTSTATUS
cli_tdis_recv(struct tevent_req
*req
)
2487 return tevent_req_simple_recv_ntstatus(req
);
2490 NTSTATUS
cli_tdis(struct cli_state
*cli
)
2492 struct tevent_context
*ev
;
2493 struct tevent_req
*req
;
2494 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2496 if (cli_has_async_calls(cli
)) {
2497 return NT_STATUS_INVALID_PARAMETER
;
2499 ev
= tevent_context_init(talloc_tos());
2503 req
= cli_tdis_send(ev
, ev
, cli
);
2507 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2510 status
= cli_tdis_recv(req
);
2516 /****************************************************************************
2517 Send a negprot command.
2518 ****************************************************************************/
2520 struct cli_negprot_state
{
2521 struct cli_state
*cli
;
2522 enum protocol_types max_protocol
;
2525 static void cli_negprot_done(struct tevent_req
*subreq
);
2527 struct tevent_req
*cli_negprot_send(TALLOC_CTX
*mem_ctx
,
2528 struct event_context
*ev
,
2529 struct cli_state
*cli
,
2530 enum protocol_types max_protocol
)
2532 struct tevent_req
*req
, *subreq
;
2533 struct cli_negprot_state
*state
;
2534 uint8_t *bytes
= NULL
;
2536 enum protocol_types tmp_protocol
;
2538 req
= tevent_req_create(mem_ctx
, &state
, struct cli_negprot_state
);
2543 state
->max_protocol
= max_protocol
;
2545 /* setup the protocol strings */
2546 for (numprots
=0; numprots
< ARRAY_SIZE(prots
); numprots
++) {
2548 if (prots
[numprots
].prot
> state
->max_protocol
) {
2551 bytes
= (uint8_t *)talloc_append_blob(
2552 state
, bytes
, data_blob_const(&c
, sizeof(c
)));
2553 if (tevent_req_nomem(bytes
, req
)) {
2554 return tevent_req_post(req
, ev
);
2556 bytes
= smb_bytes_push_str(bytes
, false,
2557 prots
[numprots
].name
,
2558 strlen(prots
[numprots
].name
)+1,
2560 if (tevent_req_nomem(bytes
, req
)) {
2561 return tevent_req_post(req
, ev
);
2565 tmp_protocol
= cli
->conn
.protocol
;
2566 cli
->conn
.protocol
= state
->max_protocol
;
2567 subreq
= cli_smb_send(state
, ev
, cli
, SMBnegprot
, 0, 0, NULL
,
2568 talloc_get_size(bytes
), bytes
);
2569 cli
->conn
.protocol
= tmp_protocol
;
2570 if (tevent_req_nomem(subreq
, req
)) {
2571 return tevent_req_post(req
, ev
);
2573 tevent_req_set_callback(subreq
, cli_negprot_done
, req
);
2577 static void cli_negprot_done(struct tevent_req
*subreq
)
2579 struct tevent_req
*req
= tevent_req_callback_data(
2580 subreq
, struct tevent_req
);
2581 struct cli_negprot_state
*state
= tevent_req_data(
2582 req
, struct cli_negprot_state
);
2583 struct cli_state
*cli
= state
->cli
;
2592 uint32_t client_capabilities
= cli
->conn
.smb1
.client
.capabilities
;
2593 uint32_t both_capabilities
;
2594 uint32_t server_capabilities
= 0;
2595 uint32_t capabilities
;
2596 uint32_t client_max_xmit
= cli
->conn
.smb1
.client
.max_xmit
;
2597 uint32_t server_max_xmit
= 0;
2599 uint32_t server_max_mux
= 0;
2600 uint16_t server_security_mode
= 0;
2601 uint32_t server_session_key
= 0;
2602 bool server_readbraw
= false;
2603 bool server_writebraw
= false;
2604 bool server_lockread
= false;
2605 bool server_writeunlock
= false;
2606 struct GUID server_guid
= GUID_zero();
2607 DATA_BLOB server_gss_blob
= data_blob_null
;
2608 uint8_t server_challenge
[8];
2609 char *server_workgroup
= NULL
;
2610 char *server_name
= NULL
;
2611 int server_time_zone
= 0;
2612 time_t server_system_time
= 0;
2613 enum protocol_types protocol
;
2615 ZERO_STRUCT(server_challenge
);
2617 status
= cli_smb_recv(subreq
, state
, &inbuf
, 1, &wct
, &vwv
,
2618 &num_bytes
, &bytes
);
2619 TALLOC_FREE(subreq
);
2620 if (!NT_STATUS_IS_OK(status
)) {
2621 tevent_req_nterror(req
, status
);
2625 flags
= CVAL(inbuf
, smb_flg
);
2627 protnum
= SVAL(vwv
, 0);
2629 if ((protnum
>= ARRAY_SIZE(prots
))
2630 || (prots
[protnum
].prot
> state
->max_protocol
)) {
2631 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
2635 protocol
= prots
[protnum
].prot
;
2637 if ((protocol
< PROTOCOL_NT1
) &&
2638 client_is_signing_mandatory(cli
)) {
2639 DEBUG(0,("cli_negprot: SMB signing is mandatory and the selected protocol level doesn't support it.\n"));
2640 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
2644 if (flags
& FLAG_SUPPORT_LOCKREAD
) {
2645 server_lockread
= true;
2646 server_writeunlock
= true;
2649 if (protocol
>= PROTOCOL_NT1
) {
2651 const char *client_signing
= NULL
;
2652 bool server_mandatory
;
2653 bool server_allowed
;
2654 const char *server_signing
= NULL
;
2659 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
2664 server_security_mode
= CVAL(vwv
+ 1, 0);
2665 server_max_mux
= SVAL(vwv
+ 1, 1);
2666 server_max_xmit
= IVAL(vwv
+ 3, 1);
2667 server_session_key
= IVAL(vwv
+ 7, 1);
2668 server_time_zone
= SVALS(vwv
+ 15, 1);
2669 server_time_zone
*= 60;
2670 /* this time arrives in real GMT */
2671 ts
= interpret_long_date(((char *)(vwv
+11))+1);
2672 server_system_time
= ts
.tv_sec
;
2673 server_capabilities
= IVAL(vwv
+ 9, 1);
2675 key_len
= CVAL(vwv
+ 16, 1);
2677 if (server_capabilities
& CAP_RAW_MODE
) {
2678 server_readbraw
= true;
2679 server_writebraw
= true;
2681 if (server_capabilities
& CAP_LOCK_AND_READ
) {
2682 server_lockread
= true;
2685 if (server_capabilities
& CAP_EXTENDED_SECURITY
) {
2686 DATA_BLOB blob1
, blob2
;
2688 if (num_bytes
< 16) {
2689 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
2693 blob1
= data_blob_const(bytes
, 16);
2694 GUID_from_data_blob(&blob1
, &server_guid
);
2696 blob1
= data_blob_const(bytes
+16, num_bytes
-16);
2697 blob2
= data_blob_dup_talloc(state
, blob1
);
2698 if (blob1
.length
> 0 &&
2699 tevent_req_nomem(blob2
.data
, req
)) {
2702 server_gss_blob
= blob2
;
2704 DATA_BLOB blob1
, blob2
;
2707 if (num_bytes
< key_len
) {
2708 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
2712 if (key_len
!= 0 && key_len
!= 8) {
2713 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
2718 memcpy(server_challenge
, bytes
, 8);
2721 blob1
= data_blob_const(bytes
+key_len
, num_bytes
-key_len
);
2722 blob2
= data_blob_const(bytes
+key_len
, num_bytes
-key_len
);
2723 if (blob1
.length
> 0) {
2724 ret
= pull_string_talloc(state
,
2726 SVAL(inbuf
, smb_flg2
),
2734 tevent_req_oom(req
);
2740 blob2
.length
-= ret
;
2741 if (blob2
.length
> 0) {
2742 ret
= pull_string_talloc(state
,
2744 SVAL(inbuf
, smb_flg2
),
2752 tevent_req_oom(req
);
2758 client_signing
= "disabled";
2759 if (client_is_signing_allowed(cli
)) {
2760 client_signing
= "allowed";
2762 if (client_is_signing_mandatory(cli
)) {
2763 client_signing
= "required";
2766 server_signing
= "not supported";
2768 server_allowed
= false;
2769 if (server_security_mode
& NEGOTIATE_SECURITY_SIGNATURES_ENABLED
) {
2770 server_signing
= "supported";
2771 server_allowed
= true;
2774 server_mandatory
= false;
2775 if (server_security_mode
& NEGOTIATE_SECURITY_SIGNATURES_REQUIRED
) {
2776 server_signing
= "required";
2777 server_mandatory
= true;
2780 ok
= cli_set_signing_negotiated(cli
,
2784 DEBUG(1,("cli_negprot: SMB signing is required, "
2785 "but client[%s] and server[%s] mismatch\n",
2786 client_signing
, server_signing
));
2787 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
2791 } else if (protocol
>= PROTOCOL_LANMAN1
) {
2797 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
2801 server_security_mode
= SVAL(vwv
+ 1, 0);
2802 server_max_xmit
= SVAL(vwv
+ 2, 0);
2803 server_max_mux
= SVAL(vwv
+ 3, 0);
2804 server_readbraw
= ((SVAL(vwv
+ 5, 0) & 0x1) != 0);
2805 server_writebraw
= ((SVAL(vwv
+ 5, 0) & 0x2) != 0);
2806 server_session_key
= IVAL(vwv
+ 6, 0);
2807 server_time_zone
= SVALS(vwv
+ 10, 0);
2808 server_time_zone
*= 60;
2809 /* this time is converted to GMT by make_unix_date */
2810 server_system_time
= make_unix_date(
2811 (char *)(vwv
+ 8), server_time_zone
);
2812 key_len
= SVAL(vwv
+ 11, 0);
2814 if (num_bytes
< key_len
) {
2815 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
2819 if (key_len
!= 0 && key_len
!= 8) {
2820 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
2825 memcpy(server_challenge
, bytes
, 8);
2828 blob1
= data_blob_const(bytes
+key_len
, num_bytes
-key_len
);
2829 if (blob1
.length
> 0) {
2830 ret
= pull_string_talloc(state
,
2832 SVAL(inbuf
, smb_flg2
),
2839 tevent_req_oom(req
);
2844 /* the old core protocol */
2845 server_time_zone
= get_time_zone(time(NULL
));
2846 server_system_time
= 0;
2847 server_max_xmit
= 1024;
2849 server_security_mode
= 0;
2852 if (server_max_xmit
< 1024) {
2853 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
2857 if (server_max_mux
< 1) {
2858 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
2863 * Now calculate the negotiated capabilities
2864 * based on the mask for:
2865 * - client only flags
2866 * - flags used in both directions
2867 * - server only flags
2869 both_capabilities
= client_capabilities
& server_capabilities
;
2870 capabilities
= client_capabilities
& SMB_CAP_CLIENT_MASK
;
2871 capabilities
|= both_capabilities
& SMB_CAP_BOTH_MASK
;
2872 capabilities
|= server_capabilities
& SMB_CAP_SERVER_MASK
;
2874 max_xmit
= MIN(client_max_xmit
, server_max_xmit
);
2876 if (server_workgroup
) {
2877 cli
->server_domain
= talloc_strdup(cli
, server_workgroup
);
2878 if (tevent_req_nomem(cli
->server_domain
, req
)) {
2883 cli
->conn
.protocol
= protocol
;
2885 cli
->conn
.smb1
.server
.capabilities
= server_capabilities
;
2886 cli
->conn
.smb1
.capabilities
= capabilities
;
2888 cli
->conn
.smb1
.server
.max_xmit
= server_max_xmit
;
2889 cli
->conn
.smb1
.max_xmit
= max_xmit
;
2891 cli
->conn
.smb1
.server
.max_mux
= server_max_mux
;
2893 cli
->conn
.smb1
.server
.security_mode
= server_security_mode
;
2895 cli
->conn
.smb1
.server
.readbraw
= server_readbraw
;
2896 cli
->conn
.smb1
.server
.writebraw
= server_writebraw
;
2897 cli
->conn
.smb1
.server
.lockread
= server_lockread
;
2898 cli
->conn
.smb1
.server
.writeunlock
= server_writeunlock
;
2900 cli
->conn
.smb1
.server
.session_key
= server_session_key
;
2902 talloc_steal(cli
, server_gss_blob
.data
);
2903 cli
->conn
.smb1
.server
.gss_blob
= server_gss_blob
;
2904 cli
->conn
.smb1
.server
.guid
= server_guid
;
2905 memcpy(cli
->conn
.smb1
.server
.challenge
, server_challenge
, 8);
2906 cli
->conn
.smb1
.server
.workgroup
= talloc_move(cli
, &server_workgroup
);
2907 cli
->conn
.smb1
.server
.name
= talloc_move(cli
, &server_name
);
2909 cli
->conn
.smb1
.server
.time_zone
= server_time_zone
;
2910 cli
->conn
.smb1
.server
.system_time
= server_system_time
;
2912 tevent_req_done(req
);
2915 NTSTATUS
cli_negprot_recv(struct tevent_req
*req
)
2917 return tevent_req_simple_recv_ntstatus(req
);
2920 NTSTATUS
cli_negprot(struct cli_state
*cli
, enum protocol_types max_protocol
)
2922 TALLOC_CTX
*frame
= talloc_stackframe();
2923 struct event_context
*ev
;
2924 struct tevent_req
*req
;
2925 NTSTATUS status
= NT_STATUS_OK
;
2927 if (cli_has_async_calls(cli
)) {
2929 * Can't use sync call while an async call is in flight
2931 status
= NT_STATUS_INVALID_PARAMETER
;
2935 ev
= event_context_init(frame
);
2937 status
= NT_STATUS_NO_MEMORY
;
2941 req
= cli_negprot_send(frame
, ev
, cli
, max_protocol
);
2943 status
= NT_STATUS_NO_MEMORY
;
2947 if (!tevent_req_poll(req
, ev
)) {
2948 status
= map_nt_error_from_unix(errno
);
2952 status
= cli_negprot_recv(req
);
2958 static NTSTATUS
cli_connect_sock(const char *host
, int name_type
,
2959 const struct sockaddr_storage
*pss
,
2960 const char *myname
, uint16_t port
,
2961 int sec_timeout
, int *pfd
, uint16_t *pport
)
2963 TALLOC_CTX
*frame
= talloc_stackframe();
2965 unsigned int i
, num_addrs
;
2966 const char **called_names
;
2967 const char **calling_names
;
2972 prog
= getenv("LIBSMB_PROG");
2974 fd
= sock_exec(prog
);
2976 return map_nt_error_from_unix(errno
);
2982 if ((pss
== NULL
) || is_zero_addr(pss
)) {
2983 struct sockaddr_storage
*addrs
;
2984 status
= resolve_name_list(talloc_tos(), host
, name_type
,
2985 &addrs
, &num_addrs
);
2986 if (!NT_STATUS_IS_OK(status
)) {
2994 called_names
= talloc_array(talloc_tos(), const char *, num_addrs
);
2995 if (called_names
== NULL
) {
2996 status
= NT_STATUS_NO_MEMORY
;
2999 called_types
= talloc_array(talloc_tos(), int, num_addrs
);
3000 if (called_types
== NULL
) {
3001 status
= NT_STATUS_NO_MEMORY
;
3004 calling_names
= talloc_array(talloc_tos(), const char *, num_addrs
);
3005 if (calling_names
== NULL
) {
3006 status
= NT_STATUS_NO_MEMORY
;
3009 for (i
=0; i
<num_addrs
; i
++) {
3010 called_names
[i
] = host
;
3011 called_types
[i
] = name_type
;
3012 calling_names
[i
] = myname
;
3014 status
= smbsock_any_connect(pss
, called_names
, called_types
,
3015 calling_names
, NULL
, num_addrs
, port
,
3016 sec_timeout
, &fd
, NULL
, &port
);
3017 if (!NT_STATUS_IS_OK(status
)) {
3020 set_socket_options(fd
, lp_socket_options());
3024 status
= NT_STATUS_OK
;
3030 NTSTATUS
cli_connect_nb(const char *host
, const struct sockaddr_storage
*dest_ss
,
3031 uint16_t port
, int name_type
, const char *myname
,
3032 int signing_state
, int flags
, struct cli_state
**pcli
)
3034 TALLOC_CTX
*frame
= talloc_stackframe();
3035 struct cli_state
*cli
;
3036 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
3041 desthost
= talloc_strdup(talloc_tos(), host
);
3042 if (desthost
== NULL
) {
3046 p
= strchr(host
, '#');
3048 name_type
= strtol(p
+1, NULL
, 16);
3049 host
= talloc_strndup(talloc_tos(), host
, p
- host
);
3055 status
= cli_connect_sock(host
, name_type
, dest_ss
, myname
, port
,
3057 if (!NT_STATUS_IS_OK(status
)) {
3061 cli
= cli_state_create(NULL
, fd
, desthost
, NULL
, signing_state
, flags
);
3067 status
= NT_STATUS_OK
;
3074 establishes a connection to after the negprot.
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_ss (optional) The the destination IP, NULL for name based lookup
3078 @param port (optional) The destination port (0 for default)
3080 NTSTATUS
cli_start_connection(struct cli_state
**output_cli
,
3081 const char *my_name
,
3082 const char *dest_host
,
3083 const struct sockaddr_storage
*dest_ss
, int port
,
3084 int signing_state
, int flags
)
3087 struct cli_state
*cli
;
3089 nt_status
= cli_connect_nb(dest_host
, dest_ss
, port
, 0x20, my_name
,
3090 signing_state
, flags
, &cli
);
3091 if (!NT_STATUS_IS_OK(nt_status
)) {
3092 DEBUG(10, ("cli_connect_nb failed: %s\n",
3093 nt_errstr(nt_status
)));
3097 nt_status
= cli_negprot(cli
, PROTOCOL_NT1
);
3098 if (!NT_STATUS_IS_OK(nt_status
)) {
3099 DEBUG(1, ("failed negprot: %s\n", nt_errstr(nt_status
)));
3105 return NT_STATUS_OK
;
3110 establishes a connection right up to doing tconX, password specified.
3111 @param output_cli A fully initialised cli structure, non-null only on success
3112 @param dest_host The netbios name of the remote host
3113 @param dest_ip (optional) The the destination IP, NULL for name based lookup
3114 @param port (optional) The destination port (0 for default)
3115 @param service (optional) The share to make the connection to. Should be 'unqualified' in any way.
3116 @param service_type The 'type' of serivice.
3117 @param user Username, unix string
3118 @param domain User's domain
3119 @param password User's password, unencrypted unix string.
3122 NTSTATUS
cli_full_connection(struct cli_state
**output_cli
,
3123 const char *my_name
,
3124 const char *dest_host
,
3125 const struct sockaddr_storage
*dest_ss
, int port
,
3126 const char *service
, const char *service_type
,
3127 const char *user
, const char *domain
,
3128 const char *password
, int flags
,
3132 struct cli_state
*cli
= NULL
;
3133 int pw_len
= password
? strlen(password
)+1 : 0;
3137 if (password
== NULL
) {
3141 nt_status
= cli_start_connection(&cli
, my_name
, dest_host
,
3142 dest_ss
, port
, signing_state
,
3145 if (!NT_STATUS_IS_OK(nt_status
)) {
3149 nt_status
= cli_session_setup(cli
, user
, password
, pw_len
, password
,
3151 if (!NT_STATUS_IS_OK(nt_status
)) {
3153 if (!(flags
& CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK
)) {
3154 DEBUG(1,("failed session setup with %s\n",
3155 nt_errstr(nt_status
)));
3160 nt_status
= cli_session_setup(cli
, "", "", 0, "", 0, domain
);
3161 if (!NT_STATUS_IS_OK(nt_status
)) {
3162 DEBUG(1,("anonymous failed session setup with %s\n",
3163 nt_errstr(nt_status
)));
3170 nt_status
= cli_tcon_andx(cli
, service
, service_type
, password
,
3172 if (!NT_STATUS_IS_OK(nt_status
)) {
3173 DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status
)));
3175 if (NT_STATUS_IS_OK(nt_status
)) {
3176 nt_status
= NT_STATUS_UNSUCCESSFUL
;
3182 nt_status
= cli_init_creds(cli
, user
, domain
, password
);
3183 if (!NT_STATUS_IS_OK(nt_status
)) {
3189 return NT_STATUS_OK
;
3192 /****************************************************************************
3193 Send an old style tcon.
3194 ****************************************************************************/
3195 NTSTATUS
cli_raw_tcon(struct cli_state
*cli
,
3196 const char *service
, const char *pass
, const char *dev
,
3197 uint16
*max_xmit
, uint16
*tid
)
3199 struct tevent_req
*req
;
3204 if (!lp_client_plaintext_auth() && (*pass
)) {
3205 DEBUG(1, ("Server requested plaintext password but 'client "
3206 "plaintext auth' is disabled\n"));
3207 return NT_STATUS_ACCESS_DENIED
;
3210 bytes
= talloc_array(talloc_tos(), uint8_t, 0);
3211 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
3212 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
),
3213 service
, strlen(service
)+1, NULL
);
3214 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
3215 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
),
3216 pass
, strlen(pass
)+1, NULL
);
3217 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
3218 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
),
3219 dev
, strlen(dev
)+1, NULL
);
3221 status
= cli_smb(talloc_tos(), cli
, SMBtcon
, 0, 0, NULL
,
3222 talloc_get_size(bytes
), bytes
, &req
,
3223 2, NULL
, &ret_vwv
, NULL
, NULL
);
3224 if (!NT_STATUS_IS_OK(status
)) {
3228 *max_xmit
= SVAL(ret_vwv
+ 0, 0);
3229 *tid
= SVAL(ret_vwv
+ 1, 0);
3231 return NT_STATUS_OK
;
3234 /* Return a cli_state pointing at the IPC$ share for the given server */
3236 struct cli_state
*get_ipc_connect(char *server
,
3237 struct sockaddr_storage
*server_ss
,
3238 const struct user_auth_info
*user_info
)
3240 struct cli_state
*cli
;
3242 uint32_t flags
= CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK
;
3244 if (user_info
->use_kerberos
) {
3245 flags
|= CLI_FULL_CONNECTION_USE_KERBEROS
;
3248 nt_status
= cli_full_connection(&cli
, NULL
, server
, server_ss
, 0, "IPC$", "IPC",
3249 user_info
->username
? user_info
->username
: "",
3251 user_info
->password
? user_info
->password
: "",
3253 SMB_SIGNING_DEFAULT
);
3255 if (NT_STATUS_IS_OK(nt_status
)) {
3257 } else if (is_ipaddress(server
)) {
3258 /* windows 9* needs a correct NMB name for connections */
3259 fstring remote_name
;
3261 if (name_status_find("*", 0, 0, server_ss
, remote_name
)) {
3262 cli
= get_ipc_connect(remote_name
, server_ss
, user_info
);
3271 * Given the IP address of a master browser on the network, return its
3272 * workgroup and connect to it.
3274 * This function is provided to allow additional processing beyond what
3275 * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
3276 * browsers and obtain each master browsers' list of domains (in case the
3277 * first master browser is recently on the network and has not yet
3278 * synchronized with other master browsers and therefore does not yet have the
3279 * entire network browse list)
3282 struct cli_state
*get_ipc_connect_master_ip(TALLOC_CTX
*ctx
,
3283 struct sockaddr_storage
*mb_ip
,
3284 const struct user_auth_info
*user_info
,
3285 char **pp_workgroup_out
)
3287 char addr
[INET6_ADDRSTRLEN
];
3289 struct cli_state
*cli
;
3290 struct sockaddr_storage server_ss
;
3292 *pp_workgroup_out
= NULL
;
3294 print_sockaddr(addr
, sizeof(addr
), mb_ip
);
3295 DEBUG(99, ("Looking up name of master browser %s\n",
3299 * Do a name status query to find out the name of the master browser.
3300 * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
3301 * master browser will not respond to a wildcard query (or, at least,
3302 * an NT4 server acting as the domain master browser will not).
3304 * We might be able to use ONLY the query on MSBROWSE, but that's not
3305 * yet been tested with all Windows versions, so until it is, leave
3306 * the original wildcard query as the first choice and fall back to
3307 * MSBROWSE if the wildcard query fails.
3309 if (!name_status_find("*", 0, 0x1d, mb_ip
, name
) &&
3310 !name_status_find(MSBROWSE
, 1, 0x1d, mb_ip
, name
)) {
3312 DEBUG(99, ("Could not retrieve name status for %s\n",
3317 if (!find_master_ip(name
, &server_ss
)) {
3318 DEBUG(99, ("Could not find master ip for %s\n", name
));
3322 *pp_workgroup_out
= talloc_strdup(ctx
, name
);
3324 DEBUG(4, ("found master browser %s, %s\n", name
, addr
));
3326 print_sockaddr(addr
, sizeof(addr
), &server_ss
);
3327 cli
= get_ipc_connect(addr
, &server_ss
, user_info
);
3333 * Return the IP address and workgroup of a master browser on the network, and
3337 struct cli_state
*get_ipc_connect_master_ip_bcast(TALLOC_CTX
*ctx
,
3338 const struct user_auth_info
*user_info
,
3339 char **pp_workgroup_out
)
3341 struct sockaddr_storage
*ip_list
;
3342 struct cli_state
*cli
;
3346 *pp_workgroup_out
= NULL
;
3348 DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
3350 /* Go looking for workgroups by broadcasting on the local network */
3352 status
= name_resolve_bcast(MSBROWSE
, 1, talloc_tos(),
3354 if (!NT_STATUS_IS_OK(status
)) {
3355 DEBUG(99, ("No master browsers responded: %s\n",
3356 nt_errstr(status
)));
3360 for (i
= 0; i
< count
; i
++) {
3361 char addr
[INET6_ADDRSTRLEN
];
3362 print_sockaddr(addr
, sizeof(addr
), &ip_list
[i
]);
3363 DEBUG(99, ("Found master browser %s\n", addr
));
3365 cli
= get_ipc_connect_master_ip(ctx
, &ip_list
[i
],
3366 user_info
, pp_workgroup_out
);