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 "auth_info.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 cli_credentials_set_conf(creds
, lp_ctx
);
77 if (username
== NULL
) {
81 if (strlen(username
) == 0) {
82 if (password
!= NULL
&& strlen(password
) == 0) {
84 * some callers pass "" as no password
86 * gensec only handles NULL as no password.
90 if (password
== NULL
) {
91 cli_credentials_set_anonymous(creds
);
96 tmp
= talloc_strdup(creds
, username
);
102 /* allow for workgroups as part of the username */
103 if ((p
= strchr_m(tmp
, '\\')) ||
104 (p
= strchr_m(tmp
, '/')) ||
105 (p
= strchr_m(tmp
, *lp_winbind_separator()))) {
111 principal
= username
;
112 username
= cli_session_setup_get_account(creds
, principal
);
113 if (username
== NULL
) {
116 ok
= strequal(username
, principal
);
119 * Ok still the same, so it's not a principal
124 if (use_kerberos
&& fallback_after_kerberos
) {
125 cli_credentials_set_kerberos_state(creds
,
126 CRED_AUTO_USE_KERBEROS
);
127 } else if (use_kerberos
) {
128 cli_credentials_set_kerberos_state(creds
,
129 CRED_MUST_USE_KERBEROS
);
131 cli_credentials_set_kerberos_state(creds
,
132 CRED_DONT_USE_KERBEROS
);
138 features
= cli_credentials_get_gensec_features(creds
);
139 features
|= GENSEC_FEATURE_NTLM_CCACHE
;
140 cli_credentials_set_gensec_features(creds
, features
);
142 if (password
!= NULL
&& strlen(password
) == 0) {
144 * some callers pass "" as no password
146 * GENSEC_FEATURE_NTLM_CCACHE only handles
147 * NULL as no password.
153 ok
= cli_credentials_set_username(creds
,
160 if (domain
!= NULL
) {
161 ok
= cli_credentials_set_domain(creds
,
169 if (principal
!= NULL
) {
170 ok
= cli_credentials_set_principal(creds
,
179 ok
= cli_credentials_set_realm(creds
,
187 if (password
!= NULL
&& strlen(password
) > 0) {
188 if (password_is_nt_hash
) {
189 struct samr_Password nt_hash
;
192 converted
= strhex_to_str((char *)nt_hash
.hash
,
193 sizeof(nt_hash
.hash
),
196 if (converted
!= sizeof(nt_hash
.hash
)) {
200 ok
= cli_credentials_set_nt_hash(creds
,
207 ok
= cli_credentials_set_password(creds
,
222 NTSTATUS
cli_session_creds_prepare_krb5(struct cli_state
*cli
,
223 struct cli_credentials
*creds
)
225 TALLOC_CTX
*frame
= talloc_stackframe();
226 const char *user_principal
= NULL
;
227 const char *user_account
= NULL
;
228 const char *user_domain
= NULL
;
229 const char *pass
= NULL
;
230 const char *target_hostname
= NULL
;
231 const DATA_BLOB
*server_blob
= NULL
;
232 bool got_kerberos_mechanism
= false;
233 enum credentials_use_kerberos krb5_state
;
234 bool try_kerberos
= false;
235 bool need_kinit
= false;
236 bool auth_requested
= true;
239 target_hostname
= smbXcli_conn_remote_name(cli
->conn
);
240 server_blob
= smbXcli_conn_server_gss_blob(cli
->conn
);
242 /* the server might not even do spnego */
243 if (server_blob
!= NULL
&& server_blob
->length
!= 0) {
244 char *OIDs
[ASN1_MAX_OIDS
] = { NULL
, };
249 * The server sent us the first part of the SPNEGO exchange in the
250 * negprot reply. It is WRONG to depend on the principal sent in the
251 * negprot reply, but right now we do it. If we don't receive one,
252 * we try to best guess, then fall back to NTLM.
254 ok
= spnego_parse_negTokenInit(frame
,
261 return NT_STATUS_INVALID_PARAMETER
;
263 if (OIDs
[0] == NULL
) {
265 return NT_STATUS_INVALID_PARAMETER
;
268 /* make sure the server understands kerberos */
269 for (i
= 0; OIDs
[i
] != NULL
; i
++) {
271 DEBUG(3,("got OID=%s\n", OIDs
[i
]));
273 DEBUGADD(3,("got OID=%s\n", OIDs
[i
]));
276 if (strcmp(OIDs
[i
], OID_KERBEROS5_OLD
) == 0 ||
277 strcmp(OIDs
[i
], OID_KERBEROS5
) == 0) {
278 got_kerberos_mechanism
= true;
284 auth_requested
= cli_credentials_authentication_requested(creds
);
285 if (auth_requested
) {
287 user_principal
= cli_credentials_get_principal(creds
, frame
);
290 return NT_STATUS_NO_MEMORY
;
293 user_account
= cli_credentials_get_username(creds
);
294 user_domain
= cli_credentials_get_domain(creds
);
295 pass
= cli_credentials_get_password(creds
);
297 krb5_state
= cli_credentials_get_kerberos_state(creds
);
299 if (krb5_state
!= CRED_DONT_USE_KERBEROS
) {
303 if (user_principal
== NULL
) {
304 try_kerberos
= false;
307 if (target_hostname
== NULL
) {
308 try_kerberos
= false;
309 } else if (is_ipaddress(target_hostname
)) {
310 try_kerberos
= false;
311 } else if (strequal(target_hostname
, "localhost")) {
312 try_kerberos
= false;
313 } else if (strequal(target_hostname
, STAR_SMBSERVER
)) {
314 try_kerberos
= false;
315 } else if (!auth_requested
) {
316 try_kerberos
= false;
319 if (krb5_state
== CRED_MUST_USE_KERBEROS
&& !try_kerberos
) {
320 DEBUG(0, ("Kerberos auth with '%s' (%s\\%s) to access "
321 "'%s' not possible\n",
322 user_principal
, user_domain
, user_account
,
325 return NT_STATUS_ACCESS_DENIED
;
328 if (pass
== NULL
|| strlen(pass
) == 0) {
330 } else if (krb5_state
== CRED_MUST_USE_KERBEROS
) {
331 need_kinit
= try_kerberos
;
332 } else if (!got_kerberos_mechanism
) {
334 * Most likely the server doesn't support
335 * Kerberos, don't waste time doing a kinit
339 need_kinit
= try_kerberos
;
349 * TODO: This should be done within the gensec layer
352 setenv(KRB5_ENV_CCNAME
, "MEMORY:cliconnect", 1);
353 ret
= kerberos_kinit_password(user_principal
, pass
,
354 0 /* no time correction for now */,
357 int dbglvl
= DBGLVL_NOTICE
;
359 if (krb5_state
== CRED_MUST_USE_KERBEROS
) {
363 DEBUG(dbglvl
, ("Kinit for %s to access %s failed: %s\n",
364 user_principal
, target_hostname
,
365 error_message(ret
)));
366 if (krb5_state
== CRED_MUST_USE_KERBEROS
) {
368 return krb5_to_nt_status(ret
);
372 * Ignore the error and hope that NTLM will work
380 static NTSTATUS
cli_state_update_after_sesssetup(struct cli_state
*cli
,
381 const char *native_os
,
382 const char *native_lm
,
383 const char *primary_domain
)
385 #define _VALID_STR(p) ((p) != NULL && (p)[0] != '\0')
387 if (!_VALID_STR(cli
->server_os
) && _VALID_STR(native_os
)) {
388 cli
->server_os
= talloc_strdup(cli
, native_os
);
389 if (cli
->server_os
== NULL
) {
390 return NT_STATUS_NO_MEMORY
;
394 if (!_VALID_STR(cli
->server_type
) && _VALID_STR(native_lm
)) {
395 cli
->server_type
= talloc_strdup(cli
, native_lm
);
396 if (cli
->server_type
== NULL
) {
397 return NT_STATUS_NO_MEMORY
;
401 if (!_VALID_STR(cli
->server_domain
) && _VALID_STR(primary_domain
)) {
402 cli
->server_domain
= talloc_strdup(cli
, primary_domain
);
403 if (cli
->server_domain
== NULL
) {
404 return NT_STATUS_NO_MEMORY
;
412 /********************************************************
413 Utility function to ensure we always return at least
414 a valid char * pointer to an empty string for the
415 cli->server_os, cli->server_type and cli->server_domain
417 *******************************************************/
419 static NTSTATUS
smb_bytes_talloc_string(TALLOC_CTX
*mem_ctx
,
426 *destlen
= clistr_pull_talloc(mem_ctx
,
433 if (*destlen
== -1) {
434 return NT_STATUS_NO_MEMORY
;
438 *dest
= talloc_strdup(mem_ctx
, "");
440 return NT_STATUS_NO_MEMORY
;
446 /****************************************************************************
447 Work out suitable capabilities to offer the server.
448 ****************************************************************************/
450 static uint32_t cli_session_setup_capabilities(struct cli_state
*cli
,
451 uint32_t sesssetup_capabilities
)
453 uint32_t client_capabilities
= smb1cli_conn_capabilities(cli
->conn
);
456 * We only send capabilities based on the mask for:
457 * - client only flags
458 * - flags used in both directions
460 * We do not echo the server only flags, except some legacy flags.
462 * SMB_CAP_LEGACY_CLIENT_MASK contains CAP_LARGE_READX and
463 * CAP_LARGE_WRITEX in order to allow us to do large reads
464 * against old Samba releases (<= 3.6.x).
466 client_capabilities
&= (SMB_CAP_BOTH_MASK
| SMB_CAP_LEGACY_CLIENT_MASK
);
469 * Session Setup specific flags CAP_DYNAMIC_REAUTH
470 * and CAP_EXTENDED_SECURITY are passed by the caller.
471 * We need that in order to do guest logins even if
472 * CAP_EXTENDED_SECURITY is negotiated.
474 client_capabilities
&= ~(CAP_DYNAMIC_REAUTH
|CAP_EXTENDED_SECURITY
);
475 sesssetup_capabilities
&= (CAP_DYNAMIC_REAUTH
|CAP_EXTENDED_SECURITY
);
476 client_capabilities
|= sesssetup_capabilities
;
478 return client_capabilities
;
481 /****************************************************************************
482 Do a NT1 guest session setup.
483 ****************************************************************************/
485 struct cli_session_setup_guest_state
{
486 struct cli_state
*cli
;
491 static void cli_session_setup_guest_done(struct tevent_req
*subreq
);
493 struct tevent_req
*cli_session_setup_guest_create(TALLOC_CTX
*mem_ctx
,
494 struct tevent_context
*ev
,
495 struct cli_state
*cli
,
496 struct tevent_req
**psmbreq
)
498 struct tevent_req
*req
, *subreq
;
499 struct cli_session_setup_guest_state
*state
;
503 req
= tevent_req_create(mem_ctx
, &state
,
504 struct cli_session_setup_guest_state
);
511 SCVAL(vwv
+0, 0, 0xFF);
514 SSVAL(vwv
+2, 0, CLI_BUFFER_SIZE
);
516 SSVAL(vwv
+4, 0, cli_state_get_vc_num(cli
));
517 SIVAL(vwv
+5, 0, smb1cli_conn_server_session_key(cli
->conn
));
522 SIVAL(vwv
+11, 0, cli_session_setup_capabilities(cli
, 0));
524 bytes
= talloc_array(state
, uint8_t, 0);
526 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "", 1, /* username */
528 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "", 1, /* workgroup */
530 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "Unix", 5, NULL
);
531 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "Samba", 6, NULL
);
538 state
->bytes
.iov_base
= (void *)bytes
;
539 state
->bytes
.iov_len
= talloc_get_size(bytes
);
541 subreq
= cli_smb_req_create(state
, ev
, cli
, SMBsesssetupX
, 0, 0, 13,
542 vwv
, 1, &state
->bytes
);
543 if (subreq
== NULL
) {
547 tevent_req_set_callback(subreq
, cli_session_setup_guest_done
, req
);
552 struct tevent_req
*cli_session_setup_guest_send(TALLOC_CTX
*mem_ctx
,
553 struct tevent_context
*ev
,
554 struct cli_state
*cli
)
556 struct tevent_req
*req
, *subreq
;
559 req
= cli_session_setup_guest_create(mem_ctx
, ev
, cli
, &subreq
);
564 status
= smb1cli_req_chain_submit(&subreq
, 1);
565 if (!NT_STATUS_IS_OK(status
)) {
566 tevent_req_nterror(req
, status
);
567 return tevent_req_post(req
, ev
);
572 static void cli_session_setup_guest_done(struct tevent_req
*subreq
)
574 struct tevent_req
*req
= tevent_req_callback_data(
575 subreq
, struct tevent_req
);
576 struct cli_session_setup_guest_state
*state
= tevent_req_data(
577 req
, struct cli_session_setup_guest_state
);
578 struct cli_state
*cli
= state
->cli
;
589 status
= cli_smb_recv(subreq
, state
, &in
, 3, &wct
, &vwv
,
592 if (!NT_STATUS_IS_OK(status
)) {
593 tevent_req_nterror(req
, status
);
597 inhdr
= in
+ NBT_HDR_SIZE
;
600 cli_state_set_uid(state
->cli
, SVAL(inhdr
, HDR_UID
));
601 smb1cli_session_set_action(cli
->smb1
.session
, SVAL(vwv
+2, 0));
603 status
= smb_bytes_talloc_string(cli
,
610 if (!NT_STATUS_IS_OK(status
)) {
611 tevent_req_nterror(req
, status
);
616 status
= smb_bytes_talloc_string(cli
,
623 if (!NT_STATUS_IS_OK(status
)) {
624 tevent_req_nterror(req
, status
);
629 status
= smb_bytes_talloc_string(cli
,
636 if (!NT_STATUS_IS_OK(status
)) {
637 tevent_req_nterror(req
, status
);
642 tevent_req_done(req
);
645 NTSTATUS
cli_session_setup_guest_recv(struct tevent_req
*req
)
647 return tevent_req_simple_recv_ntstatus(req
);
650 /* The following is calculated from :
652 * (smb_wcnt * 2) = 24 (smb_wcnt == 12 in cli_session_setup_blob_send() )
653 * (strlen("Unix") + 1 + strlen("Samba") + 1) * 2 = 22 (unicode strings at
657 #define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22)
659 struct cli_sesssetup_blob_state
{
660 struct tevent_context
*ev
;
661 struct cli_state
*cli
;
663 uint16_t max_blob_size
;
666 struct iovec
*recv_iov
;
669 const uint8_t *inbuf
;
676 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state
*state
,
677 struct tevent_req
**psubreq
);
678 static void cli_sesssetup_blob_done(struct tevent_req
*subreq
);
680 static struct tevent_req
*cli_sesssetup_blob_send(TALLOC_CTX
*mem_ctx
,
681 struct tevent_context
*ev
,
682 struct cli_state
*cli
,
685 struct tevent_req
*req
, *subreq
;
686 struct cli_sesssetup_blob_state
*state
;
687 uint32_t usable_space
;
689 req
= tevent_req_create(mem_ctx
, &state
,
690 struct cli_sesssetup_blob_state
);
698 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
699 usable_space
= UINT16_MAX
;
701 usable_space
= cli_state_available_size(cli
,
702 BASE_SESSSETUP_BLOB_PACKET_SIZE
);
705 if (usable_space
== 0) {
706 DEBUG(1, ("cli_session_setup_blob: cli->max_xmit too small "
707 "(not possible to send %u bytes)\n",
708 BASE_SESSSETUP_BLOB_PACKET_SIZE
+ 1));
709 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
710 return tevent_req_post(req
, ev
);
712 state
->max_blob_size
= MIN(usable_space
, 0xFFFF);
714 if (!cli_sesssetup_blob_next(state
, &subreq
)) {
715 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
716 return tevent_req_post(req
, ev
);
718 tevent_req_set_callback(subreq
, cli_sesssetup_blob_done
, req
);
722 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state
*state
,
723 struct tevent_req
**psubreq
)
725 struct tevent_req
*subreq
;
728 thistime
= MIN(state
->blob
.length
, state
->max_blob_size
);
730 state
->this_blob
.data
= state
->blob
.data
;
731 state
->this_blob
.length
= thistime
;
733 state
->blob
.data
+= thistime
;
734 state
->blob
.length
-= thistime
;
736 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
737 subreq
= smb2cli_session_setup_send(state
, state
->ev
,
740 state
->cli
->smb2
.session
,
742 SMB2_CAP_DFS
, /* in_capabilities */
744 0, /* in_previous_session_id */
746 if (subreq
== NULL
) {
750 uint16_t in_buf_size
= 0;
751 uint16_t in_mpx_max
= 0;
752 uint16_t in_vc_num
= 0;
753 uint32_t in_sess_key
= 0;
754 uint32_t in_capabilities
= 0;
755 const char *in_native_os
= NULL
;
756 const char *in_native_lm
= NULL
;
758 in_buf_size
= CLI_BUFFER_SIZE
;
759 in_mpx_max
= smbXcli_conn_max_requests(state
->cli
->conn
);
760 in_vc_num
= cli_state_get_vc_num(state
->cli
);
761 in_sess_key
= smb1cli_conn_server_session_key(state
->cli
->conn
);
762 in_capabilities
= cli_session_setup_capabilities(state
->cli
,
763 CAP_EXTENDED_SECURITY
);
764 in_native_os
= "Unix";
765 in_native_lm
= "Samba";
768 * For now we keep the same values as before,
769 * we may remove these in a separate commit later.
775 subreq
= smb1cli_session_setup_ext_send(state
, state
->ev
,
778 state
->cli
->smb1
.pid
,
779 state
->cli
->smb1
.session
,
788 if (subreq
== NULL
) {
796 static void cli_sesssetup_blob_done(struct tevent_req
*subreq
)
798 struct tevent_req
*req
= tevent_req_callback_data(
799 subreq
, struct tevent_req
);
800 struct cli_sesssetup_blob_state
*state
= tevent_req_data(
801 req
, struct cli_sesssetup_blob_state
);
804 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
805 status
= smb2cli_session_setup_recv(subreq
, state
,
809 status
= smb1cli_session_setup_ext_recv(subreq
, state
,
813 &state
->out_native_os
,
814 &state
->out_native_lm
);
817 if (!NT_STATUS_IS_OK(status
)
818 && !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
819 tevent_req_nterror(req
, status
);
823 state
->status
= status
;
825 status
= cli_state_update_after_sesssetup(state
->cli
,
826 state
->out_native_os
,
827 state
->out_native_lm
,
829 if (tevent_req_nterror(req
, status
)) {
833 if (state
->blob
.length
!= 0) {
837 if (!cli_sesssetup_blob_next(state
, &subreq
)) {
841 tevent_req_set_callback(subreq
, cli_sesssetup_blob_done
, req
);
844 tevent_req_done(req
);
847 static NTSTATUS
cli_sesssetup_blob_recv(struct tevent_req
*req
,
850 const uint8_t **pinbuf
,
851 struct iovec
**precv_iov
)
853 struct cli_sesssetup_blob_state
*state
= tevent_req_data(
854 req
, struct cli_sesssetup_blob_state
);
856 struct iovec
*recv_iov
;
858 if (tevent_req_is_nterror(req
, &status
)) {
859 TALLOC_FREE(state
->cli
->smb2
.session
);
860 cli_state_set_uid(state
->cli
, UID_FIELD_INVALID
);
861 tevent_req_received(req
);
865 recv_iov
= talloc_move(mem_ctx
, &state
->recv_iov
);
867 *pblob
= state
->ret_blob
;
869 if (pinbuf
!= NULL
) {
870 *pinbuf
= state
->inbuf
;
872 if (precv_iov
!= NULL
) {
873 *precv_iov
= recv_iov
;
875 /* could be NT_STATUS_MORE_PROCESSING_REQUIRED */
876 status
= state
->status
;
877 tevent_req_received(req
);
881 /****************************************************************************
882 Do a spnego/NTLMSSP encrypted session setup.
883 ****************************************************************************/
885 struct cli_session_setup_gensec_state
{
886 struct tevent_context
*ev
;
887 struct cli_state
*cli
;
888 struct auth_generic_state
*auth_generic
;
891 const uint8_t *inbuf
;
892 struct iovec
*recv_iov
;
896 DATA_BLOB session_key
;
899 static int cli_session_setup_gensec_state_destructor(
900 struct cli_session_setup_gensec_state
*state
)
902 TALLOC_FREE(state
->auth_generic
);
903 data_blob_clear_free(&state
->session_key
);
907 static void cli_session_setup_gensec_local_next(struct tevent_req
*req
);
908 static void cli_session_setup_gensec_local_done(struct tevent_req
*subreq
);
909 static void cli_session_setup_gensec_remote_next(struct tevent_req
*req
);
910 static void cli_session_setup_gensec_remote_done(struct tevent_req
*subreq
);
911 static void cli_session_setup_gensec_ready(struct tevent_req
*req
);
913 static struct tevent_req
*cli_session_setup_gensec_send(
914 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
915 struct cli_credentials
*creds
,
916 const char *target_service
,
917 const char *target_hostname
)
919 struct tevent_req
*req
;
920 struct cli_session_setup_gensec_state
*state
;
922 const DATA_BLOB
*b
= NULL
;
924 req
= tevent_req_create(mem_ctx
, &state
,
925 struct cli_session_setup_gensec_state
);
932 talloc_set_destructor(
933 state
, cli_session_setup_gensec_state_destructor
);
935 status
= auth_generic_client_prepare(state
, &state
->auth_generic
);
936 if (tevent_req_nterror(req
, status
)) {
937 return tevent_req_post(req
, ev
);
940 status
= auth_generic_set_creds(state
->auth_generic
, creds
);
941 if (tevent_req_nterror(req
, status
)) {
942 return tevent_req_post(req
, ev
);
945 gensec_want_feature(state
->auth_generic
->gensec_security
,
946 GENSEC_FEATURE_SESSION_KEY
);
948 if (target_service
!= NULL
) {
949 status
= gensec_set_target_service(
950 state
->auth_generic
->gensec_security
,
952 if (tevent_req_nterror(req
, status
)) {
953 return tevent_req_post(req
, ev
);
957 if (target_hostname
!= NULL
) {
958 status
= gensec_set_target_hostname(
959 state
->auth_generic
->gensec_security
,
961 if (tevent_req_nterror(req
, status
)) {
962 return tevent_req_post(req
, ev
);
966 b
= smbXcli_conn_server_gss_blob(cli
->conn
);
971 state
->is_anonymous
= cli_credentials_is_anonymous(state
->auth_generic
->credentials
);
973 status
= auth_generic_client_start(state
->auth_generic
,
975 if (tevent_req_nterror(req
, status
)) {
976 return tevent_req_post(req
, ev
);
979 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
980 state
->cli
->smb2
.session
= smbXcli_session_create(cli
,
982 if (tevent_req_nomem(state
->cli
->smb2
.session
, req
)) {
983 return tevent_req_post(req
, ev
);
987 cli_session_setup_gensec_local_next(req
);
988 if (!tevent_req_is_in_progress(req
)) {
989 return tevent_req_post(req
, ev
);
995 static void cli_session_setup_gensec_local_next(struct tevent_req
*req
)
997 struct cli_session_setup_gensec_state
*state
=
999 struct cli_session_setup_gensec_state
);
1000 struct tevent_req
*subreq
= NULL
;
1002 if (state
->local_ready
) {
1003 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
1007 subreq
= gensec_update_send(state
, state
->ev
,
1008 state
->auth_generic
->gensec_security
,
1010 if (tevent_req_nomem(subreq
, req
)) {
1013 tevent_req_set_callback(subreq
, cli_session_setup_gensec_local_done
, req
);
1016 static void cli_session_setup_gensec_local_done(struct tevent_req
*subreq
)
1018 struct tevent_req
*req
=
1019 tevent_req_callback_data(subreq
,
1021 struct cli_session_setup_gensec_state
*state
=
1022 tevent_req_data(req
,
1023 struct cli_session_setup_gensec_state
);
1026 status
= gensec_update_recv(subreq
, state
, &state
->blob_out
);
1027 TALLOC_FREE(subreq
);
1028 state
->blob_in
= data_blob_null
;
1029 if (!NT_STATUS_IS_OK(status
) &&
1030 !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
))
1032 tevent_req_nterror(req
, status
);
1036 if (NT_STATUS_IS_OK(status
)) {
1037 state
->local_ready
= true;
1040 if (state
->local_ready
&& state
->remote_ready
) {
1041 cli_session_setup_gensec_ready(req
);
1045 cli_session_setup_gensec_remote_next(req
);
1048 static void cli_session_setup_gensec_remote_next(struct tevent_req
*req
)
1050 struct cli_session_setup_gensec_state
*state
=
1051 tevent_req_data(req
,
1052 struct cli_session_setup_gensec_state
);
1053 struct tevent_req
*subreq
= NULL
;
1055 if (state
->remote_ready
) {
1056 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
1060 subreq
= cli_sesssetup_blob_send(state
, state
->ev
,
1061 state
->cli
, state
->blob_out
);
1062 if (tevent_req_nomem(subreq
, req
)) {
1065 tevent_req_set_callback(subreq
,
1066 cli_session_setup_gensec_remote_done
,
1070 static void cli_session_setup_gensec_remote_done(struct tevent_req
*subreq
)
1072 struct tevent_req
*req
=
1073 tevent_req_callback_data(subreq
,
1075 struct cli_session_setup_gensec_state
*state
=
1076 tevent_req_data(req
,
1077 struct cli_session_setup_gensec_state
);
1080 state
->inbuf
= NULL
;
1081 TALLOC_FREE(state
->recv_iov
);
1083 status
= cli_sesssetup_blob_recv(subreq
, state
, &state
->blob_in
,
1084 &state
->inbuf
, &state
->recv_iov
);
1085 TALLOC_FREE(subreq
);
1086 data_blob_free(&state
->blob_out
);
1087 if (!NT_STATUS_IS_OK(status
) &&
1088 !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
))
1090 tevent_req_nterror(req
, status
);
1094 if (NT_STATUS_IS_OK(status
)) {
1095 struct smbXcli_session
*session
= NULL
;
1096 bool is_guest
= false;
1098 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
1099 session
= state
->cli
->smb2
.session
;
1101 session
= state
->cli
->smb1
.session
;
1104 is_guest
= smbXcli_session_is_guest(session
);
1107 * We can't finish the gensec handshake, we don't
1108 * have a negotiated session key.
1110 * So just pretend we are completely done,
1111 * we need to continue as anonymous from this point,
1112 * as we can't get a session key.
1114 * Note that smbXcli_session_is_guest()
1115 * always returns false if we require signing.
1117 state
->blob_in
= data_blob_null
;
1118 state
->local_ready
= true;
1119 state
->is_anonymous
= true;
1122 state
->remote_ready
= true;
1125 if (state
->local_ready
&& state
->remote_ready
) {
1126 cli_session_setup_gensec_ready(req
);
1130 cli_session_setup_gensec_local_next(req
);
1133 static void cli_session_setup_gensec_ready(struct tevent_req
*req
)
1135 struct cli_session_setup_gensec_state
*state
=
1136 tevent_req_data(req
,
1137 struct cli_session_setup_gensec_state
);
1138 const char *server_domain
= NULL
;
1141 if (state
->blob_in
.length
!= 0) {
1142 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
1146 if (state
->blob_out
.length
!= 0) {
1147 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
1152 * gensec_ntlmssp_server_domain() returns NULL
1153 * if NTLMSSP is not used.
1155 * We can remove this later
1156 * and leave the server domain empty for SMB2 and above
1157 * in future releases.
1159 server_domain
= gensec_ntlmssp_server_domain(
1160 state
->auth_generic
->gensec_security
);
1162 if (state
->cli
->server_domain
[0] == '\0' && server_domain
!= NULL
) {
1163 TALLOC_FREE(state
->cli
->server_domain
);
1164 state
->cli
->server_domain
= talloc_strdup(state
->cli
,
1166 if (state
->cli
->server_domain
== NULL
) {
1167 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
1172 if (state
->is_anonymous
) {
1174 * Windows server does not set the
1175 * SMB2_SESSION_FLAG_IS_NULL flag.
1177 * This fix makes sure we do not try
1178 * to verify a signature on the final
1179 * session setup response.
1181 tevent_req_done(req
);
1185 status
= gensec_session_key(state
->auth_generic
->gensec_security
,
1186 state
, &state
->session_key
);
1187 if (tevent_req_nterror(req
, status
)) {
1191 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
1192 struct smbXcli_session
*session
= state
->cli
->smb2
.session
;
1194 status
= smb2cli_session_set_session_key(session
,
1197 if (tevent_req_nterror(req
, status
)) {
1201 struct smbXcli_session
*session
= state
->cli
->smb1
.session
;
1204 status
= smb1cli_session_set_session_key(session
,
1205 state
->session_key
);
1206 if (tevent_req_nterror(req
, status
)) {
1210 active
= smb1cli_conn_activate_signing(state
->cli
->conn
,
1216 ok
= smb1cli_conn_check_signing(state
->cli
->conn
,
1219 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1225 tevent_req_done(req
);
1228 static NTSTATUS
cli_session_setup_gensec_recv(struct tevent_req
*req
)
1230 struct cli_session_setup_gensec_state
*state
=
1231 tevent_req_data(req
,
1232 struct cli_session_setup_gensec_state
);
1235 if (tevent_req_is_nterror(req
, &status
)) {
1236 cli_state_set_uid(state
->cli
, UID_FIELD_INVALID
);
1239 return NT_STATUS_OK
;
1242 static char *cli_session_setup_get_account(TALLOC_CTX
*mem_ctx
,
1243 const char *principal
)
1247 account
= talloc_strdup(mem_ctx
, principal
);
1248 if (account
== NULL
) {
1251 p
= strchr_m(account
, '@');
1258 /****************************************************************************
1259 Do a spnego encrypted session setup.
1261 user_domain: The shortname of the domain the user/machine is a member of.
1262 dest_realm: The realm we're connecting to, if NULL we use our default realm.
1263 ****************************************************************************/
1265 struct cli_session_setup_spnego_state
{
1269 static void cli_session_setup_spnego_done(struct tevent_req
*subreq
);
1271 static struct tevent_req
*cli_session_setup_spnego_send(
1272 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
1273 struct cli_credentials
*creds
)
1275 struct tevent_req
*req
, *subreq
;
1276 struct cli_session_setup_spnego_state
*state
;
1277 const char *target_service
= NULL
;
1278 const char *target_hostname
= NULL
;
1281 req
= tevent_req_create(mem_ctx
, &state
,
1282 struct cli_session_setup_spnego_state
);
1287 target_service
= "cifs";
1288 target_hostname
= smbXcli_conn_remote_name(cli
->conn
);
1290 status
= cli_session_creds_prepare_krb5(cli
, creds
);
1291 if (tevent_req_nterror(req
, status
)) {
1292 return tevent_req_post(req
, ev
);
1295 subreq
= cli_session_setup_gensec_send(state
, ev
, cli
, creds
,
1296 target_service
, target_hostname
);
1297 if (tevent_req_nomem(subreq
, req
)) {
1298 return tevent_req_post(req
, ev
);
1300 tevent_req_set_callback(
1301 subreq
, cli_session_setup_spnego_done
, req
);
1305 static void cli_session_setup_spnego_done(struct tevent_req
*subreq
)
1307 struct tevent_req
*req
= tevent_req_callback_data(
1308 subreq
, struct tevent_req
);
1311 status
= cli_session_setup_gensec_recv(subreq
);
1312 TALLOC_FREE(subreq
);
1313 if (tevent_req_nterror(req
, status
)) {
1317 tevent_req_done(req
);
1320 static ADS_STATUS
cli_session_setup_spnego_recv(struct tevent_req
*req
)
1322 struct cli_session_setup_spnego_state
*state
= tevent_req_data(
1323 req
, struct cli_session_setup_spnego_state
);
1326 if (tevent_req_is_nterror(req
, &status
)) {
1327 state
->result
= ADS_ERROR_NT(status
);
1330 return state
->result
;
1333 struct cli_session_setup_creds_state
{
1334 struct cli_state
*cli
;
1335 DATA_BLOB apassword_blob
;
1336 DATA_BLOB upassword_blob
;
1337 DATA_BLOB lm_session_key
;
1338 DATA_BLOB session_key
;
1339 char *out_native_os
;
1340 char *out_native_lm
;
1341 char *out_primary_domain
;
1344 static void cli_session_setup_creds_cleanup(struct tevent_req
*req
,
1345 enum tevent_req_state req_state
)
1347 struct cli_session_setup_creds_state
*state
= tevent_req_data(
1348 req
, struct cli_session_setup_creds_state
);
1350 if (req_state
!= TEVENT_REQ_RECEIVED
) {
1355 * We only call data_blob_clear() as
1356 * some of the blobs point to the same memory.
1358 * We let the talloc hierachy free the memory.
1360 data_blob_clear(&state
->apassword_blob
);
1361 data_blob_clear(&state
->upassword_blob
);
1362 data_blob_clear(&state
->lm_session_key
);
1363 data_blob_clear(&state
->session_key
);
1364 ZERO_STRUCTP(state
);
1367 static void cli_session_setup_creds_done_spnego(struct tevent_req
*subreq
);
1368 static void cli_session_setup_creds_done_nt1(struct tevent_req
*subreq
);
1369 static void cli_session_setup_creds_done_lm21(struct tevent_req
*subreq
);
1371 /****************************************************************************
1372 Send a session setup. The username and workgroup is in UNIX character
1373 format and must be converted to DOS codepage format before sending. If the
1374 password is in plaintext, the same should be done.
1375 ****************************************************************************/
1377 struct tevent_req
*cli_session_setup_creds_send(TALLOC_CTX
*mem_ctx
,
1378 struct tevent_context
*ev
,
1379 struct cli_state
*cli
,
1380 struct cli_credentials
*creds
)
1382 struct tevent_req
*req
, *subreq
;
1383 struct cli_session_setup_creds_state
*state
;
1384 uint16_t sec_mode
= smb1cli_conn_server_security_mode(cli
->conn
);
1385 bool use_spnego
= false;
1387 enum credentials_use_kerberos krb5_state
;
1388 uint32_t gensec_features
;
1389 const char *username
= "";
1390 const char *domain
= "";
1391 DATA_BLOB target_info
= data_blob_null
;
1392 DATA_BLOB challenge
= data_blob_null
;
1393 uint16_t in_buf_size
= 0;
1394 uint16_t in_mpx_max
= 0;
1395 uint16_t in_vc_num
= 0;
1396 uint32_t in_sess_key
= 0;
1397 const char *in_native_os
= NULL
;
1398 const char *in_native_lm
= NULL
;
1401 req
= tevent_req_create(mem_ctx
, &state
,
1402 struct cli_session_setup_creds_state
);
1408 tevent_req_set_cleanup_fn(req
, cli_session_setup_creds_cleanup
);
1410 krb5_state
= cli_credentials_get_kerberos_state(creds
);
1411 gensec_features
= cli_credentials_get_gensec_features(creds
);
1413 switch (krb5_state
) {
1414 case CRED_MUST_USE_KERBEROS
:
1415 cli
->use_kerberos
= true;
1416 cli
->fallback_after_kerberos
= false;
1418 case CRED_AUTO_USE_KERBEROS
:
1419 cli
->use_kerberos
= true;
1420 cli
->fallback_after_kerberos
= true;
1422 case CRED_DONT_USE_KERBEROS
:
1423 cli
->use_kerberos
= false;
1424 cli
->fallback_after_kerberos
= false;
1428 if (gensec_features
& GENSEC_FEATURE_NTLM_CCACHE
) {
1429 cli
->use_ccache
= true;
1431 cli
->use_ccache
= false;
1435 * Now work out what sort of session setup we are going to
1436 * do. I have split this into separate functions to make the flow a bit
1437 * easier to understand (tridge).
1439 if (smbXcli_conn_protocol(cli
->conn
) < PROTOCOL_NT1
) {
1441 } else if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
1443 } else if (smb1cli_conn_capabilities(cli
->conn
) & CAP_EXTENDED_SECURITY
) {
1445 * if the server supports extended security then use SPNEGO
1446 * even for anonymous connections.
1454 subreq
= cli_session_setup_spnego_send(
1455 state
, ev
, cli
, creds
);
1456 if (tevent_req_nomem(subreq
, req
)) {
1457 return tevent_req_post(req
, ev
);
1459 tevent_req_set_callback(subreq
, cli_session_setup_creds_done_spnego
,
1464 if (smbXcli_conn_protocol(cli
->conn
) < PROTOCOL_LANMAN1
) {
1466 * SessionSetupAndX was introduced by LANMAN 1.0. So we skip
1467 * this step against older servers.
1469 tevent_req_done(req
);
1470 return tevent_req_post(req
, ev
);
1473 if (cli_credentials_is_anonymous(creds
)) {
1475 * Do an anonymous session setup
1477 goto non_spnego_creds_done
;
1480 if ((sec_mode
& NEGOTIATE_SECURITY_USER_LEVEL
) == 0) {
1482 * Do an anonymous session setup,
1483 * the password is passed via the tree connect.
1485 goto non_spnego_creds_done
;
1488 cli_credentials_get_ntlm_username_domain(creds
, state
,
1491 if (tevent_req_nomem(username
, req
)) {
1492 return tevent_req_post(req
, ev
);
1494 if (tevent_req_nomem(domain
, req
)) {
1495 return tevent_req_post(req
, ev
);
1498 if ((sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
) == 0) {
1499 bool use_unicode
= smbXcli_conn_use_unicode(cli
->conn
);
1500 uint8_t *bytes
= NULL
;
1501 size_t bytes_len
= 0;
1502 const char *pw
= cli_credentials_get_password(creds
);
1508 pw_len
= strlen(pw
) + 1;
1510 if (!lp_client_plaintext_auth()) {
1511 DEBUG(1, ("Server requested PLAINTEXT password but "
1512 "'client plaintext auth = no'\n"));
1513 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1514 return tevent_req_post(req
, ev
);
1517 bytes
= talloc_array(state
, uint8_t, 0);
1518 bytes
= trans2_bytes_push_str(bytes
, use_unicode
,
1519 pw
, pw_len
, &bytes_len
);
1520 if (tevent_req_nomem(bytes
, req
)) {
1521 return tevent_req_post(req
, ev
);
1526 * CAP_UNICODE, can only be negotiated by NT1.
1528 state
->upassword_blob
= data_blob_const(bytes
,
1531 state
->apassword_blob
= data_blob_const(bytes
,
1535 goto non_spnego_creds_done
;
1538 challenge
= data_blob_const(smb1cli_conn_server_challenge(cli
->conn
), 8);
1540 if (smbXcli_conn_protocol(cli
->conn
) == PROTOCOL_NT1
) {
1541 if (lp_client_ntlmv2_auth() && lp_client_use_spnego()) {
1543 * Don't send an NTLMv2 response without NTLMSSP if we
1544 * want to use spnego support.
1546 DEBUG(1, ("Server does not support EXTENDED_SECURITY "
1547 " but 'client use spnego = yes'"
1548 " and 'client ntlmv2 auth = yes' is set\n"));
1549 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1550 return tevent_req_post(req
, ev
);
1553 if (lp_client_ntlmv2_auth()) {
1554 flags
|= CLI_CRED_NTLMv2_AUTH
;
1557 * note that the 'domain' here is a best
1558 * guess - we don't know the server's domain
1559 * at this point. Windows clients also don't
1562 target_info
= NTLMv2_generate_names_blob(state
,
1565 if (tevent_req_nomem(target_info
.data
, req
)) {
1566 return tevent_req_post(req
, ev
);
1569 flags
|= CLI_CRED_NTLM_AUTH
;
1570 if (lp_client_lanman_auth()) {
1571 flags
|= CLI_CRED_LANMAN_AUTH
;
1575 if (!lp_client_lanman_auth()) {
1576 DEBUG(1, ("Server requested user level LM password but "
1577 "'client lanman auth = no' is set.\n"));
1578 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1579 return tevent_req_post(req
, ev
);
1582 flags
|= CLI_CRED_LANMAN_AUTH
;
1585 status
= cli_credentials_get_ntlm_response(creds
, state
, &flags
,
1588 &state
->apassword_blob
,
1589 &state
->upassword_blob
,
1590 &state
->lm_session_key
,
1591 &state
->session_key
);
1592 if (tevent_req_nterror(req
, status
)) {
1593 return tevent_req_post(req
, ev
);
1596 non_spnego_creds_done
:
1598 in_buf_size
= CLI_BUFFER_SIZE
;
1599 in_mpx_max
= smbXcli_conn_max_requests(cli
->conn
);
1600 in_vc_num
= cli_state_get_vc_num(cli
);
1601 in_sess_key
= smb1cli_conn_server_session_key(cli
->conn
);
1602 in_native_os
= "Unix";
1603 in_native_lm
= "Samba";
1605 if (smbXcli_conn_protocol(cli
->conn
) == PROTOCOL_NT1
) {
1606 uint32_t in_capabilities
= 0;
1608 in_capabilities
= cli_session_setup_capabilities(cli
, 0);
1611 * For now we keep the same values as before,
1612 * we may remove these in a separate commit later.
1616 subreq
= smb1cli_session_setup_nt1_send(state
, ev
,
1627 state
->apassword_blob
,
1628 state
->upassword_blob
,
1632 if (tevent_req_nomem(subreq
, req
)) {
1633 return tevent_req_post(req
, ev
);
1635 tevent_req_set_callback(subreq
, cli_session_setup_creds_done_nt1
,
1641 * For now we keep the same values as before,
1642 * we may remove these in a separate commit later.
1647 subreq
= smb1cli_session_setup_lm21_send(state
, ev
,
1658 state
->apassword_blob
,
1661 if (tevent_req_nomem(subreq
, req
)) {
1662 return tevent_req_post(req
, ev
);
1664 tevent_req_set_callback(subreq
, cli_session_setup_creds_done_lm21
,
1669 static void cli_session_setup_creds_done_spnego(struct tevent_req
*subreq
)
1671 struct tevent_req
*req
= tevent_req_callback_data(
1672 subreq
, struct tevent_req
);
1675 status
= cli_session_setup_spnego_recv(subreq
);
1676 TALLOC_FREE(subreq
);
1677 if (!ADS_ERR_OK(status
)) {
1678 DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status
)));
1679 tevent_req_nterror(req
, ads_ntstatus(status
));
1682 tevent_req_done(req
);
1685 static void cli_session_setup_creds_done_nt1(struct tevent_req
*subreq
)
1687 struct tevent_req
*req
= tevent_req_callback_data(
1688 subreq
, struct tevent_req
);
1689 struct cli_session_setup_creds_state
*state
= tevent_req_data(
1690 req
, struct cli_session_setup_creds_state
);
1691 struct cli_state
*cli
= state
->cli
;
1693 struct iovec
*recv_iov
= NULL
;
1694 const uint8_t *inbuf
= NULL
;
1697 status
= smb1cli_session_setup_nt1_recv(subreq
, state
,
1700 &state
->out_native_os
,
1701 &state
->out_native_lm
,
1702 &state
->out_primary_domain
);
1703 TALLOC_FREE(subreq
);
1704 if (!NT_STATUS_IS_OK(status
)) {
1705 DEBUG(3, ("NT1 login failed: %s\n", nt_errstr(status
)));
1706 tevent_req_nterror(req
, status
);
1710 status
= cli_state_update_after_sesssetup(state
->cli
,
1711 state
->out_native_os
,
1712 state
->out_native_lm
,
1713 state
->out_primary_domain
);
1714 if (tevent_req_nterror(req
, status
)) {
1718 ok
= smb1cli_conn_activate_signing(cli
->conn
,
1720 state
->upassword_blob
);
1722 ok
= smb1cli_conn_check_signing(cli
->conn
, inbuf
, 1);
1724 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1729 if (state
->session_key
.data
) {
1730 struct smbXcli_session
*session
= cli
->smb1
.session
;
1732 status
= smb1cli_session_set_session_key(session
,
1733 state
->session_key
);
1734 if (tevent_req_nterror(req
, status
)) {
1739 tevent_req_done(req
);
1742 static void cli_session_setup_creds_done_lm21(struct tevent_req
*subreq
)
1744 struct tevent_req
*req
= tevent_req_callback_data(
1745 subreq
, struct tevent_req
);
1746 struct cli_session_setup_creds_state
*state
= tevent_req_data(
1747 req
, struct cli_session_setup_creds_state
);
1750 status
= smb1cli_session_setup_lm21_recv(subreq
, state
,
1751 &state
->out_native_os
,
1752 &state
->out_native_lm
);
1753 TALLOC_FREE(subreq
);
1754 if (!NT_STATUS_IS_OK(status
)) {
1755 DEBUG(3, ("LM21 login failed: %s\n", nt_errstr(status
)));
1756 tevent_req_nterror(req
, status
);
1760 status
= cli_state_update_after_sesssetup(state
->cli
,
1761 state
->out_native_os
,
1762 state
->out_native_lm
,
1764 if (tevent_req_nterror(req
, status
)) {
1768 tevent_req_done(req
);
1771 NTSTATUS
cli_session_setup_creds_recv(struct tevent_req
*req
)
1773 return tevent_req_simple_recv_ntstatus(req
);
1776 NTSTATUS
cli_session_setup_creds(struct cli_state
*cli
,
1777 struct cli_credentials
*creds
)
1779 struct tevent_context
*ev
;
1780 struct tevent_req
*req
;
1781 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
1783 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
1784 return NT_STATUS_INVALID_PARAMETER
;
1786 ev
= samba_tevent_context_init(talloc_tos());
1790 req
= cli_session_setup_creds_send(ev
, ev
, cli
, creds
);
1794 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
1797 status
= cli_session_setup_creds_recv(req
);
1803 NTSTATUS
cli_session_setup_anon(struct cli_state
*cli
)
1805 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
1806 struct cli_credentials
*creds
= NULL
;
1808 creds
= cli_credentials_init_anon(cli
);
1809 if (creds
== NULL
) {
1810 return NT_STATUS_NO_MEMORY
;
1813 status
= cli_session_setup_creds(cli
, creds
);
1815 if (!NT_STATUS_IS_OK(status
)) {
1819 return NT_STATUS_OK
;
1822 /****************************************************************************
1824 *****************************************************************************/
1826 struct cli_ulogoff_state
{
1827 struct cli_state
*cli
;
1831 static void cli_ulogoff_done(struct tevent_req
*subreq
);
1833 static struct tevent_req
*cli_ulogoff_send(TALLOC_CTX
*mem_ctx
,
1834 struct tevent_context
*ev
,
1835 struct cli_state
*cli
)
1837 struct tevent_req
*req
, *subreq
;
1838 struct cli_ulogoff_state
*state
;
1840 req
= tevent_req_create(mem_ctx
, &state
, struct cli_ulogoff_state
);
1846 SCVAL(state
->vwv
+0, 0, 0xFF);
1847 SCVAL(state
->vwv
+1, 0, 0);
1848 SSVAL(state
->vwv
+2, 0, 0);
1850 subreq
= cli_smb_send(state
, ev
, cli
, SMBulogoffX
, 0, 0, 2, state
->vwv
,
1852 if (tevent_req_nomem(subreq
, req
)) {
1853 return tevent_req_post(req
, ev
);
1855 tevent_req_set_callback(subreq
, cli_ulogoff_done
, req
);
1859 static void cli_ulogoff_done(struct tevent_req
*subreq
)
1861 struct tevent_req
*req
= tevent_req_callback_data(
1862 subreq
, struct tevent_req
);
1863 struct cli_ulogoff_state
*state
= tevent_req_data(
1864 req
, struct cli_ulogoff_state
);
1867 status
= cli_smb_recv(subreq
, NULL
, NULL
, 0, NULL
, NULL
, NULL
, NULL
);
1868 if (!NT_STATUS_IS_OK(status
)) {
1869 tevent_req_nterror(req
, status
);
1872 cli_state_set_uid(state
->cli
, UID_FIELD_INVALID
);
1873 tevent_req_done(req
);
1876 static NTSTATUS
cli_ulogoff_recv(struct tevent_req
*req
)
1878 return tevent_req_simple_recv_ntstatus(req
);
1881 NTSTATUS
cli_ulogoff(struct cli_state
*cli
)
1883 struct tevent_context
*ev
;
1884 struct tevent_req
*req
;
1885 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
1887 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
1888 status
= smb2cli_logoff(cli
->conn
,
1891 if (!NT_STATUS_IS_OK(status
)) {
1894 smb2cli_session_set_id_and_flags(cli
->smb2
.session
,
1896 return NT_STATUS_OK
;
1899 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
1900 return NT_STATUS_INVALID_PARAMETER
;
1902 ev
= samba_tevent_context_init(talloc_tos());
1906 req
= cli_ulogoff_send(ev
, ev
, cli
);
1910 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
1913 status
= cli_ulogoff_recv(req
);
1919 /****************************************************************************
1921 ****************************************************************************/
1923 struct cli_tcon_andx_state
{
1924 struct cli_state
*cli
;
1929 static void cli_tcon_andx_done(struct tevent_req
*subreq
);
1931 struct tevent_req
*cli_tcon_andx_create(TALLOC_CTX
*mem_ctx
,
1932 struct tevent_context
*ev
,
1933 struct cli_state
*cli
,
1934 const char *share
, const char *dev
,
1935 const char *pass
, int passlen
,
1936 struct tevent_req
**psmbreq
)
1938 struct tevent_req
*req
, *subreq
;
1939 struct cli_tcon_andx_state
*state
;
1944 uint16_t sec_mode
= smb1cli_conn_server_security_mode(cli
->conn
);
1945 uint16_t tcon_flags
= 0;
1949 req
= tevent_req_create(mem_ctx
, &state
, struct cli_tcon_andx_state
);
1956 TALLOC_FREE(cli
->smb1
.tcon
);
1957 cli
->smb1
.tcon
= smbXcli_tcon_create(cli
);
1958 if (tevent_req_nomem(cli
->smb1
.tcon
, req
)) {
1959 return tevent_req_post(req
, ev
);
1961 smb1cli_tcon_set_id(cli
->smb1
.tcon
, UINT16_MAX
);
1963 cli
->share
= talloc_strdup(cli
, share
);
1968 /* in user level security don't send a password now */
1969 if (sec_mode
& NEGOTIATE_SECURITY_USER_LEVEL
) {
1972 } else if (pass
== NULL
) {
1973 DEBUG(1, ("Server not using user level security and no "
1974 "password supplied.\n"));
1978 if ((sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
) &&
1979 *pass
&& passlen
!= 24) {
1980 if (!lp_client_lanman_auth()) {
1981 DEBUG(1, ("Server requested LANMAN password "
1982 "(share-level security) but "
1983 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
1988 * Non-encrypted passwords - convert to DOS codepage before
1991 SMBencrypt(pass
, smb1cli_conn_server_challenge(cli
->conn
), p24
);
1993 pass
= (const char *)p24
;
1995 if((sec_mode
& (NEGOTIATE_SECURITY_USER_LEVEL
1996 |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
))
2000 if (!lp_client_plaintext_auth() && (*pass
)) {
2001 DEBUG(1, ("Server requested PLAINTEXT "
2003 "'client plaintext auth = no' or 'client ntlmv2 auth = yes'\n"));
2008 * Non-encrypted passwords - convert to DOS codepage
2011 tmp_pass
= talloc_array(talloc_tos(), uint8_t, 0);
2012 if (tevent_req_nomem(tmp_pass
, req
)) {
2013 return tevent_req_post(req
, ev
);
2015 tmp_pass
= trans2_bytes_push_str(tmp_pass
,
2016 false, /* always DOS */
2020 if (tevent_req_nomem(tmp_pass
, req
)) {
2021 return tevent_req_post(req
, ev
);
2023 pass
= (const char *)tmp_pass
;
2024 passlen
= talloc_get_size(tmp_pass
);
2028 tcon_flags
|= TCONX_FLAG_EXTENDED_RESPONSE
;
2029 tcon_flags
|= TCONX_FLAG_EXTENDED_SIGNATURES
;
2031 SCVAL(vwv
+0, 0, 0xFF);
2034 SSVAL(vwv
+2, 0, tcon_flags
);
2035 SSVAL(vwv
+3, 0, passlen
);
2037 if (passlen
&& pass
) {
2038 bytes
= (uint8_t *)talloc_memdup(state
, pass
, passlen
);
2040 bytes
= talloc_array(state
, uint8_t, 0);
2046 tmp
= talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
2047 smbXcli_conn_remote_name(cli
->conn
), share
);
2052 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), tmp
, strlen(tmp
)+1,
2057 * Add the devicetype
2059 tmp
= talloc_strdup_upper(talloc_tos(), dev
);
2064 bytes
= smb_bytes_push_str(bytes
, false, tmp
, strlen(tmp
)+1, NULL
);
2067 if (bytes
== NULL
) {
2072 state
->bytes
.iov_base
= (void *)bytes
;
2073 state
->bytes
.iov_len
= talloc_get_size(bytes
);
2075 subreq
= cli_smb_req_create(state
, ev
, cli
, SMBtconX
, 0, 0, 4, vwv
,
2077 if (subreq
== NULL
) {
2081 tevent_req_set_callback(subreq
, cli_tcon_andx_done
, req
);
2086 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
2087 return tevent_req_post(req
, ev
);
2090 struct tevent_req
*cli_tcon_andx_send(TALLOC_CTX
*mem_ctx
,
2091 struct tevent_context
*ev
,
2092 struct cli_state
*cli
,
2093 const char *share
, const char *dev
,
2094 const char *pass
, int passlen
)
2096 struct tevent_req
*req
, *subreq
;
2099 req
= cli_tcon_andx_create(mem_ctx
, ev
, cli
, share
, dev
, pass
, passlen
,
2104 if (subreq
== NULL
) {
2107 status
= smb1cli_req_chain_submit(&subreq
, 1);
2108 if (!NT_STATUS_IS_OK(status
)) {
2109 tevent_req_nterror(req
, status
);
2110 return tevent_req_post(req
, ev
);
2115 static void cli_tcon_andx_done(struct tevent_req
*subreq
)
2117 struct tevent_req
*req
= tevent_req_callback_data(
2118 subreq
, struct tevent_req
);
2119 struct cli_tcon_andx_state
*state
= tevent_req_data(
2120 req
, struct cli_tcon_andx_state
);
2121 struct cli_state
*cli
= state
->cli
;
2129 uint16_t optional_support
= 0;
2131 status
= cli_smb_recv(subreq
, state
, &in
, 0, &wct
, &vwv
,
2132 &num_bytes
, &bytes
);
2133 TALLOC_FREE(subreq
);
2134 if (!NT_STATUS_IS_OK(status
)) {
2135 tevent_req_nterror(req
, status
);
2139 inhdr
= in
+ NBT_HDR_SIZE
;
2142 if (clistr_pull_talloc(cli
,
2143 (const char *)inhdr
,
2144 SVAL(inhdr
, HDR_FLG2
),
2148 STR_TERMINATE
|STR_ASCII
) == -1) {
2149 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
2153 cli
->dev
= talloc_strdup(cli
, "");
2154 if (cli
->dev
== NULL
) {
2155 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
2160 if ((smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_NT1
) && (num_bytes
== 3)) {
2161 /* almost certainly win95 - enable bug fixes */
2166 * Make sure that we have the optional support 16-bit field. WCT > 2.
2167 * Avoids issues when connecting to Win9x boxes sharing files
2170 if ((wct
> 2) && (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_LANMAN2
)) {
2171 optional_support
= SVAL(vwv
+2, 0);
2174 if (optional_support
& SMB_EXTENDED_SIGNATURES
) {
2175 smb1cli_session_protect_session_key(cli
->smb1
.session
);
2178 smb1cli_tcon_set_values(state
->cli
->smb1
.tcon
,
2179 SVAL(inhdr
, HDR_TID
),
2181 0, /* maximal_access */
2182 0, /* guest_maximal_access */
2184 NULL
); /* fs_type */
2186 tevent_req_done(req
);
2189 NTSTATUS
cli_tcon_andx_recv(struct tevent_req
*req
)
2191 return tevent_req_simple_recv_ntstatus(req
);
2194 NTSTATUS
cli_tcon_andx(struct cli_state
*cli
, const char *share
,
2195 const char *dev
, const char *pass
, int passlen
)
2197 TALLOC_CTX
*frame
= talloc_stackframe();
2198 struct tevent_context
*ev
;
2199 struct tevent_req
*req
;
2200 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2202 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
2204 * Can't use sync call while an async call is in flight
2206 status
= NT_STATUS_INVALID_PARAMETER
;
2210 ev
= samba_tevent_context_init(frame
);
2215 req
= cli_tcon_andx_send(frame
, ev
, cli
, share
, dev
, pass
, passlen
);
2220 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2224 status
= cli_tcon_andx_recv(req
);
2230 struct cli_tree_connect_state
{
2231 struct cli_state
*cli
;
2234 static struct tevent_req
*cli_raw_tcon_send(
2235 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
2236 const char *service
, const char *pass
, const char *dev
);
2237 static NTSTATUS
cli_raw_tcon_recv(struct tevent_req
*req
,
2238 uint16_t *max_xmit
, uint16_t *tid
);
2240 static void cli_tree_connect_smb2_done(struct tevent_req
*subreq
);
2241 static void cli_tree_connect_andx_done(struct tevent_req
*subreq
);
2242 static void cli_tree_connect_raw_done(struct tevent_req
*subreq
);
2244 static struct tevent_req
*cli_tree_connect_send(
2245 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
2246 const char *share
, const char *dev
, const char *pass
)
2248 struct tevent_req
*req
, *subreq
;
2249 struct cli_tree_connect_state
*state
;
2255 passlen
= strlen(pass
) + 1;
2257 req
= tevent_req_create(mem_ctx
, &state
,
2258 struct cli_tree_connect_state
);
2264 cli
->share
= talloc_strdup(cli
, share
);
2265 if (tevent_req_nomem(cli
->share
, req
)) {
2266 return tevent_req_post(req
, ev
);
2269 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
2272 TALLOC_FREE(cli
->smb2
.tcon
);
2273 cli
->smb2
.tcon
= smbXcli_tcon_create(cli
);
2274 if (tevent_req_nomem(cli
->smb2
.tcon
, req
)) {
2275 return tevent_req_post(req
, ev
);
2278 unc
= talloc_asprintf(state
, "\\\\%s\\%s",
2279 smbXcli_conn_remote_name(cli
->conn
),
2281 if (tevent_req_nomem(unc
, req
)) {
2282 return tevent_req_post(req
, ev
);
2285 subreq
= smb2cli_tcon_send(state
, ev
, cli
->conn
, cli
->timeout
,
2286 cli
->smb2
.session
, cli
->smb2
.tcon
,
2289 if (tevent_req_nomem(subreq
, req
)) {
2290 return tevent_req_post(req
, ev
);
2292 tevent_req_set_callback(subreq
, cli_tree_connect_smb2_done
,
2297 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_LANMAN1
) {
2298 subreq
= cli_tcon_andx_send(state
, ev
, cli
, share
, dev
,
2300 if (tevent_req_nomem(subreq
, req
)) {
2301 return tevent_req_post(req
, ev
);
2303 tevent_req_set_callback(subreq
, cli_tree_connect_andx_done
,
2308 subreq
= cli_raw_tcon_send(state
, ev
, cli
, share
, pass
, dev
);
2309 if (tevent_req_nomem(subreq
, req
)) {
2310 return tevent_req_post(req
, ev
);
2312 tevent_req_set_callback(subreq
, cli_tree_connect_raw_done
, req
);
2317 static void cli_tree_connect_smb2_done(struct tevent_req
*subreq
)
2319 tevent_req_simple_finish_ntstatus(
2320 subreq
, smb2cli_tcon_recv(subreq
));
2323 static void cli_tree_connect_andx_done(struct tevent_req
*subreq
)
2325 tevent_req_simple_finish_ntstatus(
2326 subreq
, cli_tcon_andx_recv(subreq
));
2329 static void cli_tree_connect_raw_done(struct tevent_req
*subreq
)
2331 struct tevent_req
*req
= tevent_req_callback_data(
2332 subreq
, struct tevent_req
);
2333 struct cli_tree_connect_state
*state
= tevent_req_data(
2334 req
, struct cli_tree_connect_state
);
2336 uint16_t max_xmit
= 0;
2339 status
= cli_raw_tcon_recv(subreq
, &max_xmit
, &tid
);
2340 if (tevent_req_nterror(req
, status
)) {
2344 smb1cli_tcon_set_values(state
->cli
->smb1
.tcon
,
2346 0, /* optional_support */
2347 0, /* maximal_access */
2348 0, /* guest_maximal_access */
2350 NULL
); /* fs_type */
2352 tevent_req_done(req
);
2355 static NTSTATUS
cli_tree_connect_recv(struct tevent_req
*req
)
2357 return tevent_req_simple_recv_ntstatus(req
);
2360 NTSTATUS
cli_tree_connect(struct cli_state
*cli
, const char *share
,
2361 const char *dev
, const char *pass
)
2363 struct tevent_context
*ev
;
2364 struct tevent_req
*req
;
2365 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2367 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
2368 return NT_STATUS_INVALID_PARAMETER
;
2370 ev
= samba_tevent_context_init(talloc_tos());
2374 req
= cli_tree_connect_send(ev
, ev
, cli
, share
, dev
, pass
);
2378 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2381 status
= cli_tree_connect_recv(req
);
2387 NTSTATUS
cli_tree_connect_creds(struct cli_state
*cli
,
2388 const char *share
, const char *dev
,
2389 struct cli_credentials
*creds
)
2391 const char *pw
= NULL
;
2393 if (creds
!= NULL
) {
2394 pw
= cli_credentials_get_password(creds
);
2397 return cli_tree_connect(cli
, share
, dev
, pw
);
2400 /****************************************************************************
2401 Send a tree disconnect.
2402 ****************************************************************************/
2404 struct cli_tdis_state
{
2405 struct cli_state
*cli
;
2408 static void cli_tdis_done(struct tevent_req
*subreq
);
2410 static struct tevent_req
*cli_tdis_send(TALLOC_CTX
*mem_ctx
,
2411 struct tevent_context
*ev
,
2412 struct cli_state
*cli
)
2414 struct tevent_req
*req
, *subreq
;
2415 struct cli_tdis_state
*state
;
2417 req
= tevent_req_create(mem_ctx
, &state
, struct cli_tdis_state
);
2423 subreq
= cli_smb_send(state
, ev
, cli
, SMBtdis
, 0, 0, 0, NULL
, 0, NULL
);
2424 if (tevent_req_nomem(subreq
, req
)) {
2425 return tevent_req_post(req
, ev
);
2427 tevent_req_set_callback(subreq
, cli_tdis_done
, req
);
2431 static void cli_tdis_done(struct tevent_req
*subreq
)
2433 struct tevent_req
*req
= tevent_req_callback_data(
2434 subreq
, struct tevent_req
);
2435 struct cli_tdis_state
*state
= tevent_req_data(
2436 req
, struct cli_tdis_state
);
2439 status
= cli_smb_recv(subreq
, NULL
, NULL
, 0, NULL
, NULL
, NULL
, NULL
);
2440 TALLOC_FREE(subreq
);
2441 if (!NT_STATUS_IS_OK(status
)) {
2442 tevent_req_nterror(req
, status
);
2445 TALLOC_FREE(state
->cli
->smb1
.tcon
);
2446 tevent_req_done(req
);
2449 static NTSTATUS
cli_tdis_recv(struct tevent_req
*req
)
2451 return tevent_req_simple_recv_ntstatus(req
);
2454 NTSTATUS
cli_tdis(struct cli_state
*cli
)
2456 struct tevent_context
*ev
;
2457 struct tevent_req
*req
;
2458 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2460 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
2461 status
= smb2cli_tdis(cli
->conn
,
2465 if (NT_STATUS_IS_OK(status
)) {
2466 TALLOC_FREE(cli
->smb2
.tcon
);
2471 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
2472 return NT_STATUS_INVALID_PARAMETER
;
2474 ev
= samba_tevent_context_init(talloc_tos());
2478 req
= cli_tdis_send(ev
, ev
, cli
);
2482 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2485 status
= cli_tdis_recv(req
);
2491 struct cli_connect_sock_state
{
2492 const char **called_names
;
2493 const char **calling_names
;
2499 static void cli_connect_sock_done(struct tevent_req
*subreq
);
2502 * Async only if we don't have to look up the name, i.e. "pss" is set with a
2506 static struct tevent_req
*cli_connect_sock_send(
2507 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
2508 const char *host
, int name_type
, const struct sockaddr_storage
*pss
,
2509 const char *myname
, uint16_t port
)
2511 struct tevent_req
*req
, *subreq
;
2512 struct cli_connect_sock_state
*state
;
2513 struct sockaddr_storage
*addrs
;
2514 unsigned i
, num_addrs
;
2517 req
= tevent_req_create(mem_ctx
, &state
,
2518 struct cli_connect_sock_state
);
2523 if ((pss
== NULL
) || is_zero_addr(pss
)) {
2526 * Here we cheat. resolve_name_list is not async at all. So
2527 * this call will only be really async if the name lookup has
2528 * been done externally.
2531 status
= resolve_name_list(state
, host
, name_type
,
2532 &addrs
, &num_addrs
);
2533 if (!NT_STATUS_IS_OK(status
)) {
2534 tevent_req_nterror(req
, status
);
2535 return tevent_req_post(req
, ev
);
2538 addrs
= talloc_array(state
, struct sockaddr_storage
, 1);
2539 if (tevent_req_nomem(addrs
, req
)) {
2540 return tevent_req_post(req
, ev
);
2546 state
->called_names
= talloc_array(state
, const char *, num_addrs
);
2547 if (tevent_req_nomem(state
->called_names
, req
)) {
2548 return tevent_req_post(req
, ev
);
2550 state
->called_types
= talloc_array(state
, int, num_addrs
);
2551 if (tevent_req_nomem(state
->called_types
, req
)) {
2552 return tevent_req_post(req
, ev
);
2554 state
->calling_names
= talloc_array(state
, const char *, num_addrs
);
2555 if (tevent_req_nomem(state
->calling_names
, req
)) {
2556 return tevent_req_post(req
, ev
);
2558 for (i
=0; i
<num_addrs
; i
++) {
2559 state
->called_names
[i
] = host
;
2560 state
->called_types
[i
] = name_type
;
2561 state
->calling_names
[i
] = myname
;
2564 subreq
= smbsock_any_connect_send(
2565 state
, ev
, addrs
, state
->called_names
, state
->called_types
,
2566 state
->calling_names
, NULL
, num_addrs
, port
);
2567 if (tevent_req_nomem(subreq
, req
)) {
2568 return tevent_req_post(req
, ev
);
2570 tevent_req_set_callback(subreq
, cli_connect_sock_done
, req
);
2574 static void cli_connect_sock_done(struct tevent_req
*subreq
)
2576 struct tevent_req
*req
= tevent_req_callback_data(
2577 subreq
, struct tevent_req
);
2578 struct cli_connect_sock_state
*state
= tevent_req_data(
2579 req
, struct cli_connect_sock_state
);
2582 status
= smbsock_any_connect_recv(subreq
, &state
->fd
, NULL
,
2584 TALLOC_FREE(subreq
);
2585 if (tevent_req_nterror(req
, status
)) {
2588 set_socket_options(state
->fd
, lp_socket_options());
2589 tevent_req_done(req
);
2592 static NTSTATUS
cli_connect_sock_recv(struct tevent_req
*req
,
2593 int *pfd
, uint16_t *pport
)
2595 struct cli_connect_sock_state
*state
= tevent_req_data(
2596 req
, struct cli_connect_sock_state
);
2599 if (tevent_req_is_nterror(req
, &status
)) {
2603 *pport
= state
->port
;
2604 return NT_STATUS_OK
;
2607 struct cli_connect_nb_state
{
2608 const char *desthost
;
2611 struct cli_state
*cli
;
2614 static void cli_connect_nb_done(struct tevent_req
*subreq
);
2616 static struct tevent_req
*cli_connect_nb_send(
2617 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
2618 const char *host
, const struct sockaddr_storage
*dest_ss
,
2619 uint16_t port
, int name_type
, const char *myname
,
2620 int signing_state
, int flags
)
2622 struct tevent_req
*req
, *subreq
;
2623 struct cli_connect_nb_state
*state
;
2625 req
= tevent_req_create(mem_ctx
, &state
, struct cli_connect_nb_state
);
2629 state
->signing_state
= signing_state
;
2630 state
->flags
= flags
;
2633 char *p
= strchr(host
, '#');
2636 name_type
= strtol(p
+1, NULL
, 16);
2637 host
= talloc_strndup(state
, host
, p
- host
);
2638 if (tevent_req_nomem(host
, req
)) {
2639 return tevent_req_post(req
, ev
);
2643 state
->desthost
= host
;
2644 } else if (dest_ss
!= NULL
) {
2645 state
->desthost
= print_canonical_sockaddr(state
, dest_ss
);
2646 if (tevent_req_nomem(state
->desthost
, req
)) {
2647 return tevent_req_post(req
, ev
);
2650 /* No host or dest_ss given. Error out. */
2651 tevent_req_error(req
, EINVAL
);
2652 return tevent_req_post(req
, ev
);
2655 subreq
= cli_connect_sock_send(state
, ev
, host
, name_type
, dest_ss
,
2657 if (tevent_req_nomem(subreq
, req
)) {
2658 return tevent_req_post(req
, ev
);
2660 tevent_req_set_callback(subreq
, cli_connect_nb_done
, req
);
2664 static void cli_connect_nb_done(struct tevent_req
*subreq
)
2666 struct tevent_req
*req
= tevent_req_callback_data(
2667 subreq
, struct tevent_req
);
2668 struct cli_connect_nb_state
*state
= tevent_req_data(
2669 req
, struct cli_connect_nb_state
);
2674 status
= cli_connect_sock_recv(subreq
, &fd
, &port
);
2675 TALLOC_FREE(subreq
);
2676 if (tevent_req_nterror(req
, status
)) {
2680 state
->cli
= cli_state_create(state
, fd
, state
->desthost
,
2681 state
->signing_state
, state
->flags
);
2682 if (tevent_req_nomem(state
->cli
, req
)) {
2686 tevent_req_done(req
);
2689 static NTSTATUS
cli_connect_nb_recv(struct tevent_req
*req
,
2690 struct cli_state
**pcli
)
2692 struct cli_connect_nb_state
*state
= tevent_req_data(
2693 req
, struct cli_connect_nb_state
);
2696 if (tevent_req_is_nterror(req
, &status
)) {
2699 *pcli
= talloc_move(NULL
, &state
->cli
);
2700 return NT_STATUS_OK
;
2703 NTSTATUS
cli_connect_nb(const char *host
, const struct sockaddr_storage
*dest_ss
,
2704 uint16_t port
, int name_type
, const char *myname
,
2705 int signing_state
, int flags
, struct cli_state
**pcli
)
2707 struct tevent_context
*ev
;
2708 struct tevent_req
*req
;
2709 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2711 ev
= samba_tevent_context_init(talloc_tos());
2715 req
= cli_connect_nb_send(ev
, ev
, host
, dest_ss
, port
, name_type
,
2716 myname
, signing_state
, flags
);
2720 if (!tevent_req_set_endtime(req
, ev
, timeval_current_ofs(20, 0))) {
2723 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2726 status
= cli_connect_nb_recv(req
, pcli
);
2732 struct cli_start_connection_state
{
2733 struct tevent_context
*ev
;
2734 struct cli_state
*cli
;
2739 static void cli_start_connection_connected(struct tevent_req
*subreq
);
2740 static void cli_start_connection_done(struct tevent_req
*subreq
);
2743 establishes a connection to after the negprot.
2744 @param output_cli A fully initialised cli structure, non-null only on success
2745 @param dest_host The netbios name of the remote host
2746 @param dest_ss (optional) The the destination IP, NULL for name based lookup
2747 @param port (optional) The destination port (0 for default)
2750 static struct tevent_req
*cli_start_connection_send(
2751 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
2752 const char *my_name
, const char *dest_host
,
2753 const struct sockaddr_storage
*dest_ss
, int port
,
2754 int signing_state
, int flags
)
2756 struct tevent_req
*req
, *subreq
;
2757 struct cli_start_connection_state
*state
;
2759 req
= tevent_req_create(mem_ctx
, &state
,
2760 struct cli_start_connection_state
);
2766 if (signing_state
== SMB_SIGNING_IPC_DEFAULT
) {
2767 state
->min_protocol
= lp_client_ipc_min_protocol();
2768 state
->max_protocol
= lp_client_ipc_max_protocol();
2770 state
->min_protocol
= lp_client_min_protocol();
2771 state
->max_protocol
= lp_client_max_protocol();
2774 if (flags
& CLI_FULL_CONNECTION_FORCE_SMB1
) {
2775 state
->max_protocol
= MIN(state
->max_protocol
, PROTOCOL_NT1
);
2778 if (flags
& CLI_FULL_CONNECTION_DISABLE_SMB1
) {
2779 state
->min_protocol
= MAX(state
->max_protocol
, PROTOCOL_SMB2_02
);
2780 state
->max_protocol
= MAX(state
->max_protocol
, PROTOCOL_LATEST
);
2783 subreq
= cli_connect_nb_send(state
, ev
, dest_host
, dest_ss
, port
,
2784 0x20, my_name
, signing_state
, flags
);
2785 if (tevent_req_nomem(subreq
, req
)) {
2786 return tevent_req_post(req
, ev
);
2788 tevent_req_set_callback(subreq
, cli_start_connection_connected
, req
);
2792 static void cli_start_connection_connected(struct tevent_req
*subreq
)
2794 struct tevent_req
*req
= tevent_req_callback_data(
2795 subreq
, struct tevent_req
);
2796 struct cli_start_connection_state
*state
= tevent_req_data(
2797 req
, struct cli_start_connection_state
);
2800 status
= cli_connect_nb_recv(subreq
, &state
->cli
);
2801 TALLOC_FREE(subreq
);
2802 if (tevent_req_nterror(req
, status
)) {
2806 subreq
= smbXcli_negprot_send(state
, state
->ev
, state
->cli
->conn
,
2807 state
->cli
->timeout
,
2808 state
->min_protocol
,
2809 state
->max_protocol
,
2810 WINDOWS_CLIENT_PURE_SMB2_NEGPROT_INITIAL_CREDIT_ASK
);
2811 if (tevent_req_nomem(subreq
, req
)) {
2814 tevent_req_set_callback(subreq
, cli_start_connection_done
, req
);
2817 static void cli_start_connection_done(struct tevent_req
*subreq
)
2819 struct tevent_req
*req
= tevent_req_callback_data(
2820 subreq
, struct tevent_req
);
2821 struct cli_start_connection_state
*state
= tevent_req_data(
2822 req
, struct cli_start_connection_state
);
2825 status
= smbXcli_negprot_recv(subreq
);
2826 TALLOC_FREE(subreq
);
2827 if (tevent_req_nterror(req
, status
)) {
2831 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
2832 /* Ensure we ask for some initial credits. */
2833 smb2cli_conn_set_max_credits(state
->cli
->conn
,
2834 DEFAULT_SMB2_MAX_CREDITS
);
2837 tevent_req_done(req
);
2840 static NTSTATUS
cli_start_connection_recv(struct tevent_req
*req
,
2841 struct cli_state
**output_cli
)
2843 struct cli_start_connection_state
*state
= tevent_req_data(
2844 req
, struct cli_start_connection_state
);
2847 if (tevent_req_is_nterror(req
, &status
)) {
2850 *output_cli
= state
->cli
;
2852 return NT_STATUS_OK
;
2855 NTSTATUS
cli_start_connection(struct cli_state
**output_cli
,
2856 const char *my_name
,
2857 const char *dest_host
,
2858 const struct sockaddr_storage
*dest_ss
, int port
,
2859 int signing_state
, int flags
)
2861 struct tevent_context
*ev
;
2862 struct tevent_req
*req
;
2863 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2865 ev
= samba_tevent_context_init(talloc_tos());
2869 req
= cli_start_connection_send(ev
, ev
, my_name
, dest_host
, dest_ss
,
2870 port
, signing_state
, flags
);
2874 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2877 status
= cli_start_connection_recv(req
, output_cli
);
2883 struct cli_smb1_setup_encryption_blob_state
{
2888 uint16_t enc_ctx_id
;
2891 static void cli_smb1_setup_encryption_blob_done(struct tevent_req
*subreq
);
2893 static struct tevent_req
*cli_smb1_setup_encryption_blob_send(TALLOC_CTX
*mem_ctx
,
2894 struct tevent_context
*ev
,
2895 struct cli_state
*cli
,
2898 struct tevent_req
*req
= NULL
;
2899 struct cli_smb1_setup_encryption_blob_state
*state
= NULL
;
2900 struct tevent_req
*subreq
= NULL
;
2902 req
= tevent_req_create(mem_ctx
, &state
,
2903 struct cli_smb1_setup_encryption_blob_state
);
2908 if (in
.length
> CLI_BUFFER_SIZE
) {
2909 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER_MIX
);
2910 return tevent_req_post(req
, ev
);
2913 SSVAL(state
->setup
+0, 0, TRANSACT2_SETFSINFO
);
2914 SSVAL(state
->param
, 0, 0);
2915 SSVAL(state
->param
, 2, SMB_REQUEST_TRANSPORT_ENCRYPTION
);
2917 subreq
= smb1cli_trans_send(state
, ev
, cli
->conn
,
2925 NULL
, /* pipe_name */
2931 in
.data
, in
.length
, CLI_BUFFER_SIZE
);
2932 if (tevent_req_nomem(subreq
, req
)) {
2933 return tevent_req_post(req
, ev
);
2935 tevent_req_set_callback(subreq
,
2936 cli_smb1_setup_encryption_blob_done
,
2942 static void cli_smb1_setup_encryption_blob_done(struct tevent_req
*subreq
)
2944 struct tevent_req
*req
=
2945 tevent_req_callback_data(subreq
,
2947 struct cli_smb1_setup_encryption_blob_state
*state
=
2948 tevent_req_data(req
,
2949 struct cli_smb1_setup_encryption_blob_state
);
2950 uint8_t *rparam
=NULL
, *rdata
=NULL
;
2951 uint32_t num_rparam
, num_rdata
;
2954 status
= smb1cli_trans_recv(subreq
, state
,
2955 NULL
, /* recv_flags */
2956 NULL
, 0, NULL
, /* rsetup */
2957 &rparam
, 0, &num_rparam
,
2958 &rdata
, 0, &num_rdata
);
2959 TALLOC_FREE(subreq
);
2960 state
->status
= status
;
2961 if (NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
2962 status
= NT_STATUS_OK
;
2964 if (tevent_req_nterror(req
, status
)) {
2968 if (num_rparam
== 2) {
2969 state
->enc_ctx_id
= SVAL(rparam
, 0);
2971 TALLOC_FREE(rparam
);
2973 state
->out
= data_blob_const(rdata
, num_rdata
);
2975 tevent_req_done(req
);
2978 static NTSTATUS
cli_smb1_setup_encryption_blob_recv(struct tevent_req
*req
,
2979 TALLOC_CTX
*mem_ctx
,
2981 uint16_t *enc_ctx_id
)
2983 struct cli_smb1_setup_encryption_blob_state
*state
=
2984 tevent_req_data(req
,
2985 struct cli_smb1_setup_encryption_blob_state
);
2988 if (tevent_req_is_nterror(req
, &status
)) {
2989 tevent_req_received(req
);
2993 status
= state
->status
;
2996 talloc_steal(mem_ctx
, out
->data
);
2998 *enc_ctx_id
= state
->enc_ctx_id
;
3000 tevent_req_received(req
);
3004 struct cli_smb1_setup_encryption_state
{
3005 struct tevent_context
*ev
;
3006 struct cli_state
*cli
;
3007 struct smb_trans_enc_state
*es
;
3014 static void cli_smb1_setup_encryption_local_next(struct tevent_req
*req
);
3015 static void cli_smb1_setup_encryption_local_done(struct tevent_req
*subreq
);
3016 static void cli_smb1_setup_encryption_remote_next(struct tevent_req
*req
);
3017 static void cli_smb1_setup_encryption_remote_done(struct tevent_req
*subreq
);
3018 static void cli_smb1_setup_encryption_ready(struct tevent_req
*req
);
3020 static struct tevent_req
*cli_smb1_setup_encryption_send(TALLOC_CTX
*mem_ctx
,
3021 struct tevent_context
*ev
,
3022 struct cli_state
*cli
,
3023 struct cli_credentials
*creds
)
3025 struct tevent_req
*req
= NULL
;
3026 struct cli_smb1_setup_encryption_state
*state
= NULL
;
3027 struct auth_generic_state
*ags
= NULL
;
3028 const DATA_BLOB
*b
= NULL
;
3029 bool auth_requested
= false;
3030 const char *target_service
= NULL
;
3031 const char *target_hostname
= NULL
;
3034 req
= tevent_req_create(mem_ctx
, &state
,
3035 struct cli_smb1_setup_encryption_state
);
3042 auth_requested
= cli_credentials_authentication_requested(creds
);
3043 if (!auth_requested
) {
3044 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER_MIX
);
3045 return tevent_req_post(req
, ev
);
3048 target_service
= "cifs";
3049 target_hostname
= smbXcli_conn_remote_name(cli
->conn
);
3051 status
= cli_session_creds_prepare_krb5(cli
, creds
);
3052 if (tevent_req_nterror(req
, status
)) {
3053 return tevent_req_post(req
, ev
);
3056 state
->es
= talloc_zero(state
, struct smb_trans_enc_state
);
3057 if (tevent_req_nomem(state
->es
, req
)) {
3058 return tevent_req_post(req
, ev
);
3061 status
= auth_generic_client_prepare(state
->es
, &ags
);
3062 if (tevent_req_nterror(req
, status
)) {
3063 return tevent_req_post(req
, ev
);
3066 gensec_want_feature(ags
->gensec_security
,
3067 GENSEC_FEATURE_SIGN
);
3068 gensec_want_feature(ags
->gensec_security
,
3069 GENSEC_FEATURE_SEAL
);
3071 status
= auth_generic_set_creds(ags
, creds
);
3072 if (tevent_req_nterror(req
, status
)) {
3073 return tevent_req_post(req
, ev
);
3076 if (target_service
!= NULL
) {
3077 status
= gensec_set_target_service(ags
->gensec_security
,
3079 if (tevent_req_nterror(req
, status
)) {
3080 return tevent_req_post(req
, ev
);
3084 if (target_hostname
!= NULL
) {
3085 status
= gensec_set_target_hostname(ags
->gensec_security
,
3087 if (tevent_req_nterror(req
, status
)) {
3088 return tevent_req_post(req
, ev
);
3092 gensec_set_max_update_size(ags
->gensec_security
,
3095 b
= smbXcli_conn_server_gss_blob(state
->cli
->conn
);
3097 state
->blob_in
= *b
;
3100 status
= auth_generic_client_start(ags
, GENSEC_OID_SPNEGO
);
3101 if (tevent_req_nterror(req
, status
)) {
3102 return tevent_req_post(req
, ev
);
3106 * We only need the gensec_security part from here.
3108 state
->es
->gensec_security
= talloc_move(state
->es
,
3109 &ags
->gensec_security
);
3112 cli_smb1_setup_encryption_local_next(req
);
3113 if (!tevent_req_is_in_progress(req
)) {
3114 return tevent_req_post(req
, ev
);
3120 static void cli_smb1_setup_encryption_local_next(struct tevent_req
*req
)
3122 struct cli_smb1_setup_encryption_state
*state
=
3123 tevent_req_data(req
,
3124 struct cli_smb1_setup_encryption_state
);
3125 struct tevent_req
*subreq
= NULL
;
3127 if (state
->local_ready
) {
3128 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
3132 subreq
= gensec_update_send(state
, state
->ev
,
3133 state
->es
->gensec_security
,
3135 if (tevent_req_nomem(subreq
, req
)) {
3138 tevent_req_set_callback(subreq
, cli_smb1_setup_encryption_local_done
, req
);
3141 static void cli_smb1_setup_encryption_local_done(struct tevent_req
*subreq
)
3143 struct tevent_req
*req
=
3144 tevent_req_callback_data(subreq
,
3146 struct cli_smb1_setup_encryption_state
*state
=
3147 tevent_req_data(req
,
3148 struct cli_smb1_setup_encryption_state
);
3151 status
= gensec_update_recv(subreq
, state
, &state
->blob_out
);
3152 TALLOC_FREE(subreq
);
3153 state
->blob_in
= data_blob_null
;
3154 if (!NT_STATUS_IS_OK(status
) &&
3155 !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
))
3157 tevent_req_nterror(req
, status
);
3161 if (NT_STATUS_IS_OK(status
)) {
3162 state
->local_ready
= true;
3166 * We always get NT_STATUS_OK from the server even if it is not ready.
3167 * So guess the server is ready when we are ready and already sent
3168 * our last blob to the server.
3170 if (state
->local_ready
&& state
->blob_out
.length
== 0) {
3171 state
->remote_ready
= true;
3174 if (state
->local_ready
&& state
->remote_ready
) {
3175 cli_smb1_setup_encryption_ready(req
);
3179 cli_smb1_setup_encryption_remote_next(req
);
3182 static void cli_smb1_setup_encryption_remote_next(struct tevent_req
*req
)
3184 struct cli_smb1_setup_encryption_state
*state
=
3185 tevent_req_data(req
,
3186 struct cli_smb1_setup_encryption_state
);
3187 struct tevent_req
*subreq
= NULL
;
3189 if (state
->remote_ready
) {
3190 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
3194 subreq
= cli_smb1_setup_encryption_blob_send(state
, state
->ev
,
3195 state
->cli
, state
->blob_out
);
3196 if (tevent_req_nomem(subreq
, req
)) {
3199 tevent_req_set_callback(subreq
,
3200 cli_smb1_setup_encryption_remote_done
,
3204 static void cli_smb1_setup_encryption_remote_done(struct tevent_req
*subreq
)
3206 struct tevent_req
*req
=
3207 tevent_req_callback_data(subreq
,
3209 struct cli_smb1_setup_encryption_state
*state
=
3210 tevent_req_data(req
,
3211 struct cli_smb1_setup_encryption_state
);
3214 status
= cli_smb1_setup_encryption_blob_recv(subreq
, state
,
3216 &state
->es
->enc_ctx_num
);
3217 TALLOC_FREE(subreq
);
3218 data_blob_free(&state
->blob_out
);
3219 if (!NT_STATUS_IS_OK(status
) &&
3220 !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
))
3222 tevent_req_nterror(req
, status
);
3227 * We always get NT_STATUS_OK even if the server is not ready.
3228 * So guess the server is ready when we are ready and sent
3229 * our last blob to the server.
3231 if (state
->local_ready
) {
3232 state
->remote_ready
= true;
3235 if (state
->local_ready
&& state
->remote_ready
) {
3236 cli_smb1_setup_encryption_ready(req
);
3240 cli_smb1_setup_encryption_local_next(req
);
3243 static void cli_smb1_setup_encryption_ready(struct tevent_req
*req
)
3245 struct cli_smb1_setup_encryption_state
*state
=
3246 tevent_req_data(req
,
3247 struct cli_smb1_setup_encryption_state
);
3248 struct smb_trans_enc_state
*es
= NULL
;
3250 if (state
->blob_in
.length
!= 0) {
3251 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
3255 if (state
->blob_out
.length
!= 0) {
3256 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
3260 es
= talloc_move(state
->cli
->conn
, &state
->es
);
3262 smb1cli_conn_set_encryption(state
->cli
->conn
, es
);
3265 tevent_req_done(req
);
3268 static NTSTATUS
cli_smb1_setup_encryption_recv(struct tevent_req
*req
)
3270 return tevent_req_simple_recv_ntstatus(req
);
3273 NTSTATUS
cli_smb1_setup_encryption(struct cli_state
*cli
,
3274 struct cli_credentials
*creds
)
3276 struct tevent_context
*ev
= NULL
;
3277 struct tevent_req
*req
= NULL
;
3278 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
3280 ev
= samba_tevent_context_init(talloc_tos());
3284 req
= cli_smb1_setup_encryption_send(ev
, ev
, cli
, creds
);
3288 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
3291 status
= cli_smb1_setup_encryption_recv(req
);
3298 establishes a connection right up to doing tconX, password specified.
3299 @param output_cli A fully initialised cli structure, non-null only on success
3300 @param dest_host The netbios name of the remote host
3301 @param dest_ip (optional) The the destination IP, NULL for name based lookup
3302 @param port (optional) The destination port (0 for default)
3303 @param service (optional) The share to make the connection to. Should be 'unqualified' in any way.
3304 @param service_type The 'type' of serivice.
3305 @param creds The used user credentials
3308 struct cli_full_connection_creds_state
{
3309 struct tevent_context
*ev
;
3310 const char *service
;
3311 const char *service_type
;
3312 struct cli_credentials
*creds
;
3314 struct cli_state
*cli
;
3317 static int cli_full_connection_creds_state_destructor(
3318 struct cli_full_connection_creds_state
*s
)
3320 if (s
->cli
!= NULL
) {
3321 cli_shutdown(s
->cli
);
3327 static void cli_full_connection_creds_conn_done(struct tevent_req
*subreq
);
3328 static void cli_full_connection_creds_sess_start(struct tevent_req
*req
);
3329 static void cli_full_connection_creds_sess_done(struct tevent_req
*subreq
);
3330 static void cli_full_connection_creds_tcon_start(struct tevent_req
*req
);
3331 static void cli_full_connection_creds_tcon_done(struct tevent_req
*subreq
);
3333 struct tevent_req
*cli_full_connection_creds_send(
3334 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
3335 const char *my_name
, const char *dest_host
,
3336 const struct sockaddr_storage
*dest_ss
, int port
,
3337 const char *service
, const char *service_type
,
3338 struct cli_credentials
*creds
,
3339 int flags
, int signing_state
)
3341 struct tevent_req
*req
, *subreq
;
3342 struct cli_full_connection_creds_state
*state
;
3343 enum credentials_use_kerberos krb5_state
;
3344 uint32_t gensec_features
= 0;
3346 req
= tevent_req_create(mem_ctx
, &state
,
3347 struct cli_full_connection_creds_state
);
3351 talloc_set_destructor(state
, cli_full_connection_creds_state_destructor
);
3353 flags
&= ~CLI_FULL_CONNECTION_USE_KERBEROS
;
3354 flags
&= ~CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS
;
3355 flags
&= ~CLI_FULL_CONNECTION_USE_CCACHE
;
3356 flags
&= ~CLI_FULL_CONNECTION_USE_NT_HASH
;
3358 krb5_state
= cli_credentials_get_kerberos_state(creds
);
3359 switch (krb5_state
) {
3360 case CRED_MUST_USE_KERBEROS
:
3361 flags
|= CLI_FULL_CONNECTION_USE_KERBEROS
;
3362 flags
&= ~CLI_FULL_CONNECTION_DONT_SPNEGO
;
3364 case CRED_AUTO_USE_KERBEROS
:
3365 flags
|= CLI_FULL_CONNECTION_USE_KERBEROS
;
3366 flags
|= CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS
;
3368 case CRED_DONT_USE_KERBEROS
:
3372 gensec_features
= cli_credentials_get_gensec_features(creds
);
3373 if (gensec_features
& GENSEC_FEATURE_NTLM_CCACHE
) {
3374 flags
|= CLI_FULL_CONNECTION_USE_CCACHE
;
3378 state
->service
= service
;
3379 state
->service_type
= service_type
;
3380 state
->creds
= creds
;
3381 state
->flags
= flags
;
3383 subreq
= cli_start_connection_send(
3384 state
, ev
, my_name
, dest_host
, dest_ss
, port
,
3385 signing_state
, flags
);
3386 if (tevent_req_nomem(subreq
, req
)) {
3387 return tevent_req_post(req
, ev
);
3389 tevent_req_set_callback(subreq
,
3390 cli_full_connection_creds_conn_done
,
3395 static void cli_full_connection_creds_conn_done(struct tevent_req
*subreq
)
3397 struct tevent_req
*req
= tevent_req_callback_data(
3398 subreq
, struct tevent_req
);
3399 struct cli_full_connection_creds_state
*state
= tevent_req_data(
3400 req
, struct cli_full_connection_creds_state
);
3403 status
= cli_start_connection_recv(subreq
, &state
->cli
);
3404 TALLOC_FREE(subreq
);
3405 if (tevent_req_nterror(req
, status
)) {
3409 cli_full_connection_creds_sess_start(req
);
3412 static void cli_full_connection_creds_sess_start(struct tevent_req
*req
)
3414 struct cli_full_connection_creds_state
*state
= tevent_req_data(
3415 req
, struct cli_full_connection_creds_state
);
3416 struct tevent_req
*subreq
= NULL
;
3418 subreq
= cli_session_setup_creds_send(
3419 state
, state
->ev
, state
->cli
, state
->creds
);
3420 if (tevent_req_nomem(subreq
, req
)) {
3423 tevent_req_set_callback(subreq
,
3424 cli_full_connection_creds_sess_done
,
3428 static void cli_full_connection_creds_sess_done(struct tevent_req
*subreq
)
3430 struct tevent_req
*req
= tevent_req_callback_data(
3431 subreq
, struct tevent_req
);
3432 struct cli_full_connection_creds_state
*state
= tevent_req_data(
3433 req
, struct cli_full_connection_creds_state
);
3436 status
= cli_session_setup_creds_recv(subreq
);
3437 TALLOC_FREE(subreq
);
3439 if (!NT_STATUS_IS_OK(status
) &&
3440 (state
->flags
& CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK
)) {
3442 state
->flags
&= ~CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK
;
3444 state
->creds
= cli_credentials_init_anon(state
);
3445 if (tevent_req_nomem(state
->creds
, req
)) {
3449 cli_full_connection_creds_sess_start(req
);
3453 if (tevent_req_nterror(req
, status
)) {
3457 cli_full_connection_creds_tcon_start(req
);
3460 static void cli_full_connection_creds_tcon_start(struct tevent_req
*req
)
3462 struct cli_full_connection_creds_state
*state
= tevent_req_data(
3463 req
, struct cli_full_connection_creds_state
);
3464 struct tevent_req
*subreq
= NULL
;
3465 const char *password
= NULL
;
3467 if (state
->service
== NULL
) {
3468 tevent_req_done(req
);
3472 password
= cli_credentials_get_password(state
->creds
);
3474 subreq
= cli_tree_connect_send(state
, state
->ev
,
3477 state
->service_type
,
3479 if (tevent_req_nomem(subreq
, req
)) {
3482 tevent_req_set_callback(subreq
,
3483 cli_full_connection_creds_tcon_done
,
3487 static void cli_full_connection_creds_tcon_done(struct tevent_req
*subreq
)
3489 struct tevent_req
*req
= tevent_req_callback_data(
3490 subreq
, struct tevent_req
);
3493 status
= cli_tree_connect_recv(subreq
);
3494 TALLOC_FREE(subreq
);
3495 if (tevent_req_nterror(req
, status
)) {
3499 tevent_req_done(req
);
3502 NTSTATUS
cli_full_connection_creds_recv(struct tevent_req
*req
,
3503 struct cli_state
**output_cli
)
3505 struct cli_full_connection_creds_state
*state
= tevent_req_data(
3506 req
, struct cli_full_connection_creds_state
);
3509 if (tevent_req_is_nterror(req
, &status
)) {
3512 *output_cli
= state
->cli
;
3513 talloc_set_destructor(state
, NULL
);
3514 return NT_STATUS_OK
;
3517 NTSTATUS
cli_full_connection_creds(struct cli_state
**output_cli
,
3518 const char *my_name
,
3519 const char *dest_host
,
3520 const struct sockaddr_storage
*dest_ss
, int port
,
3521 const char *service
, const char *service_type
,
3522 struct cli_credentials
*creds
,
3526 struct tevent_context
*ev
;
3527 struct tevent_req
*req
;
3528 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
3530 ev
= samba_tevent_context_init(talloc_tos());
3534 req
= cli_full_connection_creds_send(
3535 ev
, ev
, my_name
, dest_host
, dest_ss
, port
, service
,
3536 service_type
, creds
, flags
, signing_state
);
3540 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
3543 status
= cli_full_connection_creds_recv(req
, output_cli
);
3549 NTSTATUS
cli_full_connection(struct cli_state
**output_cli
,
3550 const char *my_name
,
3551 const char *dest_host
,
3552 const struct sockaddr_storage
*dest_ss
, int port
,
3553 const char *service
, const char *service_type
,
3554 const char *user
, const char *domain
,
3555 const char *password
, int flags
,
3558 TALLOC_CTX
*frame
= talloc_stackframe();
3560 bool use_kerberos
= false;
3561 bool fallback_after_kerberos
= false;
3562 bool use_ccache
= false;
3563 bool pw_nt_hash
= false;
3564 struct cli_credentials
*creds
= NULL
;
3566 if (flags
& CLI_FULL_CONNECTION_USE_KERBEROS
) {
3567 use_kerberos
= true;
3570 if (flags
& CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS
) {
3571 fallback_after_kerberos
= true;
3574 if (flags
& CLI_FULL_CONNECTION_USE_CCACHE
) {
3578 if (flags
& CLI_FULL_CONNECTION_USE_NT_HASH
) {
3582 creds
= cli_session_creds_init(frame
,
3585 NULL
, /* realm (use default) */
3588 fallback_after_kerberos
,
3591 if (creds
== NULL
) {
3593 return NT_STATUS_NO_MEMORY
;
3596 status
= cli_full_connection_creds(output_cli
, my_name
,
3597 dest_host
, dest_ss
, port
,
3598 service
, service_type
,
3599 creds
, flags
, signing_state
);
3600 if (!NT_STATUS_IS_OK(status
)) {
3606 return NT_STATUS_OK
;
3609 /****************************************************************************
3610 Send an old style tcon.
3611 ****************************************************************************/
3612 struct cli_raw_tcon_state
{
3616 static void cli_raw_tcon_done(struct tevent_req
*subreq
);
3618 static struct tevent_req
*cli_raw_tcon_send(
3619 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
3620 const char *service
, const char *pass
, const char *dev
)
3622 struct tevent_req
*req
, *subreq
;
3623 struct cli_raw_tcon_state
*state
;
3626 req
= tevent_req_create(mem_ctx
, &state
, struct cli_raw_tcon_state
);
3631 if (!lp_client_plaintext_auth() && (*pass
)) {
3632 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
3633 " or 'client ntlmv2 auth = yes'\n"));
3634 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
3635 return tevent_req_post(req
, ev
);
3638 TALLOC_FREE(cli
->smb1
.tcon
);
3639 cli
->smb1
.tcon
= smbXcli_tcon_create(cli
);
3640 if (tevent_req_nomem(cli
->smb1
.tcon
, req
)) {
3641 return tevent_req_post(req
, ev
);
3643 smb1cli_tcon_set_id(cli
->smb1
.tcon
, UINT16_MAX
);
3645 bytes
= talloc_array(state
, uint8_t, 0);
3646 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
3647 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
3648 service
, strlen(service
)+1, NULL
);
3649 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
3650 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
3651 pass
, strlen(pass
)+1, NULL
);
3652 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
3653 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
3654 dev
, strlen(dev
)+1, NULL
);
3656 if (tevent_req_nomem(bytes
, req
)) {
3657 return tevent_req_post(req
, ev
);
3660 subreq
= cli_smb_send(state
, ev
, cli
, SMBtcon
, 0, 0, 0, NULL
,
3661 talloc_get_size(bytes
), bytes
);
3662 if (tevent_req_nomem(subreq
, req
)) {
3663 return tevent_req_post(req
, ev
);
3665 tevent_req_set_callback(subreq
, cli_raw_tcon_done
, req
);
3669 static void cli_raw_tcon_done(struct tevent_req
*subreq
)
3671 struct tevent_req
*req
= tevent_req_callback_data(
3672 subreq
, struct tevent_req
);
3673 struct cli_raw_tcon_state
*state
= tevent_req_data(
3674 req
, struct cli_raw_tcon_state
);
3677 status
= cli_smb_recv(subreq
, state
, NULL
, 2, NULL
, &state
->ret_vwv
,
3679 TALLOC_FREE(subreq
);
3680 if (tevent_req_nterror(req
, status
)) {
3683 tevent_req_done(req
);
3686 static NTSTATUS
cli_raw_tcon_recv(struct tevent_req
*req
,
3687 uint16_t *max_xmit
, uint16_t *tid
)
3689 struct cli_raw_tcon_state
*state
= tevent_req_data(
3690 req
, struct cli_raw_tcon_state
);
3693 if (tevent_req_is_nterror(req
, &status
)) {
3696 *max_xmit
= SVAL(state
->ret_vwv
+ 0, 0);
3697 *tid
= SVAL(state
->ret_vwv
+ 1, 0);
3698 return NT_STATUS_OK
;
3701 NTSTATUS
cli_raw_tcon(struct cli_state
*cli
,
3702 const char *service
, const char *pass
, const char *dev
,
3703 uint16_t *max_xmit
, uint16_t *tid
)
3705 struct tevent_context
*ev
;
3706 struct tevent_req
*req
;
3707 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
3709 ev
= samba_tevent_context_init(talloc_tos());
3713 req
= cli_raw_tcon_send(ev
, ev
, cli
, service
, pass
, dev
);
3717 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
3720 status
= cli_raw_tcon_recv(req
, max_xmit
, tid
);
3726 /* Return a cli_state pointing at the IPC$ share for the given server */
3728 struct cli_state
*get_ipc_connect(char *server
,
3729 struct sockaddr_storage
*server_ss
,
3730 const struct user_auth_info
*user_info
)
3732 struct cli_state
*cli
;
3734 uint32_t flags
= CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK
;
3736 if (get_cmdline_auth_info_use_kerberos(user_info
)) {
3737 flags
|= CLI_FULL_CONNECTION_USE_KERBEROS
;
3740 flags
|= CLI_FULL_CONNECTION_FORCE_SMB1
;
3742 nt_status
= cli_full_connection(&cli
, NULL
, server
, server_ss
, 0, "IPC$", "IPC",
3743 get_cmdline_auth_info_username(user_info
),
3745 get_cmdline_auth_info_password(user_info
),
3747 SMB_SIGNING_DEFAULT
);
3749 if (NT_STATUS_IS_OK(nt_status
)) {
3751 } else if (is_ipaddress(server
)) {
3752 /* windows 9* needs a correct NMB name for connections */
3753 fstring remote_name
;
3755 if (name_status_find("*", 0, 0, server_ss
, remote_name
)) {
3756 cli
= get_ipc_connect(remote_name
, server_ss
, user_info
);
3765 * Given the IP address of a master browser on the network, return its
3766 * workgroup and connect to it.
3768 * This function is provided to allow additional processing beyond what
3769 * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
3770 * browsers and obtain each master browsers' list of domains (in case the
3771 * first master browser is recently on the network and has not yet
3772 * synchronized with other master browsers and therefore does not yet have the
3773 * entire network browse list)
3776 struct cli_state
*get_ipc_connect_master_ip(TALLOC_CTX
*ctx
,
3777 struct sockaddr_storage
*mb_ip
,
3778 const struct user_auth_info
*user_info
,
3779 char **pp_workgroup_out
)
3781 char addr
[INET6_ADDRSTRLEN
];
3783 struct cli_state
*cli
;
3784 struct sockaddr_storage server_ss
;
3786 *pp_workgroup_out
= NULL
;
3788 print_sockaddr(addr
, sizeof(addr
), mb_ip
);
3789 DEBUG(99, ("Looking up name of master browser %s\n",
3793 * Do a name status query to find out the name of the master browser.
3794 * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
3795 * master browser will not respond to a wildcard query (or, at least,
3796 * an NT4 server acting as the domain master browser will not).
3798 * We might be able to use ONLY the query on MSBROWSE, but that's not
3799 * yet been tested with all Windows versions, so until it is, leave
3800 * the original wildcard query as the first choice and fall back to
3801 * MSBROWSE if the wildcard query fails.
3803 if (!name_status_find("*", 0, 0x1d, mb_ip
, name
) &&
3804 !name_status_find(MSBROWSE
, 1, 0x1d, mb_ip
, name
)) {
3806 DEBUG(99, ("Could not retrieve name status for %s\n",
3811 if (!find_master_ip(name
, &server_ss
)) {
3812 DEBUG(99, ("Could not find master ip for %s\n", name
));
3816 *pp_workgroup_out
= talloc_strdup(ctx
, name
);
3818 DEBUG(4, ("found master browser %s, %s\n", name
, addr
));
3820 print_sockaddr(addr
, sizeof(addr
), &server_ss
);
3821 cli
= get_ipc_connect(addr
, &server_ss
, user_info
);
3827 * Return the IP address and workgroup of a master browser on the network, and
3831 struct cli_state
*get_ipc_connect_master_ip_bcast(TALLOC_CTX
*ctx
,
3832 const struct user_auth_info
*user_info
,
3833 char **pp_workgroup_out
)
3835 struct sockaddr_storage
*ip_list
;
3836 struct cli_state
*cli
;
3840 *pp_workgroup_out
= NULL
;
3842 DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
3844 /* Go looking for workgroups by broadcasting on the local network */
3846 status
= name_resolve_bcast(MSBROWSE
, 1, talloc_tos(),
3848 if (!NT_STATUS_IS_OK(status
)) {
3849 DEBUG(99, ("No master browsers responded: %s\n",
3850 nt_errstr(status
)));
3854 for (i
= 0; i
< count
; i
++) {
3855 char addr
[INET6_ADDRSTRLEN
];
3856 print_sockaddr(addr
, sizeof(addr
), &ip_list
[i
]);
3857 DEBUG(99, ("Found master browser %s\n", addr
));
3859 cli
= get_ipc_connect_master_ip(ctx
, &ip_list
[i
],
3860 user_info
, pp_workgroup_out
);