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 "libsmb/namequery.h"
26 #include "auth_info.h"
27 #include "../libcli/auth/libcli_auth.h"
28 #include "../libcli/auth/spnego.h"
30 #include "auth/credentials/credentials.h"
31 #include "auth/gensec/gensec.h"
32 #include "auth/ntlmssp/ntlmssp.h"
33 #include "auth_generic.h"
34 #include "libads/kerberos_proto.h"
36 #include "../lib/util/tevent_ntstatus.h"
37 #include "async_smb.h"
38 #include "libsmb/nmblib.h"
39 #include "librpc/ndr/libndr.h"
40 #include "../libcli/smb/smbXcli_base.h"
41 #include "../libcli/smb/smb_seal.h"
42 #include "lib/param/param.h"
43 #include "../libcli/smb/smb2_negotiate_context.h"
44 #include "libads/krb5_errs.h"
46 #define STAR_SMBSERVER "*SMBSERVER"
48 static char *cli_session_setup_get_account(TALLOC_CTX
*mem_ctx
,
49 const char *principal
);
51 struct cli_credentials
*cli_session_creds_init(TALLOC_CTX
*mem_ctx
,
57 bool fallback_after_kerberos
,
59 bool password_is_nt_hash
)
61 struct loadparm_context
*lp_ctx
= NULL
;
62 struct cli_credentials
*creds
= NULL
;
63 const char *principal
= NULL
;
68 creds
= cli_credentials_init(mem_ctx
);
73 lp_ctx
= loadparm_init_s3(creds
, loadparm_s3_helpers());
77 cli_credentials_set_conf(creds
, lp_ctx
);
79 if (username
== NULL
) {
83 if (strlen(username
) == 0) {
84 if (password
!= NULL
&& strlen(password
) == 0) {
86 * some callers pass "" as no password
88 * gensec only handles NULL as no password.
92 if (password
== NULL
) {
93 cli_credentials_set_anonymous(creds
);
98 tmp
= talloc_strdup(creds
, username
);
104 /* allow for workgroups as part of the username */
105 if ((p
= strchr_m(tmp
, '\\')) ||
106 (p
= strchr_m(tmp
, '/')) ||
107 (p
= strchr_m(tmp
, *lp_winbind_separator()))) {
113 principal
= username
;
114 username
= cli_session_setup_get_account(creds
, principal
);
115 if (username
== NULL
) {
118 ok
= strequal(username
, principal
);
121 * Ok still the same, so it's not a principal
126 if (use_kerberos
&& fallback_after_kerberos
) {
127 cli_credentials_set_kerberos_state(creds
,
128 CRED_AUTO_USE_KERBEROS
);
129 } else if (use_kerberos
) {
130 cli_credentials_set_kerberos_state(creds
,
131 CRED_MUST_USE_KERBEROS
);
133 cli_credentials_set_kerberos_state(creds
,
134 CRED_DONT_USE_KERBEROS
);
140 features
= cli_credentials_get_gensec_features(creds
);
141 features
|= GENSEC_FEATURE_NTLM_CCACHE
;
142 cli_credentials_set_gensec_features(creds
, features
);
144 if (password
!= NULL
&& strlen(password
) == 0) {
146 * some callers pass "" as no password
148 * GENSEC_FEATURE_NTLM_CCACHE only handles
149 * NULL as no password.
155 ok
= cli_credentials_set_username(creds
,
162 if (domain
!= NULL
) {
163 ok
= cli_credentials_set_domain(creds
,
171 if (principal
!= NULL
) {
172 ok
= cli_credentials_set_principal(creds
,
181 ok
= cli_credentials_set_realm(creds
,
189 if (password
!= NULL
&& strlen(password
) > 0) {
190 if (password_is_nt_hash
) {
191 struct samr_Password nt_hash
;
194 converted
= strhex_to_str((char *)nt_hash
.hash
,
195 sizeof(nt_hash
.hash
),
198 if (converted
!= sizeof(nt_hash
.hash
)) {
202 ok
= cli_credentials_set_nt_hash(creds
,
209 ok
= cli_credentials_set_password(creds
,
224 NTSTATUS
cli_session_creds_prepare_krb5(struct cli_state
*cli
,
225 struct cli_credentials
*creds
)
227 TALLOC_CTX
*frame
= talloc_stackframe();
228 const char *user_principal
= NULL
;
229 const char *user_account
= NULL
;
230 const char *user_domain
= NULL
;
231 const char *pass
= NULL
;
232 char *canon_principal
= NULL
;
233 char *canon_realm
= NULL
;
234 const char *target_hostname
= NULL
;
235 enum credentials_use_kerberos krb5_state
;
236 bool try_kerberos
= false;
237 bool need_kinit
= false;
238 bool auth_requested
= true;
242 target_hostname
= smbXcli_conn_remote_name(cli
->conn
);
244 auth_requested
= cli_credentials_authentication_requested(creds
);
245 if (auth_requested
) {
247 user_principal
= cli_credentials_get_principal(creds
, frame
);
250 return NT_STATUS_NO_MEMORY
;
253 user_account
= cli_credentials_get_username(creds
);
254 user_domain
= cli_credentials_get_domain(creds
);
255 pass
= cli_credentials_get_password(creds
);
257 krb5_state
= cli_credentials_get_kerberos_state(creds
);
259 if (krb5_state
!= CRED_DONT_USE_KERBEROS
) {
263 if (user_principal
== NULL
) {
264 try_kerberos
= false;
267 if (target_hostname
== NULL
) {
268 try_kerberos
= false;
269 } else if (is_ipaddress(target_hostname
)) {
270 try_kerberos
= false;
271 } else if (strequal(target_hostname
, "localhost")) {
272 try_kerberos
= false;
273 } else if (strequal(target_hostname
, STAR_SMBSERVER
)) {
274 try_kerberos
= false;
275 } else if (!auth_requested
) {
276 try_kerberos
= false;
279 if (krb5_state
== CRED_MUST_USE_KERBEROS
&& !try_kerberos
) {
280 DEBUG(0, ("Kerberos auth with '%s' (%s\\%s) to access "
281 "'%s' not possible\n",
282 user_principal
, user_domain
, user_account
,
285 return NT_STATUS_ACCESS_DENIED
;
288 if (pass
== NULL
|| strlen(pass
) == 0) {
290 } else if (krb5_state
== CRED_MUST_USE_KERBEROS
) {
291 need_kinit
= try_kerberos
;
293 need_kinit
= try_kerberos
;
301 DBG_INFO("Doing kinit for %s to access %s\n",
302 user_principal
, target_hostname
);
305 * TODO: This should be done within the gensec layer
308 setenv(KRB5_ENV_CCNAME
, "MEMORY:cliconnect", 1);
309 ret
= kerberos_kinit_password_ext(user_principal
,
323 int dbglvl
= DBGLVL_NOTICE
;
325 if (krb5_state
== CRED_MUST_USE_KERBEROS
) {
329 DEBUG(dbglvl
, ("Kinit for %s to access %s failed: %s\n",
330 user_principal
, target_hostname
,
331 error_message(ret
)));
332 if (krb5_state
== CRED_MUST_USE_KERBEROS
) {
334 return krb5_to_nt_status(ret
);
338 * Ignore the error and hope that NTLM will work
344 ok
= cli_credentials_set_principal(creds
,
349 return NT_STATUS_NO_MEMORY
;
352 ok
= cli_credentials_set_realm(creds
,
357 return NT_STATUS_NO_MEMORY
;
360 DBG_DEBUG("Successfully authenticated as %s (%s) to access %s using "
370 static NTSTATUS
cli_state_update_after_sesssetup(struct cli_state
*cli
,
371 const char *native_os
,
372 const char *native_lm
,
373 const char *primary_domain
)
375 #define _VALID_STR(p) ((p) != NULL && (p)[0] != '\0')
377 if (!_VALID_STR(cli
->server_os
) && _VALID_STR(native_os
)) {
378 cli
->server_os
= talloc_strdup(cli
, native_os
);
379 if (cli
->server_os
== NULL
) {
380 return NT_STATUS_NO_MEMORY
;
384 if (!_VALID_STR(cli
->server_type
) && _VALID_STR(native_lm
)) {
385 cli
->server_type
= talloc_strdup(cli
, native_lm
);
386 if (cli
->server_type
== NULL
) {
387 return NT_STATUS_NO_MEMORY
;
391 if (!_VALID_STR(cli
->server_domain
) && _VALID_STR(primary_domain
)) {
392 cli
->server_domain
= talloc_strdup(cli
, primary_domain
);
393 if (cli
->server_domain
== NULL
) {
394 return NT_STATUS_NO_MEMORY
;
402 /********************************************************
403 Utility function to ensure we always return at least
404 a valid char * pointer to an empty string for the
405 cli->server_os, cli->server_type and cli->server_domain
407 *******************************************************/
409 static NTSTATUS
smb_bytes_talloc_string(TALLOC_CTX
*mem_ctx
,
416 *destlen
= clistr_pull_talloc(mem_ctx
,
423 if (*destlen
== -1) {
424 return NT_STATUS_NO_MEMORY
;
428 *dest
= talloc_strdup(mem_ctx
, "");
430 return NT_STATUS_NO_MEMORY
;
436 /****************************************************************************
437 Work out suitable capabilities to offer the server.
438 ****************************************************************************/
440 static uint32_t cli_session_setup_capabilities(struct cli_state
*cli
,
441 uint32_t sesssetup_capabilities
)
443 uint32_t client_capabilities
= smb1cli_conn_capabilities(cli
->conn
);
446 * We only send capabilities based on the mask for:
447 * - client only flags
448 * - flags used in both directions
450 * We do not echo the server only flags, except some legacy flags.
452 * SMB_CAP_LEGACY_CLIENT_MASK contains CAP_LARGE_READX and
453 * CAP_LARGE_WRITEX in order to allow us to do large reads
454 * against old Samba releases (<= 3.6.x).
456 client_capabilities
&= (SMB_CAP_BOTH_MASK
| SMB_CAP_LEGACY_CLIENT_MASK
);
459 * Session Setup specific flags CAP_DYNAMIC_REAUTH
460 * and CAP_EXTENDED_SECURITY are passed by the caller.
461 * We need that in order to do guest logins even if
462 * CAP_EXTENDED_SECURITY is negotiated.
464 client_capabilities
&= ~(CAP_DYNAMIC_REAUTH
|CAP_EXTENDED_SECURITY
);
465 sesssetup_capabilities
&= (CAP_DYNAMIC_REAUTH
|CAP_EXTENDED_SECURITY
);
466 client_capabilities
|= sesssetup_capabilities
;
468 return client_capabilities
;
471 /****************************************************************************
472 Do a NT1 guest session setup.
473 ****************************************************************************/
475 struct cli_session_setup_guest_state
{
476 struct cli_state
*cli
;
481 static void cli_session_setup_guest_done(struct tevent_req
*subreq
);
483 struct tevent_req
*cli_session_setup_guest_create(TALLOC_CTX
*mem_ctx
,
484 struct tevent_context
*ev
,
485 struct cli_state
*cli
,
486 struct tevent_req
**psmbreq
)
488 struct tevent_req
*req
, *subreq
;
489 struct cli_session_setup_guest_state
*state
;
493 req
= tevent_req_create(mem_ctx
, &state
,
494 struct cli_session_setup_guest_state
);
501 SCVAL(vwv
+0, 0, 0xFF);
504 SSVAL(vwv
+2, 0, CLI_BUFFER_SIZE
);
506 SSVAL(vwv
+4, 0, cli_state_get_vc_num(cli
));
507 SIVAL(vwv
+5, 0, smb1cli_conn_server_session_key(cli
->conn
));
512 SIVAL(vwv
+11, 0, cli_session_setup_capabilities(cli
, 0));
514 bytes
= talloc_array(state
, uint8_t, 0);
516 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "", 1, /* username */
518 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "", 1, /* workgroup */
520 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "Unix", 5, NULL
);
521 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "Samba", 6, NULL
);
528 state
->bytes
.iov_base
= (void *)bytes
;
529 state
->bytes
.iov_len
= talloc_get_size(bytes
);
531 subreq
= cli_smb_req_create(state
, ev
, cli
, SMBsesssetupX
, 0, 0, 13,
532 vwv
, 1, &state
->bytes
);
533 if (subreq
== NULL
) {
537 tevent_req_set_callback(subreq
, cli_session_setup_guest_done
, req
);
542 struct tevent_req
*cli_session_setup_guest_send(TALLOC_CTX
*mem_ctx
,
543 struct tevent_context
*ev
,
544 struct cli_state
*cli
)
546 struct tevent_req
*req
, *subreq
;
549 req
= cli_session_setup_guest_create(mem_ctx
, ev
, cli
, &subreq
);
554 status
= smb1cli_req_chain_submit(&subreq
, 1);
555 if (!NT_STATUS_IS_OK(status
)) {
556 tevent_req_nterror(req
, status
);
557 return tevent_req_post(req
, ev
);
562 static void cli_session_setup_guest_done(struct tevent_req
*subreq
)
564 struct tevent_req
*req
= tevent_req_callback_data(
565 subreq
, struct tevent_req
);
566 struct cli_session_setup_guest_state
*state
= tevent_req_data(
567 req
, struct cli_session_setup_guest_state
);
568 struct cli_state
*cli
= state
->cli
;
579 status
= cli_smb_recv(subreq
, state
, &in
, 3, &wct
, &vwv
,
582 if (!NT_STATUS_IS_OK(status
)) {
583 tevent_req_nterror(req
, status
);
587 inhdr
= in
+ NBT_HDR_SIZE
;
590 cli_state_set_uid(state
->cli
, SVAL(inhdr
, HDR_UID
));
591 smb1cli_session_set_action(cli
->smb1
.session
, SVAL(vwv
+2, 0));
593 status
= smb_bytes_talloc_string(cli
,
600 if (!NT_STATUS_IS_OK(status
)) {
601 tevent_req_nterror(req
, status
);
606 status
= smb_bytes_talloc_string(cli
,
613 if (!NT_STATUS_IS_OK(status
)) {
614 tevent_req_nterror(req
, status
);
619 status
= smb_bytes_talloc_string(cli
,
626 if (!NT_STATUS_IS_OK(status
)) {
627 tevent_req_nterror(req
, status
);
631 tevent_req_done(req
);
634 NTSTATUS
cli_session_setup_guest_recv(struct tevent_req
*req
)
636 return tevent_req_simple_recv_ntstatus(req
);
639 /* The following is calculated from :
641 * (smb_wcnt * 2) = 24 (smb_wcnt == 12 in cli_session_setup_blob_send() )
642 * (strlen("Unix") + 1 + strlen("Samba") + 1) * 2 = 22 (unicode strings at
646 #define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22)
648 struct cli_sesssetup_blob_state
{
649 struct tevent_context
*ev
;
650 struct cli_state
*cli
;
652 uint16_t max_blob_size
;
655 struct iovec
*recv_iov
;
658 const uint8_t *inbuf
;
665 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state
*state
,
666 struct tevent_req
**psubreq
);
667 static void cli_sesssetup_blob_done(struct tevent_req
*subreq
);
669 static struct tevent_req
*cli_sesssetup_blob_send(TALLOC_CTX
*mem_ctx
,
670 struct tevent_context
*ev
,
671 struct cli_state
*cli
,
674 struct tevent_req
*req
, *subreq
;
675 struct cli_sesssetup_blob_state
*state
;
676 uint32_t usable_space
;
678 req
= tevent_req_create(mem_ctx
, &state
,
679 struct cli_sesssetup_blob_state
);
687 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
688 usable_space
= UINT16_MAX
;
690 usable_space
= cli_state_available_size(cli
,
691 BASE_SESSSETUP_BLOB_PACKET_SIZE
);
694 if (usable_space
== 0) {
695 DEBUG(1, ("cli_session_setup_blob: cli->max_xmit too small "
696 "(not possible to send %u bytes)\n",
697 BASE_SESSSETUP_BLOB_PACKET_SIZE
+ 1));
698 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
699 return tevent_req_post(req
, ev
);
701 state
->max_blob_size
= MIN(usable_space
, 0xFFFF);
703 if (!cli_sesssetup_blob_next(state
, &subreq
)) {
704 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
705 return tevent_req_post(req
, ev
);
707 tevent_req_set_callback(subreq
, cli_sesssetup_blob_done
, req
);
711 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state
*state
,
712 struct tevent_req
**psubreq
)
714 struct tevent_req
*subreq
;
717 thistime
= MIN(state
->blob
.length
, state
->max_blob_size
);
719 state
->this_blob
.data
= state
->blob
.data
;
720 state
->this_blob
.length
= thistime
;
722 state
->blob
.data
+= thistime
;
723 state
->blob
.length
-= thistime
;
725 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
726 subreq
= smb2cli_session_setup_send(state
, state
->ev
,
729 state
->cli
->smb2
.session
,
731 SMB2_CAP_DFS
, /* in_capabilities */
733 0, /* in_previous_session_id */
735 if (subreq
== NULL
) {
739 uint16_t in_buf_size
= 0;
740 uint16_t in_mpx_max
= 0;
741 uint16_t in_vc_num
= 0;
742 uint32_t in_sess_key
= 0;
743 uint32_t in_capabilities
= 0;
744 const char *in_native_os
= NULL
;
745 const char *in_native_lm
= NULL
;
747 in_buf_size
= CLI_BUFFER_SIZE
;
748 in_mpx_max
= smbXcli_conn_max_requests(state
->cli
->conn
);
749 in_vc_num
= cli_state_get_vc_num(state
->cli
);
750 in_sess_key
= smb1cli_conn_server_session_key(state
->cli
->conn
);
751 in_capabilities
= cli_session_setup_capabilities(state
->cli
,
752 CAP_EXTENDED_SECURITY
);
753 in_native_os
= "Unix";
754 in_native_lm
= "Samba";
757 * For now we keep the same values as before,
758 * we may remove these in a separate commit later.
764 subreq
= smb1cli_session_setup_ext_send(state
, state
->ev
,
767 state
->cli
->smb1
.pid
,
768 state
->cli
->smb1
.session
,
777 if (subreq
== NULL
) {
785 static void cli_sesssetup_blob_done(struct tevent_req
*subreq
)
787 struct tevent_req
*req
= tevent_req_callback_data(
788 subreq
, struct tevent_req
);
789 struct cli_sesssetup_blob_state
*state
= tevent_req_data(
790 req
, struct cli_sesssetup_blob_state
);
793 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
794 status
= smb2cli_session_setup_recv(subreq
, state
,
798 status
= smb1cli_session_setup_ext_recv(subreq
, state
,
802 &state
->out_native_os
,
803 &state
->out_native_lm
);
806 if (!NT_STATUS_IS_OK(status
)
807 && !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
808 tevent_req_nterror(req
, status
);
812 state
->status
= status
;
814 status
= cli_state_update_after_sesssetup(state
->cli
,
815 state
->out_native_os
,
816 state
->out_native_lm
,
818 if (tevent_req_nterror(req
, status
)) {
822 if (state
->blob
.length
!= 0) {
826 if (!cli_sesssetup_blob_next(state
, &subreq
)) {
830 tevent_req_set_callback(subreq
, cli_sesssetup_blob_done
, req
);
833 tevent_req_done(req
);
836 static NTSTATUS
cli_sesssetup_blob_recv(struct tevent_req
*req
,
839 const uint8_t **pinbuf
,
840 struct iovec
**precv_iov
)
842 struct cli_sesssetup_blob_state
*state
= tevent_req_data(
843 req
, struct cli_sesssetup_blob_state
);
845 struct iovec
*recv_iov
;
847 if (tevent_req_is_nterror(req
, &status
)) {
848 TALLOC_FREE(state
->cli
->smb2
.session
);
849 cli_state_set_uid(state
->cli
, UID_FIELD_INVALID
);
850 tevent_req_received(req
);
854 recv_iov
= talloc_move(mem_ctx
, &state
->recv_iov
);
856 *pblob
= state
->ret_blob
;
858 if (pinbuf
!= NULL
) {
859 *pinbuf
= state
->inbuf
;
861 if (precv_iov
!= NULL
) {
862 *precv_iov
= recv_iov
;
864 /* could be NT_STATUS_MORE_PROCESSING_REQUIRED */
865 status
= state
->status
;
866 tevent_req_received(req
);
870 /****************************************************************************
871 Do a spnego/NTLMSSP encrypted session setup.
872 ****************************************************************************/
874 struct cli_session_setup_gensec_state
{
875 struct tevent_context
*ev
;
876 struct cli_state
*cli
;
877 struct auth_generic_state
*auth_generic
;
880 const uint8_t *inbuf
;
881 struct iovec
*recv_iov
;
885 DATA_BLOB session_key
;
888 static int cli_session_setup_gensec_state_destructor(
889 struct cli_session_setup_gensec_state
*state
)
891 TALLOC_FREE(state
->auth_generic
);
892 data_blob_clear_free(&state
->session_key
);
896 static void cli_session_setup_gensec_local_next(struct tevent_req
*req
);
897 static void cli_session_setup_gensec_local_done(struct tevent_req
*subreq
);
898 static void cli_session_setup_gensec_remote_next(struct tevent_req
*req
);
899 static void cli_session_setup_gensec_remote_done(struct tevent_req
*subreq
);
900 static void cli_session_setup_gensec_ready(struct tevent_req
*req
);
902 static struct tevent_req
*cli_session_setup_gensec_send(
903 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
904 struct cli_credentials
*creds
,
905 const char *target_service
,
906 const char *target_hostname
)
908 struct tevent_req
*req
;
909 struct cli_session_setup_gensec_state
*state
;
911 const DATA_BLOB
*b
= NULL
;
913 req
= tevent_req_create(mem_ctx
, &state
,
914 struct cli_session_setup_gensec_state
);
921 talloc_set_destructor(
922 state
, cli_session_setup_gensec_state_destructor
);
924 status
= auth_generic_client_prepare(state
, &state
->auth_generic
);
925 if (tevent_req_nterror(req
, status
)) {
926 return tevent_req_post(req
, ev
);
929 status
= auth_generic_set_creds(state
->auth_generic
, creds
);
930 if (tevent_req_nterror(req
, status
)) {
931 return tevent_req_post(req
, ev
);
934 gensec_want_feature(state
->auth_generic
->gensec_security
,
935 GENSEC_FEATURE_SESSION_KEY
);
937 if (target_service
!= NULL
) {
938 status
= gensec_set_target_service(
939 state
->auth_generic
->gensec_security
,
941 if (tevent_req_nterror(req
, status
)) {
942 return tevent_req_post(req
, ev
);
946 if (target_hostname
!= NULL
) {
947 status
= gensec_set_target_hostname(
948 state
->auth_generic
->gensec_security
,
950 if (tevent_req_nterror(req
, status
)) {
951 return tevent_req_post(req
, ev
);
955 b
= smbXcli_conn_server_gss_blob(cli
->conn
);
960 state
->is_anonymous
= cli_credentials_is_anonymous(state
->auth_generic
->credentials
);
962 status
= auth_generic_client_start(state
->auth_generic
,
964 if (tevent_req_nterror(req
, status
)) {
965 return tevent_req_post(req
, ev
);
968 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
969 state
->cli
->smb2
.session
= smbXcli_session_create(cli
,
971 if (tevent_req_nomem(state
->cli
->smb2
.session
, req
)) {
972 return tevent_req_post(req
, ev
);
976 cli_session_setup_gensec_local_next(req
);
977 if (!tevent_req_is_in_progress(req
)) {
978 return tevent_req_post(req
, ev
);
984 static void cli_session_setup_gensec_local_next(struct tevent_req
*req
)
986 struct cli_session_setup_gensec_state
*state
=
988 struct cli_session_setup_gensec_state
);
989 struct tevent_req
*subreq
= NULL
;
991 if (state
->local_ready
) {
992 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
996 subreq
= gensec_update_send(state
, state
->ev
,
997 state
->auth_generic
->gensec_security
,
999 if (tevent_req_nomem(subreq
, req
)) {
1002 tevent_req_set_callback(subreq
, cli_session_setup_gensec_local_done
, req
);
1005 static void cli_session_setup_gensec_local_done(struct tevent_req
*subreq
)
1007 struct tevent_req
*req
=
1008 tevent_req_callback_data(subreq
,
1010 struct cli_session_setup_gensec_state
*state
=
1011 tevent_req_data(req
,
1012 struct cli_session_setup_gensec_state
);
1015 status
= gensec_update_recv(subreq
, state
, &state
->blob_out
);
1016 TALLOC_FREE(subreq
);
1017 state
->blob_in
= data_blob_null
;
1018 if (!NT_STATUS_IS_OK(status
) &&
1019 !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
))
1021 tevent_req_nterror(req
, status
);
1025 if (NT_STATUS_IS_OK(status
)) {
1026 state
->local_ready
= true;
1029 if (state
->local_ready
&& state
->remote_ready
) {
1030 cli_session_setup_gensec_ready(req
);
1034 cli_session_setup_gensec_remote_next(req
);
1037 static void cli_session_setup_gensec_remote_next(struct tevent_req
*req
)
1039 struct cli_session_setup_gensec_state
*state
=
1040 tevent_req_data(req
,
1041 struct cli_session_setup_gensec_state
);
1042 struct tevent_req
*subreq
= NULL
;
1044 if (state
->remote_ready
) {
1045 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
1049 subreq
= cli_sesssetup_blob_send(state
, state
->ev
,
1050 state
->cli
, state
->blob_out
);
1051 if (tevent_req_nomem(subreq
, req
)) {
1054 tevent_req_set_callback(subreq
,
1055 cli_session_setup_gensec_remote_done
,
1059 static void cli_session_setup_gensec_remote_done(struct tevent_req
*subreq
)
1061 struct tevent_req
*req
=
1062 tevent_req_callback_data(subreq
,
1064 struct cli_session_setup_gensec_state
*state
=
1065 tevent_req_data(req
,
1066 struct cli_session_setup_gensec_state
);
1069 state
->inbuf
= NULL
;
1070 TALLOC_FREE(state
->recv_iov
);
1072 status
= cli_sesssetup_blob_recv(subreq
, state
, &state
->blob_in
,
1073 &state
->inbuf
, &state
->recv_iov
);
1074 TALLOC_FREE(subreq
);
1075 data_blob_free(&state
->blob_out
);
1076 if (!NT_STATUS_IS_OK(status
) &&
1077 !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
))
1079 tevent_req_nterror(req
, status
);
1083 if (NT_STATUS_IS_OK(status
)) {
1084 struct smbXcli_session
*session
= NULL
;
1085 bool is_guest
= false;
1087 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
1088 session
= state
->cli
->smb2
.session
;
1090 session
= state
->cli
->smb1
.session
;
1093 is_guest
= smbXcli_session_is_guest(session
);
1096 * We can't finish the gensec handshake, we don't
1097 * have a negotiated session key.
1099 * So just pretend we are completely done,
1100 * we need to continue as anonymous from this point,
1101 * as we can't get a session key.
1103 * Note that smbXcli_session_is_guest()
1104 * always returns false if we require signing.
1106 state
->blob_in
= data_blob_null
;
1107 state
->local_ready
= true;
1108 state
->is_anonymous
= true;
1111 state
->remote_ready
= true;
1114 if (state
->local_ready
&& state
->remote_ready
) {
1115 cli_session_setup_gensec_ready(req
);
1119 cli_session_setup_gensec_local_next(req
);
1122 static void cli_session_dump_keys(TALLOC_CTX
*mem_ctx
,
1123 struct smbXcli_session
*session
,
1124 DATA_BLOB session_key
)
1127 DATA_BLOB sig
= data_blob_null
;
1128 DATA_BLOB app
= data_blob_null
;
1129 DATA_BLOB enc
= data_blob_null
;
1130 DATA_BLOB dec
= data_blob_null
;
1131 uint64_t sid
= smb2cli_session_current_id(session
);
1133 status
= smb2cli_session_signing_key(session
, mem_ctx
, &sig
);
1134 if (!NT_STATUS_IS_OK(status
)) {
1137 status
= smbXcli_session_application_key(session
, mem_ctx
, &app
);
1138 if (!NT_STATUS_IS_OK(status
)) {
1141 status
= smb2cli_session_encryption_key(session
, mem_ctx
, &enc
);
1142 if (!NT_STATUS_IS_OK(status
)) {
1145 status
= smb2cli_session_decryption_key(session
, mem_ctx
, &dec
);
1146 if (!NT_STATUS_IS_OK(status
)) {
1150 DEBUG(0, ("debug encryption: dumping generated session keys\n"));
1151 DEBUGADD(0, ("Session Id "));
1152 dump_data(0, (uint8_t*)&sid
, sizeof(sid
));
1153 DEBUGADD(0, ("Session Key "));
1154 dump_data(0, session_key
.data
, session_key
.length
);
1155 DEBUGADD(0, ("Signing Key "));
1156 dump_data(0, sig
.data
, sig
.length
);
1157 DEBUGADD(0, ("App Key "));
1158 dump_data(0, app
.data
, app
.length
);
1160 /* In client code, ServerIn is the encryption key */
1162 DEBUGADD(0, ("ServerIn Key "));
1163 dump_data(0, enc
.data
, enc
.length
);
1164 DEBUGADD(0, ("ServerOut Key "));
1165 dump_data(0, dec
.data
, dec
.length
);
1168 data_blob_clear_free(&sig
);
1169 data_blob_clear_free(&app
);
1170 data_blob_clear_free(&enc
);
1171 data_blob_clear_free(&dec
);
1174 static void cli_session_setup_gensec_ready(struct tevent_req
*req
)
1176 struct cli_session_setup_gensec_state
*state
=
1177 tevent_req_data(req
,
1178 struct cli_session_setup_gensec_state
);
1179 const char *server_domain
= NULL
;
1182 if (state
->blob_in
.length
!= 0) {
1183 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
1187 if (state
->blob_out
.length
!= 0) {
1188 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
1193 * gensec_ntlmssp_server_domain() returns NULL
1194 * if NTLMSSP is not used.
1196 * We can remove this later
1197 * and leave the server domain empty for SMB2 and above
1198 * in future releases.
1200 server_domain
= gensec_ntlmssp_server_domain(
1201 state
->auth_generic
->gensec_security
);
1203 if (state
->cli
->server_domain
[0] == '\0' && server_domain
!= NULL
) {
1204 TALLOC_FREE(state
->cli
->server_domain
);
1205 state
->cli
->server_domain
= talloc_strdup(state
->cli
,
1207 if (state
->cli
->server_domain
== NULL
) {
1208 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
1213 if (state
->is_anonymous
) {
1215 * Windows server does not set the
1216 * SMB2_SESSION_FLAG_IS_NULL flag.
1218 * This fix makes sure we do not try
1219 * to verify a signature on the final
1220 * session setup response.
1222 tevent_req_done(req
);
1226 status
= gensec_session_key(state
->auth_generic
->gensec_security
,
1227 state
, &state
->session_key
);
1228 if (tevent_req_nterror(req
, status
)) {
1232 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
1233 struct smbXcli_session
*session
= state
->cli
->smb2
.session
;
1235 status
= smb2cli_session_set_session_key(session
,
1238 if (tevent_req_nterror(req
, status
)) {
1241 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB3_00
1242 && lp_debug_encryption())
1244 cli_session_dump_keys(state
, session
, state
->session_key
);
1247 struct smbXcli_session
*session
= state
->cli
->smb1
.session
;
1250 status
= smb1cli_session_set_session_key(session
,
1251 state
->session_key
);
1252 if (tevent_req_nterror(req
, status
)) {
1256 active
= smb1cli_conn_activate_signing(state
->cli
->conn
,
1262 ok
= smb1cli_conn_check_signing(state
->cli
->conn
,
1265 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1271 tevent_req_done(req
);
1274 static NTSTATUS
cli_session_setup_gensec_recv(struct tevent_req
*req
)
1276 struct cli_session_setup_gensec_state
*state
=
1277 tevent_req_data(req
,
1278 struct cli_session_setup_gensec_state
);
1281 if (tevent_req_is_nterror(req
, &status
)) {
1282 cli_state_set_uid(state
->cli
, UID_FIELD_INVALID
);
1285 return NT_STATUS_OK
;
1288 static char *cli_session_setup_get_account(TALLOC_CTX
*mem_ctx
,
1289 const char *principal
)
1293 account
= talloc_strdup(mem_ctx
, principal
);
1294 if (account
== NULL
) {
1297 p
= strchr_m(account
, '@');
1304 /****************************************************************************
1305 Do a spnego encrypted session setup.
1307 user_domain: The shortname of the domain the user/machine is a member of.
1308 dest_realm: The realm we're connecting to, if NULL we use our default realm.
1309 ****************************************************************************/
1311 struct cli_session_setup_spnego_state
{
1315 static void cli_session_setup_spnego_done(struct tevent_req
*subreq
);
1317 static struct tevent_req
*cli_session_setup_spnego_send(
1318 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
1319 struct cli_credentials
*creds
)
1321 struct tevent_req
*req
, *subreq
;
1322 struct cli_session_setup_spnego_state
*state
;
1323 const char *target_service
= NULL
;
1324 const char *target_hostname
= NULL
;
1327 req
= tevent_req_create(mem_ctx
, &state
,
1328 struct cli_session_setup_spnego_state
);
1333 target_service
= "cifs";
1334 target_hostname
= smbXcli_conn_remote_name(cli
->conn
);
1336 status
= cli_session_creds_prepare_krb5(cli
, creds
);
1337 if (tevent_req_nterror(req
, status
)) {
1338 return tevent_req_post(req
, ev
);
1341 DBG_INFO("Connect to %s as %s using SPNEGO\n",
1343 cli_credentials_get_principal(creds
, talloc_tos()));
1345 subreq
= cli_session_setup_gensec_send(state
, ev
, cli
, creds
,
1346 target_service
, target_hostname
);
1347 if (tevent_req_nomem(subreq
, req
)) {
1348 return tevent_req_post(req
, ev
);
1350 tevent_req_set_callback(
1351 subreq
, cli_session_setup_spnego_done
, req
);
1355 static void cli_session_setup_spnego_done(struct tevent_req
*subreq
)
1357 struct tevent_req
*req
= tevent_req_callback_data(
1358 subreq
, struct tevent_req
);
1361 status
= cli_session_setup_gensec_recv(subreq
);
1362 TALLOC_FREE(subreq
);
1363 if (tevent_req_nterror(req
, status
)) {
1367 tevent_req_done(req
);
1370 static ADS_STATUS
cli_session_setup_spnego_recv(struct tevent_req
*req
)
1372 struct cli_session_setup_spnego_state
*state
= tevent_req_data(
1373 req
, struct cli_session_setup_spnego_state
);
1376 if (tevent_req_is_nterror(req
, &status
)) {
1377 state
->result
= ADS_ERROR_NT(status
);
1380 return state
->result
;
1383 struct cli_session_setup_creds_state
{
1384 struct cli_state
*cli
;
1385 DATA_BLOB apassword_blob
;
1386 DATA_BLOB upassword_blob
;
1387 DATA_BLOB lm_session_key
;
1388 DATA_BLOB session_key
;
1389 char *out_native_os
;
1390 char *out_native_lm
;
1391 char *out_primary_domain
;
1394 static void cli_session_setup_creds_cleanup(struct tevent_req
*req
,
1395 enum tevent_req_state req_state
)
1397 struct cli_session_setup_creds_state
*state
= tevent_req_data(
1398 req
, struct cli_session_setup_creds_state
);
1400 if (req_state
!= TEVENT_REQ_RECEIVED
) {
1405 * We only call data_blob_clear() as
1406 * some of the blobs point to the same memory.
1408 * We let the talloc hierarchy free the memory.
1410 data_blob_clear(&state
->apassword_blob
);
1411 data_blob_clear(&state
->upassword_blob
);
1412 data_blob_clear(&state
->lm_session_key
);
1413 data_blob_clear(&state
->session_key
);
1414 ZERO_STRUCTP(state
);
1417 static void cli_session_setup_creds_done_spnego(struct tevent_req
*subreq
);
1418 static void cli_session_setup_creds_done_nt1(struct tevent_req
*subreq
);
1419 static void cli_session_setup_creds_done_lm21(struct tevent_req
*subreq
);
1421 /****************************************************************************
1422 Send a session setup. The username and workgroup is in UNIX character
1423 format and must be converted to DOS codepage format before sending. If the
1424 password is in plaintext, the same should be done.
1425 ****************************************************************************/
1427 struct tevent_req
*cli_session_setup_creds_send(TALLOC_CTX
*mem_ctx
,
1428 struct tevent_context
*ev
,
1429 struct cli_state
*cli
,
1430 struct cli_credentials
*creds
)
1432 struct tevent_req
*req
, *subreq
;
1433 struct cli_session_setup_creds_state
*state
;
1434 uint16_t sec_mode
= smb1cli_conn_server_security_mode(cli
->conn
);
1435 bool use_spnego
= false;
1437 enum credentials_use_kerberos krb5_state
;
1438 uint32_t gensec_features
;
1439 const char *username
= "";
1440 const char *domain
= "";
1441 DATA_BLOB target_info
= data_blob_null
;
1442 DATA_BLOB challenge
= data_blob_null
;
1443 uint16_t in_buf_size
= 0;
1444 uint16_t in_mpx_max
= 0;
1445 uint16_t in_vc_num
= 0;
1446 uint32_t in_sess_key
= 0;
1447 const char *in_native_os
= NULL
;
1448 const char *in_native_lm
= NULL
;
1451 req
= tevent_req_create(mem_ctx
, &state
,
1452 struct cli_session_setup_creds_state
);
1458 tevent_req_set_cleanup_fn(req
, cli_session_setup_creds_cleanup
);
1460 krb5_state
= cli_credentials_get_kerberos_state(creds
);
1461 gensec_features
= cli_credentials_get_gensec_features(creds
);
1463 switch (krb5_state
) {
1464 case CRED_MUST_USE_KERBEROS
:
1465 cli
->use_kerberos
= true;
1466 cli
->fallback_after_kerberos
= false;
1468 case CRED_AUTO_USE_KERBEROS
:
1469 cli
->use_kerberos
= true;
1470 cli
->fallback_after_kerberos
= true;
1472 case CRED_DONT_USE_KERBEROS
:
1473 cli
->use_kerberos
= false;
1474 cli
->fallback_after_kerberos
= false;
1478 if (gensec_features
& GENSEC_FEATURE_NTLM_CCACHE
) {
1479 cli
->use_ccache
= true;
1481 cli
->use_ccache
= false;
1485 * Now work out what sort of session setup we are going to
1486 * do. I have split this into separate functions to make the flow a bit
1487 * easier to understand (tridge).
1489 if (smbXcli_conn_protocol(cli
->conn
) < PROTOCOL_NT1
) {
1491 } else if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
1493 } else if (smb1cli_conn_capabilities(cli
->conn
) & CAP_EXTENDED_SECURITY
) {
1495 * if the server supports extended security then use SPNEGO
1496 * even for anonymous connections.
1504 subreq
= cli_session_setup_spnego_send(
1505 state
, ev
, cli
, creds
);
1506 if (tevent_req_nomem(subreq
, req
)) {
1507 return tevent_req_post(req
, ev
);
1509 tevent_req_set_callback(subreq
, cli_session_setup_creds_done_spnego
,
1514 if (smbXcli_conn_protocol(cli
->conn
) < PROTOCOL_LANMAN1
) {
1516 * SessionSetupAndX was introduced by LANMAN 1.0. So we skip
1517 * this step against older servers.
1519 tevent_req_done(req
);
1520 return tevent_req_post(req
, ev
);
1523 if (cli_credentials_is_anonymous(creds
)) {
1525 * Do an anonymous session setup
1527 goto non_spnego_creds_done
;
1530 if ((sec_mode
& NEGOTIATE_SECURITY_USER_LEVEL
) == 0) {
1532 * Do an anonymous session setup,
1533 * the password is passed via the tree connect.
1535 goto non_spnego_creds_done
;
1538 cli_credentials_get_ntlm_username_domain(creds
, state
,
1541 if (tevent_req_nomem(username
, req
)) {
1542 return tevent_req_post(req
, ev
);
1544 if (tevent_req_nomem(domain
, req
)) {
1545 return tevent_req_post(req
, ev
);
1548 DBG_INFO("Connect to %s as %s using NTLM\n", domain
, username
);
1550 if ((sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
) == 0) {
1551 bool use_unicode
= smbXcli_conn_use_unicode(cli
->conn
);
1552 uint8_t *bytes
= NULL
;
1553 size_t bytes_len
= 0;
1554 const char *pw
= cli_credentials_get_password(creds
);
1560 pw_len
= strlen(pw
) + 1;
1562 if (!lp_client_plaintext_auth()) {
1563 DEBUG(1, ("Server requested PLAINTEXT password but "
1564 "'client plaintext auth = no'\n"));
1565 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1566 return tevent_req_post(req
, ev
);
1569 bytes
= talloc_array(state
, uint8_t, 0);
1570 bytes
= trans2_bytes_push_str(bytes
, use_unicode
,
1571 pw
, pw_len
, &bytes_len
);
1572 if (tevent_req_nomem(bytes
, req
)) {
1573 return tevent_req_post(req
, ev
);
1578 * CAP_UNICODE, can only be negotiated by NT1.
1580 state
->upassword_blob
= data_blob_const(bytes
,
1583 state
->apassword_blob
= data_blob_const(bytes
,
1587 goto non_spnego_creds_done
;
1590 challenge
= data_blob_const(smb1cli_conn_server_challenge(cli
->conn
), 8);
1592 if (smbXcli_conn_protocol(cli
->conn
) == PROTOCOL_NT1
) {
1593 if (lp_client_ntlmv2_auth() && lp_client_use_spnego()) {
1595 * Don't send an NTLMv2 response without NTLMSSP if we
1596 * want to use spnego support.
1598 DEBUG(1, ("Server does not support EXTENDED_SECURITY "
1599 " but 'client use spnego = yes'"
1600 " and 'client ntlmv2 auth = yes' is set\n"));
1601 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1602 return tevent_req_post(req
, ev
);
1605 if (lp_client_ntlmv2_auth()) {
1606 flags
|= CLI_CRED_NTLMv2_AUTH
;
1609 * note that the 'domain' here is a best
1610 * guess - we don't know the server's domain
1611 * at this point. Windows clients also don't
1614 target_info
= NTLMv2_generate_names_blob(state
,
1617 if (tevent_req_nomem(target_info
.data
, req
)) {
1618 return tevent_req_post(req
, ev
);
1621 flags
|= CLI_CRED_NTLM_AUTH
;
1622 if (lp_client_lanman_auth()) {
1623 flags
|= CLI_CRED_LANMAN_AUTH
;
1627 if (!lp_client_lanman_auth()) {
1628 DEBUG(1, ("Server requested user level LM password but "
1629 "'client lanman auth = no' is set.\n"));
1630 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1631 return tevent_req_post(req
, ev
);
1634 flags
|= CLI_CRED_LANMAN_AUTH
;
1637 status
= cli_credentials_get_ntlm_response(creds
, state
, &flags
,
1640 &state
->apassword_blob
,
1641 &state
->upassword_blob
,
1642 &state
->lm_session_key
,
1643 &state
->session_key
);
1644 if (tevent_req_nterror(req
, status
)) {
1645 return tevent_req_post(req
, ev
);
1648 non_spnego_creds_done
:
1650 in_buf_size
= CLI_BUFFER_SIZE
;
1651 in_mpx_max
= smbXcli_conn_max_requests(cli
->conn
);
1652 in_vc_num
= cli_state_get_vc_num(cli
);
1653 in_sess_key
= smb1cli_conn_server_session_key(cli
->conn
);
1654 in_native_os
= "Unix";
1655 in_native_lm
= "Samba";
1657 if (smbXcli_conn_protocol(cli
->conn
) == PROTOCOL_NT1
) {
1658 uint32_t in_capabilities
= 0;
1660 in_capabilities
= cli_session_setup_capabilities(cli
, 0);
1663 * For now we keep the same values as before,
1664 * we may remove these in a separate commit later.
1668 subreq
= smb1cli_session_setup_nt1_send(state
, ev
,
1679 state
->apassword_blob
,
1680 state
->upassword_blob
,
1684 if (tevent_req_nomem(subreq
, req
)) {
1685 return tevent_req_post(req
, ev
);
1687 tevent_req_set_callback(subreq
, cli_session_setup_creds_done_nt1
,
1693 * For now we keep the same values as before,
1694 * we may remove these in a separate commit later.
1699 subreq
= smb1cli_session_setup_lm21_send(state
, ev
,
1710 state
->apassword_blob
,
1713 if (tevent_req_nomem(subreq
, req
)) {
1714 return tevent_req_post(req
, ev
);
1716 tevent_req_set_callback(subreq
, cli_session_setup_creds_done_lm21
,
1721 static void cli_session_setup_creds_done_spnego(struct tevent_req
*subreq
)
1723 struct tevent_req
*req
= tevent_req_callback_data(
1724 subreq
, struct tevent_req
);
1727 status
= cli_session_setup_spnego_recv(subreq
);
1728 TALLOC_FREE(subreq
);
1729 if (!ADS_ERR_OK(status
)) {
1730 DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status
)));
1731 tevent_req_nterror(req
, ads_ntstatus(status
));
1734 tevent_req_done(req
);
1737 static void cli_session_setup_creds_done_nt1(struct tevent_req
*subreq
)
1739 struct tevent_req
*req
= tevent_req_callback_data(
1740 subreq
, struct tevent_req
);
1741 struct cli_session_setup_creds_state
*state
= tevent_req_data(
1742 req
, struct cli_session_setup_creds_state
);
1743 struct cli_state
*cli
= state
->cli
;
1745 struct iovec
*recv_iov
= NULL
;
1746 const uint8_t *inbuf
= NULL
;
1749 status
= smb1cli_session_setup_nt1_recv(subreq
, state
,
1752 &state
->out_native_os
,
1753 &state
->out_native_lm
,
1754 &state
->out_primary_domain
);
1755 TALLOC_FREE(subreq
);
1756 if (!NT_STATUS_IS_OK(status
)) {
1757 DEBUG(3, ("NT1 login failed: %s\n", nt_errstr(status
)));
1758 tevent_req_nterror(req
, status
);
1762 status
= cli_state_update_after_sesssetup(state
->cli
,
1763 state
->out_native_os
,
1764 state
->out_native_lm
,
1765 state
->out_primary_domain
);
1766 if (tevent_req_nterror(req
, status
)) {
1770 ok
= smb1cli_conn_activate_signing(cli
->conn
,
1772 state
->upassword_blob
);
1774 ok
= smb1cli_conn_check_signing(cli
->conn
, inbuf
, 1);
1776 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1781 if (state
->session_key
.data
) {
1782 struct smbXcli_session
*session
= cli
->smb1
.session
;
1784 status
= smb1cli_session_set_session_key(session
,
1785 state
->session_key
);
1786 if (tevent_req_nterror(req
, status
)) {
1791 tevent_req_done(req
);
1794 static void cli_session_setup_creds_done_lm21(struct tevent_req
*subreq
)
1796 struct tevent_req
*req
= tevent_req_callback_data(
1797 subreq
, struct tevent_req
);
1798 struct cli_session_setup_creds_state
*state
= tevent_req_data(
1799 req
, struct cli_session_setup_creds_state
);
1802 status
= smb1cli_session_setup_lm21_recv(subreq
, state
,
1803 &state
->out_native_os
,
1804 &state
->out_native_lm
);
1805 TALLOC_FREE(subreq
);
1806 if (!NT_STATUS_IS_OK(status
)) {
1807 DEBUG(3, ("LM21 login failed: %s\n", nt_errstr(status
)));
1808 tevent_req_nterror(req
, status
);
1812 status
= cli_state_update_after_sesssetup(state
->cli
,
1813 state
->out_native_os
,
1814 state
->out_native_lm
,
1816 if (tevent_req_nterror(req
, status
)) {
1820 tevent_req_done(req
);
1823 NTSTATUS
cli_session_setup_creds_recv(struct tevent_req
*req
)
1825 return tevent_req_simple_recv_ntstatus(req
);
1828 NTSTATUS
cli_session_setup_creds(struct cli_state
*cli
,
1829 struct cli_credentials
*creds
)
1831 struct tevent_context
*ev
;
1832 struct tevent_req
*req
;
1833 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
1835 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
1836 return NT_STATUS_INVALID_PARAMETER
;
1838 ev
= samba_tevent_context_init(talloc_tos());
1842 req
= cli_session_setup_creds_send(ev
, ev
, cli
, creds
);
1846 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
1849 status
= cli_session_setup_creds_recv(req
);
1855 NTSTATUS
cli_session_setup_anon(struct cli_state
*cli
)
1858 struct cli_credentials
*creds
= NULL
;
1860 creds
= cli_credentials_init_anon(cli
);
1861 if (creds
== NULL
) {
1862 return NT_STATUS_NO_MEMORY
;
1865 status
= cli_session_setup_creds(cli
, creds
);
1867 if (!NT_STATUS_IS_OK(status
)) {
1871 return NT_STATUS_OK
;
1874 /****************************************************************************
1876 *****************************************************************************/
1878 struct cli_ulogoff_state
{
1879 struct cli_state
*cli
;
1883 static void cli_ulogoff_done(struct tevent_req
*subreq
);
1885 static struct tevent_req
*cli_ulogoff_send(TALLOC_CTX
*mem_ctx
,
1886 struct tevent_context
*ev
,
1887 struct cli_state
*cli
)
1889 struct tevent_req
*req
, *subreq
;
1890 struct cli_ulogoff_state
*state
;
1892 req
= tevent_req_create(mem_ctx
, &state
, struct cli_ulogoff_state
);
1898 SCVAL(state
->vwv
+0, 0, 0xFF);
1899 SCVAL(state
->vwv
+1, 0, 0);
1900 SSVAL(state
->vwv
+2, 0, 0);
1902 subreq
= cli_smb_send(state
, ev
, cli
, SMBulogoffX
, 0, 0, 2, state
->vwv
,
1904 if (tevent_req_nomem(subreq
, req
)) {
1905 return tevent_req_post(req
, ev
);
1907 tevent_req_set_callback(subreq
, cli_ulogoff_done
, req
);
1911 static void cli_ulogoff_done(struct tevent_req
*subreq
)
1913 struct tevent_req
*req
= tevent_req_callback_data(
1914 subreq
, struct tevent_req
);
1915 struct cli_ulogoff_state
*state
= tevent_req_data(
1916 req
, struct cli_ulogoff_state
);
1919 status
= cli_smb_recv(subreq
, NULL
, NULL
, 0, NULL
, NULL
, NULL
, NULL
);
1920 if (!NT_STATUS_IS_OK(status
)) {
1921 tevent_req_nterror(req
, status
);
1924 cli_state_set_uid(state
->cli
, UID_FIELD_INVALID
);
1925 tevent_req_done(req
);
1928 static NTSTATUS
cli_ulogoff_recv(struct tevent_req
*req
)
1930 return tevent_req_simple_recv_ntstatus(req
);
1933 NTSTATUS
cli_ulogoff(struct cli_state
*cli
)
1935 struct tevent_context
*ev
;
1936 struct tevent_req
*req
;
1937 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
1939 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
1940 status
= smb2cli_logoff(cli
->conn
,
1943 if (!NT_STATUS_IS_OK(status
)) {
1946 smb2cli_session_set_id_and_flags(cli
->smb2
.session
,
1948 return NT_STATUS_OK
;
1951 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
1952 return NT_STATUS_INVALID_PARAMETER
;
1954 ev
= samba_tevent_context_init(talloc_tos());
1958 req
= cli_ulogoff_send(ev
, ev
, cli
);
1962 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
1965 status
= cli_ulogoff_recv(req
);
1971 /****************************************************************************
1973 ****************************************************************************/
1975 struct cli_tcon_andx_state
{
1976 struct cli_state
*cli
;
1981 static void cli_tcon_andx_done(struct tevent_req
*subreq
);
1983 struct tevent_req
*cli_tcon_andx_create(TALLOC_CTX
*mem_ctx
,
1984 struct tevent_context
*ev
,
1985 struct cli_state
*cli
,
1986 const char *share
, const char *dev
,
1987 const char *pass
, int passlen
,
1988 struct tevent_req
**psmbreq
)
1990 struct tevent_req
*req
, *subreq
;
1991 struct cli_tcon_andx_state
*state
;
1996 uint16_t sec_mode
= smb1cli_conn_server_security_mode(cli
->conn
);
1997 uint16_t tcon_flags
= 0;
2001 req
= tevent_req_create(mem_ctx
, &state
, struct cli_tcon_andx_state
);
2008 TALLOC_FREE(cli
->smb1
.tcon
);
2009 cli
->smb1
.tcon
= smbXcli_tcon_create(cli
);
2010 if (tevent_req_nomem(cli
->smb1
.tcon
, req
)) {
2011 return tevent_req_post(req
, ev
);
2013 smb1cli_tcon_set_id(cli
->smb1
.tcon
, UINT16_MAX
);
2015 cli
->share
= talloc_strdup(cli
, share
);
2020 /* in user level security don't send a password now */
2021 if (sec_mode
& NEGOTIATE_SECURITY_USER_LEVEL
) {
2024 } else if (pass
== NULL
) {
2025 DEBUG(1, ("Server not using user level security and no "
2026 "password supplied.\n"));
2030 if ((sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
) &&
2031 *pass
&& passlen
!= 24) {
2032 if (!lp_client_lanman_auth()) {
2033 DEBUG(1, ("Server requested LANMAN password "
2034 "(share-level security) but "
2035 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2040 * Non-encrypted passwords - convert to DOS codepage before
2043 SMBencrypt(pass
, smb1cli_conn_server_challenge(cli
->conn
), p24
);
2045 pass
= (const char *)p24
;
2047 if((sec_mode
& (NEGOTIATE_SECURITY_USER_LEVEL
2048 |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
))
2052 if (!lp_client_plaintext_auth() && (*pass
)) {
2053 DEBUG(1, ("Server requested PLAINTEXT "
2055 "'client plaintext auth = no' or 'client ntlmv2 auth = yes'\n"));
2060 * Non-encrypted passwords - convert to DOS codepage
2063 tmp_pass
= talloc_array(talloc_tos(), uint8_t, 0);
2064 if (tevent_req_nomem(tmp_pass
, req
)) {
2065 return tevent_req_post(req
, ev
);
2067 tmp_pass
= trans2_bytes_push_str(tmp_pass
,
2068 false, /* always DOS */
2072 if (tevent_req_nomem(tmp_pass
, req
)) {
2073 return tevent_req_post(req
, ev
);
2075 pass
= (const char *)tmp_pass
;
2076 passlen
= talloc_get_size(tmp_pass
);
2080 tcon_flags
|= TCONX_FLAG_EXTENDED_RESPONSE
;
2081 tcon_flags
|= TCONX_FLAG_EXTENDED_SIGNATURES
;
2083 SCVAL(vwv
+0, 0, 0xFF);
2086 SSVAL(vwv
+2, 0, tcon_flags
);
2087 SSVAL(vwv
+3, 0, passlen
);
2089 if (passlen
&& pass
) {
2090 bytes
= (uint8_t *)talloc_memdup(state
, pass
, passlen
);
2092 bytes
= talloc_array(state
, uint8_t, 0);
2098 tmp
= talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
2099 smbXcli_conn_remote_name(cli
->conn
), share
);
2104 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), tmp
, strlen(tmp
)+1,
2109 * Add the devicetype
2111 tmp
= talloc_strdup_upper(talloc_tos(), dev
);
2116 bytes
= smb_bytes_push_str(bytes
, false, tmp
, strlen(tmp
)+1, NULL
);
2119 if (bytes
== NULL
) {
2124 state
->bytes
.iov_base
= (void *)bytes
;
2125 state
->bytes
.iov_len
= talloc_get_size(bytes
);
2127 subreq
= cli_smb_req_create(state
, ev
, cli
, SMBtconX
, 0, 0, 4, vwv
,
2129 if (subreq
== NULL
) {
2133 tevent_req_set_callback(subreq
, cli_tcon_andx_done
, req
);
2138 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
2139 return tevent_req_post(req
, ev
);
2142 struct tevent_req
*cli_tcon_andx_send(TALLOC_CTX
*mem_ctx
,
2143 struct tevent_context
*ev
,
2144 struct cli_state
*cli
,
2145 const char *share
, const char *dev
,
2146 const char *pass
, int passlen
)
2148 struct tevent_req
*req
, *subreq
;
2151 req
= cli_tcon_andx_create(mem_ctx
, ev
, cli
, share
, dev
, pass
, passlen
,
2156 if (subreq
== NULL
) {
2159 status
= smb1cli_req_chain_submit(&subreq
, 1);
2160 if (!NT_STATUS_IS_OK(status
)) {
2161 tevent_req_nterror(req
, status
);
2162 return tevent_req_post(req
, ev
);
2167 static void cli_tcon_andx_done(struct tevent_req
*subreq
)
2169 struct tevent_req
*req
= tevent_req_callback_data(
2170 subreq
, struct tevent_req
);
2171 struct cli_tcon_andx_state
*state
= tevent_req_data(
2172 req
, struct cli_tcon_andx_state
);
2173 struct cli_state
*cli
= state
->cli
;
2181 uint16_t optional_support
= 0;
2183 status
= cli_smb_recv(subreq
, state
, &in
, 0, &wct
, &vwv
,
2184 &num_bytes
, &bytes
);
2185 TALLOC_FREE(subreq
);
2186 if (!NT_STATUS_IS_OK(status
)) {
2187 tevent_req_nterror(req
, status
);
2191 inhdr
= in
+ NBT_HDR_SIZE
;
2194 if (clistr_pull_talloc(cli
,
2195 (const char *)inhdr
,
2196 SVAL(inhdr
, HDR_FLG2
),
2200 STR_TERMINATE
|STR_ASCII
) == -1) {
2201 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
2205 cli
->dev
= talloc_strdup(cli
, "");
2206 if (cli
->dev
== NULL
) {
2207 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
2212 if ((smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_NT1
) && (num_bytes
== 3)) {
2213 /* almost certainly win95 - enable bug fixes */
2218 * Make sure that we have the optional support 16-bit field. WCT > 2.
2219 * Avoids issues when connecting to Win9x boxes sharing files
2222 if ((wct
> 2) && (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_LANMAN2
)) {
2223 optional_support
= SVAL(vwv
+2, 0);
2226 if (optional_support
& SMB_EXTENDED_SIGNATURES
) {
2227 smb1cli_session_protect_session_key(cli
->smb1
.session
);
2230 smb1cli_tcon_set_values(state
->cli
->smb1
.tcon
,
2231 SVAL(inhdr
, HDR_TID
),
2233 0, /* maximal_access */
2234 0, /* guest_maximal_access */
2236 NULL
); /* fs_type */
2238 tevent_req_done(req
);
2241 NTSTATUS
cli_tcon_andx_recv(struct tevent_req
*req
)
2243 return tevent_req_simple_recv_ntstatus(req
);
2246 NTSTATUS
cli_tcon_andx(struct cli_state
*cli
, const char *share
,
2247 const char *dev
, const char *pass
, int passlen
)
2249 TALLOC_CTX
*frame
= talloc_stackframe();
2250 struct tevent_context
*ev
;
2251 struct tevent_req
*req
;
2252 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2254 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
2256 * Can't use sync call while an async call is in flight
2258 status
= NT_STATUS_INVALID_PARAMETER
;
2262 ev
= samba_tevent_context_init(frame
);
2267 req
= cli_tcon_andx_send(frame
, ev
, cli
, share
, dev
, pass
, passlen
);
2272 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2276 status
= cli_tcon_andx_recv(req
);
2282 struct cli_tree_connect_state
{
2283 struct cli_state
*cli
;
2286 static struct tevent_req
*cli_raw_tcon_send(
2287 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
2288 const char *service
, const char *pass
, const char *dev
);
2289 static NTSTATUS
cli_raw_tcon_recv(struct tevent_req
*req
,
2290 uint16_t *max_xmit
, uint16_t *tid
);
2292 static void cli_tree_connect_smb2_done(struct tevent_req
*subreq
);
2293 static void cli_tree_connect_andx_done(struct tevent_req
*subreq
);
2294 static void cli_tree_connect_raw_done(struct tevent_req
*subreq
);
2296 static struct tevent_req
*cli_tree_connect_send(
2297 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
2298 const char *share
, const char *dev
, const char *pass
)
2300 struct tevent_req
*req
, *subreq
;
2301 struct cli_tree_connect_state
*state
;
2307 passlen
= strlen(pass
) + 1;
2309 req
= tevent_req_create(mem_ctx
, &state
,
2310 struct cli_tree_connect_state
);
2316 cli
->share
= talloc_strdup(cli
, share
);
2317 if (tevent_req_nomem(cli
->share
, req
)) {
2318 return tevent_req_post(req
, ev
);
2321 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
2324 TALLOC_FREE(cli
->smb2
.tcon
);
2325 cli
->smb2
.tcon
= smbXcli_tcon_create(cli
);
2326 if (tevent_req_nomem(cli
->smb2
.tcon
, req
)) {
2327 return tevent_req_post(req
, ev
);
2330 unc
= talloc_asprintf(state
, "\\\\%s\\%s",
2331 smbXcli_conn_remote_name(cli
->conn
),
2333 if (tevent_req_nomem(unc
, req
)) {
2334 return tevent_req_post(req
, ev
);
2337 subreq
= smb2cli_tcon_send(state
, ev
, cli
->conn
, cli
->timeout
,
2338 cli
->smb2
.session
, cli
->smb2
.tcon
,
2341 if (tevent_req_nomem(subreq
, req
)) {
2342 return tevent_req_post(req
, ev
);
2344 tevent_req_set_callback(subreq
, cli_tree_connect_smb2_done
,
2349 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_LANMAN1
) {
2350 subreq
= cli_tcon_andx_send(state
, ev
, cli
, share
, dev
,
2352 if (tevent_req_nomem(subreq
, req
)) {
2353 return tevent_req_post(req
, ev
);
2355 tevent_req_set_callback(subreq
, cli_tree_connect_andx_done
,
2360 subreq
= cli_raw_tcon_send(state
, ev
, cli
, share
, pass
, dev
);
2361 if (tevent_req_nomem(subreq
, req
)) {
2362 return tevent_req_post(req
, ev
);
2364 tevent_req_set_callback(subreq
, cli_tree_connect_raw_done
, req
);
2369 static void cli_tree_connect_smb2_done(struct tevent_req
*subreq
)
2371 tevent_req_simple_finish_ntstatus(
2372 subreq
, smb2cli_tcon_recv(subreq
));
2375 static void cli_tree_connect_andx_done(struct tevent_req
*subreq
)
2377 tevent_req_simple_finish_ntstatus(
2378 subreq
, cli_tcon_andx_recv(subreq
));
2381 static void cli_tree_connect_raw_done(struct tevent_req
*subreq
)
2383 struct tevent_req
*req
= tevent_req_callback_data(
2384 subreq
, struct tevent_req
);
2385 struct cli_tree_connect_state
*state
= tevent_req_data(
2386 req
, struct cli_tree_connect_state
);
2388 uint16_t max_xmit
= 0;
2391 status
= cli_raw_tcon_recv(subreq
, &max_xmit
, &tid
);
2392 if (tevent_req_nterror(req
, status
)) {
2396 smb1cli_tcon_set_values(state
->cli
->smb1
.tcon
,
2398 0, /* optional_support */
2399 0, /* maximal_access */
2400 0, /* guest_maximal_access */
2402 NULL
); /* fs_type */
2404 tevent_req_done(req
);
2407 static NTSTATUS
cli_tree_connect_recv(struct tevent_req
*req
)
2409 return tevent_req_simple_recv_ntstatus(req
);
2412 NTSTATUS
cli_tree_connect(struct cli_state
*cli
, const char *share
,
2413 const char *dev
, const char *pass
)
2415 struct tevent_context
*ev
;
2416 struct tevent_req
*req
;
2417 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2419 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
2420 return NT_STATUS_INVALID_PARAMETER
;
2422 ev
= samba_tevent_context_init(talloc_tos());
2426 req
= cli_tree_connect_send(ev
, ev
, cli
, share
, dev
, pass
);
2430 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2433 status
= cli_tree_connect_recv(req
);
2439 NTSTATUS
cli_tree_connect_creds(struct cli_state
*cli
,
2440 const char *share
, const char *dev
,
2441 struct cli_credentials
*creds
)
2443 const char *pw
= NULL
;
2445 if (creds
!= NULL
) {
2446 pw
= cli_credentials_get_password(creds
);
2449 return cli_tree_connect(cli
, share
, dev
, pw
);
2452 /****************************************************************************
2453 Send a tree disconnect.
2454 ****************************************************************************/
2456 struct cli_tdis_state
{
2457 struct cli_state
*cli
;
2460 static void cli_tdis_done(struct tevent_req
*subreq
);
2462 static struct tevent_req
*cli_tdis_send(TALLOC_CTX
*mem_ctx
,
2463 struct tevent_context
*ev
,
2464 struct cli_state
*cli
)
2466 struct tevent_req
*req
, *subreq
;
2467 struct cli_tdis_state
*state
;
2469 req
= tevent_req_create(mem_ctx
, &state
, struct cli_tdis_state
);
2475 subreq
= cli_smb_send(state
, ev
, cli
, SMBtdis
, 0, 0, 0, NULL
, 0, NULL
);
2476 if (tevent_req_nomem(subreq
, req
)) {
2477 return tevent_req_post(req
, ev
);
2479 tevent_req_set_callback(subreq
, cli_tdis_done
, req
);
2483 static void cli_tdis_done(struct tevent_req
*subreq
)
2485 struct tevent_req
*req
= tevent_req_callback_data(
2486 subreq
, struct tevent_req
);
2487 struct cli_tdis_state
*state
= tevent_req_data(
2488 req
, struct cli_tdis_state
);
2491 status
= cli_smb_recv(subreq
, NULL
, NULL
, 0, NULL
, NULL
, NULL
, NULL
);
2492 TALLOC_FREE(subreq
);
2493 if (!NT_STATUS_IS_OK(status
)) {
2494 tevent_req_nterror(req
, status
);
2497 TALLOC_FREE(state
->cli
->smb1
.tcon
);
2498 tevent_req_done(req
);
2501 static NTSTATUS
cli_tdis_recv(struct tevent_req
*req
)
2503 return tevent_req_simple_recv_ntstatus(req
);
2506 NTSTATUS
cli_tdis(struct cli_state
*cli
)
2508 struct tevent_context
*ev
;
2509 struct tevent_req
*req
;
2510 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2512 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
2513 status
= smb2cli_tdis(cli
->conn
,
2517 if (NT_STATUS_IS_OK(status
)) {
2518 TALLOC_FREE(cli
->smb2
.tcon
);
2523 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
2524 return NT_STATUS_INVALID_PARAMETER
;
2526 ev
= samba_tevent_context_init(talloc_tos());
2530 req
= cli_tdis_send(ev
, ev
, cli
);
2534 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2537 status
= cli_tdis_recv(req
);
2543 struct cli_connect_sock_state
{
2544 const char **called_names
;
2545 const char **calling_names
;
2551 static void cli_connect_sock_done(struct tevent_req
*subreq
);
2554 * Async only if we don't have to look up the name, i.e. "pss" is set with a
2558 static struct tevent_req
*cli_connect_sock_send(
2559 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
2560 const char *host
, int name_type
, const struct sockaddr_storage
*pss
,
2561 const char *myname
, uint16_t port
)
2563 struct tevent_req
*req
, *subreq
;
2564 struct cli_connect_sock_state
*state
;
2565 struct sockaddr_storage
*addrs
;
2566 unsigned i
, num_addrs
;
2569 req
= tevent_req_create(mem_ctx
, &state
,
2570 struct cli_connect_sock_state
);
2575 if ((pss
== NULL
) || is_zero_addr(pss
)) {
2578 * Here we cheat. resolve_name_list is not async at all. So
2579 * this call will only be really async if the name lookup has
2580 * been done externally.
2583 status
= resolve_name_list(state
, host
, name_type
,
2584 &addrs
, &num_addrs
);
2585 if (!NT_STATUS_IS_OK(status
)) {
2586 tevent_req_nterror(req
, status
);
2587 return tevent_req_post(req
, ev
);
2590 addrs
= talloc_array(state
, struct sockaddr_storage
, 1);
2591 if (tevent_req_nomem(addrs
, req
)) {
2592 return tevent_req_post(req
, ev
);
2598 state
->called_names
= talloc_array(state
, const char *, num_addrs
);
2599 if (tevent_req_nomem(state
->called_names
, req
)) {
2600 return tevent_req_post(req
, ev
);
2602 state
->called_types
= talloc_array(state
, int, num_addrs
);
2603 if (tevent_req_nomem(state
->called_types
, req
)) {
2604 return tevent_req_post(req
, ev
);
2606 state
->calling_names
= talloc_array(state
, const char *, num_addrs
);
2607 if (tevent_req_nomem(state
->calling_names
, req
)) {
2608 return tevent_req_post(req
, ev
);
2610 for (i
=0; i
<num_addrs
; i
++) {
2611 state
->called_names
[i
] = host
;
2612 state
->called_types
[i
] = name_type
;
2613 state
->calling_names
[i
] = myname
;
2616 subreq
= smbsock_any_connect_send(
2617 state
, ev
, addrs
, state
->called_names
, state
->called_types
,
2618 state
->calling_names
, NULL
, num_addrs
, port
);
2619 if (tevent_req_nomem(subreq
, req
)) {
2620 return tevent_req_post(req
, ev
);
2622 tevent_req_set_callback(subreq
, cli_connect_sock_done
, req
);
2626 static void cli_connect_sock_done(struct tevent_req
*subreq
)
2628 struct tevent_req
*req
= tevent_req_callback_data(
2629 subreq
, struct tevent_req
);
2630 struct cli_connect_sock_state
*state
= tevent_req_data(
2631 req
, struct cli_connect_sock_state
);
2634 status
= smbsock_any_connect_recv(subreq
, &state
->fd
, NULL
,
2636 TALLOC_FREE(subreq
);
2637 if (tevent_req_nterror(req
, status
)) {
2640 set_socket_options(state
->fd
, lp_socket_options());
2641 tevent_req_done(req
);
2644 static NTSTATUS
cli_connect_sock_recv(struct tevent_req
*req
,
2645 int *pfd
, uint16_t *pport
)
2647 struct cli_connect_sock_state
*state
= tevent_req_data(
2648 req
, struct cli_connect_sock_state
);
2651 if (tevent_req_is_nterror(req
, &status
)) {
2655 *pport
= state
->port
;
2656 return NT_STATUS_OK
;
2659 struct cli_connect_nb_state
{
2660 const char *desthost
;
2663 struct cli_state
*cli
;
2666 static void cli_connect_nb_done(struct tevent_req
*subreq
);
2668 static struct tevent_req
*cli_connect_nb_send(
2669 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
2670 const char *host
, const struct sockaddr_storage
*dest_ss
,
2671 uint16_t port
, int name_type
, const char *myname
,
2672 int signing_state
, int flags
)
2674 struct tevent_req
*req
, *subreq
;
2675 struct cli_connect_nb_state
*state
;
2677 req
= tevent_req_create(mem_ctx
, &state
, struct cli_connect_nb_state
);
2681 state
->signing_state
= signing_state
;
2682 state
->flags
= flags
;
2685 char *p
= strchr(host
, '#');
2688 name_type
= strtol(p
+1, NULL
, 16);
2689 host
= talloc_strndup(state
, host
, p
- host
);
2690 if (tevent_req_nomem(host
, req
)) {
2691 return tevent_req_post(req
, ev
);
2695 state
->desthost
= host
;
2696 } else if (dest_ss
!= NULL
) {
2697 state
->desthost
= print_canonical_sockaddr(state
, dest_ss
);
2698 if (tevent_req_nomem(state
->desthost
, req
)) {
2699 return tevent_req_post(req
, ev
);
2702 /* No host or dest_ss given. Error out. */
2703 tevent_req_error(req
, EINVAL
);
2704 return tevent_req_post(req
, ev
);
2707 subreq
= cli_connect_sock_send(state
, ev
, host
, name_type
, dest_ss
,
2709 if (tevent_req_nomem(subreq
, req
)) {
2710 return tevent_req_post(req
, ev
);
2712 tevent_req_set_callback(subreq
, cli_connect_nb_done
, req
);
2716 static void cli_connect_nb_done(struct tevent_req
*subreq
)
2718 struct tevent_req
*req
= tevent_req_callback_data(
2719 subreq
, struct tevent_req
);
2720 struct cli_connect_nb_state
*state
= tevent_req_data(
2721 req
, struct cli_connect_nb_state
);
2726 status
= cli_connect_sock_recv(subreq
, &fd
, &port
);
2727 TALLOC_FREE(subreq
);
2728 if (tevent_req_nterror(req
, status
)) {
2732 state
->cli
= cli_state_create(state
, fd
, state
->desthost
,
2733 state
->signing_state
, state
->flags
);
2734 if (tevent_req_nomem(state
->cli
, req
)) {
2738 tevent_req_done(req
);
2741 static NTSTATUS
cli_connect_nb_recv(struct tevent_req
*req
,
2742 struct cli_state
**pcli
)
2744 struct cli_connect_nb_state
*state
= tevent_req_data(
2745 req
, struct cli_connect_nb_state
);
2748 if (tevent_req_is_nterror(req
, &status
)) {
2751 *pcli
= talloc_move(NULL
, &state
->cli
);
2752 return NT_STATUS_OK
;
2755 NTSTATUS
cli_connect_nb(const char *host
, const struct sockaddr_storage
*dest_ss
,
2756 uint16_t port
, int name_type
, const char *myname
,
2757 int signing_state
, int flags
, struct cli_state
**pcli
)
2759 struct tevent_context
*ev
;
2760 struct tevent_req
*req
;
2761 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2763 ev
= samba_tevent_context_init(talloc_tos());
2767 req
= cli_connect_nb_send(ev
, ev
, host
, dest_ss
, port
, name_type
,
2768 myname
, signing_state
, flags
);
2772 if (!tevent_req_set_endtime(req
, ev
, timeval_current_ofs(20, 0))) {
2775 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2778 status
= cli_connect_nb_recv(req
, pcli
);
2784 struct cli_start_connection_state
{
2785 struct tevent_context
*ev
;
2786 struct cli_state
*cli
;
2791 static void cli_start_connection_connected(struct tevent_req
*subreq
);
2792 static void cli_start_connection_done(struct tevent_req
*subreq
);
2795 establishes a connection to after the negprot.
2796 @param output_cli A fully initialised cli structure, non-null only on success
2797 @param dest_host The netbios name of the remote host
2798 @param dest_ss (optional) The the destination IP, NULL for name based lookup
2799 @param port (optional) The destination port (0 for default)
2802 static struct tevent_req
*cli_start_connection_send(
2803 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
2804 const char *my_name
, const char *dest_host
,
2805 const struct sockaddr_storage
*dest_ss
, int port
,
2806 int signing_state
, int flags
)
2808 struct tevent_req
*req
, *subreq
;
2809 struct cli_start_connection_state
*state
;
2811 req
= tevent_req_create(mem_ctx
, &state
,
2812 struct cli_start_connection_state
);
2818 if (signing_state
== SMB_SIGNING_IPC_DEFAULT
) {
2819 state
->min_protocol
= lp_client_ipc_min_protocol();
2820 state
->max_protocol
= lp_client_ipc_max_protocol();
2822 state
->min_protocol
= lp_client_min_protocol();
2823 state
->max_protocol
= lp_client_max_protocol();
2826 if (flags
& CLI_FULL_CONNECTION_FORCE_SMB1
) {
2827 state
->max_protocol
= MIN(state
->max_protocol
, PROTOCOL_NT1
);
2830 if (flags
& CLI_FULL_CONNECTION_DISABLE_SMB1
) {
2831 state
->min_protocol
= MAX(state
->max_protocol
, PROTOCOL_SMB2_02
);
2832 state
->max_protocol
= MAX(state
->max_protocol
, PROTOCOL_LATEST
);
2835 subreq
= cli_connect_nb_send(state
, ev
, dest_host
, dest_ss
, port
,
2836 0x20, my_name
, signing_state
, flags
);
2837 if (tevent_req_nomem(subreq
, req
)) {
2838 return tevent_req_post(req
, ev
);
2840 tevent_req_set_callback(subreq
, cli_start_connection_connected
, req
);
2844 static void cli_start_connection_connected(struct tevent_req
*subreq
)
2846 struct tevent_req
*req
= tevent_req_callback_data(
2847 subreq
, struct tevent_req
);
2848 struct cli_start_connection_state
*state
= tevent_req_data(
2849 req
, struct cli_start_connection_state
);
2852 status
= cli_connect_nb_recv(subreq
, &state
->cli
);
2853 TALLOC_FREE(subreq
);
2854 if (tevent_req_nterror(req
, status
)) {
2858 subreq
= smbXcli_negprot_send(state
, state
->ev
, state
->cli
->conn
,
2859 state
->cli
->timeout
,
2860 state
->min_protocol
,
2861 state
->max_protocol
,
2862 WINDOWS_CLIENT_PURE_SMB2_NEGPROT_INITIAL_CREDIT_ASK
);
2863 if (tevent_req_nomem(subreq
, req
)) {
2866 tevent_req_set_callback(subreq
, cli_start_connection_done
, req
);
2869 static void cli_start_connection_done(struct tevent_req
*subreq
)
2871 struct tevent_req
*req
= tevent_req_callback_data(
2872 subreq
, struct tevent_req
);
2873 struct cli_start_connection_state
*state
= tevent_req_data(
2874 req
, struct cli_start_connection_state
);
2877 status
= smbXcli_negprot_recv(subreq
);
2878 TALLOC_FREE(subreq
);
2879 if (tevent_req_nterror(req
, status
)) {
2883 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
2884 /* Ensure we ask for some initial credits. */
2885 smb2cli_conn_set_max_credits(state
->cli
->conn
,
2886 DEFAULT_SMB2_MAX_CREDITS
);
2889 tevent_req_done(req
);
2892 static NTSTATUS
cli_start_connection_recv(struct tevent_req
*req
,
2893 struct cli_state
**output_cli
)
2895 struct cli_start_connection_state
*state
= tevent_req_data(
2896 req
, struct cli_start_connection_state
);
2899 if (tevent_req_is_nterror(req
, &status
)) {
2902 *output_cli
= state
->cli
;
2904 return NT_STATUS_OK
;
2907 NTSTATUS
cli_start_connection(struct cli_state
**output_cli
,
2908 const char *my_name
,
2909 const char *dest_host
,
2910 const struct sockaddr_storage
*dest_ss
, int port
,
2911 int signing_state
, int flags
)
2913 struct tevent_context
*ev
;
2914 struct tevent_req
*req
;
2915 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2917 ev
= samba_tevent_context_init(talloc_tos());
2921 req
= cli_start_connection_send(ev
, ev
, my_name
, dest_host
, dest_ss
,
2922 port
, signing_state
, flags
);
2926 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2929 status
= cli_start_connection_recv(req
, output_cli
);
2935 struct cli_smb1_setup_encryption_blob_state
{
2940 uint16_t enc_ctx_id
;
2943 static void cli_smb1_setup_encryption_blob_done(struct tevent_req
*subreq
);
2945 static struct tevent_req
*cli_smb1_setup_encryption_blob_send(TALLOC_CTX
*mem_ctx
,
2946 struct tevent_context
*ev
,
2947 struct cli_state
*cli
,
2950 struct tevent_req
*req
= NULL
;
2951 struct cli_smb1_setup_encryption_blob_state
*state
= NULL
;
2952 struct tevent_req
*subreq
= NULL
;
2954 req
= tevent_req_create(mem_ctx
, &state
,
2955 struct cli_smb1_setup_encryption_blob_state
);
2960 if (in
.length
> CLI_BUFFER_SIZE
) {
2961 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER_MIX
);
2962 return tevent_req_post(req
, ev
);
2965 SSVAL(state
->setup
+0, 0, TRANSACT2_SETFSINFO
);
2966 SSVAL(state
->param
, 0, 0);
2967 SSVAL(state
->param
, 2, SMB_REQUEST_TRANSPORT_ENCRYPTION
);
2969 subreq
= smb1cli_trans_send(state
, ev
, cli
->conn
,
2977 NULL
, /* pipe_name */
2983 in
.data
, in
.length
, CLI_BUFFER_SIZE
);
2984 if (tevent_req_nomem(subreq
, req
)) {
2985 return tevent_req_post(req
, ev
);
2987 tevent_req_set_callback(subreq
,
2988 cli_smb1_setup_encryption_blob_done
,
2994 static void cli_smb1_setup_encryption_blob_done(struct tevent_req
*subreq
)
2996 struct tevent_req
*req
=
2997 tevent_req_callback_data(subreq
,
2999 struct cli_smb1_setup_encryption_blob_state
*state
=
3000 tevent_req_data(req
,
3001 struct cli_smb1_setup_encryption_blob_state
);
3002 uint8_t *rparam
=NULL
, *rdata
=NULL
;
3003 uint32_t num_rparam
, num_rdata
;
3006 status
= smb1cli_trans_recv(subreq
, state
,
3007 NULL
, /* recv_flags */
3008 NULL
, 0, NULL
, /* rsetup */
3009 &rparam
, 0, &num_rparam
,
3010 &rdata
, 0, &num_rdata
);
3011 TALLOC_FREE(subreq
);
3012 state
->status
= status
;
3013 if (NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
3014 status
= NT_STATUS_OK
;
3016 if (tevent_req_nterror(req
, status
)) {
3020 if (num_rparam
== 2) {
3021 state
->enc_ctx_id
= SVAL(rparam
, 0);
3023 TALLOC_FREE(rparam
);
3025 state
->out
= data_blob_const(rdata
, num_rdata
);
3027 tevent_req_done(req
);
3030 static NTSTATUS
cli_smb1_setup_encryption_blob_recv(struct tevent_req
*req
,
3031 TALLOC_CTX
*mem_ctx
,
3033 uint16_t *enc_ctx_id
)
3035 struct cli_smb1_setup_encryption_blob_state
*state
=
3036 tevent_req_data(req
,
3037 struct cli_smb1_setup_encryption_blob_state
);
3040 if (tevent_req_is_nterror(req
, &status
)) {
3041 tevent_req_received(req
);
3045 status
= state
->status
;
3048 talloc_steal(mem_ctx
, out
->data
);
3050 *enc_ctx_id
= state
->enc_ctx_id
;
3052 tevent_req_received(req
);
3056 struct cli_smb1_setup_encryption_state
{
3057 struct tevent_context
*ev
;
3058 struct cli_state
*cli
;
3059 struct smb_trans_enc_state
*es
;
3066 static void cli_smb1_setup_encryption_local_next(struct tevent_req
*req
);
3067 static void cli_smb1_setup_encryption_local_done(struct tevent_req
*subreq
);
3068 static void cli_smb1_setup_encryption_remote_next(struct tevent_req
*req
);
3069 static void cli_smb1_setup_encryption_remote_done(struct tevent_req
*subreq
);
3070 static void cli_smb1_setup_encryption_ready(struct tevent_req
*req
);
3072 static struct tevent_req
*cli_smb1_setup_encryption_send(TALLOC_CTX
*mem_ctx
,
3073 struct tevent_context
*ev
,
3074 struct cli_state
*cli
,
3075 struct cli_credentials
*creds
)
3077 struct tevent_req
*req
= NULL
;
3078 struct cli_smb1_setup_encryption_state
*state
= NULL
;
3079 struct auth_generic_state
*ags
= NULL
;
3080 const DATA_BLOB
*b
= NULL
;
3081 bool auth_requested
= false;
3082 const char *target_service
= NULL
;
3083 const char *target_hostname
= NULL
;
3086 req
= tevent_req_create(mem_ctx
, &state
,
3087 struct cli_smb1_setup_encryption_state
);
3094 auth_requested
= cli_credentials_authentication_requested(creds
);
3095 if (!auth_requested
) {
3096 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER_MIX
);
3097 return tevent_req_post(req
, ev
);
3100 target_service
= "cifs";
3101 target_hostname
= smbXcli_conn_remote_name(cli
->conn
);
3103 status
= cli_session_creds_prepare_krb5(cli
, creds
);
3104 if (tevent_req_nterror(req
, status
)) {
3105 return tevent_req_post(req
, ev
);
3108 state
->es
= talloc_zero(state
, struct smb_trans_enc_state
);
3109 if (tevent_req_nomem(state
->es
, req
)) {
3110 return tevent_req_post(req
, ev
);
3113 status
= auth_generic_client_prepare(state
->es
, &ags
);
3114 if (tevent_req_nterror(req
, status
)) {
3115 return tevent_req_post(req
, ev
);
3118 gensec_want_feature(ags
->gensec_security
,
3119 GENSEC_FEATURE_SIGN
);
3120 gensec_want_feature(ags
->gensec_security
,
3121 GENSEC_FEATURE_SEAL
);
3123 status
= auth_generic_set_creds(ags
, creds
);
3124 if (tevent_req_nterror(req
, status
)) {
3125 return tevent_req_post(req
, ev
);
3128 if (target_service
!= NULL
) {
3129 status
= gensec_set_target_service(ags
->gensec_security
,
3131 if (tevent_req_nterror(req
, status
)) {
3132 return tevent_req_post(req
, ev
);
3136 if (target_hostname
!= NULL
) {
3137 status
= gensec_set_target_hostname(ags
->gensec_security
,
3139 if (tevent_req_nterror(req
, status
)) {
3140 return tevent_req_post(req
, ev
);
3144 gensec_set_max_update_size(ags
->gensec_security
,
3147 b
= smbXcli_conn_server_gss_blob(state
->cli
->conn
);
3149 state
->blob_in
= *b
;
3152 status
= auth_generic_client_start(ags
, GENSEC_OID_SPNEGO
);
3153 if (tevent_req_nterror(req
, status
)) {
3154 return tevent_req_post(req
, ev
);
3158 * We only need the gensec_security part from here.
3160 state
->es
->gensec_security
= talloc_move(state
->es
,
3161 &ags
->gensec_security
);
3164 cli_smb1_setup_encryption_local_next(req
);
3165 if (!tevent_req_is_in_progress(req
)) {
3166 return tevent_req_post(req
, ev
);
3172 static void cli_smb1_setup_encryption_local_next(struct tevent_req
*req
)
3174 struct cli_smb1_setup_encryption_state
*state
=
3175 tevent_req_data(req
,
3176 struct cli_smb1_setup_encryption_state
);
3177 struct tevent_req
*subreq
= NULL
;
3179 if (state
->local_ready
) {
3180 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
3184 subreq
= gensec_update_send(state
, state
->ev
,
3185 state
->es
->gensec_security
,
3187 if (tevent_req_nomem(subreq
, req
)) {
3190 tevent_req_set_callback(subreq
, cli_smb1_setup_encryption_local_done
, req
);
3193 static void cli_smb1_setup_encryption_local_done(struct tevent_req
*subreq
)
3195 struct tevent_req
*req
=
3196 tevent_req_callback_data(subreq
,
3198 struct cli_smb1_setup_encryption_state
*state
=
3199 tevent_req_data(req
,
3200 struct cli_smb1_setup_encryption_state
);
3203 status
= gensec_update_recv(subreq
, state
, &state
->blob_out
);
3204 TALLOC_FREE(subreq
);
3205 state
->blob_in
= data_blob_null
;
3206 if (!NT_STATUS_IS_OK(status
) &&
3207 !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
))
3209 tevent_req_nterror(req
, status
);
3213 if (NT_STATUS_IS_OK(status
)) {
3214 state
->local_ready
= true;
3218 * We always get NT_STATUS_OK from the server even if it is not ready.
3219 * So guess the server is ready when we are ready and already sent
3220 * our last blob to the server.
3222 if (state
->local_ready
&& state
->blob_out
.length
== 0) {
3223 state
->remote_ready
= true;
3226 if (state
->local_ready
&& state
->remote_ready
) {
3227 cli_smb1_setup_encryption_ready(req
);
3231 cli_smb1_setup_encryption_remote_next(req
);
3234 static void cli_smb1_setup_encryption_remote_next(struct tevent_req
*req
)
3236 struct cli_smb1_setup_encryption_state
*state
=
3237 tevent_req_data(req
,
3238 struct cli_smb1_setup_encryption_state
);
3239 struct tevent_req
*subreq
= NULL
;
3241 if (state
->remote_ready
) {
3242 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
3246 subreq
= cli_smb1_setup_encryption_blob_send(state
, state
->ev
,
3247 state
->cli
, state
->blob_out
);
3248 if (tevent_req_nomem(subreq
, req
)) {
3251 tevent_req_set_callback(subreq
,
3252 cli_smb1_setup_encryption_remote_done
,
3256 static void cli_smb1_setup_encryption_remote_done(struct tevent_req
*subreq
)
3258 struct tevent_req
*req
=
3259 tevent_req_callback_data(subreq
,
3261 struct cli_smb1_setup_encryption_state
*state
=
3262 tevent_req_data(req
,
3263 struct cli_smb1_setup_encryption_state
);
3266 status
= cli_smb1_setup_encryption_blob_recv(subreq
, state
,
3268 &state
->es
->enc_ctx_num
);
3269 TALLOC_FREE(subreq
);
3270 data_blob_free(&state
->blob_out
);
3271 if (!NT_STATUS_IS_OK(status
) &&
3272 !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
))
3274 tevent_req_nterror(req
, status
);
3279 * We always get NT_STATUS_OK even if the server is not ready.
3280 * So guess the server is ready when we are ready and sent
3281 * our last blob to the server.
3283 if (state
->local_ready
) {
3284 state
->remote_ready
= true;
3287 if (state
->local_ready
&& state
->remote_ready
) {
3288 cli_smb1_setup_encryption_ready(req
);
3292 cli_smb1_setup_encryption_local_next(req
);
3295 static void cli_smb1_setup_encryption_ready(struct tevent_req
*req
)
3297 struct cli_smb1_setup_encryption_state
*state
=
3298 tevent_req_data(req
,
3299 struct cli_smb1_setup_encryption_state
);
3300 struct smb_trans_enc_state
*es
= NULL
;
3302 if (state
->blob_in
.length
!= 0) {
3303 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
3307 if (state
->blob_out
.length
!= 0) {
3308 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
3312 es
= talloc_move(state
->cli
->conn
, &state
->es
);
3314 smb1cli_conn_set_encryption(state
->cli
->conn
, es
);
3317 tevent_req_done(req
);
3320 static NTSTATUS
cli_smb1_setup_encryption_recv(struct tevent_req
*req
)
3322 return tevent_req_simple_recv_ntstatus(req
);
3325 NTSTATUS
cli_smb1_setup_encryption(struct cli_state
*cli
,
3326 struct cli_credentials
*creds
)
3328 struct tevent_context
*ev
= NULL
;
3329 struct tevent_req
*req
= NULL
;
3330 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
3332 ev
= samba_tevent_context_init(talloc_tos());
3336 req
= cli_smb1_setup_encryption_send(ev
, ev
, cli
, creds
);
3340 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
3343 status
= cli_smb1_setup_encryption_recv(req
);
3350 establishes a connection right up to doing tconX, password specified.
3351 @param output_cli A fully initialised cli structure, non-null only on success
3352 @param dest_host The netbios name of the remote host
3353 @param dest_ip (optional) The the destination IP, NULL for name based lookup
3354 @param port (optional) The destination port (0 for default)
3355 @param service (optional) The share to make the connection to. Should be 'unqualified' in any way.
3356 @param service_type The 'type' of serivice.
3357 @param creds The used user credentials
3360 struct cli_full_connection_creds_state
{
3361 struct tevent_context
*ev
;
3362 const char *service
;
3363 const char *service_type
;
3364 struct cli_credentials
*creds
;
3366 struct cli_state
*cli
;
3369 static int cli_full_connection_creds_state_destructor(
3370 struct cli_full_connection_creds_state
*s
)
3372 if (s
->cli
!= NULL
) {
3373 cli_shutdown(s
->cli
);
3379 static void cli_full_connection_creds_conn_done(struct tevent_req
*subreq
);
3380 static void cli_full_connection_creds_sess_start(struct tevent_req
*req
);
3381 static void cli_full_connection_creds_sess_done(struct tevent_req
*subreq
);
3382 static void cli_full_connection_creds_tcon_start(struct tevent_req
*req
);
3383 static void cli_full_connection_creds_tcon_done(struct tevent_req
*subreq
);
3385 struct tevent_req
*cli_full_connection_creds_send(
3386 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
3387 const char *my_name
, const char *dest_host
,
3388 const struct sockaddr_storage
*dest_ss
, int port
,
3389 const char *service
, const char *service_type
,
3390 struct cli_credentials
*creds
,
3391 int flags
, int signing_state
)
3393 struct tevent_req
*req
, *subreq
;
3394 struct cli_full_connection_creds_state
*state
;
3395 enum credentials_use_kerberos krb5_state
;
3396 uint32_t gensec_features
= 0;
3398 req
= tevent_req_create(mem_ctx
, &state
,
3399 struct cli_full_connection_creds_state
);
3403 talloc_set_destructor(state
, cli_full_connection_creds_state_destructor
);
3405 flags
&= ~CLI_FULL_CONNECTION_USE_KERBEROS
;
3406 flags
&= ~CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS
;
3407 flags
&= ~CLI_FULL_CONNECTION_USE_CCACHE
;
3408 flags
&= ~CLI_FULL_CONNECTION_USE_NT_HASH
;
3410 krb5_state
= cli_credentials_get_kerberos_state(creds
);
3411 switch (krb5_state
) {
3412 case CRED_MUST_USE_KERBEROS
:
3413 flags
|= CLI_FULL_CONNECTION_USE_KERBEROS
;
3414 flags
&= ~CLI_FULL_CONNECTION_DONT_SPNEGO
;
3416 case CRED_AUTO_USE_KERBEROS
:
3417 flags
|= CLI_FULL_CONNECTION_USE_KERBEROS
;
3418 flags
|= CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS
;
3420 case CRED_DONT_USE_KERBEROS
:
3424 gensec_features
= cli_credentials_get_gensec_features(creds
);
3425 if (gensec_features
& GENSEC_FEATURE_NTLM_CCACHE
) {
3426 flags
|= CLI_FULL_CONNECTION_USE_CCACHE
;
3430 state
->service
= service
;
3431 state
->service_type
= service_type
;
3432 state
->creds
= creds
;
3433 state
->flags
= flags
;
3435 subreq
= cli_start_connection_send(
3436 state
, ev
, my_name
, dest_host
, dest_ss
, port
,
3437 signing_state
, flags
);
3438 if (tevent_req_nomem(subreq
, req
)) {
3439 return tevent_req_post(req
, ev
);
3441 tevent_req_set_callback(subreq
,
3442 cli_full_connection_creds_conn_done
,
3447 static void cli_full_connection_creds_conn_done(struct tevent_req
*subreq
)
3449 struct tevent_req
*req
= tevent_req_callback_data(
3450 subreq
, struct tevent_req
);
3451 struct cli_full_connection_creds_state
*state
= tevent_req_data(
3452 req
, struct cli_full_connection_creds_state
);
3455 status
= cli_start_connection_recv(subreq
, &state
->cli
);
3456 TALLOC_FREE(subreq
);
3457 if (tevent_req_nterror(req
, status
)) {
3461 cli_full_connection_creds_sess_start(req
);
3464 static void cli_full_connection_creds_sess_start(struct tevent_req
*req
)
3466 struct cli_full_connection_creds_state
*state
= tevent_req_data(
3467 req
, struct cli_full_connection_creds_state
);
3468 struct tevent_req
*subreq
= NULL
;
3470 subreq
= cli_session_setup_creds_send(
3471 state
, state
->ev
, state
->cli
, state
->creds
);
3472 if (tevent_req_nomem(subreq
, req
)) {
3475 tevent_req_set_callback(subreq
,
3476 cli_full_connection_creds_sess_done
,
3480 static void cli_full_connection_creds_sess_done(struct tevent_req
*subreq
)
3482 struct tevent_req
*req
= tevent_req_callback_data(
3483 subreq
, struct tevent_req
);
3484 struct cli_full_connection_creds_state
*state
= tevent_req_data(
3485 req
, struct cli_full_connection_creds_state
);
3488 status
= cli_session_setup_creds_recv(subreq
);
3489 TALLOC_FREE(subreq
);
3491 if (!NT_STATUS_IS_OK(status
) &&
3492 (state
->flags
& CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK
)) {
3494 state
->flags
&= ~CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK
;
3496 state
->creds
= cli_credentials_init_anon(state
);
3497 if (tevent_req_nomem(state
->creds
, req
)) {
3501 cli_full_connection_creds_sess_start(req
);
3505 if (tevent_req_nterror(req
, status
)) {
3509 cli_full_connection_creds_tcon_start(req
);
3512 static void cli_full_connection_creds_tcon_start(struct tevent_req
*req
)
3514 struct cli_full_connection_creds_state
*state
= tevent_req_data(
3515 req
, struct cli_full_connection_creds_state
);
3516 struct tevent_req
*subreq
= NULL
;
3517 const char *password
= NULL
;
3519 if (state
->service
== NULL
) {
3520 tevent_req_done(req
);
3524 password
= cli_credentials_get_password(state
->creds
);
3526 subreq
= cli_tree_connect_send(state
, state
->ev
,
3529 state
->service_type
,
3531 if (tevent_req_nomem(subreq
, req
)) {
3534 tevent_req_set_callback(subreq
,
3535 cli_full_connection_creds_tcon_done
,
3539 static void cli_full_connection_creds_tcon_done(struct tevent_req
*subreq
)
3541 struct tevent_req
*req
= tevent_req_callback_data(
3542 subreq
, struct tevent_req
);
3545 status
= cli_tree_connect_recv(subreq
);
3546 TALLOC_FREE(subreq
);
3547 if (tevent_req_nterror(req
, status
)) {
3551 tevent_req_done(req
);
3554 NTSTATUS
cli_full_connection_creds_recv(struct tevent_req
*req
,
3555 struct cli_state
**output_cli
)
3557 struct cli_full_connection_creds_state
*state
= tevent_req_data(
3558 req
, struct cli_full_connection_creds_state
);
3561 if (tevent_req_is_nterror(req
, &status
)) {
3564 *output_cli
= state
->cli
;
3565 talloc_set_destructor(state
, NULL
);
3566 return NT_STATUS_OK
;
3569 NTSTATUS
cli_full_connection_creds(struct cli_state
**output_cli
,
3570 const char *my_name
,
3571 const char *dest_host
,
3572 const struct sockaddr_storage
*dest_ss
, int port
,
3573 const char *service
, const char *service_type
,
3574 struct cli_credentials
*creds
,
3578 struct tevent_context
*ev
;
3579 struct tevent_req
*req
;
3580 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
3582 ev
= samba_tevent_context_init(talloc_tos());
3586 req
= cli_full_connection_creds_send(
3587 ev
, ev
, my_name
, dest_host
, dest_ss
, port
, service
,
3588 service_type
, creds
, flags
, signing_state
);
3592 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
3595 status
= cli_full_connection_creds_recv(req
, output_cli
);
3601 NTSTATUS
cli_full_connection(struct cli_state
**output_cli
,
3602 const char *my_name
,
3603 const char *dest_host
,
3604 const struct sockaddr_storage
*dest_ss
, int port
,
3605 const char *service
, const char *service_type
,
3606 const char *user
, const char *domain
,
3607 const char *password
, int flags
,
3610 TALLOC_CTX
*frame
= talloc_stackframe();
3612 bool use_kerberos
= false;
3613 bool fallback_after_kerberos
= false;
3614 bool use_ccache
= false;
3615 bool pw_nt_hash
= false;
3616 struct cli_credentials
*creds
= NULL
;
3618 if (flags
& CLI_FULL_CONNECTION_USE_KERBEROS
) {
3619 use_kerberos
= true;
3622 if (flags
& CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS
) {
3623 fallback_after_kerberos
= true;
3626 if (flags
& CLI_FULL_CONNECTION_USE_CCACHE
) {
3630 if (flags
& CLI_FULL_CONNECTION_USE_NT_HASH
) {
3634 creds
= cli_session_creds_init(frame
,
3637 NULL
, /* realm (use default) */
3640 fallback_after_kerberos
,
3643 if (creds
== NULL
) {
3645 return NT_STATUS_NO_MEMORY
;
3648 status
= cli_full_connection_creds(output_cli
, my_name
,
3649 dest_host
, dest_ss
, port
,
3650 service
, service_type
,
3651 creds
, flags
, signing_state
);
3652 if (!NT_STATUS_IS_OK(status
)) {
3658 return NT_STATUS_OK
;
3661 /****************************************************************************
3662 Send an old style tcon.
3663 ****************************************************************************/
3664 struct cli_raw_tcon_state
{
3668 static void cli_raw_tcon_done(struct tevent_req
*subreq
);
3670 static struct tevent_req
*cli_raw_tcon_send(
3671 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
3672 const char *service
, const char *pass
, const char *dev
)
3674 struct tevent_req
*req
, *subreq
;
3675 struct cli_raw_tcon_state
*state
;
3678 req
= tevent_req_create(mem_ctx
, &state
, struct cli_raw_tcon_state
);
3683 if (!lp_client_plaintext_auth() && (*pass
)) {
3684 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
3685 " or 'client ntlmv2 auth = yes'\n"));
3686 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
3687 return tevent_req_post(req
, ev
);
3690 TALLOC_FREE(cli
->smb1
.tcon
);
3691 cli
->smb1
.tcon
= smbXcli_tcon_create(cli
);
3692 if (tevent_req_nomem(cli
->smb1
.tcon
, req
)) {
3693 return tevent_req_post(req
, ev
);
3695 smb1cli_tcon_set_id(cli
->smb1
.tcon
, UINT16_MAX
);
3697 bytes
= talloc_array(state
, uint8_t, 0);
3698 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
3699 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
3700 service
, strlen(service
)+1, NULL
);
3701 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
3702 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
3703 pass
, strlen(pass
)+1, NULL
);
3704 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
3705 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
3706 dev
, strlen(dev
)+1, NULL
);
3708 if (tevent_req_nomem(bytes
, req
)) {
3709 return tevent_req_post(req
, ev
);
3712 subreq
= cli_smb_send(state
, ev
, cli
, SMBtcon
, 0, 0, 0, NULL
,
3713 talloc_get_size(bytes
), bytes
);
3714 if (tevent_req_nomem(subreq
, req
)) {
3715 return tevent_req_post(req
, ev
);
3717 tevent_req_set_callback(subreq
, cli_raw_tcon_done
, req
);
3721 static void cli_raw_tcon_done(struct tevent_req
*subreq
)
3723 struct tevent_req
*req
= tevent_req_callback_data(
3724 subreq
, struct tevent_req
);
3725 struct cli_raw_tcon_state
*state
= tevent_req_data(
3726 req
, struct cli_raw_tcon_state
);
3729 status
= cli_smb_recv(subreq
, state
, NULL
, 2, NULL
, &state
->ret_vwv
,
3731 TALLOC_FREE(subreq
);
3732 if (tevent_req_nterror(req
, status
)) {
3735 tevent_req_done(req
);
3738 static NTSTATUS
cli_raw_tcon_recv(struct tevent_req
*req
,
3739 uint16_t *max_xmit
, uint16_t *tid
)
3741 struct cli_raw_tcon_state
*state
= tevent_req_data(
3742 req
, struct cli_raw_tcon_state
);
3745 if (tevent_req_is_nterror(req
, &status
)) {
3748 *max_xmit
= SVAL(state
->ret_vwv
+ 0, 0);
3749 *tid
= SVAL(state
->ret_vwv
+ 1, 0);
3750 return NT_STATUS_OK
;
3753 NTSTATUS
cli_raw_tcon(struct cli_state
*cli
,
3754 const char *service
, const char *pass
, const char *dev
,
3755 uint16_t *max_xmit
, uint16_t *tid
)
3757 struct tevent_context
*ev
;
3758 struct tevent_req
*req
;
3759 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
3761 ev
= samba_tevent_context_init(talloc_tos());
3765 req
= cli_raw_tcon_send(ev
, ev
, cli
, service
, pass
, dev
);
3769 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
3772 status
= cli_raw_tcon_recv(req
, max_xmit
, tid
);
3778 /* Return a cli_state pointing at the IPC$ share for the given server */
3780 struct cli_state
*get_ipc_connect(char *server
,
3781 struct sockaddr_storage
*server_ss
,
3782 const struct user_auth_info
*user_info
)
3784 struct cli_state
*cli
;
3786 uint32_t flags
= CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK
;
3788 if (get_cmdline_auth_info_use_kerberos(user_info
)) {
3789 flags
|= CLI_FULL_CONNECTION_USE_KERBEROS
;
3792 flags
|= CLI_FULL_CONNECTION_FORCE_SMB1
;
3794 nt_status
= cli_full_connection(&cli
, NULL
, server
, server_ss
, 0, "IPC$", "IPC",
3795 get_cmdline_auth_info_username(user_info
),
3797 get_cmdline_auth_info_password(user_info
),
3799 SMB_SIGNING_DEFAULT
);
3801 if (NT_STATUS_IS_OK(nt_status
)) {
3803 } else if (is_ipaddress(server
)) {
3804 /* windows 9* needs a correct NMB name for connections */
3805 fstring remote_name
;
3807 if (name_status_find("*", 0, 0, server_ss
, remote_name
)) {
3808 cli
= get_ipc_connect(remote_name
, server_ss
, user_info
);
3817 * Given the IP address of a master browser on the network, return its
3818 * workgroup and connect to it.
3820 * This function is provided to allow additional processing beyond what
3821 * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
3822 * browsers and obtain each master browsers' list of domains (in case the
3823 * first master browser is recently on the network and has not yet
3824 * synchronized with other master browsers and therefore does not yet have the
3825 * entire network browse list)
3828 struct cli_state
*get_ipc_connect_master_ip(TALLOC_CTX
*ctx
,
3829 struct sockaddr_storage
*mb_ip
,
3830 const struct user_auth_info
*user_info
,
3831 char **pp_workgroup_out
)
3833 char addr
[INET6_ADDRSTRLEN
];
3835 struct cli_state
*cli
;
3836 struct sockaddr_storage server_ss
;
3838 *pp_workgroup_out
= NULL
;
3840 print_sockaddr(addr
, sizeof(addr
), mb_ip
);
3841 DEBUG(99, ("Looking up name of master browser %s\n",
3845 * Do a name status query to find out the name of the master browser.
3846 * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
3847 * master browser will not respond to a wildcard query (or, at least,
3848 * an NT4 server acting as the domain master browser will not).
3850 * We might be able to use ONLY the query on MSBROWSE, but that's not
3851 * yet been tested with all Windows versions, so until it is, leave
3852 * the original wildcard query as the first choice and fall back to
3853 * MSBROWSE if the wildcard query fails.
3855 if (!name_status_find("*", 0, 0x1d, mb_ip
, name
) &&
3856 !name_status_find(MSBROWSE
, 1, 0x1d, mb_ip
, name
)) {
3858 DEBUG(99, ("Could not retrieve name status for %s\n",
3863 if (!find_master_ip(name
, &server_ss
)) {
3864 DEBUG(99, ("Could not find master ip for %s\n", name
));
3868 *pp_workgroup_out
= talloc_strdup(ctx
, name
);
3870 DEBUG(4, ("found master browser %s, %s\n", name
, addr
));
3872 print_sockaddr(addr
, sizeof(addr
), &server_ss
);
3873 cli
= get_ipc_connect(addr
, &server_ss
, user_info
);
3879 * Return the IP address and workgroup of a master browser on the network, and
3883 struct cli_state
*get_ipc_connect_master_ip_bcast(TALLOC_CTX
*ctx
,
3884 const struct user_auth_info
*user_info
,
3885 char **pp_workgroup_out
)
3887 struct sockaddr_storage
*ip_list
;
3888 struct cli_state
*cli
;
3892 *pp_workgroup_out
= NULL
;
3894 DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
3896 /* Go looking for workgroups by broadcasting on the local network */
3898 status
= name_resolve_bcast(MSBROWSE
, 1, talloc_tos(),
3900 if (!NT_STATUS_IS_OK(status
)) {
3901 DEBUG(99, ("No master browsers responded: %s\n",
3902 nt_errstr(status
)));
3906 for (i
= 0; i
< count
; i
++) {
3907 char addr
[INET6_ADDRSTRLEN
];
3908 print_sockaddr(addr
, sizeof(addr
), &ip_list
[i
]);
3909 DEBUG(99, ("Found master browser %s\n", addr
));
3911 cli
= get_ipc_connect_master_ip(ctx
, &ip_list
[i
],
3912 user_info
, pp_workgroup_out
);