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 "../libcli/auth/libcli_auth.h"
27 #include "../libcli/auth/spnego.h"
29 #include "auth/credentials/credentials.h"
30 #include "auth/gensec/gensec.h"
31 #include "auth/ntlmssp/ntlmssp.h"
32 #include "auth_generic.h"
33 #include "libads/kerberos_proto.h"
35 #include "../lib/util/tevent_ntstatus.h"
36 #include "async_smb.h"
37 #include "libsmb/nmblib.h"
38 #include "librpc/ndr/libndr.h"
39 #include "../libcli/smb/smbXcli_base.h"
40 #include "../libcli/smb/smb_seal.h"
41 #include "lib/param/param.h"
42 #include "../libcli/smb/smb2_negotiate_context.h"
44 #define STAR_SMBSERVER "*SMBSERVER"
46 static char *cli_session_setup_get_account(TALLOC_CTX
*mem_ctx
,
47 const char *principal
);
49 struct cli_credentials
*cli_session_creds_init(TALLOC_CTX
*mem_ctx
,
55 bool fallback_after_kerberos
,
57 bool password_is_nt_hash
)
59 struct loadparm_context
*lp_ctx
= NULL
;
60 struct cli_credentials
*creds
= NULL
;
61 const char *principal
= NULL
;
66 creds
= cli_credentials_init(mem_ctx
);
71 lp_ctx
= loadparm_init_s3(creds
, loadparm_s3_helpers());
75 ok
= cli_credentials_set_conf(creds
, lp_ctx
);
80 if (username
== NULL
) {
84 if (strlen(username
) == 0) {
85 if (password
!= NULL
&& strlen(password
) == 0) {
87 * some callers pass "" as no password
89 * gensec only handles NULL as no password.
93 if (password
== NULL
) {
94 cli_credentials_set_anonymous(creds
);
99 tmp
= talloc_strdup(creds
, username
);
105 /* allow for workgroups as part of the username */
106 if ((p
= strchr_m(tmp
, '\\')) ||
107 (p
= strchr_m(tmp
, '/')) ||
108 (p
= strchr_m(tmp
, *lp_winbind_separator()))) {
114 principal
= username
;
115 username
= cli_session_setup_get_account(creds
, principal
);
116 if (username
== NULL
) {
119 ok
= strequal(username
, principal
);
122 * Ok still the same, so it's not a principal
127 if (use_kerberos
&& fallback_after_kerberos
) {
128 cli_credentials_set_kerberos_state(creds
,
129 CRED_USE_KERBEROS_DESIRED
,
131 } else if (use_kerberos
) {
132 cli_credentials_set_kerberos_state(creds
,
133 CRED_USE_KERBEROS_REQUIRED
,
136 cli_credentials_set_kerberos_state(creds
,
137 CRED_USE_KERBEROS_DISABLED
,
144 features
= cli_credentials_get_gensec_features(creds
);
145 features
|= GENSEC_FEATURE_NTLM_CCACHE
;
146 cli_credentials_set_gensec_features(creds
,
150 if (password
!= NULL
&& strlen(password
) == 0) {
152 * some callers pass "" as no password
154 * GENSEC_FEATURE_NTLM_CCACHE only handles
155 * NULL as no password.
161 ok
= cli_credentials_set_username(creds
,
168 if (domain
!= NULL
) {
169 ok
= cli_credentials_set_domain(creds
,
177 if (principal
!= NULL
) {
178 ok
= cli_credentials_set_principal(creds
,
187 ok
= cli_credentials_set_realm(creds
,
195 if (password
!= NULL
&& strlen(password
) > 0) {
196 if (password_is_nt_hash
) {
197 struct samr_Password nt_hash
;
200 converted
= strhex_to_str((char *)nt_hash
.hash
,
201 sizeof(nt_hash
.hash
),
204 if (converted
!= sizeof(nt_hash
.hash
)) {
208 ok
= cli_credentials_set_nt_hash(creds
,
215 ok
= cli_credentials_set_password(creds
,
230 NTSTATUS
cli_session_creds_prepare_krb5(struct cli_state
*cli
,
231 struct cli_credentials
*creds
)
233 TALLOC_CTX
*frame
= talloc_stackframe();
234 const char *user_principal
= NULL
;
235 const char *user_account
= NULL
;
236 const char *user_domain
= NULL
;
237 const char *pass
= NULL
;
238 char *canon_principal
= NULL
;
239 char *canon_realm
= NULL
;
240 const char *target_hostname
= NULL
;
241 enum credentials_use_kerberos krb5_state
;
242 bool try_kerberos
= false;
243 bool need_kinit
= false;
244 bool auth_requested
= true;
248 target_hostname
= smbXcli_conn_remote_name(cli
->conn
);
250 auth_requested
= cli_credentials_authentication_requested(creds
);
251 if (auth_requested
) {
253 user_principal
= cli_credentials_get_principal(creds
, frame
);
256 return NT_STATUS_NO_MEMORY
;
259 user_account
= cli_credentials_get_username(creds
);
260 user_domain
= cli_credentials_get_domain(creds
);
261 pass
= cli_credentials_get_password(creds
);
263 krb5_state
= cli_credentials_get_kerberos_state(creds
);
265 if (krb5_state
!= CRED_USE_KERBEROS_DISABLED
) {
269 if (user_principal
== NULL
) {
270 try_kerberos
= false;
273 if (target_hostname
== NULL
) {
274 try_kerberos
= false;
275 } else if (is_ipaddress(target_hostname
)) {
276 try_kerberos
= false;
277 } else if (strequal(target_hostname
, "localhost")) {
278 try_kerberos
= false;
279 } else if (strequal(target_hostname
, STAR_SMBSERVER
)) {
280 try_kerberos
= false;
281 } else if (!auth_requested
) {
282 try_kerberos
= false;
285 if (krb5_state
== CRED_USE_KERBEROS_REQUIRED
&& !try_kerberos
) {
286 DEBUG(0, ("Kerberos auth with '%s' (%s\\%s) to access "
287 "'%s' not possible\n",
288 user_principal
, user_domain
, user_account
,
291 return NT_STATUS_ACCESS_DENIED
;
294 if (pass
== NULL
|| strlen(pass
) == 0) {
296 } else if (krb5_state
== CRED_USE_KERBEROS_REQUIRED
) {
297 need_kinit
= try_kerberos
;
299 need_kinit
= try_kerberos
;
307 DBG_INFO("Doing kinit for %s to access %s\n",
308 user_principal
, target_hostname
);
311 * TODO: This should be done within the gensec layer
314 setenv(KRB5_ENV_CCNAME
, "MEMORY:cliconnect", 1);
315 ret
= kerberos_kinit_password_ext(user_principal
,
329 int dbglvl
= DBGLVL_NOTICE
;
331 if (krb5_state
== CRED_USE_KERBEROS_REQUIRED
) {
335 DEBUG(dbglvl
, ("Kinit for %s to access %s failed: %s\n",
336 user_principal
, target_hostname
,
337 error_message(ret
)));
338 if (krb5_state
== CRED_USE_KERBEROS_REQUIRED
) {
340 return krb5_to_nt_status(ret
);
344 * Ignore the error and hope that NTLM will work
350 ok
= cli_credentials_set_principal(creds
,
355 return NT_STATUS_NO_MEMORY
;
358 ok
= cli_credentials_set_realm(creds
,
363 return NT_STATUS_NO_MEMORY
;
366 DBG_DEBUG("Successfully authenticated as %s (%s) to access %s using "
376 static NTSTATUS
cli_state_update_after_sesssetup(struct cli_state
*cli
,
377 const char *native_os
,
378 const char *native_lm
,
379 const char *primary_domain
)
381 #define _VALID_STR(p) ((p) != NULL && (p)[0] != '\0')
383 if (!_VALID_STR(cli
->server_os
) && _VALID_STR(native_os
)) {
384 cli
->server_os
= talloc_strdup(cli
, native_os
);
385 if (cli
->server_os
== NULL
) {
386 return NT_STATUS_NO_MEMORY
;
390 if (!_VALID_STR(cli
->server_type
) && _VALID_STR(native_lm
)) {
391 cli
->server_type
= talloc_strdup(cli
, native_lm
);
392 if (cli
->server_type
== NULL
) {
393 return NT_STATUS_NO_MEMORY
;
397 if (!_VALID_STR(cli
->server_domain
) && _VALID_STR(primary_domain
)) {
398 cli
->server_domain
= talloc_strdup(cli
, primary_domain
);
399 if (cli
->server_domain
== NULL
) {
400 return NT_STATUS_NO_MEMORY
;
408 /********************************************************
409 Utility function to ensure we always return at least
410 a valid char * pointer to an empty string for the
411 cli->server_os, cli->server_type and cli->server_domain
413 *******************************************************/
415 static NTSTATUS
smb_bytes_talloc_string(TALLOC_CTX
*mem_ctx
,
422 *destlen
= pull_string_talloc(mem_ctx
,
429 if (*destlen
== -1) {
430 return NT_STATUS_NO_MEMORY
;
434 *dest
= talloc_strdup(mem_ctx
, "");
436 return NT_STATUS_NO_MEMORY
;
442 /****************************************************************************
443 Work out suitable capabilities to offer the server.
444 ****************************************************************************/
446 static uint32_t cli_session_setup_capabilities(struct cli_state
*cli
,
447 uint32_t sesssetup_capabilities
)
449 uint32_t client_capabilities
= smb1cli_conn_capabilities(cli
->conn
);
452 * We only send capabilities based on the mask for:
453 * - client only flags
454 * - flags used in both directions
456 * We do not echo the server only flags, except some legacy flags.
458 * SMB_CAP_LEGACY_CLIENT_MASK contains CAP_LARGE_READX and
459 * CAP_LARGE_WRITEX in order to allow us to do large reads
460 * against old Samba releases (<= 3.6.x).
462 client_capabilities
&= (SMB_CAP_BOTH_MASK
| SMB_CAP_LEGACY_CLIENT_MASK
);
465 * Session Setup specific flags CAP_DYNAMIC_REAUTH
466 * and CAP_EXTENDED_SECURITY are passed by the caller.
467 * We need that in order to do guest logins even if
468 * CAP_EXTENDED_SECURITY is negotiated.
470 client_capabilities
&= ~(CAP_DYNAMIC_REAUTH
|CAP_EXTENDED_SECURITY
);
471 sesssetup_capabilities
&= (CAP_DYNAMIC_REAUTH
|CAP_EXTENDED_SECURITY
);
472 client_capabilities
|= sesssetup_capabilities
;
474 return client_capabilities
;
477 /****************************************************************************
478 Do a NT1 guest session setup.
479 ****************************************************************************/
481 struct cli_session_setup_guest_state
{
482 struct cli_state
*cli
;
487 static void cli_session_setup_guest_done(struct tevent_req
*subreq
);
489 struct tevent_req
*cli_session_setup_guest_create(TALLOC_CTX
*mem_ctx
,
490 struct tevent_context
*ev
,
491 struct cli_state
*cli
,
492 struct tevent_req
**psmbreq
)
494 struct tevent_req
*req
, *subreq
;
495 struct cli_session_setup_guest_state
*state
;
499 req
= tevent_req_create(mem_ctx
, &state
,
500 struct cli_session_setup_guest_state
);
507 SCVAL(vwv
+0, 0, 0xFF);
510 SSVAL(vwv
+2, 0, CLI_BUFFER_SIZE
);
512 SSVAL(vwv
+4, 0, cli_state_get_vc_num(cli
));
513 SIVAL(vwv
+5, 0, smb1cli_conn_server_session_key(cli
->conn
));
518 SIVAL(vwv
+11, 0, cli_session_setup_capabilities(cli
, 0));
520 bytes
= talloc_array(state
, uint8_t, 0);
522 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "", 1, /* username */
524 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "", 1, /* workgroup */
526 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "Unix", 5, NULL
);
527 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "Samba", 6, NULL
);
534 state
->bytes
.iov_base
= (void *)bytes
;
535 state
->bytes
.iov_len
= talloc_get_size(bytes
);
537 subreq
= cli_smb_req_create(state
, ev
, cli
, SMBsesssetupX
, 0, 0, 13,
538 vwv
, 1, &state
->bytes
);
539 if (subreq
== NULL
) {
543 tevent_req_set_callback(subreq
, cli_session_setup_guest_done
, req
);
548 struct tevent_req
*cli_session_setup_guest_send(TALLOC_CTX
*mem_ctx
,
549 struct tevent_context
*ev
,
550 struct cli_state
*cli
)
552 struct tevent_req
*req
, *subreq
;
555 req
= cli_session_setup_guest_create(mem_ctx
, ev
, cli
, &subreq
);
560 status
= smb1cli_req_chain_submit(&subreq
, 1);
561 if (!NT_STATUS_IS_OK(status
)) {
562 tevent_req_nterror(req
, status
);
563 return tevent_req_post(req
, ev
);
568 static void cli_session_setup_guest_done(struct tevent_req
*subreq
)
570 struct tevent_req
*req
= tevent_req_callback_data(
571 subreq
, struct tevent_req
);
572 struct cli_session_setup_guest_state
*state
= tevent_req_data(
573 req
, struct cli_session_setup_guest_state
);
574 struct cli_state
*cli
= state
->cli
;
585 status
= cli_smb_recv(subreq
, state
, &in
, 3, &wct
, &vwv
,
588 if (!NT_STATUS_IS_OK(status
)) {
589 tevent_req_nterror(req
, status
);
593 inhdr
= in
+ NBT_HDR_SIZE
;
596 cli_state_set_uid(state
->cli
, SVAL(inhdr
, HDR_UID
));
597 smb1cli_session_set_action(cli
->smb1
.session
, SVAL(vwv
+2, 0));
599 status
= smb_bytes_talloc_string(cli
,
606 if (!NT_STATUS_IS_OK(status
)) {
607 tevent_req_nterror(req
, status
);
612 status
= smb_bytes_talloc_string(cli
,
619 if (!NT_STATUS_IS_OK(status
)) {
620 tevent_req_nterror(req
, status
);
625 status
= smb_bytes_talloc_string(cli
,
632 if (!NT_STATUS_IS_OK(status
)) {
633 tevent_req_nterror(req
, status
);
637 tevent_req_done(req
);
640 NTSTATUS
cli_session_setup_guest_recv(struct tevent_req
*req
)
642 return tevent_req_simple_recv_ntstatus(req
);
645 /* The following is calculated from :
647 * (smb_wcnt * 2) = 24 (smb_wcnt == 12 in cli_session_setup_blob_send() )
648 * (strlen("Unix") + 1 + strlen("Samba") + 1) * 2 = 22 (unicode strings at
652 #define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22)
654 struct cli_sesssetup_blob_state
{
655 struct tevent_context
*ev
;
656 struct cli_state
*cli
;
658 uint16_t max_blob_size
;
661 struct iovec
*recv_iov
;
664 const uint8_t *inbuf
;
671 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state
*state
,
672 struct tevent_req
**psubreq
);
673 static void cli_sesssetup_blob_done(struct tevent_req
*subreq
);
675 static struct tevent_req
*cli_sesssetup_blob_send(TALLOC_CTX
*mem_ctx
,
676 struct tevent_context
*ev
,
677 struct cli_state
*cli
,
680 struct tevent_req
*req
, *subreq
;
681 struct cli_sesssetup_blob_state
*state
;
682 uint32_t usable_space
;
684 req
= tevent_req_create(mem_ctx
, &state
,
685 struct cli_sesssetup_blob_state
);
693 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
694 usable_space
= UINT16_MAX
;
696 usable_space
= cli_state_available_size(cli
,
697 BASE_SESSSETUP_BLOB_PACKET_SIZE
);
700 if (usable_space
== 0) {
701 DEBUG(1, ("cli_session_setup_blob: cli->max_xmit too small "
702 "(not possible to send %u bytes)\n",
703 BASE_SESSSETUP_BLOB_PACKET_SIZE
+ 1));
704 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
705 return tevent_req_post(req
, ev
);
707 state
->max_blob_size
= MIN(usable_space
, 0xFFFF);
709 if (!cli_sesssetup_blob_next(state
, &subreq
)) {
710 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
711 return tevent_req_post(req
, ev
);
713 tevent_req_set_callback(subreq
, cli_sesssetup_blob_done
, req
);
717 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state
*state
,
718 struct tevent_req
**psubreq
)
720 struct tevent_req
*subreq
;
723 thistime
= MIN(state
->blob
.length
, state
->max_blob_size
);
725 state
->this_blob
.data
= state
->blob
.data
;
726 state
->this_blob
.length
= thistime
;
728 state
->blob
.data
+= thistime
;
729 state
->blob
.length
-= thistime
;
731 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
732 subreq
= smb2cli_session_setup_send(state
, state
->ev
,
735 state
->cli
->smb2
.session
,
737 SMB2_CAP_DFS
, /* in_capabilities */
739 0, /* in_previous_session_id */
741 if (subreq
== NULL
) {
745 uint16_t in_buf_size
= 0;
746 uint16_t in_mpx_max
= 0;
747 uint16_t in_vc_num
= 0;
748 uint32_t in_sess_key
= 0;
749 uint32_t in_capabilities
= 0;
750 const char *in_native_os
= NULL
;
751 const char *in_native_lm
= NULL
;
753 in_buf_size
= CLI_BUFFER_SIZE
;
754 in_mpx_max
= smbXcli_conn_max_requests(state
->cli
->conn
);
755 in_vc_num
= cli_state_get_vc_num(state
->cli
);
756 in_sess_key
= smb1cli_conn_server_session_key(state
->cli
->conn
);
757 in_capabilities
= cli_session_setup_capabilities(state
->cli
,
758 CAP_EXTENDED_SECURITY
);
759 in_native_os
= "Unix";
760 in_native_lm
= "Samba";
763 * For now we keep the same values as before,
764 * we may remove these in a separate commit later.
770 subreq
= smb1cli_session_setup_ext_send(state
, state
->ev
,
773 state
->cli
->smb1
.pid
,
774 state
->cli
->smb1
.session
,
783 if (subreq
== NULL
) {
791 static void cli_sesssetup_blob_done(struct tevent_req
*subreq
)
793 struct tevent_req
*req
= tevent_req_callback_data(
794 subreq
, struct tevent_req
);
795 struct cli_sesssetup_blob_state
*state
= tevent_req_data(
796 req
, struct cli_sesssetup_blob_state
);
799 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
800 status
= smb2cli_session_setup_recv(subreq
, state
,
804 status
= smb1cli_session_setup_ext_recv(subreq
, state
,
808 &state
->out_native_os
,
809 &state
->out_native_lm
);
812 if (!NT_STATUS_IS_OK(status
)
813 && !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
814 tevent_req_nterror(req
, status
);
818 state
->status
= status
;
820 status
= cli_state_update_after_sesssetup(state
->cli
,
821 state
->out_native_os
,
822 state
->out_native_lm
,
824 if (tevent_req_nterror(req
, status
)) {
828 if (state
->blob
.length
!= 0) {
832 if (!cli_sesssetup_blob_next(state
, &subreq
)) {
836 tevent_req_set_callback(subreq
, cli_sesssetup_blob_done
, req
);
839 tevent_req_done(req
);
842 static NTSTATUS
cli_sesssetup_blob_recv(struct tevent_req
*req
,
845 const uint8_t **pinbuf
,
846 struct iovec
**precv_iov
)
848 struct cli_sesssetup_blob_state
*state
= tevent_req_data(
849 req
, struct cli_sesssetup_blob_state
);
851 struct iovec
*recv_iov
;
853 if (tevent_req_is_nterror(req
, &status
)) {
854 TALLOC_FREE(state
->cli
->smb2
.session
);
855 cli_state_set_uid(state
->cli
, UID_FIELD_INVALID
);
856 tevent_req_received(req
);
860 recv_iov
= talloc_move(mem_ctx
, &state
->recv_iov
);
862 *pblob
= state
->ret_blob
;
864 if (pinbuf
!= NULL
) {
865 *pinbuf
= state
->inbuf
;
867 if (precv_iov
!= NULL
) {
868 *precv_iov
= recv_iov
;
870 /* could be NT_STATUS_MORE_PROCESSING_REQUIRED */
871 status
= state
->status
;
872 tevent_req_received(req
);
876 /****************************************************************************
877 Do a spnego/NTLMSSP encrypted session setup.
878 ****************************************************************************/
880 struct cli_session_setup_gensec_state
{
881 struct tevent_context
*ev
;
882 struct cli_state
*cli
;
883 struct auth_generic_state
*auth_generic
;
886 const uint8_t *inbuf
;
887 struct iovec
*recv_iov
;
891 DATA_BLOB session_key
;
894 static int cli_session_setup_gensec_state_destructor(
895 struct cli_session_setup_gensec_state
*state
)
897 TALLOC_FREE(state
->auth_generic
);
898 data_blob_clear_free(&state
->session_key
);
902 static void cli_session_setup_gensec_local_next(struct tevent_req
*req
);
903 static void cli_session_setup_gensec_local_done(struct tevent_req
*subreq
);
904 static void cli_session_setup_gensec_remote_next(struct tevent_req
*req
);
905 static void cli_session_setup_gensec_remote_done(struct tevent_req
*subreq
);
906 static void cli_session_setup_gensec_ready(struct tevent_req
*req
);
908 static struct tevent_req
*cli_session_setup_gensec_send(
909 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
910 struct cli_credentials
*creds
,
911 const char *target_service
,
912 const char *target_hostname
)
914 struct tevent_req
*req
;
915 struct cli_session_setup_gensec_state
*state
;
917 const DATA_BLOB
*b
= NULL
;
919 req
= tevent_req_create(mem_ctx
, &state
,
920 struct cli_session_setup_gensec_state
);
927 talloc_set_destructor(
928 state
, cli_session_setup_gensec_state_destructor
);
930 status
= auth_generic_client_prepare(state
, &state
->auth_generic
);
931 if (tevent_req_nterror(req
, status
)) {
932 return tevent_req_post(req
, ev
);
935 status
= auth_generic_set_creds(state
->auth_generic
, creds
);
936 if (tevent_req_nterror(req
, status
)) {
937 return tevent_req_post(req
, ev
);
940 gensec_want_feature(state
->auth_generic
->gensec_security
,
941 GENSEC_FEATURE_SESSION_KEY
);
943 if (target_service
!= NULL
) {
944 status
= gensec_set_target_service(
945 state
->auth_generic
->gensec_security
,
947 if (tevent_req_nterror(req
, status
)) {
948 return tevent_req_post(req
, ev
);
952 if (target_hostname
!= NULL
) {
953 status
= gensec_set_target_hostname(
954 state
->auth_generic
->gensec_security
,
956 if (tevent_req_nterror(req
, status
)) {
957 return tevent_req_post(req
, ev
);
961 b
= smbXcli_conn_server_gss_blob(cli
->conn
);
966 state
->is_anonymous
= cli_credentials_is_anonymous(state
->auth_generic
->credentials
);
968 status
= auth_generic_client_start(state
->auth_generic
,
970 if (tevent_req_nterror(req
, status
)) {
971 return tevent_req_post(req
, ev
);
974 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
975 state
->cli
->smb2
.session
= smbXcli_session_create(cli
,
977 if (tevent_req_nomem(state
->cli
->smb2
.session
, req
)) {
978 return tevent_req_post(req
, ev
);
982 cli_session_setup_gensec_local_next(req
);
983 if (!tevent_req_is_in_progress(req
)) {
984 return tevent_req_post(req
, ev
);
990 static void cli_session_setup_gensec_local_next(struct tevent_req
*req
)
992 struct cli_session_setup_gensec_state
*state
=
994 struct cli_session_setup_gensec_state
);
995 struct tevent_req
*subreq
= NULL
;
997 if (state
->local_ready
) {
998 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
1002 subreq
= gensec_update_send(state
, state
->ev
,
1003 state
->auth_generic
->gensec_security
,
1005 if (tevent_req_nomem(subreq
, req
)) {
1008 tevent_req_set_callback(subreq
, cli_session_setup_gensec_local_done
, req
);
1011 static void cli_session_setup_gensec_local_done(struct tevent_req
*subreq
)
1013 struct tevent_req
*req
=
1014 tevent_req_callback_data(subreq
,
1016 struct cli_session_setup_gensec_state
*state
=
1017 tevent_req_data(req
,
1018 struct cli_session_setup_gensec_state
);
1021 status
= gensec_update_recv(subreq
, state
, &state
->blob_out
);
1022 TALLOC_FREE(subreq
);
1023 state
->blob_in
= data_blob_null
;
1024 if (!NT_STATUS_IS_OK(status
) &&
1025 !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
))
1027 tevent_req_nterror(req
, status
);
1031 if (NT_STATUS_IS_OK(status
)) {
1032 state
->local_ready
= true;
1035 if (state
->local_ready
&& state
->remote_ready
) {
1036 cli_session_setup_gensec_ready(req
);
1040 cli_session_setup_gensec_remote_next(req
);
1043 static void cli_session_setup_gensec_remote_next(struct tevent_req
*req
)
1045 struct cli_session_setup_gensec_state
*state
=
1046 tevent_req_data(req
,
1047 struct cli_session_setup_gensec_state
);
1048 struct tevent_req
*subreq
= NULL
;
1050 if (state
->remote_ready
) {
1051 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
1055 subreq
= cli_sesssetup_blob_send(state
, state
->ev
,
1056 state
->cli
, state
->blob_out
);
1057 if (tevent_req_nomem(subreq
, req
)) {
1060 tevent_req_set_callback(subreq
,
1061 cli_session_setup_gensec_remote_done
,
1065 static void cli_session_setup_gensec_remote_done(struct tevent_req
*subreq
)
1067 struct tevent_req
*req
=
1068 tevent_req_callback_data(subreq
,
1070 struct cli_session_setup_gensec_state
*state
=
1071 tevent_req_data(req
,
1072 struct cli_session_setup_gensec_state
);
1075 state
->inbuf
= NULL
;
1076 TALLOC_FREE(state
->recv_iov
);
1078 status
= cli_sesssetup_blob_recv(subreq
, state
, &state
->blob_in
,
1079 &state
->inbuf
, &state
->recv_iov
);
1080 TALLOC_FREE(subreq
);
1081 data_blob_free(&state
->blob_out
);
1082 if (!NT_STATUS_IS_OK(status
) &&
1083 !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
))
1085 tevent_req_nterror(req
, status
);
1089 if (NT_STATUS_IS_OK(status
)) {
1090 struct smbXcli_session
*session
= NULL
;
1091 bool is_guest
= false;
1093 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
1094 session
= state
->cli
->smb2
.session
;
1096 session
= state
->cli
->smb1
.session
;
1099 is_guest
= smbXcli_session_is_guest(session
);
1102 * We can't finish the gensec handshake, we don't
1103 * have a negotiated session key.
1105 * So just pretend we are completely done,
1106 * we need to continue as anonymous from this point,
1107 * as we can't get a session key.
1109 * Note that smbXcli_session_is_guest()
1110 * always returns false if we require signing.
1112 state
->blob_in
= data_blob_null
;
1113 state
->local_ready
= true;
1114 state
->is_anonymous
= true;
1117 state
->remote_ready
= true;
1120 if (state
->local_ready
&& state
->remote_ready
) {
1121 cli_session_setup_gensec_ready(req
);
1125 cli_session_setup_gensec_local_next(req
);
1128 static void cli_session_dump_keys(TALLOC_CTX
*mem_ctx
,
1129 struct smbXcli_session
*session
,
1130 DATA_BLOB session_key
)
1133 DATA_BLOB sig
= data_blob_null
;
1134 DATA_BLOB app
= data_blob_null
;
1135 DATA_BLOB enc
= data_blob_null
;
1136 DATA_BLOB dec
= data_blob_null
;
1137 uint64_t sid
= smb2cli_session_current_id(session
);
1139 status
= smb2cli_session_signing_key(session
, mem_ctx
, &sig
);
1140 if (!NT_STATUS_IS_OK(status
)) {
1143 status
= smbXcli_session_application_key(session
, mem_ctx
, &app
);
1144 if (!NT_STATUS_IS_OK(status
)) {
1147 status
= smb2cli_session_encryption_key(session
, mem_ctx
, &enc
);
1148 if (!NT_STATUS_IS_OK(status
)) {
1151 status
= smb2cli_session_decryption_key(session
, mem_ctx
, &dec
);
1152 if (!NT_STATUS_IS_OK(status
)) {
1156 DEBUG(0, ("debug encryption: dumping generated session keys\n"));
1157 DEBUGADD(0, ("Session Id "));
1158 dump_data(0, (uint8_t*)&sid
, sizeof(sid
));
1159 DEBUGADD(0, ("Session Key "));
1160 dump_data(0, session_key
.data
, session_key
.length
);
1161 DEBUGADD(0, ("Signing Key "));
1162 dump_data(0, sig
.data
, sig
.length
);
1163 DEBUGADD(0, ("App Key "));
1164 dump_data(0, app
.data
, app
.length
);
1166 /* In client code, ServerIn is the encryption key */
1168 DEBUGADD(0, ("ServerIn Key "));
1169 dump_data(0, enc
.data
, enc
.length
);
1170 DEBUGADD(0, ("ServerOut Key "));
1171 dump_data(0, dec
.data
, dec
.length
);
1174 data_blob_clear_free(&sig
);
1175 data_blob_clear_free(&app
);
1176 data_blob_clear_free(&enc
);
1177 data_blob_clear_free(&dec
);
1180 static void cli_session_setup_gensec_ready(struct tevent_req
*req
)
1182 struct cli_session_setup_gensec_state
*state
=
1183 tevent_req_data(req
,
1184 struct cli_session_setup_gensec_state
);
1185 const char *server_domain
= NULL
;
1188 if (state
->blob_in
.length
!= 0) {
1189 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
1193 if (state
->blob_out
.length
!= 0) {
1194 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
1199 * gensec_ntlmssp_server_domain() returns NULL
1200 * if NTLMSSP is not used.
1202 * We can remove this later
1203 * and leave the server domain empty for SMB2 and above
1204 * in future releases.
1206 server_domain
= gensec_ntlmssp_server_domain(
1207 state
->auth_generic
->gensec_security
);
1209 if (state
->cli
->server_domain
[0] == '\0' && server_domain
!= NULL
) {
1210 TALLOC_FREE(state
->cli
->server_domain
);
1211 state
->cli
->server_domain
= talloc_strdup(state
->cli
,
1213 if (state
->cli
->server_domain
== NULL
) {
1214 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
1219 if (state
->is_anonymous
) {
1221 * Windows server does not set the
1222 * SMB2_SESSION_FLAG_IS_NULL flag.
1224 * This fix makes sure we do not try
1225 * to verify a signature on the final
1226 * session setup response.
1228 tevent_req_done(req
);
1232 status
= gensec_session_key(state
->auth_generic
->gensec_security
,
1233 state
, &state
->session_key
);
1234 if (tevent_req_nterror(req
, status
)) {
1238 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
1239 struct smbXcli_session
*session
= state
->cli
->smb2
.session
;
1241 status
= smb2cli_session_set_session_key(session
,
1244 if (tevent_req_nterror(req
, status
)) {
1247 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB3_00
1248 && lp_debug_encryption())
1250 cli_session_dump_keys(state
, session
, state
->session_key
);
1253 struct smbXcli_session
*session
= state
->cli
->smb1
.session
;
1256 status
= smb1cli_session_set_session_key(session
,
1257 state
->session_key
);
1258 if (tevent_req_nterror(req
, status
)) {
1262 active
= smb1cli_conn_activate_signing(state
->cli
->conn
,
1268 ok
= smb1cli_conn_check_signing(state
->cli
->conn
,
1271 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1277 tevent_req_done(req
);
1280 static NTSTATUS
cli_session_setup_gensec_recv(struct tevent_req
*req
)
1282 struct cli_session_setup_gensec_state
*state
=
1283 tevent_req_data(req
,
1284 struct cli_session_setup_gensec_state
);
1287 if (tevent_req_is_nterror(req
, &status
)) {
1288 cli_state_set_uid(state
->cli
, UID_FIELD_INVALID
);
1291 return NT_STATUS_OK
;
1294 static char *cli_session_setup_get_account(TALLOC_CTX
*mem_ctx
,
1295 const char *principal
)
1299 account
= talloc_strdup(mem_ctx
, principal
);
1300 if (account
== NULL
) {
1303 p
= strchr_m(account
, '@');
1310 /****************************************************************************
1311 Do a spnego encrypted session setup.
1313 user_domain: The shortname of the domain the user/machine is a member of.
1314 dest_realm: The realm we're connecting to, if NULL we use our default realm.
1315 ****************************************************************************/
1317 struct cli_session_setup_spnego_state
{
1321 static void cli_session_setup_spnego_done(struct tevent_req
*subreq
);
1323 static struct tevent_req
*cli_session_setup_spnego_send(
1324 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
1325 struct cli_credentials
*creds
)
1327 struct tevent_req
*req
, *subreq
;
1328 struct cli_session_setup_spnego_state
*state
;
1329 const char *target_service
= NULL
;
1330 const char *target_hostname
= NULL
;
1333 req
= tevent_req_create(mem_ctx
, &state
,
1334 struct cli_session_setup_spnego_state
);
1339 target_service
= "cifs";
1340 target_hostname
= smbXcli_conn_remote_name(cli
->conn
);
1342 status
= cli_session_creds_prepare_krb5(cli
, creds
);
1343 if (tevent_req_nterror(req
, status
)) {
1344 return tevent_req_post(req
, ev
);
1347 DBG_INFO("Connect to %s as %s using SPNEGO\n",
1349 cli_credentials_get_principal(creds
, talloc_tos()));
1351 subreq
= cli_session_setup_gensec_send(state
, ev
, cli
, creds
,
1352 target_service
, target_hostname
);
1353 if (tevent_req_nomem(subreq
, req
)) {
1354 return tevent_req_post(req
, ev
);
1356 tevent_req_set_callback(
1357 subreq
, cli_session_setup_spnego_done
, req
);
1361 static void cli_session_setup_spnego_done(struct tevent_req
*subreq
)
1363 struct tevent_req
*req
= tevent_req_callback_data(
1364 subreq
, struct tevent_req
);
1367 status
= cli_session_setup_gensec_recv(subreq
);
1368 TALLOC_FREE(subreq
);
1369 if (tevent_req_nterror(req
, status
)) {
1373 tevent_req_done(req
);
1376 static ADS_STATUS
cli_session_setup_spnego_recv(struct tevent_req
*req
)
1378 struct cli_session_setup_spnego_state
*state
= tevent_req_data(
1379 req
, struct cli_session_setup_spnego_state
);
1382 if (tevent_req_is_nterror(req
, &status
)) {
1383 state
->result
= ADS_ERROR_NT(status
);
1386 return state
->result
;
1389 struct cli_session_setup_creds_state
{
1390 struct cli_state
*cli
;
1391 DATA_BLOB apassword_blob
;
1392 DATA_BLOB upassword_blob
;
1393 DATA_BLOB lm_session_key
;
1394 DATA_BLOB session_key
;
1395 char *out_native_os
;
1396 char *out_native_lm
;
1397 char *out_primary_domain
;
1400 static void cli_session_setup_creds_cleanup(struct tevent_req
*req
,
1401 enum tevent_req_state req_state
)
1403 struct cli_session_setup_creds_state
*state
= tevent_req_data(
1404 req
, struct cli_session_setup_creds_state
);
1406 if (req_state
!= TEVENT_REQ_RECEIVED
) {
1411 * We only call data_blob_clear() as
1412 * some of the blobs point to the same memory.
1414 * We let the talloc hierarchy free the memory.
1416 data_blob_clear(&state
->apassword_blob
);
1417 data_blob_clear(&state
->upassword_blob
);
1418 data_blob_clear(&state
->lm_session_key
);
1419 data_blob_clear(&state
->session_key
);
1420 ZERO_STRUCTP(state
);
1423 static void cli_session_setup_creds_done_spnego(struct tevent_req
*subreq
);
1424 static void cli_session_setup_creds_done_nt1(struct tevent_req
*subreq
);
1425 static void cli_session_setup_creds_done_lm21(struct tevent_req
*subreq
);
1427 /****************************************************************************
1428 Send a session setup. The username and workgroup is in UNIX character
1429 format and must be converted to DOS codepage format before sending. If the
1430 password is in plaintext, the same should be done.
1431 ****************************************************************************/
1433 struct tevent_req
*cli_session_setup_creds_send(TALLOC_CTX
*mem_ctx
,
1434 struct tevent_context
*ev
,
1435 struct cli_state
*cli
,
1436 struct cli_credentials
*creds
)
1438 struct tevent_req
*req
, *subreq
;
1439 struct cli_session_setup_creds_state
*state
;
1440 uint16_t sec_mode
= smb1cli_conn_server_security_mode(cli
->conn
);
1441 bool use_spnego
= false;
1443 const char *username
= "";
1444 const char *domain
= "";
1445 DATA_BLOB target_info
= data_blob_null
;
1446 DATA_BLOB challenge
= data_blob_null
;
1447 uint16_t in_buf_size
= 0;
1448 uint16_t in_mpx_max
= 0;
1449 uint16_t in_vc_num
= 0;
1450 uint32_t in_sess_key
= 0;
1451 const char *in_native_os
= NULL
;
1452 const char *in_native_lm
= NULL
;
1453 enum credentials_use_kerberos krb5_state
=
1454 cli_credentials_get_kerberos_state(creds
);
1457 req
= tevent_req_create(mem_ctx
, &state
,
1458 struct cli_session_setup_creds_state
);
1464 tevent_req_set_cleanup_fn(req
, cli_session_setup_creds_cleanup
);
1467 * Now work out what sort of session setup we are going to
1468 * do. I have split this into separate functions to make the flow a bit
1469 * easier to understand (tridge).
1471 if (smbXcli_conn_protocol(cli
->conn
) < PROTOCOL_NT1
) {
1473 } else if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
1475 } else if (smb1cli_conn_capabilities(cli
->conn
) & CAP_EXTENDED_SECURITY
) {
1477 * if the server supports extended security then use SPNEGO
1478 * even for anonymous connections.
1486 subreq
= cli_session_setup_spnego_send(
1487 state
, ev
, cli
, creds
);
1488 if (tevent_req_nomem(subreq
, req
)) {
1489 return tevent_req_post(req
, ev
);
1491 tevent_req_set_callback(subreq
, cli_session_setup_creds_done_spnego
,
1496 if (krb5_state
== CRED_USE_KERBEROS_REQUIRED
) {
1497 DBG_WARNING("Kerberos authentication requested, but "
1498 "the server does not support SPNEGO authentication\n");
1499 tevent_req_nterror(req
, NT_STATUS_NETWORK_CREDENTIAL_CONFLICT
);
1500 return tevent_req_post(req
, ev
);
1503 if (smbXcli_conn_protocol(cli
->conn
) < PROTOCOL_LANMAN1
) {
1505 * SessionSetupAndX was introduced by LANMAN 1.0. So we skip
1506 * this step against older servers.
1508 tevent_req_done(req
);
1509 return tevent_req_post(req
, ev
);
1512 if (cli_credentials_is_anonymous(creds
)) {
1514 * Do an anonymous session setup
1516 goto non_spnego_creds_done
;
1519 if ((sec_mode
& NEGOTIATE_SECURITY_USER_LEVEL
) == 0) {
1521 * Do an anonymous session setup,
1522 * the password is passed via the tree connect.
1524 goto non_spnego_creds_done
;
1527 cli_credentials_get_ntlm_username_domain(creds
, state
,
1530 if (tevent_req_nomem(username
, req
)) {
1531 return tevent_req_post(req
, ev
);
1533 if (tevent_req_nomem(domain
, req
)) {
1534 return tevent_req_post(req
, ev
);
1537 DBG_INFO("Connect to %s as %s using NTLM\n", domain
, username
);
1539 if ((sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
) == 0) {
1540 bool use_unicode
= smbXcli_conn_use_unicode(cli
->conn
);
1541 uint8_t *bytes
= NULL
;
1542 size_t bytes_len
= 0;
1543 const char *pw
= cli_credentials_get_password(creds
);
1549 pw_len
= strlen(pw
) + 1;
1551 if (!lp_client_plaintext_auth()) {
1552 DEBUG(1, ("Server requested PLAINTEXT password but "
1553 "'client plaintext auth = no'\n"));
1554 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1555 return tevent_req_post(req
, ev
);
1558 bytes
= talloc_array(state
, uint8_t, 0);
1559 bytes
= trans2_bytes_push_str(bytes
, use_unicode
,
1560 pw
, pw_len
, &bytes_len
);
1561 if (tevent_req_nomem(bytes
, req
)) {
1562 return tevent_req_post(req
, ev
);
1567 * CAP_UNICODE, can only be negotiated by NT1.
1569 state
->upassword_blob
= data_blob_const(bytes
,
1572 state
->apassword_blob
= data_blob_const(bytes
,
1576 goto non_spnego_creds_done
;
1579 challenge
= data_blob_const(smb1cli_conn_server_challenge(cli
->conn
), 8);
1581 if (smbXcli_conn_protocol(cli
->conn
) == PROTOCOL_NT1
) {
1582 if (lp_client_ntlmv2_auth() && lp_client_use_spnego()) {
1584 * Don't send an NTLMv2 response without NTLMSSP if we
1585 * want to use spnego support.
1587 DEBUG(1, ("Server does not support EXTENDED_SECURITY "
1588 " but 'client use spnego = yes'"
1589 " and 'client ntlmv2 auth = yes' is set\n"));
1590 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1591 return tevent_req_post(req
, ev
);
1594 if (lp_client_ntlmv2_auth()) {
1595 flags
|= CLI_CRED_NTLMv2_AUTH
;
1598 * note that the 'domain' here is a best
1599 * guess - we don't know the server's domain
1600 * at this point. Windows clients also don't
1603 target_info
= NTLMv2_generate_names_blob(state
,
1606 if (tevent_req_nomem(target_info
.data
, req
)) {
1607 return tevent_req_post(req
, ev
);
1610 flags
|= CLI_CRED_NTLM_AUTH
;
1611 if (lp_client_lanman_auth()) {
1612 flags
|= CLI_CRED_LANMAN_AUTH
;
1616 if (!lp_client_lanman_auth()) {
1617 DEBUG(1, ("Server requested user level LM password but "
1618 "'client lanman auth = no' is set.\n"));
1619 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1620 return tevent_req_post(req
, ev
);
1623 flags
|= CLI_CRED_LANMAN_AUTH
;
1626 status
= cli_credentials_get_ntlm_response(creds
, state
, &flags
,
1629 &state
->apassword_blob
,
1630 &state
->upassword_blob
,
1631 &state
->lm_session_key
,
1632 &state
->session_key
);
1633 if (tevent_req_nterror(req
, status
)) {
1634 return tevent_req_post(req
, ev
);
1637 non_spnego_creds_done
:
1639 in_buf_size
= CLI_BUFFER_SIZE
;
1640 in_mpx_max
= smbXcli_conn_max_requests(cli
->conn
);
1641 in_vc_num
= cli_state_get_vc_num(cli
);
1642 in_sess_key
= smb1cli_conn_server_session_key(cli
->conn
);
1643 in_native_os
= "Unix";
1644 in_native_lm
= "Samba";
1646 if (smbXcli_conn_protocol(cli
->conn
) == PROTOCOL_NT1
) {
1647 uint32_t in_capabilities
= 0;
1649 in_capabilities
= cli_session_setup_capabilities(cli
, 0);
1652 * For now we keep the same values as before,
1653 * we may remove these in a separate commit later.
1657 subreq
= smb1cli_session_setup_nt1_send(state
, ev
,
1668 state
->apassword_blob
,
1669 state
->upassword_blob
,
1673 if (tevent_req_nomem(subreq
, req
)) {
1674 return tevent_req_post(req
, ev
);
1676 tevent_req_set_callback(subreq
, cli_session_setup_creds_done_nt1
,
1682 * For now we keep the same values as before,
1683 * we may remove these in a separate commit later.
1688 subreq
= smb1cli_session_setup_lm21_send(state
, ev
,
1699 state
->apassword_blob
,
1702 if (tevent_req_nomem(subreq
, req
)) {
1703 return tevent_req_post(req
, ev
);
1705 tevent_req_set_callback(subreq
, cli_session_setup_creds_done_lm21
,
1710 static void cli_session_setup_creds_done_spnego(struct tevent_req
*subreq
)
1712 struct tevent_req
*req
= tevent_req_callback_data(
1713 subreq
, struct tevent_req
);
1716 status
= cli_session_setup_spnego_recv(subreq
);
1717 TALLOC_FREE(subreq
);
1718 if (!ADS_ERR_OK(status
)) {
1719 DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status
)));
1720 tevent_req_nterror(req
, ads_ntstatus(status
));
1723 tevent_req_done(req
);
1726 static void cli_session_setup_creds_done_nt1(struct tevent_req
*subreq
)
1728 struct tevent_req
*req
= tevent_req_callback_data(
1729 subreq
, struct tevent_req
);
1730 struct cli_session_setup_creds_state
*state
= tevent_req_data(
1731 req
, struct cli_session_setup_creds_state
);
1732 struct cli_state
*cli
= state
->cli
;
1734 struct iovec
*recv_iov
= NULL
;
1735 const uint8_t *inbuf
= NULL
;
1738 status
= smb1cli_session_setup_nt1_recv(subreq
, state
,
1741 &state
->out_native_os
,
1742 &state
->out_native_lm
,
1743 &state
->out_primary_domain
);
1744 TALLOC_FREE(subreq
);
1745 if (!NT_STATUS_IS_OK(status
)) {
1746 DEBUG(3, ("NT1 login failed: %s\n", nt_errstr(status
)));
1747 tevent_req_nterror(req
, status
);
1751 status
= cli_state_update_after_sesssetup(state
->cli
,
1752 state
->out_native_os
,
1753 state
->out_native_lm
,
1754 state
->out_primary_domain
);
1755 if (tevent_req_nterror(req
, status
)) {
1759 ok
= smb1cli_conn_activate_signing(cli
->conn
,
1761 state
->upassword_blob
);
1763 ok
= smb1cli_conn_check_signing(cli
->conn
, inbuf
, 1);
1765 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1770 if (state
->session_key
.data
) {
1771 struct smbXcli_session
*session
= cli
->smb1
.session
;
1773 status
= smb1cli_session_set_session_key(session
,
1774 state
->session_key
);
1775 if (tevent_req_nterror(req
, status
)) {
1780 tevent_req_done(req
);
1783 static void cli_session_setup_creds_done_lm21(struct tevent_req
*subreq
)
1785 struct tevent_req
*req
= tevent_req_callback_data(
1786 subreq
, struct tevent_req
);
1787 struct cli_session_setup_creds_state
*state
= tevent_req_data(
1788 req
, struct cli_session_setup_creds_state
);
1791 status
= smb1cli_session_setup_lm21_recv(subreq
, state
,
1792 &state
->out_native_os
,
1793 &state
->out_native_lm
);
1794 TALLOC_FREE(subreq
);
1795 if (!NT_STATUS_IS_OK(status
)) {
1796 DEBUG(3, ("LM21 login failed: %s\n", nt_errstr(status
)));
1797 tevent_req_nterror(req
, status
);
1801 status
= cli_state_update_after_sesssetup(state
->cli
,
1802 state
->out_native_os
,
1803 state
->out_native_lm
,
1805 if (tevent_req_nterror(req
, status
)) {
1809 tevent_req_done(req
);
1812 NTSTATUS
cli_session_setup_creds_recv(struct tevent_req
*req
)
1814 return tevent_req_simple_recv_ntstatus(req
);
1817 NTSTATUS
cli_session_setup_creds(struct cli_state
*cli
,
1818 struct cli_credentials
*creds
)
1820 struct tevent_context
*ev
;
1821 struct tevent_req
*req
;
1822 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
1824 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
1825 return NT_STATUS_INVALID_PARAMETER
;
1827 ev
= samba_tevent_context_init(talloc_tos());
1831 req
= cli_session_setup_creds_send(ev
, ev
, cli
, creds
);
1835 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
1838 status
= cli_session_setup_creds_recv(req
);
1844 NTSTATUS
cli_session_setup_anon(struct cli_state
*cli
)
1847 struct cli_credentials
*creds
= NULL
;
1849 creds
= cli_credentials_init_anon(cli
);
1850 if (creds
== NULL
) {
1851 return NT_STATUS_NO_MEMORY
;
1854 status
= cli_session_setup_creds(cli
, creds
);
1856 if (!NT_STATUS_IS_OK(status
)) {
1860 return NT_STATUS_OK
;
1863 /****************************************************************************
1865 *****************************************************************************/
1867 struct cli_ulogoff_state
{
1868 struct cli_state
*cli
;
1872 static void cli_ulogoff_done(struct tevent_req
*subreq
);
1874 static struct tevent_req
*cli_ulogoff_send(TALLOC_CTX
*mem_ctx
,
1875 struct tevent_context
*ev
,
1876 struct cli_state
*cli
)
1878 struct tevent_req
*req
, *subreq
;
1879 struct cli_ulogoff_state
*state
;
1881 req
= tevent_req_create(mem_ctx
, &state
, struct cli_ulogoff_state
);
1887 SCVAL(state
->vwv
+0, 0, 0xFF);
1888 SCVAL(state
->vwv
+1, 0, 0);
1889 SSVAL(state
->vwv
+2, 0, 0);
1891 subreq
= cli_smb_send(state
, ev
, cli
, SMBulogoffX
, 0, 0, 2, state
->vwv
,
1893 if (tevent_req_nomem(subreq
, req
)) {
1894 return tevent_req_post(req
, ev
);
1896 tevent_req_set_callback(subreq
, cli_ulogoff_done
, req
);
1900 static void cli_ulogoff_done(struct tevent_req
*subreq
)
1902 struct tevent_req
*req
= tevent_req_callback_data(
1903 subreq
, struct tevent_req
);
1904 struct cli_ulogoff_state
*state
= tevent_req_data(
1905 req
, struct cli_ulogoff_state
);
1908 status
= cli_smb_recv(subreq
, NULL
, NULL
, 0, NULL
, NULL
, NULL
, NULL
);
1909 if (!NT_STATUS_IS_OK(status
)) {
1910 tevent_req_nterror(req
, status
);
1913 cli_state_set_uid(state
->cli
, UID_FIELD_INVALID
);
1914 tevent_req_done(req
);
1917 static NTSTATUS
cli_ulogoff_recv(struct tevent_req
*req
)
1919 return tevent_req_simple_recv_ntstatus(req
);
1922 NTSTATUS
cli_ulogoff(struct cli_state
*cli
)
1924 struct tevent_context
*ev
;
1925 struct tevent_req
*req
;
1926 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
1928 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
1929 status
= smb2cli_logoff(cli
->conn
,
1932 if (!NT_STATUS_IS_OK(status
)) {
1935 smb2cli_session_set_id_and_flags(cli
->smb2
.session
,
1937 return NT_STATUS_OK
;
1940 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
1941 return NT_STATUS_INVALID_PARAMETER
;
1943 ev
= samba_tevent_context_init(talloc_tos());
1947 req
= cli_ulogoff_send(ev
, ev
, cli
);
1951 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
1954 status
= cli_ulogoff_recv(req
);
1960 /****************************************************************************
1962 ****************************************************************************/
1964 struct cli_tcon_andx_state
{
1965 struct cli_state
*cli
;
1970 static void cli_tcon_andx_done(struct tevent_req
*subreq
);
1972 struct tevent_req
*cli_tcon_andx_create(TALLOC_CTX
*mem_ctx
,
1973 struct tevent_context
*ev
,
1974 struct cli_state
*cli
,
1975 const char *share
, const char *dev
,
1976 const char *pass
, int passlen
,
1977 struct tevent_req
**psmbreq
)
1979 struct tevent_req
*req
, *subreq
;
1980 struct cli_tcon_andx_state
*state
;
1985 uint16_t sec_mode
= smb1cli_conn_server_security_mode(cli
->conn
);
1986 uint16_t tcon_flags
= 0;
1990 req
= tevent_req_create(mem_ctx
, &state
, struct cli_tcon_andx_state
);
1997 TALLOC_FREE(cli
->smb1
.tcon
);
1998 cli
->smb1
.tcon
= smbXcli_tcon_create(cli
);
1999 if (tevent_req_nomem(cli
->smb1
.tcon
, req
)) {
2000 return tevent_req_post(req
, ev
);
2002 smb1cli_tcon_set_id(cli
->smb1
.tcon
, UINT16_MAX
);
2004 cli
->share
= talloc_strdup(cli
, share
);
2009 /* in user level security don't send a password now */
2010 if (sec_mode
& NEGOTIATE_SECURITY_USER_LEVEL
) {
2013 } else if (pass
== NULL
) {
2014 DEBUG(1, ("Server not using user level security and no "
2015 "password supplied.\n"));
2019 if ((sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
) &&
2020 *pass
&& passlen
!= 24) {
2021 if (!lp_client_lanman_auth()) {
2022 DEBUG(1, ("Server requested LANMAN password "
2023 "(share-level security) but "
2024 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2029 * Non-encrypted passwords - convert to DOS codepage before
2032 SMBencrypt(pass
, smb1cli_conn_server_challenge(cli
->conn
), p24
);
2034 pass
= (const char *)p24
;
2036 if((sec_mode
& (NEGOTIATE_SECURITY_USER_LEVEL
2037 |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
))
2041 if (!lp_client_plaintext_auth() && (*pass
)) {
2042 DEBUG(1, ("Server requested PLAINTEXT "
2044 "'client plaintext auth = no' or 'client ntlmv2 auth = yes'\n"));
2049 * Non-encrypted passwords - convert to DOS codepage
2052 tmp_pass
= talloc_array(talloc_tos(), uint8_t, 0);
2053 if (tevent_req_nomem(tmp_pass
, req
)) {
2054 return tevent_req_post(req
, ev
);
2056 tmp_pass
= trans2_bytes_push_str(tmp_pass
,
2057 false, /* always DOS */
2061 if (tevent_req_nomem(tmp_pass
, req
)) {
2062 return tevent_req_post(req
, ev
);
2064 pass
= (const char *)tmp_pass
;
2065 passlen
= talloc_get_size(tmp_pass
);
2069 tcon_flags
|= TCONX_FLAG_EXTENDED_RESPONSE
;
2070 tcon_flags
|= TCONX_FLAG_EXTENDED_SIGNATURES
;
2072 SCVAL(vwv
+0, 0, 0xFF);
2075 SSVAL(vwv
+2, 0, tcon_flags
);
2076 SSVAL(vwv
+3, 0, passlen
);
2078 if (passlen
&& pass
) {
2079 bytes
= (uint8_t *)talloc_memdup(state
, pass
, passlen
);
2081 bytes
= talloc_array(state
, uint8_t, 0);
2087 tmp
= talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
2088 smbXcli_conn_remote_name(cli
->conn
), share
);
2093 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), tmp
, strlen(tmp
)+1,
2098 * Add the devicetype
2100 tmp
= talloc_strdup_upper(talloc_tos(), dev
);
2105 bytes
= smb_bytes_push_str(bytes
, false, tmp
, strlen(tmp
)+1, NULL
);
2108 if (bytes
== NULL
) {
2113 state
->bytes
.iov_base
= (void *)bytes
;
2114 state
->bytes
.iov_len
= talloc_get_size(bytes
);
2116 subreq
= cli_smb_req_create(state
, ev
, cli
, SMBtconX
, 0, 0, 4, vwv
,
2118 if (subreq
== NULL
) {
2122 tevent_req_set_callback(subreq
, cli_tcon_andx_done
, req
);
2127 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
2128 return tevent_req_post(req
, ev
);
2131 struct tevent_req
*cli_tcon_andx_send(TALLOC_CTX
*mem_ctx
,
2132 struct tevent_context
*ev
,
2133 struct cli_state
*cli
,
2134 const char *share
, const char *dev
,
2135 const char *pass
, int passlen
)
2137 struct tevent_req
*req
, *subreq
;
2140 req
= cli_tcon_andx_create(mem_ctx
, ev
, cli
, share
, dev
, pass
, passlen
,
2145 if (subreq
== NULL
) {
2148 status
= smb1cli_req_chain_submit(&subreq
, 1);
2149 if (!NT_STATUS_IS_OK(status
)) {
2150 tevent_req_nterror(req
, status
);
2151 return tevent_req_post(req
, ev
);
2156 static void cli_tcon_andx_done(struct tevent_req
*subreq
)
2158 struct tevent_req
*req
= tevent_req_callback_data(
2159 subreq
, struct tevent_req
);
2160 struct cli_tcon_andx_state
*state
= tevent_req_data(
2161 req
, struct cli_tcon_andx_state
);
2162 struct cli_state
*cli
= state
->cli
;
2170 uint16_t optional_support
= 0;
2172 status
= cli_smb_recv(subreq
, state
, &in
, 0, &wct
, &vwv
,
2173 &num_bytes
, &bytes
);
2174 TALLOC_FREE(subreq
);
2175 if (!NT_STATUS_IS_OK(status
)) {
2176 tevent_req_nterror(req
, status
);
2180 inhdr
= in
+ NBT_HDR_SIZE
;
2183 if (pull_string_talloc(cli
,
2184 (const char *)inhdr
,
2185 SVAL(inhdr
, HDR_FLG2
),
2189 STR_TERMINATE
|STR_ASCII
) == -1) {
2190 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
2194 cli
->dev
= talloc_strdup(cli
, "");
2195 if (cli
->dev
== NULL
) {
2196 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
2201 if ((smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_NT1
) && (num_bytes
== 3)) {
2202 /* almost certainly win95 - enable bug fixes */
2207 * Make sure that we have the optional support 16-bit field. WCT > 2.
2208 * Avoids issues when connecting to Win9x boxes sharing files
2211 if ((wct
> 2) && (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_LANMAN2
)) {
2212 optional_support
= SVAL(vwv
+2, 0);
2215 if (optional_support
& SMB_EXTENDED_SIGNATURES
) {
2216 smb1cli_session_protect_session_key(cli
->smb1
.session
);
2219 smb1cli_tcon_set_values(state
->cli
->smb1
.tcon
,
2220 SVAL(inhdr
, HDR_TID
),
2222 0, /* maximal_access */
2223 0, /* guest_maximal_access */
2225 NULL
); /* fs_type */
2227 tevent_req_done(req
);
2230 NTSTATUS
cli_tcon_andx_recv(struct tevent_req
*req
)
2232 return tevent_req_simple_recv_ntstatus(req
);
2235 NTSTATUS
cli_tcon_andx(struct cli_state
*cli
, const char *share
,
2236 const char *dev
, const char *pass
, int passlen
)
2238 TALLOC_CTX
*frame
= talloc_stackframe();
2239 struct tevent_context
*ev
;
2240 struct tevent_req
*req
;
2241 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2243 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
2245 * Can't use sync call while an async call is in flight
2247 status
= NT_STATUS_INVALID_PARAMETER
;
2251 ev
= samba_tevent_context_init(frame
);
2256 req
= cli_tcon_andx_send(frame
, ev
, cli
, share
, dev
, pass
, passlen
);
2261 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2265 status
= cli_tcon_andx_recv(req
);
2271 struct cli_tree_connect_state
{
2272 struct cli_state
*cli
;
2275 static struct tevent_req
*cli_raw_tcon_send(
2276 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
2277 const char *service
, const char *pass
, const char *dev
);
2278 static NTSTATUS
cli_raw_tcon_recv(struct tevent_req
*req
,
2279 uint16_t *max_xmit
, uint16_t *tid
);
2281 static void cli_tree_connect_smb2_done(struct tevent_req
*subreq
);
2282 static void cli_tree_connect_andx_done(struct tevent_req
*subreq
);
2283 static void cli_tree_connect_raw_done(struct tevent_req
*subreq
);
2285 static struct tevent_req
*cli_tree_connect_send(
2286 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
2287 const char *share
, const char *dev
, const char *pass
)
2289 struct tevent_req
*req
, *subreq
;
2290 struct cli_tree_connect_state
*state
;
2296 passlen
= strlen(pass
) + 1;
2298 req
= tevent_req_create(mem_ctx
, &state
,
2299 struct cli_tree_connect_state
);
2305 cli
->share
= talloc_strdup(cli
, share
);
2306 if (tevent_req_nomem(cli
->share
, req
)) {
2307 return tevent_req_post(req
, ev
);
2310 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
2313 TALLOC_FREE(cli
->smb2
.tcon
);
2314 cli
->smb2
.tcon
= smbXcli_tcon_create(cli
);
2315 if (tevent_req_nomem(cli
->smb2
.tcon
, req
)) {
2316 return tevent_req_post(req
, ev
);
2319 unc
= talloc_asprintf(state
, "\\\\%s\\%s",
2320 smbXcli_conn_remote_name(cli
->conn
),
2322 if (tevent_req_nomem(unc
, req
)) {
2323 return tevent_req_post(req
, ev
);
2326 subreq
= smb2cli_tcon_send(state
, ev
, cli
->conn
, cli
->timeout
,
2327 cli
->smb2
.session
, cli
->smb2
.tcon
,
2330 if (tevent_req_nomem(subreq
, req
)) {
2331 return tevent_req_post(req
, ev
);
2333 tevent_req_set_callback(subreq
, cli_tree_connect_smb2_done
,
2338 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_LANMAN1
) {
2339 subreq
= cli_tcon_andx_send(state
, ev
, cli
, share
, dev
,
2341 if (tevent_req_nomem(subreq
, req
)) {
2342 return tevent_req_post(req
, ev
);
2344 tevent_req_set_callback(subreq
, cli_tree_connect_andx_done
,
2349 subreq
= cli_raw_tcon_send(state
, ev
, cli
, share
, pass
, dev
);
2350 if (tevent_req_nomem(subreq
, req
)) {
2351 return tevent_req_post(req
, ev
);
2353 tevent_req_set_callback(subreq
, cli_tree_connect_raw_done
, req
);
2358 static void cli_tree_connect_smb2_done(struct tevent_req
*subreq
)
2360 NTSTATUS status
= smb2cli_tcon_recv(subreq
);
2361 tevent_req_simple_finish_ntstatus(subreq
, status
);
2364 static void cli_tree_connect_andx_done(struct tevent_req
*subreq
)
2366 NTSTATUS status
= cli_tcon_andx_recv(subreq
);
2367 tevent_req_simple_finish_ntstatus(subreq
, status
);
2370 static void cli_tree_connect_raw_done(struct tevent_req
*subreq
)
2372 struct tevent_req
*req
= tevent_req_callback_data(
2373 subreq
, struct tevent_req
);
2374 struct cli_tree_connect_state
*state
= tevent_req_data(
2375 req
, struct cli_tree_connect_state
);
2377 uint16_t max_xmit
= 0;
2380 status
= cli_raw_tcon_recv(subreq
, &max_xmit
, &tid
);
2381 if (tevent_req_nterror(req
, status
)) {
2385 smb1cli_tcon_set_values(state
->cli
->smb1
.tcon
,
2387 0, /* optional_support */
2388 0, /* maximal_access */
2389 0, /* guest_maximal_access */
2391 NULL
); /* fs_type */
2393 tevent_req_done(req
);
2396 static NTSTATUS
cli_tree_connect_recv(struct tevent_req
*req
)
2398 return tevent_req_simple_recv_ntstatus(req
);
2401 NTSTATUS
cli_tree_connect(struct cli_state
*cli
, const char *share
,
2402 const char *dev
, const char *pass
)
2404 struct tevent_context
*ev
;
2405 struct tevent_req
*req
;
2406 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2408 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
2409 return NT_STATUS_INVALID_PARAMETER
;
2411 ev
= samba_tevent_context_init(talloc_tos());
2415 req
= cli_tree_connect_send(ev
, ev
, cli
, share
, dev
, pass
);
2419 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2422 status
= cli_tree_connect_recv(req
);
2428 NTSTATUS
cli_tree_connect_creds(struct cli_state
*cli
,
2429 const char *share
, const char *dev
,
2430 struct cli_credentials
*creds
)
2432 const char *pw
= NULL
;
2434 if (creds
!= NULL
) {
2435 pw
= cli_credentials_get_password(creds
);
2438 return cli_tree_connect(cli
, share
, dev
, pw
);
2441 /****************************************************************************
2442 Send a tree disconnect.
2443 ****************************************************************************/
2445 struct cli_tdis_state
{
2446 struct cli_state
*cli
;
2449 static void cli_tdis_done(struct tevent_req
*subreq
);
2451 static struct tevent_req
*cli_tdis_send(TALLOC_CTX
*mem_ctx
,
2452 struct tevent_context
*ev
,
2453 struct cli_state
*cli
)
2455 struct tevent_req
*req
, *subreq
;
2456 struct cli_tdis_state
*state
;
2458 req
= tevent_req_create(mem_ctx
, &state
, struct cli_tdis_state
);
2464 subreq
= cli_smb_send(state
, ev
, cli
, SMBtdis
, 0, 0, 0, NULL
, 0, NULL
);
2465 if (tevent_req_nomem(subreq
, req
)) {
2466 return tevent_req_post(req
, ev
);
2468 tevent_req_set_callback(subreq
, cli_tdis_done
, req
);
2472 static void cli_tdis_done(struct tevent_req
*subreq
)
2474 struct tevent_req
*req
= tevent_req_callback_data(
2475 subreq
, struct tevent_req
);
2476 struct cli_tdis_state
*state
= tevent_req_data(
2477 req
, struct cli_tdis_state
);
2480 status
= cli_smb_recv(subreq
, NULL
, NULL
, 0, NULL
, NULL
, NULL
, NULL
);
2481 TALLOC_FREE(subreq
);
2482 if (!NT_STATUS_IS_OK(status
)) {
2483 tevent_req_nterror(req
, status
);
2486 TALLOC_FREE(state
->cli
->smb1
.tcon
);
2487 tevent_req_done(req
);
2490 static NTSTATUS
cli_tdis_recv(struct tevent_req
*req
)
2492 return tevent_req_simple_recv_ntstatus(req
);
2495 NTSTATUS
cli_tdis(struct cli_state
*cli
)
2497 struct tevent_context
*ev
;
2498 struct tevent_req
*req
;
2499 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2501 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
2502 status
= smb2cli_tdis(cli
->conn
,
2506 if (NT_STATUS_IS_OK(status
)) {
2507 TALLOC_FREE(cli
->smb2
.tcon
);
2512 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
2513 return NT_STATUS_INVALID_PARAMETER
;
2515 ev
= samba_tevent_context_init(talloc_tos());
2519 req
= cli_tdis_send(ev
, ev
, cli
);
2523 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2526 status
= cli_tdis_recv(req
);
2532 struct cli_connect_sock_state
{
2533 const char **called_names
;
2534 const char **calling_names
;
2540 static void cli_connect_sock_done(struct tevent_req
*subreq
);
2543 * Async only if we don't have to look up the name, i.e. "pss" is set with a
2547 static struct tevent_req
*cli_connect_sock_send(
2548 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
2549 const char *host
, int name_type
, const struct sockaddr_storage
*pss
,
2550 const char *myname
, uint16_t port
)
2552 struct tevent_req
*req
, *subreq
;
2553 struct cli_connect_sock_state
*state
;
2554 struct sockaddr_storage
*addrs
= NULL
;
2556 unsigned num_addrs
= 0;
2559 req
= tevent_req_create(mem_ctx
, &state
,
2560 struct cli_connect_sock_state
);
2565 if ((pss
== NULL
) || is_zero_addr(pss
)) {
2568 * Here we cheat. resolve_name_list is not async at all. So
2569 * this call will only be really async if the name lookup has
2570 * been done externally.
2573 status
= resolve_name_list(state
, host
, name_type
,
2574 &addrs
, &num_addrs
);
2575 if (!NT_STATUS_IS_OK(status
)) {
2576 tevent_req_nterror(req
, status
);
2577 return tevent_req_post(req
, ev
);
2580 addrs
= talloc_array(state
, struct sockaddr_storage
, 1);
2581 if (tevent_req_nomem(addrs
, req
)) {
2582 return tevent_req_post(req
, ev
);
2588 state
->called_names
= talloc_array(state
, const char *, num_addrs
);
2589 if (tevent_req_nomem(state
->called_names
, req
)) {
2590 return tevent_req_post(req
, ev
);
2592 state
->called_types
= talloc_array(state
, int, num_addrs
);
2593 if (tevent_req_nomem(state
->called_types
, req
)) {
2594 return tevent_req_post(req
, ev
);
2596 state
->calling_names
= talloc_array(state
, const char *, num_addrs
);
2597 if (tevent_req_nomem(state
->calling_names
, req
)) {
2598 return tevent_req_post(req
, ev
);
2600 for (i
=0; i
<num_addrs
; i
++) {
2601 state
->called_names
[i
] = host
;
2602 state
->called_types
[i
] = name_type
;
2603 state
->calling_names
[i
] = myname
;
2606 subreq
= smbsock_any_connect_send(
2607 state
, ev
, addrs
, state
->called_names
, state
->called_types
,
2608 state
->calling_names
, NULL
, num_addrs
, port
);
2609 if (tevent_req_nomem(subreq
, req
)) {
2610 return tevent_req_post(req
, ev
);
2612 tevent_req_set_callback(subreq
, cli_connect_sock_done
, req
);
2616 static void cli_connect_sock_done(struct tevent_req
*subreq
)
2618 struct tevent_req
*req
= tevent_req_callback_data(
2619 subreq
, struct tevent_req
);
2620 struct cli_connect_sock_state
*state
= tevent_req_data(
2621 req
, struct cli_connect_sock_state
);
2624 status
= smbsock_any_connect_recv(subreq
, &state
->fd
, NULL
,
2626 TALLOC_FREE(subreq
);
2627 if (tevent_req_nterror(req
, status
)) {
2630 set_socket_options(state
->fd
, lp_socket_options());
2631 tevent_req_done(req
);
2634 static NTSTATUS
cli_connect_sock_recv(struct tevent_req
*req
,
2635 int *pfd
, uint16_t *pport
)
2637 struct cli_connect_sock_state
*state
= tevent_req_data(
2638 req
, struct cli_connect_sock_state
);
2641 if (tevent_req_is_nterror(req
, &status
)) {
2645 *pport
= state
->port
;
2646 return NT_STATUS_OK
;
2649 struct cli_connect_nb_state
{
2650 const char *desthost
;
2651 enum smb_signing_setting signing_state
;
2653 struct cli_state
*cli
;
2656 static void cli_connect_nb_done(struct tevent_req
*subreq
);
2658 static struct tevent_req
*cli_connect_nb_send(
2659 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
2660 const char *host
, const struct sockaddr_storage
*dest_ss
,
2661 uint16_t port
, int name_type
, const char *myname
,
2662 enum smb_signing_setting signing_state
, int flags
)
2664 struct tevent_req
*req
, *subreq
;
2665 struct cli_connect_nb_state
*state
;
2667 req
= tevent_req_create(mem_ctx
, &state
, struct cli_connect_nb_state
);
2671 state
->signing_state
= signing_state
;
2672 state
->flags
= flags
;
2675 char *p
= strchr(host
, '#');
2678 name_type
= strtol(p
+1, NULL
, 16);
2679 host
= talloc_strndup(state
, host
, p
- host
);
2680 if (tevent_req_nomem(host
, req
)) {
2681 return tevent_req_post(req
, ev
);
2685 state
->desthost
= host
;
2686 } else if (dest_ss
!= NULL
) {
2687 state
->desthost
= print_canonical_sockaddr(state
, dest_ss
);
2688 if (tevent_req_nomem(state
->desthost
, req
)) {
2689 return tevent_req_post(req
, ev
);
2692 /* No host or dest_ss given. Error out. */
2693 tevent_req_error(req
, EINVAL
);
2694 return tevent_req_post(req
, ev
);
2697 subreq
= cli_connect_sock_send(state
, ev
, host
, name_type
, dest_ss
,
2699 if (tevent_req_nomem(subreq
, req
)) {
2700 return tevent_req_post(req
, ev
);
2702 tevent_req_set_callback(subreq
, cli_connect_nb_done
, req
);
2706 static void cli_connect_nb_done(struct tevent_req
*subreq
)
2708 struct tevent_req
*req
= tevent_req_callback_data(
2709 subreq
, struct tevent_req
);
2710 struct cli_connect_nb_state
*state
= tevent_req_data(
2711 req
, struct cli_connect_nb_state
);
2716 status
= cli_connect_sock_recv(subreq
, &fd
, &port
);
2717 TALLOC_FREE(subreq
);
2718 if (tevent_req_nterror(req
, status
)) {
2722 state
->cli
= cli_state_create(state
, fd
, state
->desthost
,
2723 state
->signing_state
, state
->flags
);
2724 if (tevent_req_nomem(state
->cli
, req
)) {
2728 tevent_req_done(req
);
2731 static NTSTATUS
cli_connect_nb_recv(struct tevent_req
*req
,
2732 struct cli_state
**pcli
)
2734 struct cli_connect_nb_state
*state
= tevent_req_data(
2735 req
, struct cli_connect_nb_state
);
2738 if (tevent_req_is_nterror(req
, &status
)) {
2741 *pcli
= talloc_move(NULL
, &state
->cli
);
2742 return NT_STATUS_OK
;
2745 NTSTATUS
cli_connect_nb(const char *host
, const struct sockaddr_storage
*dest_ss
,
2746 uint16_t port
, int name_type
, const char *myname
,
2747 enum smb_signing_setting signing_state
, int flags
, struct cli_state
**pcli
)
2749 struct tevent_context
*ev
;
2750 struct tevent_req
*req
;
2751 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2753 ev
= samba_tevent_context_init(talloc_tos());
2757 req
= cli_connect_nb_send(ev
, ev
, host
, dest_ss
, port
, name_type
,
2758 myname
, signing_state
, flags
);
2762 if (!tevent_req_set_endtime(req
, ev
, timeval_current_ofs(20, 0))) {
2765 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2768 status
= cli_connect_nb_recv(req
, pcli
);
2774 struct cli_start_connection_state
{
2775 struct tevent_context
*ev
;
2776 struct cli_state
*cli
;
2779 struct smb2_negotiate_contexts
*negotiate_contexts
;
2782 static void cli_start_connection_connected(struct tevent_req
*subreq
);
2783 static void cli_start_connection_done(struct tevent_req
*subreq
);
2786 establishes a connection to after the negprot.
2787 @param output_cli A fully initialised cli structure, non-null only on success
2788 @param dest_host The netbios name of the remote host
2789 @param dest_ss (optional) The destination IP, NULL for name based lookup
2790 @param port (optional) The destination port (0 for default)
2793 static struct tevent_req
*cli_start_connection_send(
2794 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
2795 const char *my_name
, const char *dest_host
,
2796 const struct sockaddr_storage
*dest_ss
, int port
,
2797 enum smb_signing_setting signing_state
, int flags
,
2798 struct smb2_negotiate_contexts
*negotiate_contexts
)
2800 struct tevent_req
*req
, *subreq
;
2801 struct cli_start_connection_state
*state
;
2803 req
= tevent_req_create(mem_ctx
, &state
,
2804 struct cli_start_connection_state
);
2810 if (flags
& CLI_FULL_CONNECTION_IPC
) {
2811 state
->min_protocol
= lp_client_ipc_min_protocol();
2812 state
->max_protocol
= lp_client_ipc_max_protocol();
2814 state
->min_protocol
= lp_client_min_protocol();
2815 state
->max_protocol
= lp_client_max_protocol();
2818 if (flags
& CLI_FULL_CONNECTION_FORCE_SMB1
) {
2819 state
->max_protocol
= MIN(state
->max_protocol
,
2821 state
->min_protocol
= MIN(state
->min_protocol
,
2822 state
->max_protocol
);
2825 if (flags
& CLI_FULL_CONNECTION_DISABLE_SMB1
) {
2826 state
->min_protocol
= MAX(state
->min_protocol
,
2828 state
->max_protocol
= MAX(state
->max_protocol
,
2829 state
->min_protocol
);
2832 state
->negotiate_contexts
= talloc_zero(
2833 state
, struct smb2_negotiate_contexts
);
2834 if (tevent_req_nomem(state
->negotiate_contexts
, req
)) {
2835 return tevent_req_post(req
, ev
);
2838 if (flags
& CLI_FULL_CONNECTION_REQUEST_POSIX
) {
2841 status
= smb2_negotiate_context_add(
2842 state
->negotiate_contexts
,
2843 state
->negotiate_contexts
,
2844 SMB2_POSIX_EXTENSIONS_AVAILABLE
,
2845 (const uint8_t *)SMB2_CREATE_TAG_POSIX
,
2846 strlen(SMB2_CREATE_TAG_POSIX
));
2847 if (tevent_req_nterror(req
, status
)) {
2848 return tevent_req_post(req
, ev
);
2852 if (negotiate_contexts
!= NULL
) {
2855 for (i
=0; i
<negotiate_contexts
->num_contexts
; i
++) {
2856 struct smb2_negotiate_context
*ctx
=
2857 &negotiate_contexts
->contexts
[i
];
2860 status
= smb2_negotiate_context_add(
2861 state
->negotiate_contexts
,
2862 state
->negotiate_contexts
,
2866 if (tevent_req_nterror(req
, status
)) {
2867 return tevent_req_post(req
, ev
);
2872 subreq
= cli_connect_nb_send(state
, ev
, dest_host
, dest_ss
, port
,
2873 0x20, my_name
, signing_state
, flags
);
2874 if (tevent_req_nomem(subreq
, req
)) {
2875 return tevent_req_post(req
, ev
);
2877 tevent_req_set_callback(subreq
, cli_start_connection_connected
, req
);
2881 static void cli_start_connection_connected(struct tevent_req
*subreq
)
2883 struct tevent_req
*req
= tevent_req_callback_data(
2884 subreq
, struct tevent_req
);
2885 struct cli_start_connection_state
*state
= tevent_req_data(
2886 req
, struct cli_start_connection_state
);
2889 status
= cli_connect_nb_recv(subreq
, &state
->cli
);
2890 TALLOC_FREE(subreq
);
2891 if (tevent_req_nterror(req
, status
)) {
2895 subreq
= smbXcli_negprot_send(
2899 state
->cli
->timeout
,
2900 state
->min_protocol
,
2901 state
->max_protocol
,
2902 WINDOWS_CLIENT_PURE_SMB2_NEGPROT_INITIAL_CREDIT_ASK
,
2903 state
->negotiate_contexts
);
2904 if (tevent_req_nomem(subreq
, req
)) {
2907 tevent_req_set_callback(subreq
, cli_start_connection_done
, req
);
2910 static void cli_start_connection_done(struct tevent_req
*subreq
)
2912 struct tevent_req
*req
= tevent_req_callback_data(
2913 subreq
, struct tevent_req
);
2914 struct cli_start_connection_state
*state
= tevent_req_data(
2915 req
, struct cli_start_connection_state
);
2918 status
= smbXcli_negprot_recv(subreq
, NULL
, NULL
);
2919 TALLOC_FREE(subreq
);
2920 if (tevent_req_nterror(req
, status
)) {
2924 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
2925 /* Ensure we ask for some initial credits. */
2926 smb2cli_conn_set_max_credits(state
->cli
->conn
,
2927 DEFAULT_SMB2_MAX_CREDITS
);
2930 tevent_req_done(req
);
2933 static NTSTATUS
cli_start_connection_recv(struct tevent_req
*req
,
2934 struct cli_state
**output_cli
)
2936 struct cli_start_connection_state
*state
= tevent_req_data(
2937 req
, struct cli_start_connection_state
);
2940 if (tevent_req_is_nterror(req
, &status
)) {
2943 *output_cli
= state
->cli
;
2945 return NT_STATUS_OK
;
2948 NTSTATUS
cli_start_connection(struct cli_state
**output_cli
,
2949 const char *my_name
,
2950 const char *dest_host
,
2951 const struct sockaddr_storage
*dest_ss
, int port
,
2952 enum smb_signing_setting signing_state
, int flags
)
2954 struct tevent_context
*ev
;
2955 struct tevent_req
*req
;
2956 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2958 ev
= samba_tevent_context_init(talloc_tos());
2962 req
= cli_start_connection_send(ev
, ev
, my_name
, dest_host
, dest_ss
,
2963 port
, signing_state
, flags
, NULL
);
2967 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2970 status
= cli_start_connection_recv(req
, output_cli
);
2976 struct cli_smb1_setup_encryption_blob_state
{
2981 uint16_t enc_ctx_id
;
2984 static void cli_smb1_setup_encryption_blob_done(struct tevent_req
*subreq
);
2986 static struct tevent_req
*cli_smb1_setup_encryption_blob_send(TALLOC_CTX
*mem_ctx
,
2987 struct tevent_context
*ev
,
2988 struct cli_state
*cli
,
2991 struct tevent_req
*req
= NULL
;
2992 struct cli_smb1_setup_encryption_blob_state
*state
= NULL
;
2993 struct tevent_req
*subreq
= NULL
;
2995 req
= tevent_req_create(mem_ctx
, &state
,
2996 struct cli_smb1_setup_encryption_blob_state
);
3001 if (in
.length
> CLI_BUFFER_SIZE
) {
3002 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER_MIX
);
3003 return tevent_req_post(req
, ev
);
3006 SSVAL(state
->setup
+0, 0, TRANSACT2_SETFSINFO
);
3007 SSVAL(state
->param
, 0, 0);
3008 SSVAL(state
->param
, 2, SMB_REQUEST_TRANSPORT_ENCRYPTION
);
3010 subreq
= smb1cli_trans_send(state
, ev
, cli
->conn
,
3018 NULL
, /* pipe_name */
3024 in
.data
, in
.length
, CLI_BUFFER_SIZE
);
3025 if (tevent_req_nomem(subreq
, req
)) {
3026 return tevent_req_post(req
, ev
);
3028 tevent_req_set_callback(subreq
,
3029 cli_smb1_setup_encryption_blob_done
,
3035 static void cli_smb1_setup_encryption_blob_done(struct tevent_req
*subreq
)
3037 struct tevent_req
*req
=
3038 tevent_req_callback_data(subreq
,
3040 struct cli_smb1_setup_encryption_blob_state
*state
=
3041 tevent_req_data(req
,
3042 struct cli_smb1_setup_encryption_blob_state
);
3043 uint8_t *rparam
=NULL
, *rdata
=NULL
;
3044 uint32_t num_rparam
, num_rdata
;
3047 status
= smb1cli_trans_recv(subreq
, state
,
3048 NULL
, /* recv_flags */
3049 NULL
, 0, NULL
, /* rsetup */
3050 &rparam
, 0, &num_rparam
,
3051 &rdata
, 0, &num_rdata
);
3052 TALLOC_FREE(subreq
);
3053 state
->status
= status
;
3054 if (NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
3055 status
= NT_STATUS_OK
;
3057 if (tevent_req_nterror(req
, status
)) {
3061 if (num_rparam
== 2) {
3062 state
->enc_ctx_id
= SVAL(rparam
, 0);
3064 TALLOC_FREE(rparam
);
3066 state
->out
= data_blob_const(rdata
, num_rdata
);
3068 tevent_req_done(req
);
3071 static NTSTATUS
cli_smb1_setup_encryption_blob_recv(struct tevent_req
*req
,
3072 TALLOC_CTX
*mem_ctx
,
3074 uint16_t *enc_ctx_id
)
3076 struct cli_smb1_setup_encryption_blob_state
*state
=
3077 tevent_req_data(req
,
3078 struct cli_smb1_setup_encryption_blob_state
);
3081 if (tevent_req_is_nterror(req
, &status
)) {
3082 tevent_req_received(req
);
3086 status
= state
->status
;
3089 talloc_steal(mem_ctx
, out
->data
);
3091 *enc_ctx_id
= state
->enc_ctx_id
;
3093 tevent_req_received(req
);
3097 struct cli_smb1_setup_encryption_state
{
3098 struct tevent_context
*ev
;
3099 struct cli_state
*cli
;
3100 struct smb_trans_enc_state
*es
;
3107 static void cli_smb1_setup_encryption_local_next(struct tevent_req
*req
);
3108 static void cli_smb1_setup_encryption_local_done(struct tevent_req
*subreq
);
3109 static void cli_smb1_setup_encryption_remote_next(struct tevent_req
*req
);
3110 static void cli_smb1_setup_encryption_remote_done(struct tevent_req
*subreq
);
3111 static void cli_smb1_setup_encryption_ready(struct tevent_req
*req
);
3113 static struct tevent_req
*cli_smb1_setup_encryption_send(TALLOC_CTX
*mem_ctx
,
3114 struct tevent_context
*ev
,
3115 struct cli_state
*cli
,
3116 struct cli_credentials
*creds
)
3118 struct tevent_req
*req
= NULL
;
3119 struct cli_smb1_setup_encryption_state
*state
= NULL
;
3120 struct auth_generic_state
*ags
= NULL
;
3121 const DATA_BLOB
*b
= NULL
;
3122 bool auth_requested
= false;
3123 const char *target_service
= NULL
;
3124 const char *target_hostname
= NULL
;
3127 req
= tevent_req_create(mem_ctx
, &state
,
3128 struct cli_smb1_setup_encryption_state
);
3135 auth_requested
= cli_credentials_authentication_requested(creds
);
3136 if (!auth_requested
) {
3137 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER_MIX
);
3138 return tevent_req_post(req
, ev
);
3141 target_service
= "cifs";
3142 target_hostname
= smbXcli_conn_remote_name(cli
->conn
);
3144 status
= cli_session_creds_prepare_krb5(cli
, creds
);
3145 if (tevent_req_nterror(req
, status
)) {
3146 return tevent_req_post(req
, ev
);
3149 state
->es
= talloc_zero(state
, struct smb_trans_enc_state
);
3150 if (tevent_req_nomem(state
->es
, req
)) {
3151 return tevent_req_post(req
, ev
);
3154 status
= auth_generic_client_prepare(state
->es
, &ags
);
3155 if (tevent_req_nterror(req
, status
)) {
3156 return tevent_req_post(req
, ev
);
3159 gensec_want_feature(ags
->gensec_security
,
3160 GENSEC_FEATURE_SIGN
);
3161 gensec_want_feature(ags
->gensec_security
,
3162 GENSEC_FEATURE_SEAL
);
3164 status
= auth_generic_set_creds(ags
, creds
);
3165 if (tevent_req_nterror(req
, status
)) {
3166 return tevent_req_post(req
, ev
);
3169 if (target_service
!= NULL
) {
3170 status
= gensec_set_target_service(ags
->gensec_security
,
3172 if (tevent_req_nterror(req
, status
)) {
3173 return tevent_req_post(req
, ev
);
3177 if (target_hostname
!= NULL
) {
3178 status
= gensec_set_target_hostname(ags
->gensec_security
,
3180 if (tevent_req_nterror(req
, status
)) {
3181 return tevent_req_post(req
, ev
);
3185 gensec_set_max_update_size(ags
->gensec_security
,
3188 b
= smbXcli_conn_server_gss_blob(state
->cli
->conn
);
3190 state
->blob_in
= *b
;
3193 status
= auth_generic_client_start(ags
, GENSEC_OID_SPNEGO
);
3194 if (tevent_req_nterror(req
, status
)) {
3195 return tevent_req_post(req
, ev
);
3199 * We only need the gensec_security part from here.
3201 state
->es
->gensec_security
= talloc_move(state
->es
,
3202 &ags
->gensec_security
);
3205 cli_smb1_setup_encryption_local_next(req
);
3206 if (!tevent_req_is_in_progress(req
)) {
3207 return tevent_req_post(req
, ev
);
3213 static void cli_smb1_setup_encryption_local_next(struct tevent_req
*req
)
3215 struct cli_smb1_setup_encryption_state
*state
=
3216 tevent_req_data(req
,
3217 struct cli_smb1_setup_encryption_state
);
3218 struct tevent_req
*subreq
= NULL
;
3220 if (state
->local_ready
) {
3221 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
3225 subreq
= gensec_update_send(state
, state
->ev
,
3226 state
->es
->gensec_security
,
3228 if (tevent_req_nomem(subreq
, req
)) {
3231 tevent_req_set_callback(subreq
, cli_smb1_setup_encryption_local_done
, req
);
3234 static void cli_smb1_setup_encryption_local_done(struct tevent_req
*subreq
)
3236 struct tevent_req
*req
=
3237 tevent_req_callback_data(subreq
,
3239 struct cli_smb1_setup_encryption_state
*state
=
3240 tevent_req_data(req
,
3241 struct cli_smb1_setup_encryption_state
);
3244 status
= gensec_update_recv(subreq
, state
, &state
->blob_out
);
3245 TALLOC_FREE(subreq
);
3246 state
->blob_in
= data_blob_null
;
3247 if (!NT_STATUS_IS_OK(status
) &&
3248 !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
))
3250 tevent_req_nterror(req
, status
);
3254 if (NT_STATUS_IS_OK(status
)) {
3255 state
->local_ready
= true;
3259 * We always get NT_STATUS_OK from the server even if it is not ready.
3260 * So guess the server is ready when we are ready and already sent
3261 * our last blob to the server.
3263 if (state
->local_ready
&& state
->blob_out
.length
== 0) {
3264 state
->remote_ready
= true;
3267 if (state
->local_ready
&& state
->remote_ready
) {
3268 cli_smb1_setup_encryption_ready(req
);
3272 cli_smb1_setup_encryption_remote_next(req
);
3275 static void cli_smb1_setup_encryption_remote_next(struct tevent_req
*req
)
3277 struct cli_smb1_setup_encryption_state
*state
=
3278 tevent_req_data(req
,
3279 struct cli_smb1_setup_encryption_state
);
3280 struct tevent_req
*subreq
= NULL
;
3282 if (state
->remote_ready
) {
3283 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
3287 subreq
= cli_smb1_setup_encryption_blob_send(state
, state
->ev
,
3288 state
->cli
, state
->blob_out
);
3289 if (tevent_req_nomem(subreq
, req
)) {
3292 tevent_req_set_callback(subreq
,
3293 cli_smb1_setup_encryption_remote_done
,
3297 static void cli_smb1_setup_encryption_remote_done(struct tevent_req
*subreq
)
3299 struct tevent_req
*req
=
3300 tevent_req_callback_data(subreq
,
3302 struct cli_smb1_setup_encryption_state
*state
=
3303 tevent_req_data(req
,
3304 struct cli_smb1_setup_encryption_state
);
3307 status
= cli_smb1_setup_encryption_blob_recv(subreq
, state
,
3309 &state
->es
->enc_ctx_num
);
3310 TALLOC_FREE(subreq
);
3311 data_blob_free(&state
->blob_out
);
3312 if (!NT_STATUS_IS_OK(status
) &&
3313 !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
))
3315 tevent_req_nterror(req
, status
);
3320 * We always get NT_STATUS_OK even if the server is not ready.
3321 * So guess the server is ready when we are ready and sent
3322 * our last blob to the server.
3324 if (state
->local_ready
) {
3325 state
->remote_ready
= true;
3328 if (state
->local_ready
&& state
->remote_ready
) {
3329 cli_smb1_setup_encryption_ready(req
);
3333 cli_smb1_setup_encryption_local_next(req
);
3336 static void cli_smb1_setup_encryption_ready(struct tevent_req
*req
)
3338 struct cli_smb1_setup_encryption_state
*state
=
3339 tevent_req_data(req
,
3340 struct cli_smb1_setup_encryption_state
);
3341 struct smb_trans_enc_state
*es
= NULL
;
3343 if (state
->blob_in
.length
!= 0) {
3344 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
3348 if (state
->blob_out
.length
!= 0) {
3349 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
3353 es
= talloc_move(state
->cli
->conn
, &state
->es
);
3355 smb1cli_conn_set_encryption(state
->cli
->conn
, es
);
3358 tevent_req_done(req
);
3361 static NTSTATUS
cli_smb1_setup_encryption_recv(struct tevent_req
*req
)
3363 return tevent_req_simple_recv_ntstatus(req
);
3366 NTSTATUS
cli_smb1_setup_encryption(struct cli_state
*cli
,
3367 struct cli_credentials
*creds
)
3369 struct tevent_context
*ev
= NULL
;
3370 struct tevent_req
*req
= NULL
;
3371 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
3373 ev
= samba_tevent_context_init(talloc_tos());
3377 req
= cli_smb1_setup_encryption_send(ev
, ev
, cli
, creds
);
3381 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
3384 status
= cli_smb1_setup_encryption_recv(req
);
3391 establishes a connection right up to doing tconX, password specified.
3392 @param output_cli A fully initialised cli structure, non-null only on success
3393 @param dest_host The netbios name of the remote host
3394 @param dest_ip (optional) The the destination IP, NULL for name based lookup
3395 @param port (optional) The destination port (0 for default)
3396 @param service (optional) The share to make the connection to. Should be 'unqualified' in any way.
3397 @param service_type The 'type' of serivice.
3398 @param creds The used user credentials
3401 struct cli_full_connection_creds_state
{
3402 struct tevent_context
*ev
;
3403 const char *service
;
3404 const char *service_type
;
3405 struct cli_credentials
*creds
;
3407 struct cli_state
*cli
;
3410 static int cli_full_connection_creds_state_destructor(
3411 struct cli_full_connection_creds_state
*s
)
3413 if (s
->cli
!= NULL
) {
3414 cli_shutdown(s
->cli
);
3420 static void cli_full_connection_creds_conn_done(struct tevent_req
*subreq
);
3421 static void cli_full_connection_creds_sess_done(struct tevent_req
*subreq
);
3422 static void cli_full_connection_creds_enc_start(struct tevent_req
*req
);
3423 static void cli_full_connection_creds_enc_tcon(struct tevent_req
*subreq
);
3424 static void cli_full_connection_creds_enc_ver(struct tevent_req
*subreq
);
3425 static void cli_full_connection_creds_enc_done(struct tevent_req
*subreq
);
3426 static void cli_full_connection_creds_enc_tdis(struct tevent_req
*req
);
3427 static void cli_full_connection_creds_enc_finished(struct tevent_req
*subreq
);
3428 static void cli_full_connection_creds_tcon_start(struct tevent_req
*req
);
3429 static void cli_full_connection_creds_tcon_done(struct tevent_req
*subreq
);
3431 struct tevent_req
*cli_full_connection_creds_send(
3432 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
3433 const char *my_name
, const char *dest_host
,
3434 const struct sockaddr_storage
*dest_ss
, int port
,
3435 const char *service
, const char *service_type
,
3436 struct cli_credentials
*creds
,
3438 struct smb2_negotiate_contexts
*negotiate_contexts
)
3440 struct tevent_req
*req
, *subreq
;
3441 struct cli_full_connection_creds_state
*state
;
3442 enum smb_signing_setting signing_state
;
3443 enum smb_encryption_setting encryption_state
=
3444 cli_credentials_get_smb_encryption(creds
);
3446 req
= tevent_req_create(mem_ctx
, &state
,
3447 struct cli_full_connection_creds_state
);
3451 talloc_set_destructor(state
, cli_full_connection_creds_state_destructor
);
3454 state
->service
= service
;
3455 state
->service_type
= service_type
;
3456 state
->creds
= creds
;
3457 state
->flags
= flags
;
3459 if (flags
& CLI_FULL_CONNECTION_IPC
) {
3460 signing_state
= cli_credentials_get_smb_ipc_signing(creds
);
3462 signing_state
= cli_credentials_get_smb_signing(creds
);
3465 if (encryption_state
== SMB_ENCRYPTION_REQUIRED
) {
3466 if (flags
& CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK
) {
3467 encryption_state
= SMB_ENCRYPTION_DESIRED
;
3471 if (encryption_state
>= SMB_ENCRYPTION_DESIRED
) {
3472 signing_state
= SMB_SIGNING_REQUIRED
;
3475 subreq
= cli_start_connection_send(
3476 state
, ev
, my_name
, dest_host
, dest_ss
, port
,
3477 signing_state
, flags
,
3478 negotiate_contexts
);
3479 if (tevent_req_nomem(subreq
, req
)) {
3480 return tevent_req_post(req
, ev
);
3482 tevent_req_set_callback(subreq
,
3483 cli_full_connection_creds_conn_done
,
3488 static void cli_full_connection_creds_conn_done(struct tevent_req
*subreq
)
3490 struct tevent_req
*req
= tevent_req_callback_data(
3491 subreq
, struct tevent_req
);
3492 struct cli_full_connection_creds_state
*state
= tevent_req_data(
3493 req
, struct cli_full_connection_creds_state
);
3496 status
= cli_start_connection_recv(subreq
, &state
->cli
);
3497 TALLOC_FREE(subreq
);
3498 if (tevent_req_nterror(req
, status
)) {
3502 subreq
= cli_session_setup_creds_send(
3503 state
, state
->ev
, state
->cli
, state
->creds
);
3504 if (tevent_req_nomem(subreq
, req
)) {
3507 tevent_req_set_callback(subreq
,
3508 cli_full_connection_creds_sess_done
,
3512 static void cli_full_connection_creds_sess_done(struct tevent_req
*subreq
)
3514 struct tevent_req
*req
= tevent_req_callback_data(
3515 subreq
, struct tevent_req
);
3516 struct cli_full_connection_creds_state
*state
= tevent_req_data(
3517 req
, struct cli_full_connection_creds_state
);
3520 status
= cli_session_setup_creds_recv(subreq
);
3521 TALLOC_FREE(subreq
);
3523 if (!NT_STATUS_IS_OK(status
) &&
3524 (state
->flags
& CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK
)) {
3526 state
->flags
&= ~CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK
;
3528 state
->creds
= cli_credentials_init_anon(state
);
3529 if (tevent_req_nomem(state
->creds
, req
)) {
3533 subreq
= cli_session_setup_creds_send(
3534 state
, state
->ev
, state
->cli
, state
->creds
);
3535 if (tevent_req_nomem(subreq
, req
)) {
3538 tevent_req_set_callback(subreq
,
3539 cli_full_connection_creds_sess_done
,
3544 if (tevent_req_nterror(req
, status
)) {
3548 cli_full_connection_creds_enc_start(req
);
3551 static void cli_full_connection_creds_enc_start(struct tevent_req
*req
)
3553 struct cli_full_connection_creds_state
*state
= tevent_req_data(
3554 req
, struct cli_full_connection_creds_state
);
3555 enum smb_encryption_setting encryption_state
=
3556 cli_credentials_get_smb_encryption(state
->creds
);
3557 struct tevent_req
*subreq
= NULL
;
3560 if (encryption_state
< SMB_ENCRYPTION_DESIRED
) {
3561 cli_full_connection_creds_tcon_start(req
);
3565 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
3566 status
= smb2cli_session_encryption_on(state
->cli
->smb2
.session
);
3567 if (NT_STATUS_EQUAL(status
, NT_STATUS_NOT_SUPPORTED
)) {
3568 if (encryption_state
< SMB_ENCRYPTION_REQUIRED
) {
3569 cli_full_connection_creds_tcon_start(req
);
3572 d_printf("Encryption required and "
3573 "server doesn't support "
3574 "SMB3 encryption - failing connect\n");
3575 tevent_req_nterror(req
, status
);
3577 } else if (!NT_STATUS_IS_OK(status
)) {
3578 d_printf("Encryption required and "
3579 "setup failed with error %s.\n",
3581 tevent_req_nterror(req
, status
);
3585 cli_full_connection_creds_tcon_start(req
);
3589 if (!SERVER_HAS_UNIX_CIFS(state
->cli
)) {
3590 if (encryption_state
< SMB_ENCRYPTION_REQUIRED
) {
3591 cli_full_connection_creds_tcon_start(req
);
3595 status
= NT_STATUS_NOT_SUPPORTED
;
3596 d_printf("Encryption required and "
3597 "server doesn't support "
3598 "SMB1 Unix Extensions - failing connect\n");
3599 tevent_req_nterror(req
, status
);
3604 * We do a tcon on IPC$ just to setup the encryption,
3605 * the real tcon will be encrypted then.
3607 subreq
= cli_tree_connect_send(state
, state
->ev
, state
->cli
,
3608 "IPC$", "IPC", NULL
);
3609 if (tevent_req_nomem(subreq
, req
)) {
3612 tevent_req_set_callback(subreq
, cli_full_connection_creds_enc_tcon
, req
);
3615 static void cli_full_connection_creds_enc_tcon(struct tevent_req
*subreq
)
3617 struct tevent_req
*req
= tevent_req_callback_data(
3618 subreq
, struct tevent_req
);
3619 struct cli_full_connection_creds_state
*state
= tevent_req_data(
3620 req
, struct cli_full_connection_creds_state
);
3623 status
= cli_tree_connect_recv(subreq
);
3624 TALLOC_FREE(subreq
);
3625 if (tevent_req_nterror(req
, status
)) {
3629 subreq
= cli_unix_extensions_version_send(state
, state
->ev
, state
->cli
);
3630 if (tevent_req_nomem(subreq
, req
)) {
3633 tevent_req_set_callback(subreq
, cli_full_connection_creds_enc_ver
, req
);
3636 static void cli_full_connection_creds_enc_ver(struct tevent_req
*subreq
)
3638 struct tevent_req
*req
= tevent_req_callback_data(
3639 subreq
, struct tevent_req
);
3640 struct cli_full_connection_creds_state
*state
= tevent_req_data(
3641 req
, struct cli_full_connection_creds_state
);
3642 enum smb_encryption_setting encryption_state
=
3643 cli_credentials_get_smb_encryption(state
->creds
);
3644 uint16_t major
, minor
;
3645 uint32_t caplow
, caphigh
;
3648 status
= cli_unix_extensions_version_recv(subreq
,
3652 TALLOC_FREE(subreq
);
3653 if (!NT_STATUS_IS_OK(status
)) {
3654 if (encryption_state
< SMB_ENCRYPTION_REQUIRED
) {
3655 /* disconnect ipc$ followed by the real tree connect */
3656 cli_full_connection_creds_enc_tdis(req
);
3659 DEBUG(10, ("%s: cli_unix_extensions_version "
3660 "returned %s\n", __func__
, nt_errstr(status
)));
3661 tevent_req_nterror(req
, NT_STATUS_UNKNOWN_REVISION
);
3665 if (!(caplow
& CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP
)) {
3666 if (encryption_state
< SMB_ENCRYPTION_REQUIRED
) {
3667 /* disconnect ipc$ followed by the real tree connect */
3668 cli_full_connection_creds_enc_tdis(req
);
3671 DEBUG(10, ("%s: CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP "
3672 "not supported\n", __func__
));
3673 tevent_req_nterror(req
, NT_STATUS_UNSUPPORTED_COMPRESSION
);
3677 subreq
= cli_smb1_setup_encryption_send(state
, state
->ev
,
3680 if (tevent_req_nomem(subreq
, req
)) {
3683 tevent_req_set_callback(subreq
,
3684 cli_full_connection_creds_enc_done
,
3688 static void cli_full_connection_creds_enc_done(struct tevent_req
*subreq
)
3690 struct tevent_req
*req
= tevent_req_callback_data(
3691 subreq
, struct tevent_req
);
3694 status
= cli_smb1_setup_encryption_recv(subreq
);
3695 TALLOC_FREE(subreq
);
3696 if (tevent_req_nterror(req
, status
)) {
3700 /* disconnect ipc$ followed by the real tree connect */
3701 cli_full_connection_creds_enc_tdis(req
);
3704 static void cli_full_connection_creds_enc_tdis(struct tevent_req
*req
)
3706 struct cli_full_connection_creds_state
*state
= tevent_req_data(
3707 req
, struct cli_full_connection_creds_state
);
3708 struct tevent_req
*subreq
= NULL
;
3710 subreq
= cli_tdis_send(state
, state
->ev
, state
->cli
);
3711 if (tevent_req_nomem(subreq
, req
)) {
3714 tevent_req_set_callback(subreq
,
3715 cli_full_connection_creds_enc_finished
,
3719 static void cli_full_connection_creds_enc_finished(struct tevent_req
*subreq
)
3721 struct tevent_req
*req
= tevent_req_callback_data(
3722 subreq
, struct tevent_req
);
3725 status
= cli_tdis_recv(subreq
);
3726 TALLOC_FREE(subreq
);
3727 if (tevent_req_nterror(req
, status
)) {
3731 cli_full_connection_creds_tcon_start(req
);
3734 static void cli_full_connection_creds_tcon_start(struct tevent_req
*req
)
3736 struct cli_full_connection_creds_state
*state
= tevent_req_data(
3737 req
, struct cli_full_connection_creds_state
);
3738 struct tevent_req
*subreq
= NULL
;
3739 const char *password
= NULL
;
3741 if (state
->service
== NULL
) {
3742 tevent_req_done(req
);
3746 password
= cli_credentials_get_password(state
->creds
);
3748 subreq
= cli_tree_connect_send(state
, state
->ev
,
3751 state
->service_type
,
3753 if (tevent_req_nomem(subreq
, req
)) {
3756 tevent_req_set_callback(subreq
,
3757 cli_full_connection_creds_tcon_done
,
3761 static void cli_full_connection_creds_tcon_done(struct tevent_req
*subreq
)
3763 struct tevent_req
*req
= tevent_req_callback_data(
3764 subreq
, struct tevent_req
);
3767 status
= cli_tree_connect_recv(subreq
);
3768 TALLOC_FREE(subreq
);
3769 if (tevent_req_nterror(req
, status
)) {
3773 tevent_req_done(req
);
3776 NTSTATUS
cli_full_connection_creds_recv(struct tevent_req
*req
,
3777 struct cli_state
**output_cli
)
3779 struct cli_full_connection_creds_state
*state
= tevent_req_data(
3780 req
, struct cli_full_connection_creds_state
);
3783 if (tevent_req_is_nterror(req
, &status
)) {
3786 *output_cli
= state
->cli
;
3787 talloc_set_destructor(state
, NULL
);
3788 return NT_STATUS_OK
;
3791 NTSTATUS
cli_full_connection_creds(struct cli_state
**output_cli
,
3792 const char *my_name
,
3793 const char *dest_host
,
3794 const struct sockaddr_storage
*dest_ss
, int port
,
3795 const char *service
, const char *service_type
,
3796 struct cli_credentials
*creds
,
3799 struct tevent_context
*ev
;
3800 struct tevent_req
*req
;
3801 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
3803 ev
= samba_tevent_context_init(talloc_tos());
3807 req
= cli_full_connection_creds_send(
3808 ev
, ev
, my_name
, dest_host
, dest_ss
, port
, service
,
3809 service_type
, creds
, flags
,
3814 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
3817 status
= cli_full_connection_creds_recv(req
, output_cli
);
3823 /****************************************************************************
3824 Send an old style tcon.
3825 ****************************************************************************/
3826 struct cli_raw_tcon_state
{
3830 static void cli_raw_tcon_done(struct tevent_req
*subreq
);
3832 static struct tevent_req
*cli_raw_tcon_send(
3833 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
3834 const char *service
, const char *pass
, const char *dev
)
3836 struct tevent_req
*req
, *subreq
;
3837 struct cli_raw_tcon_state
*state
;
3840 req
= tevent_req_create(mem_ctx
, &state
, struct cli_raw_tcon_state
);
3845 if (!lp_client_plaintext_auth() && (*pass
)) {
3846 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
3847 " or 'client ntlmv2 auth = yes'\n"));
3848 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
3849 return tevent_req_post(req
, ev
);
3852 TALLOC_FREE(cli
->smb1
.tcon
);
3853 cli
->smb1
.tcon
= smbXcli_tcon_create(cli
);
3854 if (tevent_req_nomem(cli
->smb1
.tcon
, req
)) {
3855 return tevent_req_post(req
, ev
);
3857 smb1cli_tcon_set_id(cli
->smb1
.tcon
, UINT16_MAX
);
3859 bytes
= talloc_array(state
, uint8_t, 0);
3860 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
3861 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
3862 service
, strlen(service
)+1, NULL
);
3863 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
3864 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
3865 pass
, strlen(pass
)+1, NULL
);
3866 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
3867 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
3868 dev
, strlen(dev
)+1, NULL
);
3870 if (tevent_req_nomem(bytes
, req
)) {
3871 return tevent_req_post(req
, ev
);
3874 subreq
= cli_smb_send(state
, ev
, cli
, SMBtcon
, 0, 0, 0, NULL
,
3875 talloc_get_size(bytes
), bytes
);
3876 if (tevent_req_nomem(subreq
, req
)) {
3877 return tevent_req_post(req
, ev
);
3879 tevent_req_set_callback(subreq
, cli_raw_tcon_done
, req
);
3883 static void cli_raw_tcon_done(struct tevent_req
*subreq
)
3885 struct tevent_req
*req
= tevent_req_callback_data(
3886 subreq
, struct tevent_req
);
3887 struct cli_raw_tcon_state
*state
= tevent_req_data(
3888 req
, struct cli_raw_tcon_state
);
3891 status
= cli_smb_recv(subreq
, state
, NULL
, 2, NULL
, &state
->ret_vwv
,
3893 TALLOC_FREE(subreq
);
3894 if (tevent_req_nterror(req
, status
)) {
3897 tevent_req_done(req
);
3900 static NTSTATUS
cli_raw_tcon_recv(struct tevent_req
*req
,
3901 uint16_t *max_xmit
, uint16_t *tid
)
3903 struct cli_raw_tcon_state
*state
= tevent_req_data(
3904 req
, struct cli_raw_tcon_state
);
3907 if (tevent_req_is_nterror(req
, &status
)) {
3910 *max_xmit
= SVAL(state
->ret_vwv
+ 0, 0);
3911 *tid
= SVAL(state
->ret_vwv
+ 1, 0);
3912 return NT_STATUS_OK
;
3915 NTSTATUS
cli_raw_tcon(struct cli_state
*cli
,
3916 const char *service
, const char *pass
, const char *dev
,
3917 uint16_t *max_xmit
, uint16_t *tid
)
3919 struct tevent_context
*ev
;
3920 struct tevent_req
*req
;
3921 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
3923 ev
= samba_tevent_context_init(talloc_tos());
3927 req
= cli_raw_tcon_send(ev
, ev
, cli
, service
, pass
, dev
);
3931 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
3934 status
= cli_raw_tcon_recv(req
, max_xmit
, tid
);
3940 /* Return a cli_state pointing at the IPC$ share for the given server */
3942 struct cli_state
*get_ipc_connect(char *server
,
3943 struct sockaddr_storage
*server_ss
,
3944 struct cli_credentials
*creds
)
3946 struct cli_state
*cli
;
3948 uint32_t flags
= CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK
;
3950 flags
|= CLI_FULL_CONNECTION_FORCE_SMB1
;
3951 flags
|= CLI_FULL_CONNECTION_IPC
;
3953 nt_status
= cli_full_connection_creds(&cli
, NULL
, server
, server_ss
, 0, "IPC$", "IPC",
3957 if (NT_STATUS_IS_OK(nt_status
)) {
3960 if (is_ipaddress(server
)) {
3961 /* windows 9* needs a correct NMB name for connections */
3962 fstring remote_name
;
3964 if (name_status_find("*", 0, 0, server_ss
, remote_name
)) {
3965 cli
= get_ipc_connect(remote_name
, server_ss
, creds
);
3974 * Given the IP address of a master browser on the network, return its
3975 * workgroup and connect to it.
3977 * This function is provided to allow additional processing beyond what
3978 * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
3979 * browsers and obtain each master browsers' list of domains (in case the
3980 * first master browser is recently on the network and has not yet
3981 * synchronized with other master browsers and therefore does not yet have the
3982 * entire network browse list)
3985 struct cli_state
*get_ipc_connect_master_ip(TALLOC_CTX
*ctx
,
3986 struct sockaddr_storage
*mb_ip
,
3987 struct cli_credentials
*creds
,
3988 char **pp_workgroup_out
)
3990 char addr
[INET6_ADDRSTRLEN
];
3992 struct cli_state
*cli
;
3993 struct sockaddr_storage server_ss
;
3995 *pp_workgroup_out
= NULL
;
3997 print_sockaddr(addr
, sizeof(addr
), mb_ip
);
3998 DEBUG(99, ("Looking up name of master browser %s\n",
4002 * Do a name status query to find out the name of the master browser.
4003 * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
4004 * master browser will not respond to a wildcard query (or, at least,
4005 * an NT4 server acting as the domain master browser will not).
4007 * We might be able to use ONLY the query on MSBROWSE, but that's not
4008 * yet been tested with all Windows versions, so until it is, leave
4009 * the original wildcard query as the first choice and fall back to
4010 * MSBROWSE if the wildcard query fails.
4012 if (!name_status_find("*", 0, 0x1d, mb_ip
, name
) &&
4013 !name_status_find(MSBROWSE
, 1, 0x1d, mb_ip
, name
)) {
4015 DEBUG(99, ("Could not retrieve name status for %s\n",
4020 if (!find_master_ip(name
, &server_ss
)) {
4021 DEBUG(99, ("Could not find master ip for %s\n", name
));
4025 *pp_workgroup_out
= talloc_strdup(ctx
, name
);
4027 DEBUG(4, ("found master browser %s, %s\n", name
, addr
));
4029 print_sockaddr(addr
, sizeof(addr
), &server_ss
);
4030 cli
= get_ipc_connect(addr
, &server_ss
, creds
);