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
);
632 tevent_req_done(req
);
635 NTSTATUS
cli_session_setup_guest_recv(struct tevent_req
*req
)
637 return tevent_req_simple_recv_ntstatus(req
);
640 /* The following is calculated from :
642 * (smb_wcnt * 2) = 24 (smb_wcnt == 12 in cli_session_setup_blob_send() )
643 * (strlen("Unix") + 1 + strlen("Samba") + 1) * 2 = 22 (unicode strings at
647 #define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22)
649 struct cli_sesssetup_blob_state
{
650 struct tevent_context
*ev
;
651 struct cli_state
*cli
;
653 uint16_t max_blob_size
;
656 struct iovec
*recv_iov
;
659 const uint8_t *inbuf
;
666 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state
*state
,
667 struct tevent_req
**psubreq
);
668 static void cli_sesssetup_blob_done(struct tevent_req
*subreq
);
670 static struct tevent_req
*cli_sesssetup_blob_send(TALLOC_CTX
*mem_ctx
,
671 struct tevent_context
*ev
,
672 struct cli_state
*cli
,
675 struct tevent_req
*req
, *subreq
;
676 struct cli_sesssetup_blob_state
*state
;
677 uint32_t usable_space
;
679 req
= tevent_req_create(mem_ctx
, &state
,
680 struct cli_sesssetup_blob_state
);
688 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
689 usable_space
= UINT16_MAX
;
691 usable_space
= cli_state_available_size(cli
,
692 BASE_SESSSETUP_BLOB_PACKET_SIZE
);
695 if (usable_space
== 0) {
696 DEBUG(1, ("cli_session_setup_blob: cli->max_xmit too small "
697 "(not possible to send %u bytes)\n",
698 BASE_SESSSETUP_BLOB_PACKET_SIZE
+ 1));
699 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
700 return tevent_req_post(req
, ev
);
702 state
->max_blob_size
= MIN(usable_space
, 0xFFFF);
704 if (!cli_sesssetup_blob_next(state
, &subreq
)) {
705 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
706 return tevent_req_post(req
, ev
);
708 tevent_req_set_callback(subreq
, cli_sesssetup_blob_done
, req
);
712 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state
*state
,
713 struct tevent_req
**psubreq
)
715 struct tevent_req
*subreq
;
718 thistime
= MIN(state
->blob
.length
, state
->max_blob_size
);
720 state
->this_blob
.data
= state
->blob
.data
;
721 state
->this_blob
.length
= thistime
;
723 state
->blob
.data
+= thistime
;
724 state
->blob
.length
-= thistime
;
726 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
727 subreq
= smb2cli_session_setup_send(state
, state
->ev
,
730 state
->cli
->smb2
.session
,
732 SMB2_CAP_DFS
, /* in_capabilities */
734 0, /* in_previous_session_id */
736 if (subreq
== NULL
) {
740 uint16_t in_buf_size
= 0;
741 uint16_t in_mpx_max
= 0;
742 uint16_t in_vc_num
= 0;
743 uint32_t in_sess_key
= 0;
744 uint32_t in_capabilities
= 0;
745 const char *in_native_os
= NULL
;
746 const char *in_native_lm
= NULL
;
748 in_buf_size
= CLI_BUFFER_SIZE
;
749 in_mpx_max
= smbXcli_conn_max_requests(state
->cli
->conn
);
750 in_vc_num
= cli_state_get_vc_num(state
->cli
);
751 in_sess_key
= smb1cli_conn_server_session_key(state
->cli
->conn
);
752 in_capabilities
= cli_session_setup_capabilities(state
->cli
,
753 CAP_EXTENDED_SECURITY
);
754 in_native_os
= "Unix";
755 in_native_lm
= "Samba";
758 * For now we keep the same values as before,
759 * we may remove these in a separate commit later.
765 subreq
= smb1cli_session_setup_ext_send(state
, state
->ev
,
768 state
->cli
->smb1
.pid
,
769 state
->cli
->smb1
.session
,
778 if (subreq
== NULL
) {
786 static void cli_sesssetup_blob_done(struct tevent_req
*subreq
)
788 struct tevent_req
*req
= tevent_req_callback_data(
789 subreq
, struct tevent_req
);
790 struct cli_sesssetup_blob_state
*state
= tevent_req_data(
791 req
, struct cli_sesssetup_blob_state
);
794 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
795 status
= smb2cli_session_setup_recv(subreq
, state
,
799 status
= smb1cli_session_setup_ext_recv(subreq
, state
,
803 &state
->out_native_os
,
804 &state
->out_native_lm
);
807 if (!NT_STATUS_IS_OK(status
)
808 && !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
809 tevent_req_nterror(req
, status
);
813 state
->status
= status
;
815 status
= cli_state_update_after_sesssetup(state
->cli
,
816 state
->out_native_os
,
817 state
->out_native_lm
,
819 if (tevent_req_nterror(req
, status
)) {
823 if (state
->blob
.length
!= 0) {
827 if (!cli_sesssetup_blob_next(state
, &subreq
)) {
831 tevent_req_set_callback(subreq
, cli_sesssetup_blob_done
, req
);
834 tevent_req_done(req
);
837 static NTSTATUS
cli_sesssetup_blob_recv(struct tevent_req
*req
,
840 const uint8_t **pinbuf
,
841 struct iovec
**precv_iov
)
843 struct cli_sesssetup_blob_state
*state
= tevent_req_data(
844 req
, struct cli_sesssetup_blob_state
);
846 struct iovec
*recv_iov
;
848 if (tevent_req_is_nterror(req
, &status
)) {
849 TALLOC_FREE(state
->cli
->smb2
.session
);
850 cli_state_set_uid(state
->cli
, UID_FIELD_INVALID
);
851 tevent_req_received(req
);
855 recv_iov
= talloc_move(mem_ctx
, &state
->recv_iov
);
857 *pblob
= state
->ret_blob
;
859 if (pinbuf
!= NULL
) {
860 *pinbuf
= state
->inbuf
;
862 if (precv_iov
!= NULL
) {
863 *precv_iov
= recv_iov
;
865 /* could be NT_STATUS_MORE_PROCESSING_REQUIRED */
866 status
= state
->status
;
867 tevent_req_received(req
);
871 /****************************************************************************
872 Do a spnego/NTLMSSP encrypted session setup.
873 ****************************************************************************/
875 struct cli_session_setup_gensec_state
{
876 struct tevent_context
*ev
;
877 struct cli_state
*cli
;
878 struct auth_generic_state
*auth_generic
;
881 const uint8_t *inbuf
;
882 struct iovec
*recv_iov
;
886 DATA_BLOB session_key
;
889 static int cli_session_setup_gensec_state_destructor(
890 struct cli_session_setup_gensec_state
*state
)
892 TALLOC_FREE(state
->auth_generic
);
893 data_blob_clear_free(&state
->session_key
);
897 static void cli_session_setup_gensec_local_next(struct tevent_req
*req
);
898 static void cli_session_setup_gensec_local_done(struct tevent_req
*subreq
);
899 static void cli_session_setup_gensec_remote_next(struct tevent_req
*req
);
900 static void cli_session_setup_gensec_remote_done(struct tevent_req
*subreq
);
901 static void cli_session_setup_gensec_ready(struct tevent_req
*req
);
903 static struct tevent_req
*cli_session_setup_gensec_send(
904 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
905 struct cli_credentials
*creds
,
906 const char *target_service
,
907 const char *target_hostname
)
909 struct tevent_req
*req
;
910 struct cli_session_setup_gensec_state
*state
;
912 const DATA_BLOB
*b
= NULL
;
914 req
= tevent_req_create(mem_ctx
, &state
,
915 struct cli_session_setup_gensec_state
);
922 talloc_set_destructor(
923 state
, cli_session_setup_gensec_state_destructor
);
925 status
= auth_generic_client_prepare(state
, &state
->auth_generic
);
926 if (tevent_req_nterror(req
, status
)) {
927 return tevent_req_post(req
, ev
);
930 status
= auth_generic_set_creds(state
->auth_generic
, creds
);
931 if (tevent_req_nterror(req
, status
)) {
932 return tevent_req_post(req
, ev
);
935 gensec_want_feature(state
->auth_generic
->gensec_security
,
936 GENSEC_FEATURE_SESSION_KEY
);
938 if (target_service
!= NULL
) {
939 status
= gensec_set_target_service(
940 state
->auth_generic
->gensec_security
,
942 if (tevent_req_nterror(req
, status
)) {
943 return tevent_req_post(req
, ev
);
947 if (target_hostname
!= NULL
) {
948 status
= gensec_set_target_hostname(
949 state
->auth_generic
->gensec_security
,
951 if (tevent_req_nterror(req
, status
)) {
952 return tevent_req_post(req
, ev
);
956 b
= smbXcli_conn_server_gss_blob(cli
->conn
);
961 state
->is_anonymous
= cli_credentials_is_anonymous(state
->auth_generic
->credentials
);
963 status
= auth_generic_client_start(state
->auth_generic
,
965 if (tevent_req_nterror(req
, status
)) {
966 return tevent_req_post(req
, ev
);
969 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
970 state
->cli
->smb2
.session
= smbXcli_session_create(cli
,
972 if (tevent_req_nomem(state
->cli
->smb2
.session
, req
)) {
973 return tevent_req_post(req
, ev
);
977 cli_session_setup_gensec_local_next(req
);
978 if (!tevent_req_is_in_progress(req
)) {
979 return tevent_req_post(req
, ev
);
985 static void cli_session_setup_gensec_local_next(struct tevent_req
*req
)
987 struct cli_session_setup_gensec_state
*state
=
989 struct cli_session_setup_gensec_state
);
990 struct tevent_req
*subreq
= NULL
;
992 if (state
->local_ready
) {
993 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
997 subreq
= gensec_update_send(state
, state
->ev
,
998 state
->auth_generic
->gensec_security
,
1000 if (tevent_req_nomem(subreq
, req
)) {
1003 tevent_req_set_callback(subreq
, cli_session_setup_gensec_local_done
, req
);
1006 static void cli_session_setup_gensec_local_done(struct tevent_req
*subreq
)
1008 struct tevent_req
*req
=
1009 tevent_req_callback_data(subreq
,
1011 struct cli_session_setup_gensec_state
*state
=
1012 tevent_req_data(req
,
1013 struct cli_session_setup_gensec_state
);
1016 status
= gensec_update_recv(subreq
, state
, &state
->blob_out
);
1017 TALLOC_FREE(subreq
);
1018 state
->blob_in
= data_blob_null
;
1019 if (!NT_STATUS_IS_OK(status
) &&
1020 !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
))
1022 tevent_req_nterror(req
, status
);
1026 if (NT_STATUS_IS_OK(status
)) {
1027 state
->local_ready
= true;
1030 if (state
->local_ready
&& state
->remote_ready
) {
1031 cli_session_setup_gensec_ready(req
);
1035 cli_session_setup_gensec_remote_next(req
);
1038 static void cli_session_setup_gensec_remote_next(struct tevent_req
*req
)
1040 struct cli_session_setup_gensec_state
*state
=
1041 tevent_req_data(req
,
1042 struct cli_session_setup_gensec_state
);
1043 struct tevent_req
*subreq
= NULL
;
1045 if (state
->remote_ready
) {
1046 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
1050 subreq
= cli_sesssetup_blob_send(state
, state
->ev
,
1051 state
->cli
, state
->blob_out
);
1052 if (tevent_req_nomem(subreq
, req
)) {
1055 tevent_req_set_callback(subreq
,
1056 cli_session_setup_gensec_remote_done
,
1060 static void cli_session_setup_gensec_remote_done(struct tevent_req
*subreq
)
1062 struct tevent_req
*req
=
1063 tevent_req_callback_data(subreq
,
1065 struct cli_session_setup_gensec_state
*state
=
1066 tevent_req_data(req
,
1067 struct cli_session_setup_gensec_state
);
1070 state
->inbuf
= NULL
;
1071 TALLOC_FREE(state
->recv_iov
);
1073 status
= cli_sesssetup_blob_recv(subreq
, state
, &state
->blob_in
,
1074 &state
->inbuf
, &state
->recv_iov
);
1075 TALLOC_FREE(subreq
);
1076 data_blob_free(&state
->blob_out
);
1077 if (!NT_STATUS_IS_OK(status
) &&
1078 !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
))
1080 tevent_req_nterror(req
, status
);
1084 if (NT_STATUS_IS_OK(status
)) {
1085 struct smbXcli_session
*session
= NULL
;
1086 bool is_guest
= false;
1088 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
1089 session
= state
->cli
->smb2
.session
;
1091 session
= state
->cli
->smb1
.session
;
1094 is_guest
= smbXcli_session_is_guest(session
);
1097 * We can't finish the gensec handshake, we don't
1098 * have a negotiated session key.
1100 * So just pretend we are completely done,
1101 * we need to continue as anonymous from this point,
1102 * as we can't get a session key.
1104 * Note that smbXcli_session_is_guest()
1105 * always returns false if we require signing.
1107 state
->blob_in
= data_blob_null
;
1108 state
->local_ready
= true;
1109 state
->is_anonymous
= true;
1112 state
->remote_ready
= true;
1115 if (state
->local_ready
&& state
->remote_ready
) {
1116 cli_session_setup_gensec_ready(req
);
1120 cli_session_setup_gensec_local_next(req
);
1123 static void cli_session_dump_keys(TALLOC_CTX
*mem_ctx
,
1124 struct smbXcli_session
*session
,
1125 DATA_BLOB session_key
)
1128 DATA_BLOB sig
= data_blob_null
;
1129 DATA_BLOB app
= data_blob_null
;
1130 DATA_BLOB enc
= data_blob_null
;
1131 DATA_BLOB dec
= data_blob_null
;
1132 uint64_t sid
= smb2cli_session_current_id(session
);
1134 status
= smb2cli_session_signing_key(session
, mem_ctx
, &sig
);
1135 if (!NT_STATUS_IS_OK(status
)) {
1138 status
= smbXcli_session_application_key(session
, mem_ctx
, &app
);
1139 if (!NT_STATUS_IS_OK(status
)) {
1142 status
= smb2cli_session_encryption_key(session
, mem_ctx
, &enc
);
1143 if (!NT_STATUS_IS_OK(status
)) {
1146 status
= smb2cli_session_decryption_key(session
, mem_ctx
, &dec
);
1147 if (!NT_STATUS_IS_OK(status
)) {
1151 DEBUG(0, ("debug encryption: dumping generated session keys\n"));
1152 DEBUGADD(0, ("Session Id "));
1153 dump_data(0, (uint8_t*)&sid
, sizeof(sid
));
1154 DEBUGADD(0, ("Session Key "));
1155 dump_data(0, session_key
.data
, session_key
.length
);
1156 DEBUGADD(0, ("Signing Key "));
1157 dump_data(0, sig
.data
, sig
.length
);
1158 DEBUGADD(0, ("App Key "));
1159 dump_data(0, app
.data
, app
.length
);
1161 /* In client code, ServerIn is the encryption key */
1163 DEBUGADD(0, ("ServerIn Key "));
1164 dump_data(0, enc
.data
, enc
.length
);
1165 DEBUGADD(0, ("ServerOut Key "));
1166 dump_data(0, dec
.data
, dec
.length
);
1169 data_blob_clear_free(&sig
);
1170 data_blob_clear_free(&app
);
1171 data_blob_clear_free(&enc
);
1172 data_blob_clear_free(&dec
);
1175 static void cli_session_setup_gensec_ready(struct tevent_req
*req
)
1177 struct cli_session_setup_gensec_state
*state
=
1178 tevent_req_data(req
,
1179 struct cli_session_setup_gensec_state
);
1180 const char *server_domain
= NULL
;
1183 if (state
->blob_in
.length
!= 0) {
1184 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
1188 if (state
->blob_out
.length
!= 0) {
1189 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
1194 * gensec_ntlmssp_server_domain() returns NULL
1195 * if NTLMSSP is not used.
1197 * We can remove this later
1198 * and leave the server domain empty for SMB2 and above
1199 * in future releases.
1201 server_domain
= gensec_ntlmssp_server_domain(
1202 state
->auth_generic
->gensec_security
);
1204 if (state
->cli
->server_domain
[0] == '\0' && server_domain
!= NULL
) {
1205 TALLOC_FREE(state
->cli
->server_domain
);
1206 state
->cli
->server_domain
= talloc_strdup(state
->cli
,
1208 if (state
->cli
->server_domain
== NULL
) {
1209 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
1214 if (state
->is_anonymous
) {
1216 * Windows server does not set the
1217 * SMB2_SESSION_FLAG_IS_NULL flag.
1219 * This fix makes sure we do not try
1220 * to verify a signature on the final
1221 * session setup response.
1223 tevent_req_done(req
);
1227 status
= gensec_session_key(state
->auth_generic
->gensec_security
,
1228 state
, &state
->session_key
);
1229 if (tevent_req_nterror(req
, status
)) {
1233 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
1234 struct smbXcli_session
*session
= state
->cli
->smb2
.session
;
1236 status
= smb2cli_session_set_session_key(session
,
1239 if (tevent_req_nterror(req
, status
)) {
1242 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB3_00
1243 && lp_debug_encryption())
1245 cli_session_dump_keys(state
, session
, state
->session_key
);
1248 struct smbXcli_session
*session
= state
->cli
->smb1
.session
;
1251 status
= smb1cli_session_set_session_key(session
,
1252 state
->session_key
);
1253 if (tevent_req_nterror(req
, status
)) {
1257 active
= smb1cli_conn_activate_signing(state
->cli
->conn
,
1263 ok
= smb1cli_conn_check_signing(state
->cli
->conn
,
1266 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1272 tevent_req_done(req
);
1275 static NTSTATUS
cli_session_setup_gensec_recv(struct tevent_req
*req
)
1277 struct cli_session_setup_gensec_state
*state
=
1278 tevent_req_data(req
,
1279 struct cli_session_setup_gensec_state
);
1282 if (tevent_req_is_nterror(req
, &status
)) {
1283 cli_state_set_uid(state
->cli
, UID_FIELD_INVALID
);
1286 return NT_STATUS_OK
;
1289 static char *cli_session_setup_get_account(TALLOC_CTX
*mem_ctx
,
1290 const char *principal
)
1294 account
= talloc_strdup(mem_ctx
, principal
);
1295 if (account
== NULL
) {
1298 p
= strchr_m(account
, '@');
1305 /****************************************************************************
1306 Do a spnego encrypted session setup.
1308 user_domain: The shortname of the domain the user/machine is a member of.
1309 dest_realm: The realm we're connecting to, if NULL we use our default realm.
1310 ****************************************************************************/
1312 struct cli_session_setup_spnego_state
{
1316 static void cli_session_setup_spnego_done(struct tevent_req
*subreq
);
1318 static struct tevent_req
*cli_session_setup_spnego_send(
1319 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
1320 struct cli_credentials
*creds
)
1322 struct tevent_req
*req
, *subreq
;
1323 struct cli_session_setup_spnego_state
*state
;
1324 const char *target_service
= NULL
;
1325 const char *target_hostname
= NULL
;
1328 req
= tevent_req_create(mem_ctx
, &state
,
1329 struct cli_session_setup_spnego_state
);
1334 target_service
= "cifs";
1335 target_hostname
= smbXcli_conn_remote_name(cli
->conn
);
1337 status
= cli_session_creds_prepare_krb5(cli
, creds
);
1338 if (tevent_req_nterror(req
, status
)) {
1339 return tevent_req_post(req
, ev
);
1342 DBG_INFO("Connect to %s as %s using SPNEGO\n",
1344 cli_credentials_get_principal(creds
, talloc_tos()));
1346 subreq
= cli_session_setup_gensec_send(state
, ev
, cli
, creds
,
1347 target_service
, target_hostname
);
1348 if (tevent_req_nomem(subreq
, req
)) {
1349 return tevent_req_post(req
, ev
);
1351 tevent_req_set_callback(
1352 subreq
, cli_session_setup_spnego_done
, req
);
1356 static void cli_session_setup_spnego_done(struct tevent_req
*subreq
)
1358 struct tevent_req
*req
= tevent_req_callback_data(
1359 subreq
, struct tevent_req
);
1362 status
= cli_session_setup_gensec_recv(subreq
);
1363 TALLOC_FREE(subreq
);
1364 if (tevent_req_nterror(req
, status
)) {
1368 tevent_req_done(req
);
1371 static ADS_STATUS
cli_session_setup_spnego_recv(struct tevent_req
*req
)
1373 struct cli_session_setup_spnego_state
*state
= tevent_req_data(
1374 req
, struct cli_session_setup_spnego_state
);
1377 if (tevent_req_is_nterror(req
, &status
)) {
1378 state
->result
= ADS_ERROR_NT(status
);
1381 return state
->result
;
1384 struct cli_session_setup_creds_state
{
1385 struct cli_state
*cli
;
1386 DATA_BLOB apassword_blob
;
1387 DATA_BLOB upassword_blob
;
1388 DATA_BLOB lm_session_key
;
1389 DATA_BLOB session_key
;
1390 char *out_native_os
;
1391 char *out_native_lm
;
1392 char *out_primary_domain
;
1395 static void cli_session_setup_creds_cleanup(struct tevent_req
*req
,
1396 enum tevent_req_state req_state
)
1398 struct cli_session_setup_creds_state
*state
= tevent_req_data(
1399 req
, struct cli_session_setup_creds_state
);
1401 if (req_state
!= TEVENT_REQ_RECEIVED
) {
1406 * We only call data_blob_clear() as
1407 * some of the blobs point to the same memory.
1409 * We let the talloc hierachy free the memory.
1411 data_blob_clear(&state
->apassword_blob
);
1412 data_blob_clear(&state
->upassword_blob
);
1413 data_blob_clear(&state
->lm_session_key
);
1414 data_blob_clear(&state
->session_key
);
1415 ZERO_STRUCTP(state
);
1418 static void cli_session_setup_creds_done_spnego(struct tevent_req
*subreq
);
1419 static void cli_session_setup_creds_done_nt1(struct tevent_req
*subreq
);
1420 static void cli_session_setup_creds_done_lm21(struct tevent_req
*subreq
);
1422 /****************************************************************************
1423 Send a session setup. The username and workgroup is in UNIX character
1424 format and must be converted to DOS codepage format before sending. If the
1425 password is in plaintext, the same should be done.
1426 ****************************************************************************/
1428 struct tevent_req
*cli_session_setup_creds_send(TALLOC_CTX
*mem_ctx
,
1429 struct tevent_context
*ev
,
1430 struct cli_state
*cli
,
1431 struct cli_credentials
*creds
)
1433 struct tevent_req
*req
, *subreq
;
1434 struct cli_session_setup_creds_state
*state
;
1435 uint16_t sec_mode
= smb1cli_conn_server_security_mode(cli
->conn
);
1436 bool use_spnego
= false;
1438 enum credentials_use_kerberos krb5_state
;
1439 uint32_t gensec_features
;
1440 const char *username
= "";
1441 const char *domain
= "";
1442 DATA_BLOB target_info
= data_blob_null
;
1443 DATA_BLOB challenge
= data_blob_null
;
1444 uint16_t in_buf_size
= 0;
1445 uint16_t in_mpx_max
= 0;
1446 uint16_t in_vc_num
= 0;
1447 uint32_t in_sess_key
= 0;
1448 const char *in_native_os
= NULL
;
1449 const char *in_native_lm
= NULL
;
1452 req
= tevent_req_create(mem_ctx
, &state
,
1453 struct cli_session_setup_creds_state
);
1459 tevent_req_set_cleanup_fn(req
, cli_session_setup_creds_cleanup
);
1461 krb5_state
= cli_credentials_get_kerberos_state(creds
);
1462 gensec_features
= cli_credentials_get_gensec_features(creds
);
1464 switch (krb5_state
) {
1465 case CRED_MUST_USE_KERBEROS
:
1466 cli
->use_kerberos
= true;
1467 cli
->fallback_after_kerberos
= false;
1469 case CRED_AUTO_USE_KERBEROS
:
1470 cli
->use_kerberos
= true;
1471 cli
->fallback_after_kerberos
= true;
1473 case CRED_DONT_USE_KERBEROS
:
1474 cli
->use_kerberos
= false;
1475 cli
->fallback_after_kerberos
= false;
1479 if (gensec_features
& GENSEC_FEATURE_NTLM_CCACHE
) {
1480 cli
->use_ccache
= true;
1482 cli
->use_ccache
= false;
1486 * Now work out what sort of session setup we are going to
1487 * do. I have split this into separate functions to make the flow a bit
1488 * easier to understand (tridge).
1490 if (smbXcli_conn_protocol(cli
->conn
) < PROTOCOL_NT1
) {
1492 } else if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
1494 } else if (smb1cli_conn_capabilities(cli
->conn
) & CAP_EXTENDED_SECURITY
) {
1496 * if the server supports extended security then use SPNEGO
1497 * even for anonymous connections.
1505 subreq
= cli_session_setup_spnego_send(
1506 state
, ev
, cli
, creds
);
1507 if (tevent_req_nomem(subreq
, req
)) {
1508 return tevent_req_post(req
, ev
);
1510 tevent_req_set_callback(subreq
, cli_session_setup_creds_done_spnego
,
1515 if (smbXcli_conn_protocol(cli
->conn
) < PROTOCOL_LANMAN1
) {
1517 * SessionSetupAndX was introduced by LANMAN 1.0. So we skip
1518 * this step against older servers.
1520 tevent_req_done(req
);
1521 return tevent_req_post(req
, ev
);
1524 if (cli_credentials_is_anonymous(creds
)) {
1526 * Do an anonymous session setup
1528 goto non_spnego_creds_done
;
1531 if ((sec_mode
& NEGOTIATE_SECURITY_USER_LEVEL
) == 0) {
1533 * Do an anonymous session setup,
1534 * the password is passed via the tree connect.
1536 goto non_spnego_creds_done
;
1539 cli_credentials_get_ntlm_username_domain(creds
, state
,
1542 if (tevent_req_nomem(username
, req
)) {
1543 return tevent_req_post(req
, ev
);
1545 if (tevent_req_nomem(domain
, req
)) {
1546 return tevent_req_post(req
, ev
);
1549 DBG_INFO("Connect to %s as %s using NTLM\n", domain
, username
);
1551 if ((sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
) == 0) {
1552 bool use_unicode
= smbXcli_conn_use_unicode(cli
->conn
);
1553 uint8_t *bytes
= NULL
;
1554 size_t bytes_len
= 0;
1555 const char *pw
= cli_credentials_get_password(creds
);
1561 pw_len
= strlen(pw
) + 1;
1563 if (!lp_client_plaintext_auth()) {
1564 DEBUG(1, ("Server requested PLAINTEXT password but "
1565 "'client plaintext auth = no'\n"));
1566 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1567 return tevent_req_post(req
, ev
);
1570 bytes
= talloc_array(state
, uint8_t, 0);
1571 bytes
= trans2_bytes_push_str(bytes
, use_unicode
,
1572 pw
, pw_len
, &bytes_len
);
1573 if (tevent_req_nomem(bytes
, req
)) {
1574 return tevent_req_post(req
, ev
);
1579 * CAP_UNICODE, can only be negotiated by NT1.
1581 state
->upassword_blob
= data_blob_const(bytes
,
1584 state
->apassword_blob
= data_blob_const(bytes
,
1588 goto non_spnego_creds_done
;
1591 challenge
= data_blob_const(smb1cli_conn_server_challenge(cli
->conn
), 8);
1593 if (smbXcli_conn_protocol(cli
->conn
) == PROTOCOL_NT1
) {
1594 if (lp_client_ntlmv2_auth() && lp_client_use_spnego()) {
1596 * Don't send an NTLMv2 response without NTLMSSP if we
1597 * want to use spnego support.
1599 DEBUG(1, ("Server does not support EXTENDED_SECURITY "
1600 " but 'client use spnego = yes'"
1601 " and 'client ntlmv2 auth = yes' is set\n"));
1602 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1603 return tevent_req_post(req
, ev
);
1606 if (lp_client_ntlmv2_auth()) {
1607 flags
|= CLI_CRED_NTLMv2_AUTH
;
1610 * note that the 'domain' here is a best
1611 * guess - we don't know the server's domain
1612 * at this point. Windows clients also don't
1615 target_info
= NTLMv2_generate_names_blob(state
,
1618 if (tevent_req_nomem(target_info
.data
, req
)) {
1619 return tevent_req_post(req
, ev
);
1622 flags
|= CLI_CRED_NTLM_AUTH
;
1623 if (lp_client_lanman_auth()) {
1624 flags
|= CLI_CRED_LANMAN_AUTH
;
1628 if (!lp_client_lanman_auth()) {
1629 DEBUG(1, ("Server requested user level LM password but "
1630 "'client lanman auth = no' is set.\n"));
1631 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1632 return tevent_req_post(req
, ev
);
1635 flags
|= CLI_CRED_LANMAN_AUTH
;
1638 status
= cli_credentials_get_ntlm_response(creds
, state
, &flags
,
1641 &state
->apassword_blob
,
1642 &state
->upassword_blob
,
1643 &state
->lm_session_key
,
1644 &state
->session_key
);
1645 if (tevent_req_nterror(req
, status
)) {
1646 return tevent_req_post(req
, ev
);
1649 non_spnego_creds_done
:
1651 in_buf_size
= CLI_BUFFER_SIZE
;
1652 in_mpx_max
= smbXcli_conn_max_requests(cli
->conn
);
1653 in_vc_num
= cli_state_get_vc_num(cli
);
1654 in_sess_key
= smb1cli_conn_server_session_key(cli
->conn
);
1655 in_native_os
= "Unix";
1656 in_native_lm
= "Samba";
1658 if (smbXcli_conn_protocol(cli
->conn
) == PROTOCOL_NT1
) {
1659 uint32_t in_capabilities
= 0;
1661 in_capabilities
= cli_session_setup_capabilities(cli
, 0);
1664 * For now we keep the same values as before,
1665 * we may remove these in a separate commit later.
1669 subreq
= smb1cli_session_setup_nt1_send(state
, ev
,
1680 state
->apassword_blob
,
1681 state
->upassword_blob
,
1685 if (tevent_req_nomem(subreq
, req
)) {
1686 return tevent_req_post(req
, ev
);
1688 tevent_req_set_callback(subreq
, cli_session_setup_creds_done_nt1
,
1694 * For now we keep the same values as before,
1695 * we may remove these in a separate commit later.
1700 subreq
= smb1cli_session_setup_lm21_send(state
, ev
,
1711 state
->apassword_blob
,
1714 if (tevent_req_nomem(subreq
, req
)) {
1715 return tevent_req_post(req
, ev
);
1717 tevent_req_set_callback(subreq
, cli_session_setup_creds_done_lm21
,
1722 static void cli_session_setup_creds_done_spnego(struct tevent_req
*subreq
)
1724 struct tevent_req
*req
= tevent_req_callback_data(
1725 subreq
, struct tevent_req
);
1728 status
= cli_session_setup_spnego_recv(subreq
);
1729 TALLOC_FREE(subreq
);
1730 if (!ADS_ERR_OK(status
)) {
1731 DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status
)));
1732 tevent_req_nterror(req
, ads_ntstatus(status
));
1735 tevent_req_done(req
);
1738 static void cli_session_setup_creds_done_nt1(struct tevent_req
*subreq
)
1740 struct tevent_req
*req
= tevent_req_callback_data(
1741 subreq
, struct tevent_req
);
1742 struct cli_session_setup_creds_state
*state
= tevent_req_data(
1743 req
, struct cli_session_setup_creds_state
);
1744 struct cli_state
*cli
= state
->cli
;
1746 struct iovec
*recv_iov
= NULL
;
1747 const uint8_t *inbuf
= NULL
;
1750 status
= smb1cli_session_setup_nt1_recv(subreq
, state
,
1753 &state
->out_native_os
,
1754 &state
->out_native_lm
,
1755 &state
->out_primary_domain
);
1756 TALLOC_FREE(subreq
);
1757 if (!NT_STATUS_IS_OK(status
)) {
1758 DEBUG(3, ("NT1 login failed: %s\n", nt_errstr(status
)));
1759 tevent_req_nterror(req
, status
);
1763 status
= cli_state_update_after_sesssetup(state
->cli
,
1764 state
->out_native_os
,
1765 state
->out_native_lm
,
1766 state
->out_primary_domain
);
1767 if (tevent_req_nterror(req
, status
)) {
1771 ok
= smb1cli_conn_activate_signing(cli
->conn
,
1773 state
->upassword_blob
);
1775 ok
= smb1cli_conn_check_signing(cli
->conn
, inbuf
, 1);
1777 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1782 if (state
->session_key
.data
) {
1783 struct smbXcli_session
*session
= cli
->smb1
.session
;
1785 status
= smb1cli_session_set_session_key(session
,
1786 state
->session_key
);
1787 if (tevent_req_nterror(req
, status
)) {
1792 tevent_req_done(req
);
1795 static void cli_session_setup_creds_done_lm21(struct tevent_req
*subreq
)
1797 struct tevent_req
*req
= tevent_req_callback_data(
1798 subreq
, struct tevent_req
);
1799 struct cli_session_setup_creds_state
*state
= tevent_req_data(
1800 req
, struct cli_session_setup_creds_state
);
1803 status
= smb1cli_session_setup_lm21_recv(subreq
, state
,
1804 &state
->out_native_os
,
1805 &state
->out_native_lm
);
1806 TALLOC_FREE(subreq
);
1807 if (!NT_STATUS_IS_OK(status
)) {
1808 DEBUG(3, ("LM21 login failed: %s\n", nt_errstr(status
)));
1809 tevent_req_nterror(req
, status
);
1813 status
= cli_state_update_after_sesssetup(state
->cli
,
1814 state
->out_native_os
,
1815 state
->out_native_lm
,
1817 if (tevent_req_nterror(req
, status
)) {
1821 tevent_req_done(req
);
1824 NTSTATUS
cli_session_setup_creds_recv(struct tevent_req
*req
)
1826 return tevent_req_simple_recv_ntstatus(req
);
1829 NTSTATUS
cli_session_setup_creds(struct cli_state
*cli
,
1830 struct cli_credentials
*creds
)
1832 struct tevent_context
*ev
;
1833 struct tevent_req
*req
;
1834 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
1836 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
1837 return NT_STATUS_INVALID_PARAMETER
;
1839 ev
= samba_tevent_context_init(talloc_tos());
1843 req
= cli_session_setup_creds_send(ev
, ev
, cli
, creds
);
1847 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
1850 status
= cli_session_setup_creds_recv(req
);
1856 NTSTATUS
cli_session_setup_anon(struct cli_state
*cli
)
1858 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
1859 struct cli_credentials
*creds
= NULL
;
1861 creds
= cli_credentials_init_anon(cli
);
1862 if (creds
== NULL
) {
1863 return NT_STATUS_NO_MEMORY
;
1866 status
= cli_session_setup_creds(cli
, creds
);
1868 if (!NT_STATUS_IS_OK(status
)) {
1872 return NT_STATUS_OK
;
1875 /****************************************************************************
1877 *****************************************************************************/
1879 struct cli_ulogoff_state
{
1880 struct cli_state
*cli
;
1884 static void cli_ulogoff_done(struct tevent_req
*subreq
);
1886 static struct tevent_req
*cli_ulogoff_send(TALLOC_CTX
*mem_ctx
,
1887 struct tevent_context
*ev
,
1888 struct cli_state
*cli
)
1890 struct tevent_req
*req
, *subreq
;
1891 struct cli_ulogoff_state
*state
;
1893 req
= tevent_req_create(mem_ctx
, &state
, struct cli_ulogoff_state
);
1899 SCVAL(state
->vwv
+0, 0, 0xFF);
1900 SCVAL(state
->vwv
+1, 0, 0);
1901 SSVAL(state
->vwv
+2, 0, 0);
1903 subreq
= cli_smb_send(state
, ev
, cli
, SMBulogoffX
, 0, 0, 2, state
->vwv
,
1905 if (tevent_req_nomem(subreq
, req
)) {
1906 return tevent_req_post(req
, ev
);
1908 tevent_req_set_callback(subreq
, cli_ulogoff_done
, req
);
1912 static void cli_ulogoff_done(struct tevent_req
*subreq
)
1914 struct tevent_req
*req
= tevent_req_callback_data(
1915 subreq
, struct tevent_req
);
1916 struct cli_ulogoff_state
*state
= tevent_req_data(
1917 req
, struct cli_ulogoff_state
);
1920 status
= cli_smb_recv(subreq
, NULL
, NULL
, 0, NULL
, NULL
, NULL
, NULL
);
1921 if (!NT_STATUS_IS_OK(status
)) {
1922 tevent_req_nterror(req
, status
);
1925 cli_state_set_uid(state
->cli
, UID_FIELD_INVALID
);
1926 tevent_req_done(req
);
1929 static NTSTATUS
cli_ulogoff_recv(struct tevent_req
*req
)
1931 return tevent_req_simple_recv_ntstatus(req
);
1934 NTSTATUS
cli_ulogoff(struct cli_state
*cli
)
1936 struct tevent_context
*ev
;
1937 struct tevent_req
*req
;
1938 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
1940 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
1941 status
= smb2cli_logoff(cli
->conn
,
1944 if (!NT_STATUS_IS_OK(status
)) {
1947 smb2cli_session_set_id_and_flags(cli
->smb2
.session
,
1949 return NT_STATUS_OK
;
1952 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
1953 return NT_STATUS_INVALID_PARAMETER
;
1955 ev
= samba_tevent_context_init(talloc_tos());
1959 req
= cli_ulogoff_send(ev
, ev
, cli
);
1963 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
1966 status
= cli_ulogoff_recv(req
);
1972 /****************************************************************************
1974 ****************************************************************************/
1976 struct cli_tcon_andx_state
{
1977 struct cli_state
*cli
;
1982 static void cli_tcon_andx_done(struct tevent_req
*subreq
);
1984 struct tevent_req
*cli_tcon_andx_create(TALLOC_CTX
*mem_ctx
,
1985 struct tevent_context
*ev
,
1986 struct cli_state
*cli
,
1987 const char *share
, const char *dev
,
1988 const char *pass
, int passlen
,
1989 struct tevent_req
**psmbreq
)
1991 struct tevent_req
*req
, *subreq
;
1992 struct cli_tcon_andx_state
*state
;
1997 uint16_t sec_mode
= smb1cli_conn_server_security_mode(cli
->conn
);
1998 uint16_t tcon_flags
= 0;
2002 req
= tevent_req_create(mem_ctx
, &state
, struct cli_tcon_andx_state
);
2009 TALLOC_FREE(cli
->smb1
.tcon
);
2010 cli
->smb1
.tcon
= smbXcli_tcon_create(cli
);
2011 if (tevent_req_nomem(cli
->smb1
.tcon
, req
)) {
2012 return tevent_req_post(req
, ev
);
2014 smb1cli_tcon_set_id(cli
->smb1
.tcon
, UINT16_MAX
);
2016 cli
->share
= talloc_strdup(cli
, share
);
2021 /* in user level security don't send a password now */
2022 if (sec_mode
& NEGOTIATE_SECURITY_USER_LEVEL
) {
2025 } else if (pass
== NULL
) {
2026 DEBUG(1, ("Server not using user level security and no "
2027 "password supplied.\n"));
2031 if ((sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
) &&
2032 *pass
&& passlen
!= 24) {
2033 if (!lp_client_lanman_auth()) {
2034 DEBUG(1, ("Server requested LANMAN password "
2035 "(share-level security) but "
2036 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2041 * Non-encrypted passwords - convert to DOS codepage before
2044 SMBencrypt(pass
, smb1cli_conn_server_challenge(cli
->conn
), p24
);
2046 pass
= (const char *)p24
;
2048 if((sec_mode
& (NEGOTIATE_SECURITY_USER_LEVEL
2049 |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
))
2053 if (!lp_client_plaintext_auth() && (*pass
)) {
2054 DEBUG(1, ("Server requested PLAINTEXT "
2056 "'client plaintext auth = no' or 'client ntlmv2 auth = yes'\n"));
2061 * Non-encrypted passwords - convert to DOS codepage
2064 tmp_pass
= talloc_array(talloc_tos(), uint8_t, 0);
2065 if (tevent_req_nomem(tmp_pass
, req
)) {
2066 return tevent_req_post(req
, ev
);
2068 tmp_pass
= trans2_bytes_push_str(tmp_pass
,
2069 false, /* always DOS */
2073 if (tevent_req_nomem(tmp_pass
, req
)) {
2074 return tevent_req_post(req
, ev
);
2076 pass
= (const char *)tmp_pass
;
2077 passlen
= talloc_get_size(tmp_pass
);
2081 tcon_flags
|= TCONX_FLAG_EXTENDED_RESPONSE
;
2082 tcon_flags
|= TCONX_FLAG_EXTENDED_SIGNATURES
;
2084 SCVAL(vwv
+0, 0, 0xFF);
2087 SSVAL(vwv
+2, 0, tcon_flags
);
2088 SSVAL(vwv
+3, 0, passlen
);
2090 if (passlen
&& pass
) {
2091 bytes
= (uint8_t *)talloc_memdup(state
, pass
, passlen
);
2093 bytes
= talloc_array(state
, uint8_t, 0);
2099 tmp
= talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
2100 smbXcli_conn_remote_name(cli
->conn
), share
);
2105 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), tmp
, strlen(tmp
)+1,
2110 * Add the devicetype
2112 tmp
= talloc_strdup_upper(talloc_tos(), dev
);
2117 bytes
= smb_bytes_push_str(bytes
, false, tmp
, strlen(tmp
)+1, NULL
);
2120 if (bytes
== NULL
) {
2125 state
->bytes
.iov_base
= (void *)bytes
;
2126 state
->bytes
.iov_len
= talloc_get_size(bytes
);
2128 subreq
= cli_smb_req_create(state
, ev
, cli
, SMBtconX
, 0, 0, 4, vwv
,
2130 if (subreq
== NULL
) {
2134 tevent_req_set_callback(subreq
, cli_tcon_andx_done
, req
);
2139 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
2140 return tevent_req_post(req
, ev
);
2143 struct tevent_req
*cli_tcon_andx_send(TALLOC_CTX
*mem_ctx
,
2144 struct tevent_context
*ev
,
2145 struct cli_state
*cli
,
2146 const char *share
, const char *dev
,
2147 const char *pass
, int passlen
)
2149 struct tevent_req
*req
, *subreq
;
2152 req
= cli_tcon_andx_create(mem_ctx
, ev
, cli
, share
, dev
, pass
, passlen
,
2157 if (subreq
== NULL
) {
2160 status
= smb1cli_req_chain_submit(&subreq
, 1);
2161 if (!NT_STATUS_IS_OK(status
)) {
2162 tevent_req_nterror(req
, status
);
2163 return tevent_req_post(req
, ev
);
2168 static void cli_tcon_andx_done(struct tevent_req
*subreq
)
2170 struct tevent_req
*req
= tevent_req_callback_data(
2171 subreq
, struct tevent_req
);
2172 struct cli_tcon_andx_state
*state
= tevent_req_data(
2173 req
, struct cli_tcon_andx_state
);
2174 struct cli_state
*cli
= state
->cli
;
2182 uint16_t optional_support
= 0;
2184 status
= cli_smb_recv(subreq
, state
, &in
, 0, &wct
, &vwv
,
2185 &num_bytes
, &bytes
);
2186 TALLOC_FREE(subreq
);
2187 if (!NT_STATUS_IS_OK(status
)) {
2188 tevent_req_nterror(req
, status
);
2192 inhdr
= in
+ NBT_HDR_SIZE
;
2195 if (clistr_pull_talloc(cli
,
2196 (const char *)inhdr
,
2197 SVAL(inhdr
, HDR_FLG2
),
2201 STR_TERMINATE
|STR_ASCII
) == -1) {
2202 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
2206 cli
->dev
= talloc_strdup(cli
, "");
2207 if (cli
->dev
== NULL
) {
2208 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
2213 if ((smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_NT1
) && (num_bytes
== 3)) {
2214 /* almost certainly win95 - enable bug fixes */
2219 * Make sure that we have the optional support 16-bit field. WCT > 2.
2220 * Avoids issues when connecting to Win9x boxes sharing files
2223 if ((wct
> 2) && (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_LANMAN2
)) {
2224 optional_support
= SVAL(vwv
+2, 0);
2227 if (optional_support
& SMB_EXTENDED_SIGNATURES
) {
2228 smb1cli_session_protect_session_key(cli
->smb1
.session
);
2231 smb1cli_tcon_set_values(state
->cli
->smb1
.tcon
,
2232 SVAL(inhdr
, HDR_TID
),
2234 0, /* maximal_access */
2235 0, /* guest_maximal_access */
2237 NULL
); /* fs_type */
2239 tevent_req_done(req
);
2242 NTSTATUS
cli_tcon_andx_recv(struct tevent_req
*req
)
2244 return tevent_req_simple_recv_ntstatus(req
);
2247 NTSTATUS
cli_tcon_andx(struct cli_state
*cli
, const char *share
,
2248 const char *dev
, const char *pass
, int passlen
)
2250 TALLOC_CTX
*frame
= talloc_stackframe();
2251 struct tevent_context
*ev
;
2252 struct tevent_req
*req
;
2253 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2255 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
2257 * Can't use sync call while an async call is in flight
2259 status
= NT_STATUS_INVALID_PARAMETER
;
2263 ev
= samba_tevent_context_init(frame
);
2268 req
= cli_tcon_andx_send(frame
, ev
, cli
, share
, dev
, pass
, passlen
);
2273 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2277 status
= cli_tcon_andx_recv(req
);
2283 struct cli_tree_connect_state
{
2284 struct cli_state
*cli
;
2287 static struct tevent_req
*cli_raw_tcon_send(
2288 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
2289 const char *service
, const char *pass
, const char *dev
);
2290 static NTSTATUS
cli_raw_tcon_recv(struct tevent_req
*req
,
2291 uint16_t *max_xmit
, uint16_t *tid
);
2293 static void cli_tree_connect_smb2_done(struct tevent_req
*subreq
);
2294 static void cli_tree_connect_andx_done(struct tevent_req
*subreq
);
2295 static void cli_tree_connect_raw_done(struct tevent_req
*subreq
);
2297 static struct tevent_req
*cli_tree_connect_send(
2298 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
2299 const char *share
, const char *dev
, const char *pass
)
2301 struct tevent_req
*req
, *subreq
;
2302 struct cli_tree_connect_state
*state
;
2308 passlen
= strlen(pass
) + 1;
2310 req
= tevent_req_create(mem_ctx
, &state
,
2311 struct cli_tree_connect_state
);
2317 cli
->share
= talloc_strdup(cli
, share
);
2318 if (tevent_req_nomem(cli
->share
, req
)) {
2319 return tevent_req_post(req
, ev
);
2322 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
2325 TALLOC_FREE(cli
->smb2
.tcon
);
2326 cli
->smb2
.tcon
= smbXcli_tcon_create(cli
);
2327 if (tevent_req_nomem(cli
->smb2
.tcon
, req
)) {
2328 return tevent_req_post(req
, ev
);
2331 unc
= talloc_asprintf(state
, "\\\\%s\\%s",
2332 smbXcli_conn_remote_name(cli
->conn
),
2334 if (tevent_req_nomem(unc
, req
)) {
2335 return tevent_req_post(req
, ev
);
2338 subreq
= smb2cli_tcon_send(state
, ev
, cli
->conn
, cli
->timeout
,
2339 cli
->smb2
.session
, cli
->smb2
.tcon
,
2342 if (tevent_req_nomem(subreq
, req
)) {
2343 return tevent_req_post(req
, ev
);
2345 tevent_req_set_callback(subreq
, cli_tree_connect_smb2_done
,
2350 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_LANMAN1
) {
2351 subreq
= cli_tcon_andx_send(state
, ev
, cli
, share
, dev
,
2353 if (tevent_req_nomem(subreq
, req
)) {
2354 return tevent_req_post(req
, ev
);
2356 tevent_req_set_callback(subreq
, cli_tree_connect_andx_done
,
2361 subreq
= cli_raw_tcon_send(state
, ev
, cli
, share
, pass
, dev
);
2362 if (tevent_req_nomem(subreq
, req
)) {
2363 return tevent_req_post(req
, ev
);
2365 tevent_req_set_callback(subreq
, cli_tree_connect_raw_done
, req
);
2370 static void cli_tree_connect_smb2_done(struct tevent_req
*subreq
)
2372 tevent_req_simple_finish_ntstatus(
2373 subreq
, smb2cli_tcon_recv(subreq
));
2376 static void cli_tree_connect_andx_done(struct tevent_req
*subreq
)
2378 tevent_req_simple_finish_ntstatus(
2379 subreq
, cli_tcon_andx_recv(subreq
));
2382 static void cli_tree_connect_raw_done(struct tevent_req
*subreq
)
2384 struct tevent_req
*req
= tevent_req_callback_data(
2385 subreq
, struct tevent_req
);
2386 struct cli_tree_connect_state
*state
= tevent_req_data(
2387 req
, struct cli_tree_connect_state
);
2389 uint16_t max_xmit
= 0;
2392 status
= cli_raw_tcon_recv(subreq
, &max_xmit
, &tid
);
2393 if (tevent_req_nterror(req
, status
)) {
2397 smb1cli_tcon_set_values(state
->cli
->smb1
.tcon
,
2399 0, /* optional_support */
2400 0, /* maximal_access */
2401 0, /* guest_maximal_access */
2403 NULL
); /* fs_type */
2405 tevent_req_done(req
);
2408 static NTSTATUS
cli_tree_connect_recv(struct tevent_req
*req
)
2410 return tevent_req_simple_recv_ntstatus(req
);
2413 NTSTATUS
cli_tree_connect(struct cli_state
*cli
, const char *share
,
2414 const char *dev
, const char *pass
)
2416 struct tevent_context
*ev
;
2417 struct tevent_req
*req
;
2418 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2420 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
2421 return NT_STATUS_INVALID_PARAMETER
;
2423 ev
= samba_tevent_context_init(talloc_tos());
2427 req
= cli_tree_connect_send(ev
, ev
, cli
, share
, dev
, pass
);
2431 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2434 status
= cli_tree_connect_recv(req
);
2440 NTSTATUS
cli_tree_connect_creds(struct cli_state
*cli
,
2441 const char *share
, const char *dev
,
2442 struct cli_credentials
*creds
)
2444 const char *pw
= NULL
;
2446 if (creds
!= NULL
) {
2447 pw
= cli_credentials_get_password(creds
);
2450 return cli_tree_connect(cli
, share
, dev
, pw
);
2453 /****************************************************************************
2454 Send a tree disconnect.
2455 ****************************************************************************/
2457 struct cli_tdis_state
{
2458 struct cli_state
*cli
;
2461 static void cli_tdis_done(struct tevent_req
*subreq
);
2463 static struct tevent_req
*cli_tdis_send(TALLOC_CTX
*mem_ctx
,
2464 struct tevent_context
*ev
,
2465 struct cli_state
*cli
)
2467 struct tevent_req
*req
, *subreq
;
2468 struct cli_tdis_state
*state
;
2470 req
= tevent_req_create(mem_ctx
, &state
, struct cli_tdis_state
);
2476 subreq
= cli_smb_send(state
, ev
, cli
, SMBtdis
, 0, 0, 0, NULL
, 0, NULL
);
2477 if (tevent_req_nomem(subreq
, req
)) {
2478 return tevent_req_post(req
, ev
);
2480 tevent_req_set_callback(subreq
, cli_tdis_done
, req
);
2484 static void cli_tdis_done(struct tevent_req
*subreq
)
2486 struct tevent_req
*req
= tevent_req_callback_data(
2487 subreq
, struct tevent_req
);
2488 struct cli_tdis_state
*state
= tevent_req_data(
2489 req
, struct cli_tdis_state
);
2492 status
= cli_smb_recv(subreq
, NULL
, NULL
, 0, NULL
, NULL
, NULL
, NULL
);
2493 TALLOC_FREE(subreq
);
2494 if (!NT_STATUS_IS_OK(status
)) {
2495 tevent_req_nterror(req
, status
);
2498 TALLOC_FREE(state
->cli
->smb1
.tcon
);
2499 tevent_req_done(req
);
2502 static NTSTATUS
cli_tdis_recv(struct tevent_req
*req
)
2504 return tevent_req_simple_recv_ntstatus(req
);
2507 NTSTATUS
cli_tdis(struct cli_state
*cli
)
2509 struct tevent_context
*ev
;
2510 struct tevent_req
*req
;
2511 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2513 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
2514 status
= smb2cli_tdis(cli
->conn
,
2518 if (NT_STATUS_IS_OK(status
)) {
2519 TALLOC_FREE(cli
->smb2
.tcon
);
2524 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
2525 return NT_STATUS_INVALID_PARAMETER
;
2527 ev
= samba_tevent_context_init(talloc_tos());
2531 req
= cli_tdis_send(ev
, ev
, cli
);
2535 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2538 status
= cli_tdis_recv(req
);
2544 struct cli_connect_sock_state
{
2545 const char **called_names
;
2546 const char **calling_names
;
2552 static void cli_connect_sock_done(struct tevent_req
*subreq
);
2555 * Async only if we don't have to look up the name, i.e. "pss" is set with a
2559 static struct tevent_req
*cli_connect_sock_send(
2560 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
2561 const char *host
, int name_type
, const struct sockaddr_storage
*pss
,
2562 const char *myname
, uint16_t port
)
2564 struct tevent_req
*req
, *subreq
;
2565 struct cli_connect_sock_state
*state
;
2566 struct sockaddr_storage
*addrs
;
2567 unsigned i
, num_addrs
;
2570 req
= tevent_req_create(mem_ctx
, &state
,
2571 struct cli_connect_sock_state
);
2576 if ((pss
== NULL
) || is_zero_addr(pss
)) {
2579 * Here we cheat. resolve_name_list is not async at all. So
2580 * this call will only be really async if the name lookup has
2581 * been done externally.
2584 status
= resolve_name_list(state
, host
, name_type
,
2585 &addrs
, &num_addrs
);
2586 if (!NT_STATUS_IS_OK(status
)) {
2587 tevent_req_nterror(req
, status
);
2588 return tevent_req_post(req
, ev
);
2591 addrs
= talloc_array(state
, struct sockaddr_storage
, 1);
2592 if (tevent_req_nomem(addrs
, req
)) {
2593 return tevent_req_post(req
, ev
);
2599 state
->called_names
= talloc_array(state
, const char *, num_addrs
);
2600 if (tevent_req_nomem(state
->called_names
, req
)) {
2601 return tevent_req_post(req
, ev
);
2603 state
->called_types
= talloc_array(state
, int, num_addrs
);
2604 if (tevent_req_nomem(state
->called_types
, req
)) {
2605 return tevent_req_post(req
, ev
);
2607 state
->calling_names
= talloc_array(state
, const char *, num_addrs
);
2608 if (tevent_req_nomem(state
->calling_names
, req
)) {
2609 return tevent_req_post(req
, ev
);
2611 for (i
=0; i
<num_addrs
; i
++) {
2612 state
->called_names
[i
] = host
;
2613 state
->called_types
[i
] = name_type
;
2614 state
->calling_names
[i
] = myname
;
2617 subreq
= smbsock_any_connect_send(
2618 state
, ev
, addrs
, state
->called_names
, state
->called_types
,
2619 state
->calling_names
, NULL
, num_addrs
, port
);
2620 if (tevent_req_nomem(subreq
, req
)) {
2621 return tevent_req_post(req
, ev
);
2623 tevent_req_set_callback(subreq
, cli_connect_sock_done
, req
);
2627 static void cli_connect_sock_done(struct tevent_req
*subreq
)
2629 struct tevent_req
*req
= tevent_req_callback_data(
2630 subreq
, struct tevent_req
);
2631 struct cli_connect_sock_state
*state
= tevent_req_data(
2632 req
, struct cli_connect_sock_state
);
2635 status
= smbsock_any_connect_recv(subreq
, &state
->fd
, NULL
,
2637 TALLOC_FREE(subreq
);
2638 if (tevent_req_nterror(req
, status
)) {
2641 set_socket_options(state
->fd
, lp_socket_options());
2642 tevent_req_done(req
);
2645 static NTSTATUS
cli_connect_sock_recv(struct tevent_req
*req
,
2646 int *pfd
, uint16_t *pport
)
2648 struct cli_connect_sock_state
*state
= tevent_req_data(
2649 req
, struct cli_connect_sock_state
);
2652 if (tevent_req_is_nterror(req
, &status
)) {
2656 *pport
= state
->port
;
2657 return NT_STATUS_OK
;
2660 struct cli_connect_nb_state
{
2661 const char *desthost
;
2664 struct cli_state
*cli
;
2667 static void cli_connect_nb_done(struct tevent_req
*subreq
);
2669 static struct tevent_req
*cli_connect_nb_send(
2670 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
2671 const char *host
, const struct sockaddr_storage
*dest_ss
,
2672 uint16_t port
, int name_type
, const char *myname
,
2673 int signing_state
, int flags
)
2675 struct tevent_req
*req
, *subreq
;
2676 struct cli_connect_nb_state
*state
;
2678 req
= tevent_req_create(mem_ctx
, &state
, struct cli_connect_nb_state
);
2682 state
->signing_state
= signing_state
;
2683 state
->flags
= flags
;
2686 char *p
= strchr(host
, '#');
2689 name_type
= strtol(p
+1, NULL
, 16);
2690 host
= talloc_strndup(state
, host
, p
- host
);
2691 if (tevent_req_nomem(host
, req
)) {
2692 return tevent_req_post(req
, ev
);
2696 state
->desthost
= host
;
2697 } else if (dest_ss
!= NULL
) {
2698 state
->desthost
= print_canonical_sockaddr(state
, dest_ss
);
2699 if (tevent_req_nomem(state
->desthost
, req
)) {
2700 return tevent_req_post(req
, ev
);
2703 /* No host or dest_ss given. Error out. */
2704 tevent_req_error(req
, EINVAL
);
2705 return tevent_req_post(req
, ev
);
2708 subreq
= cli_connect_sock_send(state
, ev
, host
, name_type
, dest_ss
,
2710 if (tevent_req_nomem(subreq
, req
)) {
2711 return tevent_req_post(req
, ev
);
2713 tevent_req_set_callback(subreq
, cli_connect_nb_done
, req
);
2717 static void cli_connect_nb_done(struct tevent_req
*subreq
)
2719 struct tevent_req
*req
= tevent_req_callback_data(
2720 subreq
, struct tevent_req
);
2721 struct cli_connect_nb_state
*state
= tevent_req_data(
2722 req
, struct cli_connect_nb_state
);
2727 status
= cli_connect_sock_recv(subreq
, &fd
, &port
);
2728 TALLOC_FREE(subreq
);
2729 if (tevent_req_nterror(req
, status
)) {
2733 state
->cli
= cli_state_create(state
, fd
, state
->desthost
,
2734 state
->signing_state
, state
->flags
);
2735 if (tevent_req_nomem(state
->cli
, req
)) {
2739 tevent_req_done(req
);
2742 static NTSTATUS
cli_connect_nb_recv(struct tevent_req
*req
,
2743 struct cli_state
**pcli
)
2745 struct cli_connect_nb_state
*state
= tevent_req_data(
2746 req
, struct cli_connect_nb_state
);
2749 if (tevent_req_is_nterror(req
, &status
)) {
2752 *pcli
= talloc_move(NULL
, &state
->cli
);
2753 return NT_STATUS_OK
;
2756 NTSTATUS
cli_connect_nb(const char *host
, const struct sockaddr_storage
*dest_ss
,
2757 uint16_t port
, int name_type
, const char *myname
,
2758 int signing_state
, int flags
, struct cli_state
**pcli
)
2760 struct tevent_context
*ev
;
2761 struct tevent_req
*req
;
2762 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2764 ev
= samba_tevent_context_init(talloc_tos());
2768 req
= cli_connect_nb_send(ev
, ev
, host
, dest_ss
, port
, name_type
,
2769 myname
, signing_state
, flags
);
2773 if (!tevent_req_set_endtime(req
, ev
, timeval_current_ofs(20, 0))) {
2776 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2779 status
= cli_connect_nb_recv(req
, pcli
);
2785 struct cli_start_connection_state
{
2786 struct tevent_context
*ev
;
2787 struct cli_state
*cli
;
2792 static void cli_start_connection_connected(struct tevent_req
*subreq
);
2793 static void cli_start_connection_done(struct tevent_req
*subreq
);
2796 establishes a connection to after the negprot.
2797 @param output_cli A fully initialised cli structure, non-null only on success
2798 @param dest_host The netbios name of the remote host
2799 @param dest_ss (optional) The the destination IP, NULL for name based lookup
2800 @param port (optional) The destination port (0 for default)
2803 static struct tevent_req
*cli_start_connection_send(
2804 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
2805 const char *my_name
, const char *dest_host
,
2806 const struct sockaddr_storage
*dest_ss
, int port
,
2807 int signing_state
, int flags
)
2809 struct tevent_req
*req
, *subreq
;
2810 struct cli_start_connection_state
*state
;
2812 req
= tevent_req_create(mem_ctx
, &state
,
2813 struct cli_start_connection_state
);
2819 if (signing_state
== SMB_SIGNING_IPC_DEFAULT
) {
2820 state
->min_protocol
= lp_client_ipc_min_protocol();
2821 state
->max_protocol
= lp_client_ipc_max_protocol();
2823 state
->min_protocol
= lp_client_min_protocol();
2824 state
->max_protocol
= lp_client_max_protocol();
2827 if (flags
& CLI_FULL_CONNECTION_FORCE_SMB1
) {
2828 state
->max_protocol
= MIN(state
->max_protocol
, PROTOCOL_NT1
);
2831 if (flags
& CLI_FULL_CONNECTION_DISABLE_SMB1
) {
2832 state
->min_protocol
= MAX(state
->max_protocol
, PROTOCOL_SMB2_02
);
2833 state
->max_protocol
= MAX(state
->max_protocol
, PROTOCOL_LATEST
);
2836 subreq
= cli_connect_nb_send(state
, ev
, dest_host
, dest_ss
, port
,
2837 0x20, my_name
, signing_state
, flags
);
2838 if (tevent_req_nomem(subreq
, req
)) {
2839 return tevent_req_post(req
, ev
);
2841 tevent_req_set_callback(subreq
, cli_start_connection_connected
, req
);
2845 static void cli_start_connection_connected(struct tevent_req
*subreq
)
2847 struct tevent_req
*req
= tevent_req_callback_data(
2848 subreq
, struct tevent_req
);
2849 struct cli_start_connection_state
*state
= tevent_req_data(
2850 req
, struct cli_start_connection_state
);
2853 status
= cli_connect_nb_recv(subreq
, &state
->cli
);
2854 TALLOC_FREE(subreq
);
2855 if (tevent_req_nterror(req
, status
)) {
2859 subreq
= smbXcli_negprot_send(state
, state
->ev
, state
->cli
->conn
,
2860 state
->cli
->timeout
,
2861 state
->min_protocol
,
2862 state
->max_protocol
,
2863 WINDOWS_CLIENT_PURE_SMB2_NEGPROT_INITIAL_CREDIT_ASK
);
2864 if (tevent_req_nomem(subreq
, req
)) {
2867 tevent_req_set_callback(subreq
, cli_start_connection_done
, req
);
2870 static void cli_start_connection_done(struct tevent_req
*subreq
)
2872 struct tevent_req
*req
= tevent_req_callback_data(
2873 subreq
, struct tevent_req
);
2874 struct cli_start_connection_state
*state
= tevent_req_data(
2875 req
, struct cli_start_connection_state
);
2878 status
= smbXcli_negprot_recv(subreq
);
2879 TALLOC_FREE(subreq
);
2880 if (tevent_req_nterror(req
, status
)) {
2884 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
2885 /* Ensure we ask for some initial credits. */
2886 smb2cli_conn_set_max_credits(state
->cli
->conn
,
2887 DEFAULT_SMB2_MAX_CREDITS
);
2890 tevent_req_done(req
);
2893 static NTSTATUS
cli_start_connection_recv(struct tevent_req
*req
,
2894 struct cli_state
**output_cli
)
2896 struct cli_start_connection_state
*state
= tevent_req_data(
2897 req
, struct cli_start_connection_state
);
2900 if (tevent_req_is_nterror(req
, &status
)) {
2903 *output_cli
= state
->cli
;
2905 return NT_STATUS_OK
;
2908 NTSTATUS
cli_start_connection(struct cli_state
**output_cli
,
2909 const char *my_name
,
2910 const char *dest_host
,
2911 const struct sockaddr_storage
*dest_ss
, int port
,
2912 int signing_state
, int flags
)
2914 struct tevent_context
*ev
;
2915 struct tevent_req
*req
;
2916 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2918 ev
= samba_tevent_context_init(talloc_tos());
2922 req
= cli_start_connection_send(ev
, ev
, my_name
, dest_host
, dest_ss
,
2923 port
, signing_state
, flags
);
2927 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2930 status
= cli_start_connection_recv(req
, output_cli
);
2936 struct cli_smb1_setup_encryption_blob_state
{
2941 uint16_t enc_ctx_id
;
2944 static void cli_smb1_setup_encryption_blob_done(struct tevent_req
*subreq
);
2946 static struct tevent_req
*cli_smb1_setup_encryption_blob_send(TALLOC_CTX
*mem_ctx
,
2947 struct tevent_context
*ev
,
2948 struct cli_state
*cli
,
2951 struct tevent_req
*req
= NULL
;
2952 struct cli_smb1_setup_encryption_blob_state
*state
= NULL
;
2953 struct tevent_req
*subreq
= NULL
;
2955 req
= tevent_req_create(mem_ctx
, &state
,
2956 struct cli_smb1_setup_encryption_blob_state
);
2961 if (in
.length
> CLI_BUFFER_SIZE
) {
2962 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER_MIX
);
2963 return tevent_req_post(req
, ev
);
2966 SSVAL(state
->setup
+0, 0, TRANSACT2_SETFSINFO
);
2967 SSVAL(state
->param
, 0, 0);
2968 SSVAL(state
->param
, 2, SMB_REQUEST_TRANSPORT_ENCRYPTION
);
2970 subreq
= smb1cli_trans_send(state
, ev
, cli
->conn
,
2978 NULL
, /* pipe_name */
2984 in
.data
, in
.length
, CLI_BUFFER_SIZE
);
2985 if (tevent_req_nomem(subreq
, req
)) {
2986 return tevent_req_post(req
, ev
);
2988 tevent_req_set_callback(subreq
,
2989 cli_smb1_setup_encryption_blob_done
,
2995 static void cli_smb1_setup_encryption_blob_done(struct tevent_req
*subreq
)
2997 struct tevent_req
*req
=
2998 tevent_req_callback_data(subreq
,
3000 struct cli_smb1_setup_encryption_blob_state
*state
=
3001 tevent_req_data(req
,
3002 struct cli_smb1_setup_encryption_blob_state
);
3003 uint8_t *rparam
=NULL
, *rdata
=NULL
;
3004 uint32_t num_rparam
, num_rdata
;
3007 status
= smb1cli_trans_recv(subreq
, state
,
3008 NULL
, /* recv_flags */
3009 NULL
, 0, NULL
, /* rsetup */
3010 &rparam
, 0, &num_rparam
,
3011 &rdata
, 0, &num_rdata
);
3012 TALLOC_FREE(subreq
);
3013 state
->status
= status
;
3014 if (NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
3015 status
= NT_STATUS_OK
;
3017 if (tevent_req_nterror(req
, status
)) {
3021 if (num_rparam
== 2) {
3022 state
->enc_ctx_id
= SVAL(rparam
, 0);
3024 TALLOC_FREE(rparam
);
3026 state
->out
= data_blob_const(rdata
, num_rdata
);
3028 tevent_req_done(req
);
3031 static NTSTATUS
cli_smb1_setup_encryption_blob_recv(struct tevent_req
*req
,
3032 TALLOC_CTX
*mem_ctx
,
3034 uint16_t *enc_ctx_id
)
3036 struct cli_smb1_setup_encryption_blob_state
*state
=
3037 tevent_req_data(req
,
3038 struct cli_smb1_setup_encryption_blob_state
);
3041 if (tevent_req_is_nterror(req
, &status
)) {
3042 tevent_req_received(req
);
3046 status
= state
->status
;
3049 talloc_steal(mem_ctx
, out
->data
);
3051 *enc_ctx_id
= state
->enc_ctx_id
;
3053 tevent_req_received(req
);
3057 struct cli_smb1_setup_encryption_state
{
3058 struct tevent_context
*ev
;
3059 struct cli_state
*cli
;
3060 struct smb_trans_enc_state
*es
;
3067 static void cli_smb1_setup_encryption_local_next(struct tevent_req
*req
);
3068 static void cli_smb1_setup_encryption_local_done(struct tevent_req
*subreq
);
3069 static void cli_smb1_setup_encryption_remote_next(struct tevent_req
*req
);
3070 static void cli_smb1_setup_encryption_remote_done(struct tevent_req
*subreq
);
3071 static void cli_smb1_setup_encryption_ready(struct tevent_req
*req
);
3073 static struct tevent_req
*cli_smb1_setup_encryption_send(TALLOC_CTX
*mem_ctx
,
3074 struct tevent_context
*ev
,
3075 struct cli_state
*cli
,
3076 struct cli_credentials
*creds
)
3078 struct tevent_req
*req
= NULL
;
3079 struct cli_smb1_setup_encryption_state
*state
= NULL
;
3080 struct auth_generic_state
*ags
= NULL
;
3081 const DATA_BLOB
*b
= NULL
;
3082 bool auth_requested
= false;
3083 const char *target_service
= NULL
;
3084 const char *target_hostname
= NULL
;
3087 req
= tevent_req_create(mem_ctx
, &state
,
3088 struct cli_smb1_setup_encryption_state
);
3095 auth_requested
= cli_credentials_authentication_requested(creds
);
3096 if (!auth_requested
) {
3097 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER_MIX
);
3098 return tevent_req_post(req
, ev
);
3101 target_service
= "cifs";
3102 target_hostname
= smbXcli_conn_remote_name(cli
->conn
);
3104 status
= cli_session_creds_prepare_krb5(cli
, creds
);
3105 if (tevent_req_nterror(req
, status
)) {
3106 return tevent_req_post(req
, ev
);
3109 state
->es
= talloc_zero(state
, struct smb_trans_enc_state
);
3110 if (tevent_req_nomem(state
->es
, req
)) {
3111 return tevent_req_post(req
, ev
);
3114 status
= auth_generic_client_prepare(state
->es
, &ags
);
3115 if (tevent_req_nterror(req
, status
)) {
3116 return tevent_req_post(req
, ev
);
3119 gensec_want_feature(ags
->gensec_security
,
3120 GENSEC_FEATURE_SIGN
);
3121 gensec_want_feature(ags
->gensec_security
,
3122 GENSEC_FEATURE_SEAL
);
3124 status
= auth_generic_set_creds(ags
, creds
);
3125 if (tevent_req_nterror(req
, status
)) {
3126 return tevent_req_post(req
, ev
);
3129 if (target_service
!= NULL
) {
3130 status
= gensec_set_target_service(ags
->gensec_security
,
3132 if (tevent_req_nterror(req
, status
)) {
3133 return tevent_req_post(req
, ev
);
3137 if (target_hostname
!= NULL
) {
3138 status
= gensec_set_target_hostname(ags
->gensec_security
,
3140 if (tevent_req_nterror(req
, status
)) {
3141 return tevent_req_post(req
, ev
);
3145 gensec_set_max_update_size(ags
->gensec_security
,
3148 b
= smbXcli_conn_server_gss_blob(state
->cli
->conn
);
3150 state
->blob_in
= *b
;
3153 status
= auth_generic_client_start(ags
, GENSEC_OID_SPNEGO
);
3154 if (tevent_req_nterror(req
, status
)) {
3155 return tevent_req_post(req
, ev
);
3159 * We only need the gensec_security part from here.
3161 state
->es
->gensec_security
= talloc_move(state
->es
,
3162 &ags
->gensec_security
);
3165 cli_smb1_setup_encryption_local_next(req
);
3166 if (!tevent_req_is_in_progress(req
)) {
3167 return tevent_req_post(req
, ev
);
3173 static void cli_smb1_setup_encryption_local_next(struct tevent_req
*req
)
3175 struct cli_smb1_setup_encryption_state
*state
=
3176 tevent_req_data(req
,
3177 struct cli_smb1_setup_encryption_state
);
3178 struct tevent_req
*subreq
= NULL
;
3180 if (state
->local_ready
) {
3181 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
3185 subreq
= gensec_update_send(state
, state
->ev
,
3186 state
->es
->gensec_security
,
3188 if (tevent_req_nomem(subreq
, req
)) {
3191 tevent_req_set_callback(subreq
, cli_smb1_setup_encryption_local_done
, req
);
3194 static void cli_smb1_setup_encryption_local_done(struct tevent_req
*subreq
)
3196 struct tevent_req
*req
=
3197 tevent_req_callback_data(subreq
,
3199 struct cli_smb1_setup_encryption_state
*state
=
3200 tevent_req_data(req
,
3201 struct cli_smb1_setup_encryption_state
);
3204 status
= gensec_update_recv(subreq
, state
, &state
->blob_out
);
3205 TALLOC_FREE(subreq
);
3206 state
->blob_in
= data_blob_null
;
3207 if (!NT_STATUS_IS_OK(status
) &&
3208 !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
))
3210 tevent_req_nterror(req
, status
);
3214 if (NT_STATUS_IS_OK(status
)) {
3215 state
->local_ready
= true;
3219 * We always get NT_STATUS_OK from the server even if it is not ready.
3220 * So guess the server is ready when we are ready and already sent
3221 * our last blob to the server.
3223 if (state
->local_ready
&& state
->blob_out
.length
== 0) {
3224 state
->remote_ready
= true;
3227 if (state
->local_ready
&& state
->remote_ready
) {
3228 cli_smb1_setup_encryption_ready(req
);
3232 cli_smb1_setup_encryption_remote_next(req
);
3235 static void cli_smb1_setup_encryption_remote_next(struct tevent_req
*req
)
3237 struct cli_smb1_setup_encryption_state
*state
=
3238 tevent_req_data(req
,
3239 struct cli_smb1_setup_encryption_state
);
3240 struct tevent_req
*subreq
= NULL
;
3242 if (state
->remote_ready
) {
3243 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
3247 subreq
= cli_smb1_setup_encryption_blob_send(state
, state
->ev
,
3248 state
->cli
, state
->blob_out
);
3249 if (tevent_req_nomem(subreq
, req
)) {
3252 tevent_req_set_callback(subreq
,
3253 cli_smb1_setup_encryption_remote_done
,
3257 static void cli_smb1_setup_encryption_remote_done(struct tevent_req
*subreq
)
3259 struct tevent_req
*req
=
3260 tevent_req_callback_data(subreq
,
3262 struct cli_smb1_setup_encryption_state
*state
=
3263 tevent_req_data(req
,
3264 struct cli_smb1_setup_encryption_state
);
3267 status
= cli_smb1_setup_encryption_blob_recv(subreq
, state
,
3269 &state
->es
->enc_ctx_num
);
3270 TALLOC_FREE(subreq
);
3271 data_blob_free(&state
->blob_out
);
3272 if (!NT_STATUS_IS_OK(status
) &&
3273 !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
))
3275 tevent_req_nterror(req
, status
);
3280 * We always get NT_STATUS_OK even if the server is not ready.
3281 * So guess the server is ready when we are ready and sent
3282 * our last blob to the server.
3284 if (state
->local_ready
) {
3285 state
->remote_ready
= true;
3288 if (state
->local_ready
&& state
->remote_ready
) {
3289 cli_smb1_setup_encryption_ready(req
);
3293 cli_smb1_setup_encryption_local_next(req
);
3296 static void cli_smb1_setup_encryption_ready(struct tevent_req
*req
)
3298 struct cli_smb1_setup_encryption_state
*state
=
3299 tevent_req_data(req
,
3300 struct cli_smb1_setup_encryption_state
);
3301 struct smb_trans_enc_state
*es
= NULL
;
3303 if (state
->blob_in
.length
!= 0) {
3304 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
3308 if (state
->blob_out
.length
!= 0) {
3309 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
3313 es
= talloc_move(state
->cli
->conn
, &state
->es
);
3315 smb1cli_conn_set_encryption(state
->cli
->conn
, es
);
3318 tevent_req_done(req
);
3321 static NTSTATUS
cli_smb1_setup_encryption_recv(struct tevent_req
*req
)
3323 return tevent_req_simple_recv_ntstatus(req
);
3326 NTSTATUS
cli_smb1_setup_encryption(struct cli_state
*cli
,
3327 struct cli_credentials
*creds
)
3329 struct tevent_context
*ev
= NULL
;
3330 struct tevent_req
*req
= NULL
;
3331 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
3333 ev
= samba_tevent_context_init(talloc_tos());
3337 req
= cli_smb1_setup_encryption_send(ev
, ev
, cli
, creds
);
3341 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
3344 status
= cli_smb1_setup_encryption_recv(req
);
3351 establishes a connection right up to doing tconX, password specified.
3352 @param output_cli A fully initialised cli structure, non-null only on success
3353 @param dest_host The netbios name of the remote host
3354 @param dest_ip (optional) The the destination IP, NULL for name based lookup
3355 @param port (optional) The destination port (0 for default)
3356 @param service (optional) The share to make the connection to. Should be 'unqualified' in any way.
3357 @param service_type The 'type' of serivice.
3358 @param creds The used user credentials
3361 struct cli_full_connection_creds_state
{
3362 struct tevent_context
*ev
;
3363 const char *service
;
3364 const char *service_type
;
3365 struct cli_credentials
*creds
;
3367 struct cli_state
*cli
;
3370 static int cli_full_connection_creds_state_destructor(
3371 struct cli_full_connection_creds_state
*s
)
3373 if (s
->cli
!= NULL
) {
3374 cli_shutdown(s
->cli
);
3380 static void cli_full_connection_creds_conn_done(struct tevent_req
*subreq
);
3381 static void cli_full_connection_creds_sess_start(struct tevent_req
*req
);
3382 static void cli_full_connection_creds_sess_done(struct tevent_req
*subreq
);
3383 static void cli_full_connection_creds_tcon_start(struct tevent_req
*req
);
3384 static void cli_full_connection_creds_tcon_done(struct tevent_req
*subreq
);
3386 struct tevent_req
*cli_full_connection_creds_send(
3387 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
3388 const char *my_name
, const char *dest_host
,
3389 const struct sockaddr_storage
*dest_ss
, int port
,
3390 const char *service
, const char *service_type
,
3391 struct cli_credentials
*creds
,
3392 int flags
, int signing_state
)
3394 struct tevent_req
*req
, *subreq
;
3395 struct cli_full_connection_creds_state
*state
;
3396 enum credentials_use_kerberos krb5_state
;
3397 uint32_t gensec_features
= 0;
3399 req
= tevent_req_create(mem_ctx
, &state
,
3400 struct cli_full_connection_creds_state
);
3404 talloc_set_destructor(state
, cli_full_connection_creds_state_destructor
);
3406 flags
&= ~CLI_FULL_CONNECTION_USE_KERBEROS
;
3407 flags
&= ~CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS
;
3408 flags
&= ~CLI_FULL_CONNECTION_USE_CCACHE
;
3409 flags
&= ~CLI_FULL_CONNECTION_USE_NT_HASH
;
3411 krb5_state
= cli_credentials_get_kerberos_state(creds
);
3412 switch (krb5_state
) {
3413 case CRED_MUST_USE_KERBEROS
:
3414 flags
|= CLI_FULL_CONNECTION_USE_KERBEROS
;
3415 flags
&= ~CLI_FULL_CONNECTION_DONT_SPNEGO
;
3417 case CRED_AUTO_USE_KERBEROS
:
3418 flags
|= CLI_FULL_CONNECTION_USE_KERBEROS
;
3419 flags
|= CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS
;
3421 case CRED_DONT_USE_KERBEROS
:
3425 gensec_features
= cli_credentials_get_gensec_features(creds
);
3426 if (gensec_features
& GENSEC_FEATURE_NTLM_CCACHE
) {
3427 flags
|= CLI_FULL_CONNECTION_USE_CCACHE
;
3431 state
->service
= service
;
3432 state
->service_type
= service_type
;
3433 state
->creds
= creds
;
3434 state
->flags
= flags
;
3436 subreq
= cli_start_connection_send(
3437 state
, ev
, my_name
, dest_host
, dest_ss
, port
,
3438 signing_state
, flags
);
3439 if (tevent_req_nomem(subreq
, req
)) {
3440 return tevent_req_post(req
, ev
);
3442 tevent_req_set_callback(subreq
,
3443 cli_full_connection_creds_conn_done
,
3448 static void cli_full_connection_creds_conn_done(struct tevent_req
*subreq
)
3450 struct tevent_req
*req
= tevent_req_callback_data(
3451 subreq
, struct tevent_req
);
3452 struct cli_full_connection_creds_state
*state
= tevent_req_data(
3453 req
, struct cli_full_connection_creds_state
);
3456 status
= cli_start_connection_recv(subreq
, &state
->cli
);
3457 TALLOC_FREE(subreq
);
3458 if (tevent_req_nterror(req
, status
)) {
3462 cli_full_connection_creds_sess_start(req
);
3465 static void cli_full_connection_creds_sess_start(struct tevent_req
*req
)
3467 struct cli_full_connection_creds_state
*state
= tevent_req_data(
3468 req
, struct cli_full_connection_creds_state
);
3469 struct tevent_req
*subreq
= NULL
;
3471 subreq
= cli_session_setup_creds_send(
3472 state
, state
->ev
, state
->cli
, state
->creds
);
3473 if (tevent_req_nomem(subreq
, req
)) {
3476 tevent_req_set_callback(subreq
,
3477 cli_full_connection_creds_sess_done
,
3481 static void cli_full_connection_creds_sess_done(struct tevent_req
*subreq
)
3483 struct tevent_req
*req
= tevent_req_callback_data(
3484 subreq
, struct tevent_req
);
3485 struct cli_full_connection_creds_state
*state
= tevent_req_data(
3486 req
, struct cli_full_connection_creds_state
);
3489 status
= cli_session_setup_creds_recv(subreq
);
3490 TALLOC_FREE(subreq
);
3492 if (!NT_STATUS_IS_OK(status
) &&
3493 (state
->flags
& CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK
)) {
3495 state
->flags
&= ~CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK
;
3497 state
->creds
= cli_credentials_init_anon(state
);
3498 if (tevent_req_nomem(state
->creds
, req
)) {
3502 cli_full_connection_creds_sess_start(req
);
3506 if (tevent_req_nterror(req
, status
)) {
3510 cli_full_connection_creds_tcon_start(req
);
3513 static void cli_full_connection_creds_tcon_start(struct tevent_req
*req
)
3515 struct cli_full_connection_creds_state
*state
= tevent_req_data(
3516 req
, struct cli_full_connection_creds_state
);
3517 struct tevent_req
*subreq
= NULL
;
3518 const char *password
= NULL
;
3520 if (state
->service
== NULL
) {
3521 tevent_req_done(req
);
3525 password
= cli_credentials_get_password(state
->creds
);
3527 subreq
= cli_tree_connect_send(state
, state
->ev
,
3530 state
->service_type
,
3532 if (tevent_req_nomem(subreq
, req
)) {
3535 tevent_req_set_callback(subreq
,
3536 cli_full_connection_creds_tcon_done
,
3540 static void cli_full_connection_creds_tcon_done(struct tevent_req
*subreq
)
3542 struct tevent_req
*req
= tevent_req_callback_data(
3543 subreq
, struct tevent_req
);
3546 status
= cli_tree_connect_recv(subreq
);
3547 TALLOC_FREE(subreq
);
3548 if (tevent_req_nterror(req
, status
)) {
3552 tevent_req_done(req
);
3555 NTSTATUS
cli_full_connection_creds_recv(struct tevent_req
*req
,
3556 struct cli_state
**output_cli
)
3558 struct cli_full_connection_creds_state
*state
= tevent_req_data(
3559 req
, struct cli_full_connection_creds_state
);
3562 if (tevent_req_is_nterror(req
, &status
)) {
3565 *output_cli
= state
->cli
;
3566 talloc_set_destructor(state
, NULL
);
3567 return NT_STATUS_OK
;
3570 NTSTATUS
cli_full_connection_creds(struct cli_state
**output_cli
,
3571 const char *my_name
,
3572 const char *dest_host
,
3573 const struct sockaddr_storage
*dest_ss
, int port
,
3574 const char *service
, const char *service_type
,
3575 struct cli_credentials
*creds
,
3579 struct tevent_context
*ev
;
3580 struct tevent_req
*req
;
3581 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
3583 ev
= samba_tevent_context_init(talloc_tos());
3587 req
= cli_full_connection_creds_send(
3588 ev
, ev
, my_name
, dest_host
, dest_ss
, port
, service
,
3589 service_type
, creds
, flags
, signing_state
);
3593 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
3596 status
= cli_full_connection_creds_recv(req
, output_cli
);
3602 NTSTATUS
cli_full_connection(struct cli_state
**output_cli
,
3603 const char *my_name
,
3604 const char *dest_host
,
3605 const struct sockaddr_storage
*dest_ss
, int port
,
3606 const char *service
, const char *service_type
,
3607 const char *user
, const char *domain
,
3608 const char *password
, int flags
,
3611 TALLOC_CTX
*frame
= talloc_stackframe();
3613 bool use_kerberos
= false;
3614 bool fallback_after_kerberos
= false;
3615 bool use_ccache
= false;
3616 bool pw_nt_hash
= false;
3617 struct cli_credentials
*creds
= NULL
;
3619 if (flags
& CLI_FULL_CONNECTION_USE_KERBEROS
) {
3620 use_kerberos
= true;
3623 if (flags
& CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS
) {
3624 fallback_after_kerberos
= true;
3627 if (flags
& CLI_FULL_CONNECTION_USE_CCACHE
) {
3631 if (flags
& CLI_FULL_CONNECTION_USE_NT_HASH
) {
3635 creds
= cli_session_creds_init(frame
,
3638 NULL
, /* realm (use default) */
3641 fallback_after_kerberos
,
3644 if (creds
== NULL
) {
3646 return NT_STATUS_NO_MEMORY
;
3649 status
= cli_full_connection_creds(output_cli
, my_name
,
3650 dest_host
, dest_ss
, port
,
3651 service
, service_type
,
3652 creds
, flags
, signing_state
);
3653 if (!NT_STATUS_IS_OK(status
)) {
3659 return NT_STATUS_OK
;
3662 /****************************************************************************
3663 Send an old style tcon.
3664 ****************************************************************************/
3665 struct cli_raw_tcon_state
{
3669 static void cli_raw_tcon_done(struct tevent_req
*subreq
);
3671 static struct tevent_req
*cli_raw_tcon_send(
3672 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
3673 const char *service
, const char *pass
, const char *dev
)
3675 struct tevent_req
*req
, *subreq
;
3676 struct cli_raw_tcon_state
*state
;
3679 req
= tevent_req_create(mem_ctx
, &state
, struct cli_raw_tcon_state
);
3684 if (!lp_client_plaintext_auth() && (*pass
)) {
3685 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
3686 " or 'client ntlmv2 auth = yes'\n"));
3687 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
3688 return tevent_req_post(req
, ev
);
3691 TALLOC_FREE(cli
->smb1
.tcon
);
3692 cli
->smb1
.tcon
= smbXcli_tcon_create(cli
);
3693 if (tevent_req_nomem(cli
->smb1
.tcon
, req
)) {
3694 return tevent_req_post(req
, ev
);
3696 smb1cli_tcon_set_id(cli
->smb1
.tcon
, UINT16_MAX
);
3698 bytes
= talloc_array(state
, uint8_t, 0);
3699 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
3700 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
3701 service
, strlen(service
)+1, NULL
);
3702 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
3703 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
3704 pass
, strlen(pass
)+1, NULL
);
3705 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
3706 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
3707 dev
, strlen(dev
)+1, NULL
);
3709 if (tevent_req_nomem(bytes
, req
)) {
3710 return tevent_req_post(req
, ev
);
3713 subreq
= cli_smb_send(state
, ev
, cli
, SMBtcon
, 0, 0, 0, NULL
,
3714 talloc_get_size(bytes
), bytes
);
3715 if (tevent_req_nomem(subreq
, req
)) {
3716 return tevent_req_post(req
, ev
);
3718 tevent_req_set_callback(subreq
, cli_raw_tcon_done
, req
);
3722 static void cli_raw_tcon_done(struct tevent_req
*subreq
)
3724 struct tevent_req
*req
= tevent_req_callback_data(
3725 subreq
, struct tevent_req
);
3726 struct cli_raw_tcon_state
*state
= tevent_req_data(
3727 req
, struct cli_raw_tcon_state
);
3730 status
= cli_smb_recv(subreq
, state
, NULL
, 2, NULL
, &state
->ret_vwv
,
3732 TALLOC_FREE(subreq
);
3733 if (tevent_req_nterror(req
, status
)) {
3736 tevent_req_done(req
);
3739 static NTSTATUS
cli_raw_tcon_recv(struct tevent_req
*req
,
3740 uint16_t *max_xmit
, uint16_t *tid
)
3742 struct cli_raw_tcon_state
*state
= tevent_req_data(
3743 req
, struct cli_raw_tcon_state
);
3746 if (tevent_req_is_nterror(req
, &status
)) {
3749 *max_xmit
= SVAL(state
->ret_vwv
+ 0, 0);
3750 *tid
= SVAL(state
->ret_vwv
+ 1, 0);
3751 return NT_STATUS_OK
;
3754 NTSTATUS
cli_raw_tcon(struct cli_state
*cli
,
3755 const char *service
, const char *pass
, const char *dev
,
3756 uint16_t *max_xmit
, uint16_t *tid
)
3758 struct tevent_context
*ev
;
3759 struct tevent_req
*req
;
3760 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
3762 ev
= samba_tevent_context_init(talloc_tos());
3766 req
= cli_raw_tcon_send(ev
, ev
, cli
, service
, pass
, dev
);
3770 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
3773 status
= cli_raw_tcon_recv(req
, max_xmit
, tid
);
3779 /* Return a cli_state pointing at the IPC$ share for the given server */
3781 struct cli_state
*get_ipc_connect(char *server
,
3782 struct sockaddr_storage
*server_ss
,
3783 const struct user_auth_info
*user_info
)
3785 struct cli_state
*cli
;
3787 uint32_t flags
= CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK
;
3789 if (get_cmdline_auth_info_use_kerberos(user_info
)) {
3790 flags
|= CLI_FULL_CONNECTION_USE_KERBEROS
;
3793 flags
|= CLI_FULL_CONNECTION_FORCE_SMB1
;
3795 nt_status
= cli_full_connection(&cli
, NULL
, server
, server_ss
, 0, "IPC$", "IPC",
3796 get_cmdline_auth_info_username(user_info
),
3798 get_cmdline_auth_info_password(user_info
),
3800 SMB_SIGNING_DEFAULT
);
3802 if (NT_STATUS_IS_OK(nt_status
)) {
3804 } else if (is_ipaddress(server
)) {
3805 /* windows 9* needs a correct NMB name for connections */
3806 fstring remote_name
;
3808 if (name_status_find("*", 0, 0, server_ss
, remote_name
)) {
3809 cli
= get_ipc_connect(remote_name
, server_ss
, user_info
);
3818 * Given the IP address of a master browser on the network, return its
3819 * workgroup and connect to it.
3821 * This function is provided to allow additional processing beyond what
3822 * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
3823 * browsers and obtain each master browsers' list of domains (in case the
3824 * first master browser is recently on the network and has not yet
3825 * synchronized with other master browsers and therefore does not yet have the
3826 * entire network browse list)
3829 struct cli_state
*get_ipc_connect_master_ip(TALLOC_CTX
*ctx
,
3830 struct sockaddr_storage
*mb_ip
,
3831 const struct user_auth_info
*user_info
,
3832 char **pp_workgroup_out
)
3834 char addr
[INET6_ADDRSTRLEN
];
3836 struct cli_state
*cli
;
3837 struct sockaddr_storage server_ss
;
3839 *pp_workgroup_out
= NULL
;
3841 print_sockaddr(addr
, sizeof(addr
), mb_ip
);
3842 DEBUG(99, ("Looking up name of master browser %s\n",
3846 * Do a name status query to find out the name of the master browser.
3847 * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
3848 * master browser will not respond to a wildcard query (or, at least,
3849 * an NT4 server acting as the domain master browser will not).
3851 * We might be able to use ONLY the query on MSBROWSE, but that's not
3852 * yet been tested with all Windows versions, so until it is, leave
3853 * the original wildcard query as the first choice and fall back to
3854 * MSBROWSE if the wildcard query fails.
3856 if (!name_status_find("*", 0, 0x1d, mb_ip
, name
) &&
3857 !name_status_find(MSBROWSE
, 1, 0x1d, mb_ip
, name
)) {
3859 DEBUG(99, ("Could not retrieve name status for %s\n",
3864 if (!find_master_ip(name
, &server_ss
)) {
3865 DEBUG(99, ("Could not find master ip for %s\n", name
));
3869 *pp_workgroup_out
= talloc_strdup(ctx
, name
);
3871 DEBUG(4, ("found master browser %s, %s\n", name
, addr
));
3873 print_sockaddr(addr
, sizeof(addr
), &server_ss
);
3874 cli
= get_ipc_connect(addr
, &server_ss
, user_info
);
3880 * Return the IP address and workgroup of a master browser on the network, and
3884 struct cli_state
*get_ipc_connect_master_ip_bcast(TALLOC_CTX
*ctx
,
3885 const struct user_auth_info
*user_info
,
3886 char **pp_workgroup_out
)
3888 struct sockaddr_storage
*ip_list
;
3889 struct cli_state
*cli
;
3893 *pp_workgroup_out
= NULL
;
3895 DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
3897 /* Go looking for workgroups by broadcasting on the local network */
3899 status
= name_resolve_bcast(MSBROWSE
, 1, talloc_tos(),
3901 if (!NT_STATUS_IS_OK(status
)) {
3902 DEBUG(99, ("No master browsers responded: %s\n",
3903 nt_errstr(status
)));
3907 for (i
= 0; i
< count
; i
++) {
3908 char addr
[INET6_ADDRSTRLEN
];
3909 print_sockaddr(addr
, sizeof(addr
), &ip_list
[i
]);
3910 DEBUG(99, ("Found master browser %s\n", addr
));
3912 cli
= get_ipc_connect_master_ip(ctx
, &ip_list
[i
],
3913 user_info
, pp_workgroup_out
);