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"
36 #include "../libcli/smb/smbXcli_base.h"
39 #define STAR_SMBSERVER "*SMBSERVER"
41 /********************************************************
42 Utility function to ensure we always return at least
43 a valid char * pointer to an empty string for the
44 cli->server_os, cli->server_type and cli->server_domain
46 *******************************************************/
48 static NTSTATUS
smb_bytes_talloc_string(TALLOC_CTX
*mem_ctx
,
55 *destlen
= clistr_pull_talloc(mem_ctx
,
57 SVAL(inbuf
, smb_flg2
),
63 return NT_STATUS_NO_MEMORY
;
67 *dest
= talloc_strdup(mem_ctx
, "");
69 return NT_STATUS_NO_MEMORY
;
76 * Set the user session key for a connection
77 * @param cli The cli structure to add it too
78 * @param session_key The session key used. (A copy of this is taken for the cli struct)
82 static void cli_set_session_key (struct cli_state
*cli
, const DATA_BLOB session_key
)
84 cli
->user_session_key
= data_blob(session_key
.data
, session_key
.length
);
87 /****************************************************************************
88 Do an old lanman2 style session setup.
89 ****************************************************************************/
91 struct cli_session_setup_lanman2_state
{
92 struct cli_state
*cli
;
97 static void cli_session_setup_lanman2_done(struct tevent_req
*subreq
);
99 static struct tevent_req
*cli_session_setup_lanman2_send(
100 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
101 struct cli_state
*cli
, const char *user
,
102 const char *pass
, size_t passlen
,
103 const char *workgroup
)
105 struct tevent_req
*req
, *subreq
;
106 struct cli_session_setup_lanman2_state
*state
;
107 DATA_BLOB lm_response
= data_blob_null
;
111 uint16_t sec_mode
= cli_state_security_mode(cli
);
113 req
= tevent_req_create(mem_ctx
, &state
,
114 struct cli_session_setup_lanman2_state
);
123 * if in share level security then don't send a password now
125 if (!(sec_mode
& NEGOTIATE_SECURITY_USER_LEVEL
)) {
130 && (sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
)
133 * Encrypted mode needed, and non encrypted password
136 lm_response
= data_blob(NULL
, 24);
137 if (tevent_req_nomem(lm_response
.data
, req
)) {
138 return tevent_req_post(req
, ev
);
141 if (!SMBencrypt(pass
, cli_state_server_challenge(cli
),
142 (uint8_t *)lm_response
.data
)) {
143 DEBUG(1, ("Password is > 14 chars in length, and is "
144 "therefore incompatible with Lanman "
145 "authentication\n"));
146 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
147 return tevent_req_post(req
, ev
);
149 } else if ((sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
)
152 * Encrypted mode needed, and encrypted password
155 lm_response
= data_blob(pass
, passlen
);
156 if (tevent_req_nomem(lm_response
.data
, req
)) {
157 return tevent_req_post(req
, ev
);
159 } else if (passlen
> 0) {
161 size_t converted_size
;
163 * Plaintext mode needed, assume plaintext supplied.
165 buf
= talloc_array(talloc_tos(), uint8_t, 0);
166 buf
= smb_bytes_push_str(buf
, cli_ucs2(cli
), pass
, passlen
+1,
168 if (tevent_req_nomem(buf
, req
)) {
169 return tevent_req_post(req
, ev
);
171 lm_response
= data_blob(pass
, passlen
);
173 if (tevent_req_nomem(lm_response
.data
, req
)) {
174 return tevent_req_post(req
, ev
);
178 SCVAL(vwv
+0, 0, 0xff);
181 SSVAL(vwv
+2, 0, CLI_BUFFER_SIZE
);
184 SIVAL(vwv
+5, 0, cli_state_server_session_key(cli
));
185 SSVAL(vwv
+7, 0, lm_response
.length
);
187 bytes
= talloc_array(state
, uint8_t, lm_response
.length
);
188 if (tevent_req_nomem(bytes
, req
)) {
189 return tevent_req_post(req
, ev
);
191 if (lm_response
.length
!= 0) {
192 memcpy(bytes
, lm_response
.data
, lm_response
.length
);
194 data_blob_free(&lm_response
);
196 tmp
= talloc_strdup_upper(talloc_tos(), user
);
197 if (tevent_req_nomem(tmp
, req
)) {
198 return tevent_req_post(req
, ev
);
200 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), tmp
, strlen(tmp
)+1,
204 tmp
= talloc_strdup_upper(talloc_tos(), workgroup
);
205 if (tevent_req_nomem(tmp
, req
)) {
206 return tevent_req_post(req
, ev
);
208 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), tmp
, strlen(tmp
)+1,
210 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), "Unix", 5, NULL
);
211 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), "Samba", 6, NULL
);
213 if (tevent_req_nomem(bytes
, req
)) {
214 return tevent_req_post(req
, ev
);
217 subreq
= cli_smb_send(state
, ev
, cli
, SMBsesssetupX
, 0, 10, vwv
,
218 talloc_get_size(bytes
), bytes
);
219 if (tevent_req_nomem(subreq
, req
)) {
220 return tevent_req_post(req
, ev
);
222 tevent_req_set_callback(subreq
, cli_session_setup_lanman2_done
, req
);
226 static void cli_session_setup_lanman2_done(struct tevent_req
*subreq
)
228 struct tevent_req
*req
= tevent_req_callback_data(
229 subreq
, struct tevent_req
);
230 struct cli_session_setup_lanman2_state
*state
= tevent_req_data(
231 req
, struct cli_session_setup_lanman2_state
);
232 struct cli_state
*cli
= state
->cli
;
243 status
= cli_smb_recv(subreq
, state
, &in
, 3, &wct
, &vwv
,
246 if (!NT_STATUS_IS_OK(status
)) {
247 tevent_req_nterror(req
, status
);
254 cli_state_set_uid(state
->cli
, SVAL(inbuf
, smb_uid
));
255 cli
->is_guestlogin
= ((SVAL(vwv
+2, 0) & 1) != 0);
257 status
= smb_bytes_talloc_string(cli
,
264 if (!NT_STATUS_IS_OK(status
)) {
265 tevent_req_nterror(req
, status
);
270 status
= smb_bytes_talloc_string(cli
,
277 if (!NT_STATUS_IS_OK(status
)) {
278 tevent_req_nterror(req
, status
);
283 status
= smb_bytes_talloc_string(cli
,
290 if (!NT_STATUS_IS_OK(status
)) {
291 tevent_req_nterror(req
, status
);
296 status
= cli_set_username(cli
, state
->user
);
297 if (tevent_req_nterror(req
, status
)) {
300 tevent_req_done(req
);
303 static NTSTATUS
cli_session_setup_lanman2_recv(struct tevent_req
*req
)
305 return tevent_req_simple_recv_ntstatus(req
);
308 static NTSTATUS
cli_session_setup_lanman2(struct cli_state
*cli
, const char *user
,
309 const char *pass
, size_t passlen
,
310 const char *workgroup
)
312 TALLOC_CTX
*frame
= talloc_stackframe();
313 struct event_context
*ev
;
314 struct tevent_req
*req
;
315 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
317 if (cli_has_async_calls(cli
)) {
319 * Can't use sync call while an async call is in flight
321 status
= NT_STATUS_INVALID_PARAMETER
;
324 ev
= event_context_init(frame
);
328 req
= cli_session_setup_lanman2_send(frame
, ev
, cli
, user
, pass
, passlen
,
333 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
336 status
= cli_session_setup_lanman2_recv(req
);
342 /****************************************************************************
343 Work out suitable capabilities to offer the server.
344 ****************************************************************************/
346 static uint32_t cli_session_setup_capabilities(struct cli_state
*cli
,
347 uint32_t sesssetup_capabilities
)
349 uint32_t client_capabilities
= cli_state_capabilities(cli
);
352 * We only send capabilities based on the mask for:
353 * - client only flags
354 * - flags used in both directions
356 * We do not echo the server only flags.
358 client_capabilities
&= (SMB_CAP_BOTH_MASK
| SMB_CAP_CLIENT_MASK
);
361 * Session Setup specific flags CAP_DYNAMIC_REAUTH
362 * and CAP_EXTENDED_SECURITY are passed by the caller.
363 * We need that in order to do guest logins even if
364 * CAP_EXTENDED_SECURITY is negotiated.
366 client_capabilities
&= ~(CAP_DYNAMIC_REAUTH
|CAP_EXTENDED_SECURITY
);
367 sesssetup_capabilities
&= (CAP_DYNAMIC_REAUTH
|CAP_EXTENDED_SECURITY
);
368 client_capabilities
|= sesssetup_capabilities
;
370 return client_capabilities
;
373 /****************************************************************************
374 Do a NT1 guest session setup.
375 ****************************************************************************/
377 struct cli_session_setup_guest_state
{
378 struct cli_state
*cli
;
383 static void cli_session_setup_guest_done(struct tevent_req
*subreq
);
385 struct tevent_req
*cli_session_setup_guest_create(TALLOC_CTX
*mem_ctx
,
386 struct event_context
*ev
,
387 struct cli_state
*cli
,
388 struct tevent_req
**psmbreq
)
390 struct tevent_req
*req
, *subreq
;
391 struct cli_session_setup_guest_state
*state
;
395 req
= tevent_req_create(mem_ctx
, &state
,
396 struct cli_session_setup_guest_state
);
403 SCVAL(vwv
+0, 0, 0xFF);
406 SSVAL(vwv
+2, 0, CLI_BUFFER_SIZE
);
408 SSVAL(vwv
+4, 0, cli_state_get_vc_num(cli
));
409 SIVAL(vwv
+5, 0, cli_state_server_session_key(cli
));
414 SIVAL(vwv
+11, 0, cli_session_setup_capabilities(cli
, 0));
416 bytes
= talloc_array(state
, uint8_t, 0);
418 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), "", 1, /* username */
420 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), "", 1, /* workgroup */
422 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), "Unix", 5, NULL
);
423 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), "Samba", 6, NULL
);
430 state
->bytes
.iov_base
= (void *)bytes
;
431 state
->bytes
.iov_len
= talloc_get_size(bytes
);
433 subreq
= cli_smb_req_create(state
, ev
, cli
, SMBsesssetupX
, 0, 13, vwv
,
435 if (subreq
== NULL
) {
439 tevent_req_set_callback(subreq
, cli_session_setup_guest_done
, req
);
444 struct tevent_req
*cli_session_setup_guest_send(TALLOC_CTX
*mem_ctx
,
445 struct event_context
*ev
,
446 struct cli_state
*cli
)
448 struct tevent_req
*req
, *subreq
;
451 req
= cli_session_setup_guest_create(mem_ctx
, ev
, cli
, &subreq
);
456 status
= cli_smb_req_send(subreq
);
457 if (NT_STATUS_IS_OK(status
)) {
458 tevent_req_nterror(req
, status
);
459 return tevent_req_post(req
, ev
);
464 static void cli_session_setup_guest_done(struct tevent_req
*subreq
)
466 struct tevent_req
*req
= tevent_req_callback_data(
467 subreq
, struct tevent_req
);
468 struct cli_session_setup_guest_state
*state
= tevent_req_data(
469 req
, struct cli_session_setup_guest_state
);
470 struct cli_state
*cli
= state
->cli
;
481 status
= cli_smb_recv(subreq
, state
, &in
, 3, &wct
, &vwv
,
484 if (!NT_STATUS_IS_OK(status
)) {
485 tevent_req_nterror(req
, status
);
492 cli_state_set_uid(state
->cli
, SVAL(inbuf
, smb_uid
));
493 cli
->is_guestlogin
= ((SVAL(vwv
+2, 0) & 1) != 0);
495 status
= smb_bytes_talloc_string(cli
,
502 if (!NT_STATUS_IS_OK(status
)) {
503 tevent_req_nterror(req
, status
);
508 status
= smb_bytes_talloc_string(cli
,
515 if (!NT_STATUS_IS_OK(status
)) {
516 tevent_req_nterror(req
, status
);
521 status
= smb_bytes_talloc_string(cli
,
528 if (!NT_STATUS_IS_OK(status
)) {
529 tevent_req_nterror(req
, status
);
534 status
= cli_set_username(cli
, "");
535 if (!NT_STATUS_IS_OK(status
)) {
536 tevent_req_nterror(req
, status
);
539 tevent_req_done(req
);
542 NTSTATUS
cli_session_setup_guest_recv(struct tevent_req
*req
)
544 return tevent_req_simple_recv_ntstatus(req
);
547 static NTSTATUS
cli_session_setup_guest(struct cli_state
*cli
)
549 TALLOC_CTX
*frame
= talloc_stackframe();
550 struct event_context
*ev
;
551 struct tevent_req
*req
;
552 NTSTATUS status
= NT_STATUS_OK
;
554 if (cli_has_async_calls(cli
)) {
556 * Can't use sync call while an async call is in flight
558 status
= NT_STATUS_INVALID_PARAMETER
;
562 ev
= event_context_init(frame
);
564 status
= NT_STATUS_NO_MEMORY
;
568 req
= cli_session_setup_guest_send(frame
, ev
, cli
);
570 status
= NT_STATUS_NO_MEMORY
;
574 if (!tevent_req_poll(req
, ev
)) {
575 status
= map_nt_error_from_unix(errno
);
579 status
= cli_session_setup_guest_recv(req
);
585 /****************************************************************************
586 Do a NT1 plaintext session setup.
587 ****************************************************************************/
589 struct cli_session_setup_plain_state
{
590 struct cli_state
*cli
;
595 static void cli_session_setup_plain_done(struct tevent_req
*subreq
);
597 static struct tevent_req
*cli_session_setup_plain_send(
598 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
599 struct cli_state
*cli
,
600 const char *user
, const char *pass
, const char *workgroup
)
602 struct tevent_req
*req
, *subreq
;
603 struct cli_session_setup_plain_state
*state
;
609 req
= tevent_req_create(mem_ctx
, &state
,
610 struct cli_session_setup_plain_state
);
618 SCVAL(vwv
+0, 0, 0xff);
621 SSVAL(vwv
+2, 0, CLI_BUFFER_SIZE
);
623 SSVAL(vwv
+4, 0, cli_state_get_vc_num(cli
));
624 SIVAL(vwv
+5, 0, cli_state_server_session_key(cli
));
629 SIVAL(vwv
+11, 0, cli_session_setup_capabilities(cli
, 0));
631 bytes
= talloc_array(state
, uint8_t, 0);
632 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), pass
, strlen(pass
)+1,
634 if (tevent_req_nomem(bytes
, req
)) {
635 return tevent_req_post(req
, ev
);
637 SSVAL(vwv
+ (cli_ucs2(cli
) ? 8 : 7), 0, passlen
);
639 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
),
640 user
, strlen(user
)+1, NULL
);
641 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
),
642 workgroup
, strlen(workgroup
)+1, NULL
);
643 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
),
646 version
= talloc_asprintf(talloc_tos(), "Samba %s",
647 samba_version_string());
648 if (tevent_req_nomem(version
, req
)){
649 return tevent_req_post(req
, ev
);
651 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
),
652 version
, strlen(version
)+1, NULL
);
653 TALLOC_FREE(version
);
655 if (tevent_req_nomem(bytes
, req
)) {
656 return tevent_req_post(req
, ev
);
659 subreq
= cli_smb_send(state
, ev
, cli
, SMBsesssetupX
, 0, 13, vwv
,
660 talloc_get_size(bytes
), bytes
);
661 if (tevent_req_nomem(subreq
, req
)) {
662 return tevent_req_post(req
, ev
);
664 tevent_req_set_callback(subreq
, cli_session_setup_plain_done
, req
);
668 static void cli_session_setup_plain_done(struct tevent_req
*subreq
)
670 struct tevent_req
*req
= tevent_req_callback_data(
671 subreq
, struct tevent_req
);
672 struct cli_session_setup_plain_state
*state
= tevent_req_data(
673 req
, struct cli_session_setup_plain_state
);
674 struct cli_state
*cli
= state
->cli
;
685 status
= cli_smb_recv(subreq
, state
, &in
, 3, &wct
, &vwv
,
688 if (tevent_req_nterror(req
, status
)) {
695 cli_state_set_uid(state
->cli
, SVAL(inbuf
, smb_uid
));
696 cli
->is_guestlogin
= ((SVAL(vwv
+2, 0) & 1) != 0);
698 status
= smb_bytes_talloc_string(cli
,
705 if (!NT_STATUS_IS_OK(status
)) {
706 tevent_req_nterror(req
, status
);
711 status
= smb_bytes_talloc_string(cli
,
718 if (!NT_STATUS_IS_OK(status
)) {
719 tevent_req_nterror(req
, status
);
724 status
= smb_bytes_talloc_string(cli
,
731 if (!NT_STATUS_IS_OK(status
)) {
732 tevent_req_nterror(req
, status
);
737 status
= cli_set_username(cli
, state
->user
);
738 if (tevent_req_nterror(req
, status
)) {
742 tevent_req_done(req
);
745 static NTSTATUS
cli_session_setup_plain_recv(struct tevent_req
*req
)
747 return tevent_req_simple_recv_ntstatus(req
);
750 static NTSTATUS
cli_session_setup_plain(struct cli_state
*cli
,
751 const char *user
, const char *pass
,
752 const char *workgroup
)
754 TALLOC_CTX
*frame
= talloc_stackframe();
755 struct event_context
*ev
;
756 struct tevent_req
*req
;
757 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
759 if (cli_has_async_calls(cli
)) {
761 * Can't use sync call while an async call is in flight
763 status
= NT_STATUS_INVALID_PARAMETER
;
766 ev
= event_context_init(frame
);
770 req
= cli_session_setup_plain_send(frame
, ev
, cli
, user
, pass
,
775 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
778 status
= cli_session_setup_plain_recv(req
);
784 /****************************************************************************
785 do a NT1 NTLM/LM encrypted session setup - for when extended security
787 @param cli client state to create do session setup on
789 @param pass *either* cleartext password (passlen !=24) or LM response.
790 @param ntpass NT response, implies ntpasslen >=24, implies pass is not clear
791 @param workgroup The user's domain.
792 ****************************************************************************/
794 struct cli_session_setup_nt1_state
{
795 struct cli_state
*cli
;
798 DATA_BLOB session_key
;
802 static void cli_session_setup_nt1_done(struct tevent_req
*subreq
);
804 static struct tevent_req
*cli_session_setup_nt1_send(
805 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
806 struct cli_state
*cli
, const char *user
,
807 const char *pass
, size_t passlen
,
808 const char *ntpass
, size_t ntpasslen
,
809 const char *workgroup
)
811 struct tevent_req
*req
, *subreq
;
812 struct cli_session_setup_nt1_state
*state
;
813 DATA_BLOB lm_response
= data_blob_null
;
814 DATA_BLOB nt_response
= data_blob_null
;
815 DATA_BLOB session_key
= data_blob_null
;
818 char *workgroup_upper
;
820 req
= tevent_req_create(mem_ctx
, &state
,
821 struct cli_session_setup_nt1_state
);
830 /* do nothing - guest login */
831 } else if (passlen
!= 24) {
832 if (lp_client_ntlmv2_auth()) {
833 DATA_BLOB server_chal
;
834 DATA_BLOB names_blob
;
837 data_blob_const(cli_state_server_challenge(cli
),
841 * note that the 'workgroup' here is a best
842 * guess - we don't know the server's domain
843 * at this point. Windows clients also don't
846 names_blob
= NTLMv2_generate_names_blob(
847 NULL
, NULL
, workgroup
);
849 if (tevent_req_nomem(names_blob
.data
, req
)) {
850 return tevent_req_post(req
, ev
);
853 if (!SMBNTLMv2encrypt(NULL
, user
, workgroup
, pass
,
854 &server_chal
, &names_blob
,
855 &lm_response
, &nt_response
,
856 NULL
, &session_key
)) {
857 data_blob_free(&names_blob
);
859 req
, NT_STATUS_ACCESS_DENIED
);
860 return tevent_req_post(req
, ev
);
862 data_blob_free(&names_blob
);
866 E_md4hash(pass
, nt_hash
);
869 nt_response
= data_blob_null
;
871 nt_response
= data_blob(NULL
, 24);
872 if (tevent_req_nomem(nt_response
.data
, req
)) {
873 return tevent_req_post(req
, ev
);
876 SMBNTencrypt(pass
, cli_state_server_challenge(cli
),
879 /* non encrypted password supplied. Ignore ntpass. */
880 if (lp_client_lanman_auth()) {
882 lm_response
= data_blob(NULL
, 24);
883 if (tevent_req_nomem(lm_response
.data
, req
)) {
884 return tevent_req_post(req
, ev
);
887 if (!SMBencrypt(pass
,
888 cli_state_server_challenge(cli
),
891 * Oops, the LM response is
892 * invalid, just put the NT
893 * response there instead
895 data_blob_free(&lm_response
);
896 lm_response
= data_blob(
902 * LM disabled, place NT# in LM field
905 lm_response
= data_blob(
906 nt_response
.data
, nt_response
.length
);
909 if (tevent_req_nomem(lm_response
.data
, req
)) {
910 return tevent_req_post(req
, ev
);
913 session_key
= data_blob(NULL
, 16);
914 if (tevent_req_nomem(session_key
.data
, req
)) {
915 return tevent_req_post(req
, ev
);
918 E_deshash(pass
, session_key
.data
);
919 memset(&session_key
.data
[8], '\0', 8);
921 SMBsesskeygen_ntv1(nt_hash
, session_key
.data
);
925 /* pre-encrypted password supplied. Only used for
926 security=server, can't do
927 signing because we don't have original key */
929 lm_response
= data_blob(pass
, passlen
);
930 if (tevent_req_nomem(lm_response
.data
, req
)) {
931 return tevent_req_post(req
, ev
);
934 nt_response
= data_blob(ntpass
, ntpasslen
);
935 if (tevent_req_nomem(nt_response
.data
, req
)) {
936 return tevent_req_post(req
, ev
);
941 state
->response
= data_blob_talloc(
942 state
, lm_response
.data
, lm_response
.length
);
944 state
->response
= data_blob_talloc(
945 state
, nt_response
.data
, nt_response
.length
);
947 if (tevent_req_nomem(state
->response
.data
, req
)) {
948 return tevent_req_post(req
, ev
);
951 if (session_key
.data
) {
952 state
->session_key
= data_blob_talloc(
953 state
, session_key
.data
, session_key
.length
);
954 if (tevent_req_nomem(state
->session_key
.data
, req
)) {
955 return tevent_req_post(req
, ev
);
958 data_blob_free(&session_key
);
960 SCVAL(vwv
+0, 0, 0xff);
963 SSVAL(vwv
+2, 0, CLI_BUFFER_SIZE
);
965 SSVAL(vwv
+4, 0, cli_state_get_vc_num(cli
));
966 SIVAL(vwv
+5, 0, cli_state_server_session_key(cli
));
967 SSVAL(vwv
+7, 0, lm_response
.length
);
968 SSVAL(vwv
+8, 0, nt_response
.length
);
971 SIVAL(vwv
+11, 0, cli_session_setup_capabilities(cli
, 0));
973 bytes
= talloc_array(state
, uint8_t,
974 lm_response
.length
+ nt_response
.length
);
975 if (tevent_req_nomem(bytes
, req
)) {
976 return tevent_req_post(req
, ev
);
978 if (lm_response
.length
!= 0) {
979 memcpy(bytes
, lm_response
.data
, lm_response
.length
);
981 if (nt_response
.length
!= 0) {
982 memcpy(bytes
+ lm_response
.length
,
983 nt_response
.data
, nt_response
.length
);
985 data_blob_free(&lm_response
);
986 data_blob_free(&nt_response
);
988 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
),
989 user
, strlen(user
)+1, NULL
);
992 * Upper case here might help some NTLMv2 implementations
994 workgroup_upper
= talloc_strdup_upper(talloc_tos(), workgroup
);
995 if (tevent_req_nomem(workgroup_upper
, req
)) {
996 return tevent_req_post(req
, ev
);
998 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
),
999 workgroup_upper
, strlen(workgroup_upper
)+1,
1001 TALLOC_FREE(workgroup_upper
);
1003 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), "Unix", 5, NULL
);
1004 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), "Samba", 6, NULL
);
1005 if (tevent_req_nomem(bytes
, req
)) {
1006 return tevent_req_post(req
, ev
);
1009 subreq
= cli_smb_send(state
, ev
, cli
, SMBsesssetupX
, 0, 13, vwv
,
1010 talloc_get_size(bytes
), bytes
);
1011 if (tevent_req_nomem(subreq
, req
)) {
1012 return tevent_req_post(req
, ev
);
1014 tevent_req_set_callback(subreq
, cli_session_setup_nt1_done
, req
);
1018 static void cli_session_setup_nt1_done(struct tevent_req
*subreq
)
1020 struct tevent_req
*req
= tevent_req_callback_data(
1021 subreq
, struct tevent_req
);
1022 struct cli_session_setup_nt1_state
*state
= tevent_req_data(
1023 req
, struct cli_session_setup_nt1_state
);
1024 struct cli_state
*cli
= state
->cli
;
1035 status
= cli_smb_recv(subreq
, state
, &in
, 3, &wct
, &vwv
,
1036 &num_bytes
, &bytes
);
1037 TALLOC_FREE(subreq
);
1038 if (!NT_STATUS_IS_OK(status
)) {
1039 tevent_req_nterror(req
, status
);
1046 cli_state_set_uid(state
->cli
, SVAL(inbuf
, smb_uid
));
1047 cli
->is_guestlogin
= ((SVAL(vwv
+2, 0) & 1) != 0);
1049 status
= smb_bytes_talloc_string(cli
,
1055 if (!NT_STATUS_IS_OK(status
)) {
1056 tevent_req_nterror(req
, status
);
1061 status
= smb_bytes_talloc_string(cli
,
1067 if (!NT_STATUS_IS_OK(status
)) {
1068 tevent_req_nterror(req
, status
);
1073 status
= smb_bytes_talloc_string(cli
,
1075 &cli
->server_domain
,
1079 if (!NT_STATUS_IS_OK(status
)) {
1080 tevent_req_nterror(req
, status
);
1085 status
= cli_set_username(cli
, state
->user
);
1086 if (tevent_req_nterror(req
, status
)) {
1089 if (cli_simple_set_signing(cli
, state
->session_key
, state
->response
)
1090 && !cli_check_sign_mac(cli
, (char *)in
, 1)) {
1091 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1094 if (state
->session_key
.data
) {
1095 /* Have plaintext orginal */
1096 cli_set_session_key(cli
, state
->session_key
);
1098 tevent_req_done(req
);
1101 static NTSTATUS
cli_session_setup_nt1_recv(struct tevent_req
*req
)
1103 return tevent_req_simple_recv_ntstatus(req
);
1106 static NTSTATUS
cli_session_setup_nt1(struct cli_state
*cli
, const char *user
,
1107 const char *pass
, size_t passlen
,
1108 const char *ntpass
, size_t ntpasslen
,
1109 const char *workgroup
)
1111 TALLOC_CTX
*frame
= talloc_stackframe();
1112 struct event_context
*ev
;
1113 struct tevent_req
*req
;
1114 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
1116 if (cli_has_async_calls(cli
)) {
1118 * Can't use sync call while an async call is in flight
1120 status
= NT_STATUS_INVALID_PARAMETER
;
1123 ev
= event_context_init(frame
);
1127 req
= cli_session_setup_nt1_send(frame
, ev
, cli
, user
, pass
, passlen
,
1128 ntpass
, ntpasslen
, workgroup
);
1132 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
1135 status
= cli_session_setup_nt1_recv(req
);
1141 /* The following is calculated from :
1143 * (smb_wcnt * 2) = 24 (smb_wcnt == 12 in cli_session_setup_blob_send() )
1144 * (strlen("Unix") + 1 + strlen("Samba") + 1) * 2 = 22 (unicode strings at
1148 #define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22)
1150 struct cli_sesssetup_blob_state
{
1151 struct tevent_context
*ev
;
1152 struct cli_state
*cli
;
1154 uint16_t max_blob_size
;
1158 DATA_BLOB smb2_blob
;
1159 struct iovec
*recv_iov
;
1166 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state
*state
,
1167 struct tevent_req
**psubreq
);
1168 static void cli_sesssetup_blob_done(struct tevent_req
*subreq
);
1170 static struct tevent_req
*cli_sesssetup_blob_send(TALLOC_CTX
*mem_ctx
,
1171 struct tevent_context
*ev
,
1172 struct cli_state
*cli
,
1175 struct tevent_req
*req
, *subreq
;
1176 struct cli_sesssetup_blob_state
*state
;
1177 uint32_t usable_space
;
1179 req
= tevent_req_create(mem_ctx
, &state
,
1180 struct cli_sesssetup_blob_state
);
1188 if (cli_state_protocol(cli
) >= PROTOCOL_SMB2_02
) {
1189 usable_space
= UINT16_MAX
;
1191 usable_space
= cli_state_available_size(cli
,
1192 BASE_SESSSETUP_BLOB_PACKET_SIZE
);
1195 if (usable_space
== 0) {
1196 DEBUG(1, ("cli_session_setup_blob: cli->max_xmit too small "
1197 "(not possible to send %u bytes)\n",
1198 BASE_SESSSETUP_BLOB_PACKET_SIZE
+ 1));
1199 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1200 return tevent_req_post(req
, ev
);
1202 state
->max_blob_size
= MIN(usable_space
, 0xFFFF);
1204 if (!cli_sesssetup_blob_next(state
, &subreq
)) {
1205 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
1206 return tevent_req_post(req
, ev
);
1208 tevent_req_set_callback(subreq
, cli_sesssetup_blob_done
, req
);
1212 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state
*state
,
1213 struct tevent_req
**psubreq
)
1215 struct tevent_req
*subreq
;
1218 thistime
= MIN(state
->blob
.length
, state
->max_blob_size
);
1220 if (cli_state_protocol(state
->cli
) >= PROTOCOL_SMB2_02
) {
1222 state
->smb2_blob
.data
= state
->blob
.data
;
1223 state
->smb2_blob
.length
= thistime
;
1225 state
->blob
.data
+= thistime
;
1226 state
->blob
.length
-= thistime
;
1228 subreq
= smb2cli_session_setup_send(state
, state
->ev
,
1230 state
->cli
->timeout
,
1231 state
->cli
->smb2
.session
,
1233 SMB2_CAP_DFS
, /* in_capabilities */
1235 NULL
, /* in_previous_session */
1237 if (subreq
== NULL
) {
1244 SCVAL(state
->vwv
+0, 0, 0xFF);
1245 SCVAL(state
->vwv
+0, 1, 0);
1246 SSVAL(state
->vwv
+1, 0, 0);
1247 SSVAL(state
->vwv
+2, 0, CLI_BUFFER_SIZE
);
1248 SSVAL(state
->vwv
+3, 0, 2);
1249 SSVAL(state
->vwv
+4, 0, 1);
1250 SIVAL(state
->vwv
+5, 0, 0);
1252 SSVAL(state
->vwv
+7, 0, thistime
);
1254 SSVAL(state
->vwv
+8, 0, 0);
1255 SSVAL(state
->vwv
+9, 0, 0);
1256 SIVAL(state
->vwv
+10, 0,
1257 cli_session_setup_capabilities(state
->cli
, CAP_EXTENDED_SECURITY
));
1259 state
->buf
= (uint8_t *)talloc_memdup(state
, state
->blob
.data
,
1261 if (state
->buf
== NULL
) {
1264 state
->blob
.data
+= thistime
;
1265 state
->blob
.length
-= thistime
;
1267 state
->buf
= smb_bytes_push_str(state
->buf
, cli_ucs2(state
->cli
),
1269 state
->buf
= smb_bytes_push_str(state
->buf
, cli_ucs2(state
->cli
),
1271 if (state
->buf
== NULL
) {
1274 subreq
= cli_smb_send(state
, state
->ev
, state
->cli
, SMBsesssetupX
, 0,
1276 talloc_get_size(state
->buf
), state
->buf
);
1277 if (subreq
== NULL
) {
1284 static void cli_sesssetup_blob_done(struct tevent_req
*subreq
)
1286 struct tevent_req
*req
= tevent_req_callback_data(
1287 subreq
, struct tevent_req
);
1288 struct cli_sesssetup_blob_state
*state
= tevent_req_data(
1289 req
, struct cli_sesssetup_blob_state
);
1290 struct cli_state
*cli
= state
->cli
;
1297 uint16_t blob_length
;
1301 if (cli_state_protocol(state
->cli
) >= PROTOCOL_SMB2_02
) {
1302 status
= smb2cli_session_setup_recv(subreq
, state
,
1306 status
= cli_smb_recv(subreq
, state
, &inbuf
, 4, &wct
, &vwv
,
1307 &num_bytes
, &bytes
);
1308 TALLOC_FREE(state
->buf
);
1310 TALLOC_FREE(subreq
);
1311 if (!NT_STATUS_IS_OK(status
)
1312 && !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1313 tevent_req_nterror(req
, status
);
1317 state
->status
= status
;
1319 if (cli_state_protocol(state
->cli
) >= PROTOCOL_SMB2_02
) {
1323 state
->inbuf
= (char *)inbuf
;
1324 cli_state_set_uid(state
->cli
, SVAL(inbuf
, smb_uid
));
1325 cli
->is_guestlogin
= ((SVAL(vwv
+2, 0) & 1) != 0);
1327 blob_length
= SVAL(vwv
+3, 0);
1328 if (blob_length
> num_bytes
) {
1329 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
1332 state
->ret_blob
= data_blob_const(bytes
, blob_length
);
1334 p
= bytes
+ blob_length
;
1336 status
= smb_bytes_talloc_string(cli
,
1343 if (!NT_STATUS_IS_OK(status
)) {
1344 tevent_req_nterror(req
, status
);
1349 status
= smb_bytes_talloc_string(cli
,
1356 if (!NT_STATUS_IS_OK(status
)) {
1357 tevent_req_nterror(req
, status
);
1362 status
= smb_bytes_talloc_string(cli
,
1364 &cli
->server_domain
,
1369 if (!NT_STATUS_IS_OK(status
)) {
1370 tevent_req_nterror(req
, status
);
1376 if (state
->blob
.length
!= 0) {
1380 if (!cli_sesssetup_blob_next(state
, &subreq
)) {
1381 tevent_req_oom(req
);
1384 tevent_req_set_callback(subreq
, cli_sesssetup_blob_done
, req
);
1387 tevent_req_done(req
);
1390 static NTSTATUS
cli_sesssetup_blob_recv(struct tevent_req
*req
,
1391 TALLOC_CTX
*mem_ctx
,
1394 struct iovec
**precv_iov
)
1396 struct cli_sesssetup_blob_state
*state
= tevent_req_data(
1397 req
, struct cli_sesssetup_blob_state
);
1400 struct iovec
*recv_iov
;
1402 if (tevent_req_is_nterror(req
, &status
)) {
1403 TALLOC_FREE(state
->cli
->smb2
.session
);
1404 cli_state_set_uid(state
->cli
, UID_FIELD_INVALID
);
1408 inbuf
= talloc_move(mem_ctx
, &state
->inbuf
);
1409 recv_iov
= talloc_move(mem_ctx
, &state
->recv_iov
);
1410 if (pblob
!= NULL
) {
1411 *pblob
= state
->ret_blob
;
1413 if (pinbuf
!= NULL
) {
1416 if (precv_iov
!= NULL
) {
1417 *precv_iov
= recv_iov
;
1419 /* could be NT_STATUS_MORE_PROCESSING_REQUIRED */
1420 return state
->status
;
1425 /****************************************************************************
1426 Use in-memory credentials cache
1427 ****************************************************************************/
1429 static void use_in_memory_ccache(void) {
1430 setenv(KRB5_ENV_CCNAME
, "MEMORY:cliconnect", 1);
1433 /****************************************************************************
1434 Do a spnego/kerberos encrypted session setup.
1435 ****************************************************************************/
1437 struct cli_session_setup_kerberos_state
{
1438 struct cli_state
*cli
;
1439 DATA_BLOB negTokenTarg
;
1440 DATA_BLOB session_key_krb5
;
1441 ADS_STATUS ads_status
;
1444 static void cli_session_setup_kerberos_done(struct tevent_req
*subreq
);
1446 static struct tevent_req
*cli_session_setup_kerberos_send(
1447 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
1448 const char *principal
)
1450 struct tevent_req
*req
, *subreq
;
1451 struct cli_session_setup_kerberos_state
*state
;
1454 DEBUG(2,("Doing kerberos session setup\n"));
1456 req
= tevent_req_create(mem_ctx
, &state
,
1457 struct cli_session_setup_kerberos_state
);
1462 state
->ads_status
= ADS_SUCCESS
;
1465 * Ok, this is cheating: spnego_gen_krb5_negTokenInit can block if
1466 * we have to acquire a ticket. To be fixed later :-)
1468 rc
= spnego_gen_krb5_negTokenInit(state
, principal
, 0, &state
->negTokenTarg
,
1469 &state
->session_key_krb5
, 0, NULL
);
1471 DEBUG(1, ("cli_session_setup_kerberos: "
1472 "spnego_gen_krb5_negTokenInit failed: %s\n",
1473 error_message(rc
)));
1474 state
->ads_status
= ADS_ERROR_KRB5(rc
);
1475 tevent_req_nterror(req
, NT_STATUS_UNSUCCESSFUL
);
1476 return tevent_req_post(req
, ev
);
1480 file_save("negTokenTarg.dat", state
->negTokenTarg
.data
,
1481 state
->negTokenTarg
.length
);
1484 if (cli_state_protocol(cli
) >= PROTOCOL_SMB2_02
) {
1485 state
->cli
->smb2
.session
= smbXcli_session_create(cli
,
1487 if (tevent_req_nomem(state
->cli
->smb2
.session
, req
)) {
1488 return tevent_req_post(req
, ev
);
1492 subreq
= cli_sesssetup_blob_send(state
, ev
, cli
, state
->negTokenTarg
);
1493 if (tevent_req_nomem(subreq
, req
)) {
1494 return tevent_req_post(req
, ev
);
1496 tevent_req_set_callback(subreq
, cli_session_setup_kerberos_done
, req
);
1500 static void cli_session_setup_kerberos_done(struct tevent_req
*subreq
)
1502 struct tevent_req
*req
= tevent_req_callback_data(
1503 subreq
, struct tevent_req
);
1504 struct cli_session_setup_kerberos_state
*state
= tevent_req_data(
1505 req
, struct cli_session_setup_kerberos_state
);
1507 struct iovec
*recv_iov
= NULL
;
1510 status
= cli_sesssetup_blob_recv(subreq
, state
,
1511 NULL
, &inbuf
, &recv_iov
);
1512 TALLOC_FREE(subreq
);
1513 if (!NT_STATUS_IS_OK(status
)) {
1514 tevent_req_nterror(req
, status
);
1518 cli_set_session_key(state
->cli
, state
->session_key_krb5
);
1520 if (cli_state_protocol(state
->cli
) >= PROTOCOL_SMB2_02
) {
1521 struct smbXcli_session
*session
= state
->cli
->smb2
.session
;
1522 status
= smb2cli_session_update_session_key(session
,
1523 state
->session_key_krb5
,
1525 if (tevent_req_nterror(req
, status
)) {
1529 if (cli_simple_set_signing(state
->cli
, state
->session_key_krb5
,
1531 && !cli_check_sign_mac(state
->cli
, inbuf
, 1)) {
1532 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1537 tevent_req_done(req
);
1540 static ADS_STATUS
cli_session_setup_kerberos_recv(struct tevent_req
*req
)
1542 struct cli_session_setup_kerberos_state
*state
= tevent_req_data(
1543 req
, struct cli_session_setup_kerberos_state
);
1546 if (tevent_req_is_nterror(req
, &status
)) {
1547 return ADS_ERROR_NT(status
);
1549 return state
->ads_status
;
1552 static ADS_STATUS
cli_session_setup_kerberos(struct cli_state
*cli
,
1553 const char *principal
)
1555 struct tevent_context
*ev
;
1556 struct tevent_req
*req
;
1557 ADS_STATUS status
= ADS_ERROR_NT(NT_STATUS_NO_MEMORY
);
1559 if (cli_has_async_calls(cli
)) {
1560 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
1562 ev
= tevent_context_init(talloc_tos());
1566 req
= cli_session_setup_kerberos_send(ev
, ev
, cli
, principal
);
1570 if (!tevent_req_poll(req
, ev
)) {
1571 status
= ADS_ERROR_SYSTEM(errno
);
1574 status
= cli_session_setup_kerberos_recv(req
);
1579 #endif /* HAVE_KRB5 */
1581 /****************************************************************************
1582 Do a spnego/NTLMSSP encrypted session setup.
1583 ****************************************************************************/
1585 struct cli_session_setup_ntlmssp_state
{
1586 struct tevent_context
*ev
;
1587 struct cli_state
*cli
;
1588 struct ntlmssp_state
*ntlmssp_state
;
1593 static int cli_session_setup_ntlmssp_state_destructor(
1594 struct cli_session_setup_ntlmssp_state
*state
)
1596 if (state
->ntlmssp_state
!= NULL
) {
1597 TALLOC_FREE(state
->ntlmssp_state
);
1602 static void cli_session_setup_ntlmssp_done(struct tevent_req
*req
);
1604 static struct tevent_req
*cli_session_setup_ntlmssp_send(
1605 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
1606 const char *user
, const char *pass
, const char *domain
)
1608 struct tevent_req
*req
, *subreq
;
1609 struct cli_session_setup_ntlmssp_state
*state
;
1612 const char *OIDs_ntlm
[] = {OID_NTLMSSP
, NULL
};
1614 req
= tevent_req_create(mem_ctx
, &state
,
1615 struct cli_session_setup_ntlmssp_state
);
1623 state
->ntlmssp_state
= NULL
;
1624 talloc_set_destructor(
1625 state
, cli_session_setup_ntlmssp_state_destructor
);
1627 status
= ntlmssp_client_start(state
,
1630 lp_client_ntlmv2_auth(),
1631 &state
->ntlmssp_state
);
1632 if (!NT_STATUS_IS_OK(status
)) {
1635 ntlmssp_want_feature(state
->ntlmssp_state
,
1636 NTLMSSP_FEATURE_SESSION_KEY
);
1637 if (cli
->use_ccache
) {
1638 ntlmssp_want_feature(state
->ntlmssp_state
,
1639 NTLMSSP_FEATURE_CCACHE
);
1641 status
= ntlmssp_set_username(state
->ntlmssp_state
, user
);
1642 if (!NT_STATUS_IS_OK(status
)) {
1645 status
= ntlmssp_set_domain(state
->ntlmssp_state
, domain
);
1646 if (!NT_STATUS_IS_OK(status
)) {
1649 status
= ntlmssp_set_password(state
->ntlmssp_state
, pass
);
1650 if (!NT_STATUS_IS_OK(status
)) {
1653 status
= ntlmssp_update(state
->ntlmssp_state
, data_blob_null
,
1655 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1659 state
->blob_out
= spnego_gen_negTokenInit(state
, OIDs_ntlm
, &blob_out
, NULL
);
1660 data_blob_free(&blob_out
);
1662 if (cli_state_protocol(cli
) >= PROTOCOL_SMB2_02
) {
1663 state
->cli
->smb2
.session
= smbXcli_session_create(cli
,
1665 if (tevent_req_nomem(state
->cli
->smb2
.session
, req
)) {
1666 return tevent_req_post(req
, ev
);
1670 subreq
= cli_sesssetup_blob_send(state
, ev
, cli
, state
->blob_out
);
1671 if (tevent_req_nomem(subreq
, req
)) {
1672 return tevent_req_post(req
, ev
);
1674 tevent_req_set_callback(subreq
, cli_session_setup_ntlmssp_done
, req
);
1677 tevent_req_nterror(req
, status
);
1678 return tevent_req_post(req
, ev
);
1681 static void cli_session_setup_ntlmssp_done(struct tevent_req
*subreq
)
1683 struct tevent_req
*req
= tevent_req_callback_data(
1684 subreq
, struct tevent_req
);
1685 struct cli_session_setup_ntlmssp_state
*state
= tevent_req_data(
1686 req
, struct cli_session_setup_ntlmssp_state
);
1687 DATA_BLOB blob_in
, msg_in
, blob_out
;
1689 struct iovec
*recv_iov
= NULL
;
1693 status
= cli_sesssetup_blob_recv(subreq
, talloc_tos(), &blob_in
,
1695 TALLOC_FREE(subreq
);
1696 data_blob_free(&state
->blob_out
);
1698 if (NT_STATUS_IS_OK(status
)) {
1699 if (state
->cli
->server_domain
[0] == '\0') {
1700 TALLOC_FREE(state
->cli
->server_domain
);
1701 state
->cli
->server_domain
= talloc_strdup(state
->cli
,
1702 state
->ntlmssp_state
->server
.netbios_domain
);
1703 if (state
->cli
->server_domain
== NULL
) {
1704 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
1708 cli_set_session_key(
1709 state
->cli
, state
->ntlmssp_state
->session_key
);
1711 if (cli_state_protocol(state
->cli
) >= PROTOCOL_SMB2_02
) {
1712 struct smbXcli_session
*session
= state
->cli
->smb2
.session
;
1713 status
= smb2cli_session_update_session_key(session
,
1714 state
->ntlmssp_state
->session_key
,
1716 if (tevent_req_nterror(req
, status
)) {
1720 if (cli_simple_set_signing(
1721 state
->cli
, state
->ntlmssp_state
->session_key
,
1723 && !cli_check_sign_mac(state
->cli
, inbuf
, 1)) {
1724 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1728 TALLOC_FREE(state
->ntlmssp_state
);
1729 tevent_req_done(req
);
1732 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1733 tevent_req_nterror(req
, status
);
1737 if (blob_in
.length
== 0) {
1738 tevent_req_nterror(req
, NT_STATUS_UNSUCCESSFUL
);
1742 if ((state
->turn
== 1)
1743 && NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1744 DATA_BLOB tmp_blob
= data_blob_null
;
1745 /* the server might give us back two challenges */
1746 parse_ret
= spnego_parse_challenge(state
, blob_in
, &msg_in
,
1748 data_blob_free(&tmp_blob
);
1750 parse_ret
= spnego_parse_auth_response(state
, blob_in
, status
,
1751 OID_NTLMSSP
, &msg_in
);
1756 DEBUG(3,("Failed to parse auth response\n"));
1757 if (NT_STATUS_IS_OK(status
)
1758 || NT_STATUS_EQUAL(status
,
1759 NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1761 req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
1766 status
= ntlmssp_update(state
->ntlmssp_state
, msg_in
, &blob_out
);
1768 if (!NT_STATUS_IS_OK(status
)
1769 && !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1770 TALLOC_FREE(state
->ntlmssp_state
);
1771 tevent_req_nterror(req
, status
);
1775 state
->blob_out
= spnego_gen_auth(state
, blob_out
);
1776 if (tevent_req_nomem(state
->blob_out
.data
, req
)) {
1780 subreq
= cli_sesssetup_blob_send(state
, state
->ev
, state
->cli
,
1782 if (tevent_req_nomem(subreq
, req
)) {
1785 tevent_req_set_callback(subreq
, cli_session_setup_ntlmssp_done
, req
);
1788 static NTSTATUS
cli_session_setup_ntlmssp_recv(struct tevent_req
*req
)
1790 struct cli_session_setup_ntlmssp_state
*state
= tevent_req_data(
1791 req
, struct cli_session_setup_ntlmssp_state
);
1794 if (tevent_req_is_nterror(req
, &status
)) {
1795 cli_state_set_uid(state
->cli
, UID_FIELD_INVALID
);
1798 return NT_STATUS_OK
;
1801 static NTSTATUS
cli_session_setup_ntlmssp(struct cli_state
*cli
,
1806 struct tevent_context
*ev
;
1807 struct tevent_req
*req
;
1808 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
1810 if (cli_has_async_calls(cli
)) {
1811 return NT_STATUS_INVALID_PARAMETER
;
1813 ev
= tevent_context_init(talloc_tos());
1817 req
= cli_session_setup_ntlmssp_send(ev
, ev
, cli
, user
, pass
, domain
);
1821 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
1824 status
= cli_session_setup_ntlmssp_recv(req
);
1830 /****************************************************************************
1831 Do a spnego encrypted session setup.
1833 user_domain: The shortname of the domain the user/machine is a member of.
1834 dest_realm: The realm we're connecting to, if NULL we use our default realm.
1835 ****************************************************************************/
1837 static ADS_STATUS
cli_session_setup_spnego(struct cli_state
*cli
,
1840 const char *user_domain
,
1841 const char * dest_realm
)
1843 char *principal
= NULL
;
1844 char *OIDs
[ASN1_MAX_OIDS
];
1846 const DATA_BLOB
*server_blob
;
1847 DATA_BLOB blob
= data_blob_null
;
1848 const char *p
= NULL
;
1849 char *account
= NULL
;
1852 server_blob
= cli_state_server_gss_blob(cli
);
1854 blob
= data_blob(server_blob
->data
, server_blob
->length
);
1857 DEBUG(3,("Doing spnego session setup (blob length=%lu)\n", (unsigned long)blob
.length
));
1859 /* the server might not even do spnego */
1860 if (blob
.length
== 0) {
1861 DEBUG(3,("server didn't supply a full spnego negprot\n"));
1866 file_save("negprot.dat", cli
->secblob
.data
, cli
->secblob
.length
);
1869 /* The server sent us the first part of the SPNEGO exchange in the
1870 * negprot reply. It is WRONG to depend on the principal sent in the
1871 * negprot reply, but right now we do it. If we don't receive one,
1872 * we try to best guess, then fall back to NTLM. */
1873 if (!spnego_parse_negTokenInit(talloc_tos(), blob
, OIDs
, &principal
, NULL
) ||
1875 data_blob_free(&blob
);
1876 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
1878 data_blob_free(&blob
);
1880 /* make sure the server understands kerberos */
1881 for (i
=0;OIDs
[i
];i
++) {
1883 DEBUG(3,("got OID=%s\n", OIDs
[i
]));
1885 DEBUGADD(3,("got OID=%s\n", OIDs
[i
]));
1886 if (strcmp(OIDs
[i
], OID_KERBEROS5_OLD
) == 0 ||
1887 strcmp(OIDs
[i
], OID_KERBEROS5
) == 0) {
1888 cli
->got_kerberos_mechanism
= True
;
1890 talloc_free(OIDs
[i
]);
1893 DEBUG(3,("got principal=%s\n", principal
? principal
: "<null>"));
1895 status
= cli_set_username(cli
, user
);
1896 if (!NT_STATUS_IS_OK(status
)) {
1897 TALLOC_FREE(principal
);
1898 return ADS_ERROR_NT(status
);
1902 /* If password is set we reauthenticate to kerberos server
1903 * and do not store results */
1905 if (user
&& *user
&& cli
->got_kerberos_mechanism
&& cli
->use_kerberos
) {
1907 const char *remote_name
= cli_state_remote_name(cli
);
1909 if (pass
&& *pass
) {
1912 use_in_memory_ccache();
1913 ret
= kerberos_kinit_password(user
, pass
, 0 /* no time correction for now */, NULL
);
1916 TALLOC_FREE(principal
);
1917 DEBUG(0, ("Kinit failed: %s\n", error_message(ret
)));
1918 if (cli
->fallback_after_kerberos
)
1920 return ADS_ERROR_KRB5(ret
);
1924 /* We may not be allowed to use the server-supplied SPNEGO principal, or it may not have been supplied to us
1926 if (!lp_client_use_spnego_principal() || strequal(principal
, ADS_IGNORE_PRINCIPAL
)) {
1927 TALLOC_FREE(principal
);
1930 if (principal
== NULL
&&
1931 !is_ipaddress(remote_name
) &&
1932 !strequal(STAR_SMBSERVER
,
1936 DEBUG(3,("cli_session_setup_spnego: using target "
1937 "hostname not SPNEGO principal\n"));
1939 host
= strchr_m(remote_name
, '.');
1941 realm
= SMB_STRDUP(dest_realm
);
1943 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY
);
1949 realm
= kerberos_get_realm_from_hostname(remote_name
);
1951 /* NetBIOS name - use our realm. */
1952 realm
= kerberos_get_default_realm_from_ccache();
1956 if (realm
== NULL
|| *realm
== '\0') {
1957 realm
= SMB_STRDUP(lp_realm());
1959 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY
);
1962 DEBUG(3,("cli_session_setup_spnego: cannot "
1963 "get realm from dest_realm %s, "
1964 "desthost %s. Using default "
1965 "smb.conf realm %s\n",
1966 dest_realm
? dest_realm
: "<null>",
1971 principal
= talloc_asprintf(talloc_tos(),
1977 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY
);
1979 DEBUG(3,("cli_session_setup_spnego: guessed "
1980 "server principal=%s\n",
1981 principal
? principal
: "<null>"));
1987 rc
= cli_session_setup_kerberos(cli
, principal
);
1988 if (ADS_ERR_OK(rc
) || !cli
->fallback_after_kerberos
) {
1989 TALLOC_FREE(principal
);
1996 TALLOC_FREE(principal
);
2000 account
= talloc_strdup(talloc_tos(), user
);
2002 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY
);
2005 /* when falling back to ntlmssp while authenticating with a machine
2006 * account strip off the realm - gd */
2008 if ((p
= strchr_m(user
, '@')) != NULL
) {
2009 account
[PTR_DIFF(p
,user
)] = '\0';
2012 return ADS_ERROR_NT(cli_session_setup_ntlmssp(cli
, account
, pass
, user_domain
));
2015 /****************************************************************************
2016 Send a session setup. The username and workgroup is in UNIX character
2017 format and must be converted to DOS codepage format before sending. If the
2018 password is in plaintext, the same should be done.
2019 ****************************************************************************/
2021 NTSTATUS
cli_session_setup(struct cli_state
*cli
,
2023 const char *pass
, int passlen
,
2024 const char *ntpass
, int ntpasslen
,
2025 const char *workgroup
)
2029 uint16_t sec_mode
= cli_state_security_mode(cli
);
2032 user2
= talloc_strdup(talloc_tos(), user
);
2034 user2
= talloc_strdup(talloc_tos(), "");
2036 if (user2
== NULL
) {
2037 return NT_STATUS_NO_MEMORY
;
2044 /* allow for workgroups as part of the username */
2045 if ((p
=strchr_m(user2
,'\\')) || (p
=strchr_m(user2
,'/')) ||
2046 (p
=strchr_m(user2
,*lp_winbind_separator()))) {
2053 if (cli_state_protocol(cli
) < PROTOCOL_LANMAN1
) {
2054 return NT_STATUS_OK
;
2057 /* now work out what sort of session setup we are going to
2058 do. I have split this into separate functions to make the
2059 flow a bit easier to understand (tridge) */
2061 /* if its an older server then we have to use the older request format */
2063 if (cli_state_protocol(cli
) < PROTOCOL_NT1
) {
2064 if (!lp_client_lanman_auth() && passlen
!= 24 && (*pass
)) {
2065 DEBUG(1, ("Server requested LM password but 'client lanman auth = no'"
2066 " or 'client ntlmv2 auth = yes'\n"));
2067 return NT_STATUS_ACCESS_DENIED
;
2070 if ((sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
) == 0 &&
2071 !lp_client_plaintext_auth() && (*pass
)) {
2072 DEBUG(1, ("Server requested LM password but 'client plaintext auth = no'"
2073 " or 'client ntlmv2 auth = yes'\n"));
2074 return NT_STATUS_ACCESS_DENIED
;
2077 return cli_session_setup_lanman2(cli
, user
, pass
, passlen
,
2081 if (cli_state_protocol(cli
) >= PROTOCOL_SMB2_02
) {
2082 const char *remote_realm
= cli_state_remote_realm(cli
);
2083 ADS_STATUS status
= cli_session_setup_spnego(cli
, user
, pass
,
2086 if (!ADS_ERR_OK(status
)) {
2087 DEBUG(3, ("SMB2-SPNEGO login failed: %s\n", ads_errstr(status
)));
2088 return ads_ntstatus(status
);
2090 return NT_STATUS_OK
;
2093 /* if no user is supplied then we have to do an anonymous connection.
2094 passwords are ignored */
2096 if (!user
|| !*user
)
2097 return cli_session_setup_guest(cli
);
2099 /* if the server is share level then send a plaintext null
2100 password at this point. The password is sent in the tree
2103 if ((sec_mode
& NEGOTIATE_SECURITY_USER_LEVEL
) == 0)
2104 return cli_session_setup_plain(cli
, user
, "", workgroup
);
2106 /* if the server doesn't support encryption then we have to use
2107 plaintext. The second password is ignored */
2109 if ((sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
) == 0) {
2110 if (!lp_client_plaintext_auth() && (*pass
)) {
2111 DEBUG(1, ("Server requested LM password but 'client plaintext auth = no'"
2112 " or 'client ntlmv2 auth = yes'\n"));
2113 return NT_STATUS_ACCESS_DENIED
;
2115 return cli_session_setup_plain(cli
, user
, pass
, workgroup
);
2118 /* if the server supports extended security then use SPNEGO */
2120 if (cli_state_capabilities(cli
) & CAP_EXTENDED_SECURITY
) {
2121 const char *remote_realm
= cli_state_remote_realm(cli
);
2122 ADS_STATUS status
= cli_session_setup_spnego(cli
, user
, pass
,
2125 if (!ADS_ERR_OK(status
)) {
2126 DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status
)));
2127 return ads_ntstatus(status
);
2132 /* otherwise do a NT1 style session setup */
2133 status
= cli_session_setup_nt1(cli
, user
, pass
, passlen
,
2134 ntpass
, ntpasslen
, workgroup
);
2135 if (!NT_STATUS_IS_OK(status
)) {
2136 DEBUG(3,("cli_session_setup: NT1 session setup "
2137 "failed: %s\n", nt_errstr(status
)));
2142 return NT_STATUS_OK
;
2145 /****************************************************************************
2147 *****************************************************************************/
2149 struct cli_ulogoff_state
{
2150 struct cli_state
*cli
;
2154 static void cli_ulogoff_done(struct tevent_req
*subreq
);
2156 struct tevent_req
*cli_ulogoff_send(TALLOC_CTX
*mem_ctx
,
2157 struct tevent_context
*ev
,
2158 struct cli_state
*cli
)
2160 struct tevent_req
*req
, *subreq
;
2161 struct cli_ulogoff_state
*state
;
2163 req
= tevent_req_create(mem_ctx
, &state
, struct cli_ulogoff_state
);
2169 SCVAL(state
->vwv
+0, 0, 0xFF);
2170 SCVAL(state
->vwv
+1, 0, 0);
2171 SSVAL(state
->vwv
+2, 0, 0);
2173 subreq
= cli_smb_send(state
, ev
, cli
, SMBulogoffX
, 0, 2, state
->vwv
,
2175 if (tevent_req_nomem(subreq
, req
)) {
2176 return tevent_req_post(req
, ev
);
2178 tevent_req_set_callback(subreq
, cli_ulogoff_done
, req
);
2182 static void cli_ulogoff_done(struct tevent_req
*subreq
)
2184 struct tevent_req
*req
= tevent_req_callback_data(
2185 subreq
, struct tevent_req
);
2186 struct cli_ulogoff_state
*state
= tevent_req_data(
2187 req
, struct cli_ulogoff_state
);
2190 status
= cli_smb_recv(subreq
, NULL
, NULL
, 0, NULL
, NULL
, NULL
, NULL
);
2191 if (!NT_STATUS_IS_OK(status
)) {
2192 tevent_req_nterror(req
, status
);
2195 cli_state_set_uid(state
->cli
, UID_FIELD_INVALID
);
2196 tevent_req_done(req
);
2199 NTSTATUS
cli_ulogoff_recv(struct tevent_req
*req
)
2201 return tevent_req_simple_recv_ntstatus(req
);
2204 NTSTATUS
cli_ulogoff(struct cli_state
*cli
)
2206 struct tevent_context
*ev
;
2207 struct tevent_req
*req
;
2208 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2210 if (cli_has_async_calls(cli
)) {
2211 return NT_STATUS_INVALID_PARAMETER
;
2213 ev
= tevent_context_init(talloc_tos());
2217 req
= cli_ulogoff_send(ev
, ev
, cli
);
2221 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2224 status
= cli_ulogoff_recv(req
);
2230 /****************************************************************************
2232 ****************************************************************************/
2234 struct cli_tcon_andx_state
{
2235 struct cli_state
*cli
;
2240 static void cli_tcon_andx_done(struct tevent_req
*subreq
);
2242 struct tevent_req
*cli_tcon_andx_create(TALLOC_CTX
*mem_ctx
,
2243 struct event_context
*ev
,
2244 struct cli_state
*cli
,
2245 const char *share
, const char *dev
,
2246 const char *pass
, int passlen
,
2247 struct tevent_req
**psmbreq
)
2249 struct tevent_req
*req
, *subreq
;
2250 struct cli_tcon_andx_state
*state
;
2255 uint16_t sec_mode
= cli_state_security_mode(cli
);
2259 req
= tevent_req_create(mem_ctx
, &state
, struct cli_tcon_andx_state
);
2266 cli
->share
= talloc_strdup(cli
, share
);
2271 /* in user level security don't send a password now */
2272 if (sec_mode
& NEGOTIATE_SECURITY_USER_LEVEL
) {
2275 } else if (pass
== NULL
) {
2276 DEBUG(1, ("Server not using user level security and no "
2277 "password supplied.\n"));
2281 if ((sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
) &&
2282 *pass
&& passlen
!= 24) {
2283 if (!lp_client_lanman_auth()) {
2284 DEBUG(1, ("Server requested LANMAN password "
2285 "(share-level security) but "
2286 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2291 * Non-encrypted passwords - convert to DOS codepage before
2294 SMBencrypt(pass
, cli_state_server_challenge(cli
), p24
);
2296 pass
= (const char *)p24
;
2298 if((sec_mode
& (NEGOTIATE_SECURITY_USER_LEVEL
2299 |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
))
2303 if (!lp_client_plaintext_auth() && (*pass
)) {
2304 DEBUG(1, ("Server requested plaintext "
2306 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2311 * Non-encrypted passwords - convert to DOS codepage
2314 tmp_pass
= talloc_array(talloc_tos(), uint8
, 0);
2315 if (tevent_req_nomem(tmp_pass
, req
)) {
2316 return tevent_req_post(req
, ev
);
2318 tmp_pass
= trans2_bytes_push_str(tmp_pass
,
2319 false, /* always DOS */
2323 if (tevent_req_nomem(tmp_pass
, req
)) {
2324 return tevent_req_post(req
, ev
);
2326 pass
= (const char *)tmp_pass
;
2327 passlen
= talloc_get_size(tmp_pass
);
2331 SCVAL(vwv
+0, 0, 0xFF);
2334 SSVAL(vwv
+2, 0, TCONX_FLAG_EXTENDED_RESPONSE
);
2335 SSVAL(vwv
+3, 0, passlen
);
2337 if (passlen
&& pass
) {
2338 bytes
= (uint8_t *)talloc_memdup(state
, pass
, passlen
);
2340 bytes
= talloc_array(state
, uint8_t, 0);
2346 tmp
= talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
2347 cli_state_remote_name(cli
), share
);
2352 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), tmp
, strlen(tmp
)+1,
2357 * Add the devicetype
2359 tmp
= talloc_strdup_upper(talloc_tos(), dev
);
2364 bytes
= smb_bytes_push_str(bytes
, false, tmp
, strlen(tmp
)+1, NULL
);
2367 if (bytes
== NULL
) {
2372 state
->bytes
.iov_base
= (void *)bytes
;
2373 state
->bytes
.iov_len
= talloc_get_size(bytes
);
2375 subreq
= cli_smb_req_create(state
, ev
, cli
, SMBtconX
, 0, 4, vwv
,
2377 if (subreq
== NULL
) {
2381 tevent_req_set_callback(subreq
, cli_tcon_andx_done
, req
);
2386 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
2387 return tevent_req_post(req
, ev
);
2390 struct tevent_req
*cli_tcon_andx_send(TALLOC_CTX
*mem_ctx
,
2391 struct event_context
*ev
,
2392 struct cli_state
*cli
,
2393 const char *share
, const char *dev
,
2394 const char *pass
, int passlen
)
2396 struct tevent_req
*req
, *subreq
;
2399 req
= cli_tcon_andx_create(mem_ctx
, ev
, cli
, share
, dev
, pass
, passlen
,
2404 if (subreq
== NULL
) {
2407 status
= cli_smb_req_send(subreq
);
2408 if (!NT_STATUS_IS_OK(status
)) {
2409 tevent_req_nterror(req
, status
);
2410 return tevent_req_post(req
, ev
);
2415 static void cli_tcon_andx_done(struct tevent_req
*subreq
)
2417 struct tevent_req
*req
= tevent_req_callback_data(
2418 subreq
, struct tevent_req
);
2419 struct cli_tcon_andx_state
*state
= tevent_req_data(
2420 req
, struct cli_tcon_andx_state
);
2421 struct cli_state
*cli
= state
->cli
;
2430 status
= cli_smb_recv(subreq
, state
, &in
, 0, &wct
, &vwv
,
2431 &num_bytes
, &bytes
);
2432 TALLOC_FREE(subreq
);
2433 if (!NT_STATUS_IS_OK(status
)) {
2434 tevent_req_nterror(req
, status
);
2441 if (clistr_pull_talloc(cli
,
2443 SVAL(inbuf
, smb_flg2
),
2447 STR_TERMINATE
|STR_ASCII
) == -1) {
2448 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
2452 cli
->dev
= talloc_strdup(cli
, "");
2453 if (cli
->dev
== NULL
) {
2454 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
2459 if ((cli_state_protocol(cli
) >= PROTOCOL_NT1
) && (num_bytes
== 3)) {
2460 /* almost certainly win95 - enable bug fixes */
2465 * Make sure that we have the optional support 16-bit field. WCT > 2.
2466 * Avoids issues when connecting to Win9x boxes sharing files
2469 cli
->dfsroot
= false;
2471 if ((wct
> 2) && (cli_state_protocol(cli
) >= PROTOCOL_LANMAN2
)) {
2472 cli
->dfsroot
= ((SVAL(vwv
+2, 0) & SMB_SHARE_IN_DFS
) != 0);
2475 cli
->smb1
.tid
= SVAL(inbuf
,smb_tid
);
2476 tevent_req_done(req
);
2479 NTSTATUS
cli_tcon_andx_recv(struct tevent_req
*req
)
2481 return tevent_req_simple_recv_ntstatus(req
);
2484 NTSTATUS
cli_tcon_andx(struct cli_state
*cli
, const char *share
,
2485 const char *dev
, const char *pass
, int passlen
)
2487 TALLOC_CTX
*frame
= talloc_stackframe();
2488 struct event_context
*ev
;
2489 struct tevent_req
*req
;
2490 NTSTATUS status
= NT_STATUS_OK
;
2492 if (cli_has_async_calls(cli
)) {
2494 * Can't use sync call while an async call is in flight
2496 status
= NT_STATUS_INVALID_PARAMETER
;
2500 ev
= event_context_init(frame
);
2502 status
= NT_STATUS_NO_MEMORY
;
2506 req
= cli_tcon_andx_send(frame
, ev
, cli
, share
, dev
, pass
, passlen
);
2508 status
= NT_STATUS_NO_MEMORY
;
2512 if (!tevent_req_poll(req
, ev
)) {
2513 status
= map_nt_error_from_unix(errno
);
2517 status
= cli_tcon_andx_recv(req
);
2523 NTSTATUS
cli_tree_connect(struct cli_state
*cli
, const char *share
,
2524 const char *dev
, const char *pass
, int passlen
)
2526 cli
->share
= talloc_strdup(cli
, share
);
2528 return NT_STATUS_NO_MEMORY
;
2531 if (cli_state_protocol(cli
) >= PROTOCOL_SMB2_02
) {
2532 return smb2cli_tcon(cli
, share
);
2535 return cli_tcon_andx(cli
, share
, dev
, pass
, passlen
);
2538 /****************************************************************************
2539 Send a tree disconnect.
2540 ****************************************************************************/
2542 struct cli_tdis_state
{
2543 struct cli_state
*cli
;
2546 static void cli_tdis_done(struct tevent_req
*subreq
);
2548 struct tevent_req
*cli_tdis_send(TALLOC_CTX
*mem_ctx
,
2549 struct tevent_context
*ev
,
2550 struct cli_state
*cli
)
2552 struct tevent_req
*req
, *subreq
;
2553 struct cli_tdis_state
*state
;
2555 req
= tevent_req_create(mem_ctx
, &state
, struct cli_tdis_state
);
2561 subreq
= cli_smb_send(state
, ev
, cli
, SMBtdis
, 0, 0, NULL
, 0, NULL
);
2562 if (tevent_req_nomem(subreq
, req
)) {
2563 return tevent_req_post(req
, ev
);
2565 tevent_req_set_callback(subreq
, cli_tdis_done
, req
);
2569 static void cli_tdis_done(struct tevent_req
*subreq
)
2571 struct tevent_req
*req
= tevent_req_callback_data(
2572 subreq
, struct tevent_req
);
2573 struct cli_tdis_state
*state
= tevent_req_data(
2574 req
, struct cli_tdis_state
);
2577 status
= cli_smb_recv(subreq
, NULL
, NULL
, 0, NULL
, NULL
, NULL
, NULL
);
2578 TALLOC_FREE(subreq
);
2579 if (!NT_STATUS_IS_OK(status
)) {
2580 tevent_req_nterror(req
, status
);
2583 state
->cli
->smb1
.tid
= UINT16_MAX
;
2584 tevent_req_done(req
);
2587 NTSTATUS
cli_tdis_recv(struct tevent_req
*req
)
2589 return tevent_req_simple_recv_ntstatus(req
);
2592 NTSTATUS
cli_tdis(struct cli_state
*cli
)
2594 struct tevent_context
*ev
;
2595 struct tevent_req
*req
;
2596 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2598 if (cli_has_async_calls(cli
)) {
2599 return NT_STATUS_INVALID_PARAMETER
;
2601 ev
= tevent_context_init(talloc_tos());
2605 req
= cli_tdis_send(ev
, ev
, cli
);
2609 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2612 status
= cli_tdis_recv(req
);
2618 struct tevent_req
*cli_negprot_send(TALLOC_CTX
*mem_ctx
,
2619 struct event_context
*ev
,
2620 struct cli_state
*cli
,
2621 enum protocol_types max_protocol
)
2623 return smbXcli_negprot_send(mem_ctx
, ev
,
2624 cli
->conn
, cli
->timeout
,
2625 PROTOCOL_CORE
, max_protocol
);
2628 NTSTATUS
cli_negprot_recv(struct tevent_req
*req
)
2630 return smbXcli_negprot_recv(req
);
2633 NTSTATUS
cli_negprot(struct cli_state
*cli
, enum protocol_types max_protocol
)
2635 return smbXcli_negprot(cli
->conn
, cli
->timeout
,
2636 PROTOCOL_CORE
, max_protocol
);
2639 static NTSTATUS
cli_connect_sock(const char *host
, int name_type
,
2640 const struct sockaddr_storage
*pss
,
2641 const char *myname
, uint16_t port
,
2642 int sec_timeout
, int *pfd
, uint16_t *pport
)
2644 TALLOC_CTX
*frame
= talloc_stackframe();
2646 unsigned int i
, num_addrs
;
2647 const char **called_names
;
2648 const char **calling_names
;
2653 prog
= getenv("LIBSMB_PROG");
2655 fd
= sock_exec(prog
);
2657 return map_nt_error_from_unix(errno
);
2663 if ((pss
== NULL
) || is_zero_addr(pss
)) {
2664 struct sockaddr_storage
*addrs
;
2665 status
= resolve_name_list(talloc_tos(), host
, name_type
,
2666 &addrs
, &num_addrs
);
2667 if (!NT_STATUS_IS_OK(status
)) {
2675 called_names
= talloc_array(talloc_tos(), const char *, num_addrs
);
2676 if (called_names
== NULL
) {
2677 status
= NT_STATUS_NO_MEMORY
;
2680 called_types
= talloc_array(talloc_tos(), int, num_addrs
);
2681 if (called_types
== NULL
) {
2682 status
= NT_STATUS_NO_MEMORY
;
2685 calling_names
= talloc_array(talloc_tos(), const char *, num_addrs
);
2686 if (calling_names
== NULL
) {
2687 status
= NT_STATUS_NO_MEMORY
;
2690 for (i
=0; i
<num_addrs
; i
++) {
2691 called_names
[i
] = host
;
2692 called_types
[i
] = name_type
;
2693 calling_names
[i
] = myname
;
2695 status
= smbsock_any_connect(pss
, called_names
, called_types
,
2696 calling_names
, NULL
, num_addrs
, port
,
2697 sec_timeout
, &fd
, NULL
, &port
);
2698 if (!NT_STATUS_IS_OK(status
)) {
2701 set_socket_options(fd
, lp_socket_options());
2705 status
= NT_STATUS_OK
;
2711 NTSTATUS
cli_connect_nb(const char *host
, const struct sockaddr_storage
*dest_ss
,
2712 uint16_t port
, int name_type
, const char *myname
,
2713 int signing_state
, int flags
, struct cli_state
**pcli
)
2715 TALLOC_CTX
*frame
= talloc_stackframe();
2716 struct cli_state
*cli
;
2717 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2722 desthost
= talloc_strdup(talloc_tos(), host
);
2723 if (desthost
== NULL
) {
2727 p
= strchr(host
, '#');
2729 name_type
= strtol(p
+1, NULL
, 16);
2730 host
= talloc_strndup(talloc_tos(), host
, p
- host
);
2736 status
= cli_connect_sock(host
, name_type
, dest_ss
, myname
, port
,
2738 if (!NT_STATUS_IS_OK(status
)) {
2742 cli
= cli_state_create(NULL
, fd
, desthost
, NULL
, signing_state
, flags
);
2750 status
= NT_STATUS_OK
;
2757 establishes a connection to after the negprot.
2758 @param output_cli A fully initialised cli structure, non-null only on success
2759 @param dest_host The netbios name of the remote host
2760 @param dest_ss (optional) The the destination IP, NULL for name based lookup
2761 @param port (optional) The destination port (0 for default)
2763 NTSTATUS
cli_start_connection(struct cli_state
**output_cli
,
2764 const char *my_name
,
2765 const char *dest_host
,
2766 const struct sockaddr_storage
*dest_ss
, int port
,
2767 int signing_state
, int flags
)
2770 struct cli_state
*cli
;
2772 nt_status
= cli_connect_nb(dest_host
, dest_ss
, port
, 0x20, my_name
,
2773 signing_state
, flags
, &cli
);
2774 if (!NT_STATUS_IS_OK(nt_status
)) {
2775 DEBUG(10, ("cli_connect_nb failed: %s\n",
2776 nt_errstr(nt_status
)));
2780 nt_status
= cli_negprot(cli
, PROTOCOL_NT1
);
2781 if (!NT_STATUS_IS_OK(nt_status
)) {
2782 DEBUG(1, ("failed negprot: %s\n", nt_errstr(nt_status
)));
2788 return NT_STATUS_OK
;
2793 establishes a connection right up to doing tconX, password specified.
2794 @param output_cli A fully initialised cli structure, non-null only on success
2795 @param dest_host The netbios name of the remote host
2796 @param dest_ip (optional) The the destination IP, NULL for name based lookup
2797 @param port (optional) The destination port (0 for default)
2798 @param service (optional) The share to make the connection to. Should be 'unqualified' in any way.
2799 @param service_type The 'type' of serivice.
2800 @param user Username, unix string
2801 @param domain User's domain
2802 @param password User's password, unencrypted unix string.
2805 NTSTATUS
cli_full_connection(struct cli_state
**output_cli
,
2806 const char *my_name
,
2807 const char *dest_host
,
2808 const struct sockaddr_storage
*dest_ss
, int port
,
2809 const char *service
, const char *service_type
,
2810 const char *user
, const char *domain
,
2811 const char *password
, int flags
,
2815 struct cli_state
*cli
= NULL
;
2816 int pw_len
= password
? strlen(password
)+1 : 0;
2820 if (password
== NULL
) {
2824 nt_status
= cli_start_connection(&cli
, my_name
, dest_host
,
2825 dest_ss
, port
, signing_state
,
2828 if (!NT_STATUS_IS_OK(nt_status
)) {
2832 nt_status
= cli_session_setup(cli
, user
, password
, pw_len
, password
,
2834 if (!NT_STATUS_IS_OK(nt_status
)) {
2836 if (!(flags
& CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK
)) {
2837 DEBUG(1,("failed session setup with %s\n",
2838 nt_errstr(nt_status
)));
2843 nt_status
= cli_session_setup(cli
, "", "", 0, "", 0, domain
);
2844 if (!NT_STATUS_IS_OK(nt_status
)) {
2845 DEBUG(1,("anonymous failed session setup with %s\n",
2846 nt_errstr(nt_status
)));
2853 nt_status
= cli_tcon_andx(cli
, service
, service_type
, password
,
2855 if (!NT_STATUS_IS_OK(nt_status
)) {
2856 DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status
)));
2858 if (NT_STATUS_IS_OK(nt_status
)) {
2859 nt_status
= NT_STATUS_UNSUCCESSFUL
;
2865 nt_status
= cli_init_creds(cli
, user
, domain
, password
);
2866 if (!NT_STATUS_IS_OK(nt_status
)) {
2872 return NT_STATUS_OK
;
2875 /****************************************************************************
2876 Send an old style tcon.
2877 ****************************************************************************/
2878 NTSTATUS
cli_raw_tcon(struct cli_state
*cli
,
2879 const char *service
, const char *pass
, const char *dev
,
2880 uint16
*max_xmit
, uint16
*tid
)
2882 struct tevent_req
*req
;
2887 if (!lp_client_plaintext_auth() && (*pass
)) {
2888 DEBUG(1, ("Server requested plaintext password but 'client "
2889 "plaintext auth' is disabled\n"));
2890 return NT_STATUS_ACCESS_DENIED
;
2893 bytes
= talloc_array(talloc_tos(), uint8_t, 0);
2894 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
2895 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
),
2896 service
, strlen(service
)+1, NULL
);
2897 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
2898 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
),
2899 pass
, strlen(pass
)+1, NULL
);
2900 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
2901 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
),
2902 dev
, strlen(dev
)+1, NULL
);
2904 status
= cli_smb(talloc_tos(), cli
, SMBtcon
, 0, 0, NULL
,
2905 talloc_get_size(bytes
), bytes
, &req
,
2906 2, NULL
, &ret_vwv
, NULL
, NULL
);
2907 if (!NT_STATUS_IS_OK(status
)) {
2911 *max_xmit
= SVAL(ret_vwv
+ 0, 0);
2912 *tid
= SVAL(ret_vwv
+ 1, 0);
2914 return NT_STATUS_OK
;
2917 /* Return a cli_state pointing at the IPC$ share for the given server */
2919 struct cli_state
*get_ipc_connect(char *server
,
2920 struct sockaddr_storage
*server_ss
,
2921 const struct user_auth_info
*user_info
)
2923 struct cli_state
*cli
;
2925 uint32_t flags
= CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK
;
2927 if (user_info
->use_kerberos
) {
2928 flags
|= CLI_FULL_CONNECTION_USE_KERBEROS
;
2931 nt_status
= cli_full_connection(&cli
, NULL
, server
, server_ss
, 0, "IPC$", "IPC",
2932 user_info
->username
? user_info
->username
: "",
2934 user_info
->password
? user_info
->password
: "",
2936 SMB_SIGNING_DEFAULT
);
2938 if (NT_STATUS_IS_OK(nt_status
)) {
2940 } else if (is_ipaddress(server
)) {
2941 /* windows 9* needs a correct NMB name for connections */
2942 fstring remote_name
;
2944 if (name_status_find("*", 0, 0, server_ss
, remote_name
)) {
2945 cli
= get_ipc_connect(remote_name
, server_ss
, user_info
);
2954 * Given the IP address of a master browser on the network, return its
2955 * workgroup and connect to it.
2957 * This function is provided to allow additional processing beyond what
2958 * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
2959 * browsers and obtain each master browsers' list of domains (in case the
2960 * first master browser is recently on the network and has not yet
2961 * synchronized with other master browsers and therefore does not yet have the
2962 * entire network browse list)
2965 struct cli_state
*get_ipc_connect_master_ip(TALLOC_CTX
*ctx
,
2966 struct sockaddr_storage
*mb_ip
,
2967 const struct user_auth_info
*user_info
,
2968 char **pp_workgroup_out
)
2970 char addr
[INET6_ADDRSTRLEN
];
2972 struct cli_state
*cli
;
2973 struct sockaddr_storage server_ss
;
2975 *pp_workgroup_out
= NULL
;
2977 print_sockaddr(addr
, sizeof(addr
), mb_ip
);
2978 DEBUG(99, ("Looking up name of master browser %s\n",
2982 * Do a name status query to find out the name of the master browser.
2983 * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
2984 * master browser will not respond to a wildcard query (or, at least,
2985 * an NT4 server acting as the domain master browser will not).
2987 * We might be able to use ONLY the query on MSBROWSE, but that's not
2988 * yet been tested with all Windows versions, so until it is, leave
2989 * the original wildcard query as the first choice and fall back to
2990 * MSBROWSE if the wildcard query fails.
2992 if (!name_status_find("*", 0, 0x1d, mb_ip
, name
) &&
2993 !name_status_find(MSBROWSE
, 1, 0x1d, mb_ip
, name
)) {
2995 DEBUG(99, ("Could not retrieve name status for %s\n",
3000 if (!find_master_ip(name
, &server_ss
)) {
3001 DEBUG(99, ("Could not find master ip for %s\n", name
));
3005 *pp_workgroup_out
= talloc_strdup(ctx
, name
);
3007 DEBUG(4, ("found master browser %s, %s\n", name
, addr
));
3009 print_sockaddr(addr
, sizeof(addr
), &server_ss
);
3010 cli
= get_ipc_connect(addr
, &server_ss
, user_info
);
3016 * Return the IP address and workgroup of a master browser on the network, and
3020 struct cli_state
*get_ipc_connect_master_ip_bcast(TALLOC_CTX
*ctx
,
3021 const struct user_auth_info
*user_info
,
3022 char **pp_workgroup_out
)
3024 struct sockaddr_storage
*ip_list
;
3025 struct cli_state
*cli
;
3029 *pp_workgroup_out
= NULL
;
3031 DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
3033 /* Go looking for workgroups by broadcasting on the local network */
3035 status
= name_resolve_bcast(MSBROWSE
, 1, talloc_tos(),
3037 if (!NT_STATUS_IS_OK(status
)) {
3038 DEBUG(99, ("No master browsers responded: %s\n",
3039 nt_errstr(status
)));
3043 for (i
= 0; i
< count
; i
++) {
3044 char addr
[INET6_ADDRSTRLEN
];
3045 print_sockaddr(addr
, sizeof(addr
), &ip_list
[i
]);
3046 DEBUG(99, ("Found master browser %s\n", addr
));
3048 cli
= get_ipc_connect_master_ip(ctx
, &ip_list
[i
],
3049 user_info
, pp_workgroup_out
);