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 "lib/param/param.h"
42 #define STAR_SMBSERVER "*SMBSERVER"
44 static char *cli_session_setup_get_account(TALLOC_CTX
*mem_ctx
,
45 const char *principal
);
47 struct cli_credentials
*cli_session_creds_init(TALLOC_CTX
*mem_ctx
,
53 bool fallback_after_kerberos
,
55 bool password_is_nt_hash
)
57 struct loadparm_context
*lp_ctx
= NULL
;
58 struct cli_credentials
*creds
= NULL
;
59 const char *principal
= NULL
;
64 creds
= cli_credentials_init(mem_ctx
);
69 lp_ctx
= loadparm_init_s3(creds
, loadparm_s3_helpers());
73 cli_credentials_set_conf(creds
, lp_ctx
);
79 if (username
== NULL
) {
83 if (strlen(username
) == 0) {
84 if (password
!= NULL
&& strlen(password
) == 0) {
86 * some callers pass "" as no password
88 * gensec only handles NULL as no password.
92 if (password
== NULL
) {
93 cli_credentials_set_anonymous(creds
);
98 tmp
= talloc_strdup(creds
, username
);
104 /* allow for workgroups as part of the username */
105 if ((p
= strchr_m(tmp
, '\\')) ||
106 (p
= strchr_m(tmp
, '/')) ||
107 (p
= strchr_m(tmp
, *lp_winbind_separator()))) {
113 principal
= username
;
114 username
= cli_session_setup_get_account(creds
, principal
);
115 if (username
== NULL
) {
118 ok
= strequal(username
, principal
);
121 * Ok still the same, so it's not a principal
126 if (use_kerberos
&& fallback_after_kerberos
) {
127 cli_credentials_set_kerberos_state(creds
,
128 CRED_AUTO_USE_KERBEROS
);
129 } else if (use_kerberos
) {
130 cli_credentials_set_kerberos_state(creds
,
131 CRED_MUST_USE_KERBEROS
);
133 cli_credentials_set_kerberos_state(creds
,
134 CRED_DONT_USE_KERBEROS
);
140 features
= cli_credentials_get_gensec_features(creds
);
141 features
|= GENSEC_FEATURE_NTLM_CCACHE
;
142 cli_credentials_set_gensec_features(creds
, features
);
144 if (password
!= NULL
&& strlen(password
) == 0) {
146 * some callers pass "" as no password
148 * GENSEC_FEATURE_NTLM_CCACHE only handles
149 * NULL as no password.
155 ok
= cli_credentials_set_username(creds
,
162 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 /********************************************************
223 Utility function to ensure we always return at least
224 a valid char * pointer to an empty string for the
225 cli->server_os, cli->server_type and cli->server_domain
227 *******************************************************/
229 static NTSTATUS
smb_bytes_talloc_string(TALLOC_CTX
*mem_ctx
,
236 *destlen
= clistr_pull_talloc(mem_ctx
,
243 if (*destlen
== -1) {
244 return NT_STATUS_NO_MEMORY
;
248 *dest
= talloc_strdup(mem_ctx
, "");
250 return NT_STATUS_NO_MEMORY
;
256 /****************************************************************************
257 Work out suitable capabilities to offer the server.
258 ****************************************************************************/
260 static uint32_t cli_session_setup_capabilities(struct cli_state
*cli
,
261 uint32_t sesssetup_capabilities
)
263 uint32_t client_capabilities
= smb1cli_conn_capabilities(cli
->conn
);
266 * We only send capabilities based on the mask for:
267 * - client only flags
268 * - flags used in both directions
270 * We do not echo the server only flags, except some legacy flags.
272 * SMB_CAP_LEGACY_CLIENT_MASK contains CAP_LARGE_READX and
273 * CAP_LARGE_WRITEX in order to allow us to do large reads
274 * against old Samba releases (<= 3.6.x).
276 client_capabilities
&= (SMB_CAP_BOTH_MASK
| SMB_CAP_LEGACY_CLIENT_MASK
);
279 * Session Setup specific flags CAP_DYNAMIC_REAUTH
280 * and CAP_EXTENDED_SECURITY are passed by the caller.
281 * We need that in order to do guest logins even if
282 * CAP_EXTENDED_SECURITY is negotiated.
284 client_capabilities
&= ~(CAP_DYNAMIC_REAUTH
|CAP_EXTENDED_SECURITY
);
285 sesssetup_capabilities
&= (CAP_DYNAMIC_REAUTH
|CAP_EXTENDED_SECURITY
);
286 client_capabilities
|= sesssetup_capabilities
;
288 return client_capabilities
;
291 /****************************************************************************
292 Do a NT1 guest session setup.
293 ****************************************************************************/
295 struct cli_session_setup_guest_state
{
296 struct cli_state
*cli
;
301 static void cli_session_setup_guest_done(struct tevent_req
*subreq
);
303 struct tevent_req
*cli_session_setup_guest_create(TALLOC_CTX
*mem_ctx
,
304 struct tevent_context
*ev
,
305 struct cli_state
*cli
,
306 struct tevent_req
**psmbreq
)
308 struct tevent_req
*req
, *subreq
;
309 struct cli_session_setup_guest_state
*state
;
313 req
= tevent_req_create(mem_ctx
, &state
,
314 struct cli_session_setup_guest_state
);
321 SCVAL(vwv
+0, 0, 0xFF);
324 SSVAL(vwv
+2, 0, CLI_BUFFER_SIZE
);
326 SSVAL(vwv
+4, 0, cli_state_get_vc_num(cli
));
327 SIVAL(vwv
+5, 0, smb1cli_conn_server_session_key(cli
->conn
));
332 SIVAL(vwv
+11, 0, cli_session_setup_capabilities(cli
, 0));
334 bytes
= talloc_array(state
, uint8_t, 0);
336 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "", 1, /* username */
338 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "", 1, /* workgroup */
340 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "Unix", 5, NULL
);
341 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "Samba", 6, NULL
);
348 state
->bytes
.iov_base
= (void *)bytes
;
349 state
->bytes
.iov_len
= talloc_get_size(bytes
);
351 subreq
= cli_smb_req_create(state
, ev
, cli
, SMBsesssetupX
, 0, 0, 13,
352 vwv
, 1, &state
->bytes
);
353 if (subreq
== NULL
) {
357 tevent_req_set_callback(subreq
, cli_session_setup_guest_done
, req
);
362 struct tevent_req
*cli_session_setup_guest_send(TALLOC_CTX
*mem_ctx
,
363 struct tevent_context
*ev
,
364 struct cli_state
*cli
)
366 struct tevent_req
*req
, *subreq
;
369 req
= cli_session_setup_guest_create(mem_ctx
, ev
, cli
, &subreq
);
374 status
= smb1cli_req_chain_submit(&subreq
, 1);
375 if (!NT_STATUS_IS_OK(status
)) {
376 tevent_req_nterror(req
, status
);
377 return tevent_req_post(req
, ev
);
382 static void cli_session_setup_guest_done(struct tevent_req
*subreq
)
384 struct tevent_req
*req
= tevent_req_callback_data(
385 subreq
, struct tevent_req
);
386 struct cli_session_setup_guest_state
*state
= tevent_req_data(
387 req
, struct cli_session_setup_guest_state
);
388 struct cli_state
*cli
= state
->cli
;
399 status
= cli_smb_recv(subreq
, state
, &in
, 3, &wct
, &vwv
,
402 if (!NT_STATUS_IS_OK(status
)) {
403 tevent_req_nterror(req
, status
);
407 inhdr
= in
+ NBT_HDR_SIZE
;
410 cli_state_set_uid(state
->cli
, SVAL(inhdr
, HDR_UID
));
411 smb1cli_session_set_action(cli
->smb1
.session
, SVAL(vwv
+2, 0));
413 status
= smb_bytes_talloc_string(cli
,
420 if (!NT_STATUS_IS_OK(status
)) {
421 tevent_req_nterror(req
, status
);
426 status
= smb_bytes_talloc_string(cli
,
433 if (!NT_STATUS_IS_OK(status
)) {
434 tevent_req_nterror(req
, status
);
439 status
= smb_bytes_talloc_string(cli
,
446 if (!NT_STATUS_IS_OK(status
)) {
447 tevent_req_nterror(req
, status
);
452 tevent_req_done(req
);
455 NTSTATUS
cli_session_setup_guest_recv(struct tevent_req
*req
)
457 return tevent_req_simple_recv_ntstatus(req
);
460 /* The following is calculated from :
462 * (smb_wcnt * 2) = 24 (smb_wcnt == 12 in cli_session_setup_blob_send() )
463 * (strlen("Unix") + 1 + strlen("Samba") + 1) * 2 = 22 (unicode strings at
467 #define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22)
469 struct cli_sesssetup_blob_state
{
470 struct tevent_context
*ev
;
471 struct cli_state
*cli
;
473 uint16_t max_blob_size
;
476 struct iovec
*recv_iov
;
479 const uint8_t *inbuf
;
486 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state
*state
,
487 struct tevent_req
**psubreq
);
488 static void cli_sesssetup_blob_done(struct tevent_req
*subreq
);
490 static struct tevent_req
*cli_sesssetup_blob_send(TALLOC_CTX
*mem_ctx
,
491 struct tevent_context
*ev
,
492 struct cli_state
*cli
,
495 struct tevent_req
*req
, *subreq
;
496 struct cli_sesssetup_blob_state
*state
;
497 uint32_t usable_space
;
499 req
= tevent_req_create(mem_ctx
, &state
,
500 struct cli_sesssetup_blob_state
);
508 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
509 usable_space
= UINT16_MAX
;
511 usable_space
= cli_state_available_size(cli
,
512 BASE_SESSSETUP_BLOB_PACKET_SIZE
);
515 if (usable_space
== 0) {
516 DEBUG(1, ("cli_session_setup_blob: cli->max_xmit too small "
517 "(not possible to send %u bytes)\n",
518 BASE_SESSSETUP_BLOB_PACKET_SIZE
+ 1));
519 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
520 return tevent_req_post(req
, ev
);
522 state
->max_blob_size
= MIN(usable_space
, 0xFFFF);
524 if (!cli_sesssetup_blob_next(state
, &subreq
)) {
525 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
526 return tevent_req_post(req
, ev
);
528 tevent_req_set_callback(subreq
, cli_sesssetup_blob_done
, req
);
532 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state
*state
,
533 struct tevent_req
**psubreq
)
535 struct tevent_req
*subreq
;
538 thistime
= MIN(state
->blob
.length
, state
->max_blob_size
);
540 state
->this_blob
.data
= state
->blob
.data
;
541 state
->this_blob
.length
= thistime
;
543 state
->blob
.data
+= thistime
;
544 state
->blob
.length
-= thistime
;
546 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
547 subreq
= smb2cli_session_setup_send(state
, state
->ev
,
550 state
->cli
->smb2
.session
,
552 SMB2_CAP_DFS
, /* in_capabilities */
554 0, /* in_previous_session_id */
556 if (subreq
== NULL
) {
560 uint16_t in_buf_size
= 0;
561 uint16_t in_mpx_max
= 0;
562 uint16_t in_vc_num
= 0;
563 uint32_t in_sess_key
= 0;
564 uint32_t in_capabilities
= 0;
565 const char *in_native_os
= NULL
;
566 const char *in_native_lm
= NULL
;
568 in_buf_size
= CLI_BUFFER_SIZE
;
569 in_mpx_max
= smbXcli_conn_max_requests(state
->cli
->conn
);
570 in_vc_num
= cli_state_get_vc_num(state
->cli
);
571 in_sess_key
= smb1cli_conn_server_session_key(state
->cli
->conn
);
572 in_capabilities
= cli_session_setup_capabilities(state
->cli
,
573 CAP_EXTENDED_SECURITY
);
574 in_native_os
= "Unix";
575 in_native_lm
= "Samba";
578 * For now we keep the same values as before,
579 * we may remove these in a separate commit later.
585 subreq
= smb1cli_session_setup_ext_send(state
, state
->ev
,
588 state
->cli
->smb1
.pid
,
589 state
->cli
->smb1
.session
,
598 if (subreq
== NULL
) {
606 static void cli_sesssetup_blob_done(struct tevent_req
*subreq
)
608 struct tevent_req
*req
= tevent_req_callback_data(
609 subreq
, struct tevent_req
);
610 struct cli_sesssetup_blob_state
*state
= tevent_req_data(
611 req
, struct cli_sesssetup_blob_state
);
612 struct cli_state
*cli
= state
->cli
;
615 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
616 status
= smb2cli_session_setup_recv(subreq
, state
,
620 status
= smb1cli_session_setup_ext_recv(subreq
, state
,
624 &state
->out_native_os
,
625 &state
->out_native_lm
);
628 if (!NT_STATUS_IS_OK(status
)
629 && !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
630 tevent_req_nterror(req
, status
);
634 if (cli
->server_os
== NULL
) {
635 cli
->server_os
= talloc_move(cli
, &state
->out_native_os
);
637 if (cli
->server_type
== NULL
) {
638 cli
->server_type
= talloc_move(cli
, &state
->out_native_lm
);
641 state
->status
= status
;
643 if (state
->blob
.length
!= 0) {
647 if (!cli_sesssetup_blob_next(state
, &subreq
)) {
651 tevent_req_set_callback(subreq
, cli_sesssetup_blob_done
, req
);
654 tevent_req_done(req
);
657 static NTSTATUS
cli_sesssetup_blob_recv(struct tevent_req
*req
,
660 const uint8_t **pinbuf
,
661 struct iovec
**precv_iov
)
663 struct cli_sesssetup_blob_state
*state
= tevent_req_data(
664 req
, struct cli_sesssetup_blob_state
);
666 struct iovec
*recv_iov
;
668 if (tevent_req_is_nterror(req
, &status
)) {
669 TALLOC_FREE(state
->cli
->smb2
.session
);
670 cli_state_set_uid(state
->cli
, UID_FIELD_INVALID
);
671 tevent_req_received(req
);
675 recv_iov
= talloc_move(mem_ctx
, &state
->recv_iov
);
677 *pblob
= state
->ret_blob
;
679 if (pinbuf
!= NULL
) {
680 *pinbuf
= state
->inbuf
;
682 if (precv_iov
!= NULL
) {
683 *precv_iov
= recv_iov
;
685 /* could be NT_STATUS_MORE_PROCESSING_REQUIRED */
686 status
= state
->status
;
687 tevent_req_received(req
);
691 /****************************************************************************
692 Use in-memory credentials cache
693 ****************************************************************************/
695 static void use_in_memory_ccache(void) {
696 setenv(KRB5_ENV_CCNAME
, "MEMORY:cliconnect", 1);
699 /****************************************************************************
700 Do a spnego/NTLMSSP encrypted session setup.
701 ****************************************************************************/
703 struct cli_session_setup_gensec_state
{
704 struct tevent_context
*ev
;
705 struct cli_state
*cli
;
706 struct auth_generic_state
*auth_generic
;
709 const uint8_t *inbuf
;
710 struct iovec
*recv_iov
;
714 DATA_BLOB session_key
;
717 static int cli_session_setup_gensec_state_destructor(
718 struct cli_session_setup_gensec_state
*state
)
720 TALLOC_FREE(state
->auth_generic
);
721 data_blob_clear_free(&state
->session_key
);
725 static void cli_session_setup_gensec_local_next(struct tevent_req
*req
);
726 static void cli_session_setup_gensec_local_done(struct tevent_req
*subreq
);
727 static void cli_session_setup_gensec_remote_next(struct tevent_req
*req
);
728 static void cli_session_setup_gensec_remote_done(struct tevent_req
*subreq
);
729 static void cli_session_setup_gensec_ready(struct tevent_req
*req
);
731 static struct tevent_req
*cli_session_setup_gensec_send(
732 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
733 struct cli_credentials
*creds
,
734 const char *target_service
,
735 const char *target_hostname
)
737 struct tevent_req
*req
;
738 struct cli_session_setup_gensec_state
*state
;
740 const DATA_BLOB
*b
= NULL
;
742 req
= tevent_req_create(mem_ctx
, &state
,
743 struct cli_session_setup_gensec_state
);
750 talloc_set_destructor(
751 state
, cli_session_setup_gensec_state_destructor
);
753 status
= auth_generic_client_prepare(state
, &state
->auth_generic
);
754 if (tevent_req_nterror(req
, status
)) {
755 return tevent_req_post(req
, ev
);
758 status
= auth_generic_set_creds(state
->auth_generic
, creds
);
759 if (tevent_req_nterror(req
, status
)) {
760 return tevent_req_post(req
, ev
);
763 gensec_want_feature(state
->auth_generic
->gensec_security
,
764 GENSEC_FEATURE_SESSION_KEY
);
766 if (target_service
!= NULL
) {
767 status
= gensec_set_target_service(
768 state
->auth_generic
->gensec_security
,
770 if (tevent_req_nterror(req
, status
)) {
771 return tevent_req_post(req
, ev
);
775 if (target_hostname
!= NULL
) {
776 status
= gensec_set_target_hostname(
777 state
->auth_generic
->gensec_security
,
779 if (tevent_req_nterror(req
, status
)) {
780 return tevent_req_post(req
, ev
);
784 b
= smbXcli_conn_server_gss_blob(cli
->conn
);
789 state
->is_anonymous
= cli_credentials_is_anonymous(state
->auth_generic
->credentials
);
791 status
= auth_generic_client_start(state
->auth_generic
,
793 if (tevent_req_nterror(req
, status
)) {
794 return tevent_req_post(req
, ev
);
797 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
798 state
->cli
->smb2
.session
= smbXcli_session_create(cli
,
800 if (tevent_req_nomem(state
->cli
->smb2
.session
, req
)) {
801 return tevent_req_post(req
, ev
);
805 cli_session_setup_gensec_local_next(req
);
806 if (!tevent_req_is_in_progress(req
)) {
807 return tevent_req_post(req
, ev
);
813 static void cli_session_setup_gensec_local_next(struct tevent_req
*req
)
815 struct cli_session_setup_gensec_state
*state
=
817 struct cli_session_setup_gensec_state
);
818 struct tevent_req
*subreq
= NULL
;
820 if (state
->local_ready
) {
821 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
825 subreq
= gensec_update_send(state
, state
->ev
,
826 state
->auth_generic
->gensec_security
,
828 if (tevent_req_nomem(subreq
, req
)) {
831 tevent_req_set_callback(subreq
, cli_session_setup_gensec_local_done
, req
);
834 static void cli_session_setup_gensec_local_done(struct tevent_req
*subreq
)
836 struct tevent_req
*req
=
837 tevent_req_callback_data(subreq
,
839 struct cli_session_setup_gensec_state
*state
=
841 struct cli_session_setup_gensec_state
);
844 status
= gensec_update_recv(subreq
, state
, &state
->blob_out
);
846 state
->blob_in
= data_blob_null
;
847 if (!NT_STATUS_IS_OK(status
) &&
848 !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
))
850 tevent_req_nterror(req
, status
);
854 if (NT_STATUS_IS_OK(status
)) {
855 state
->local_ready
= true;
858 if (state
->local_ready
&& state
->remote_ready
) {
859 cli_session_setup_gensec_ready(req
);
863 cli_session_setup_gensec_remote_next(req
);
866 static void cli_session_setup_gensec_remote_next(struct tevent_req
*req
)
868 struct cli_session_setup_gensec_state
*state
=
870 struct cli_session_setup_gensec_state
);
871 struct tevent_req
*subreq
= NULL
;
873 if (state
->remote_ready
) {
874 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
878 subreq
= cli_sesssetup_blob_send(state
, state
->ev
,
879 state
->cli
, state
->blob_out
);
880 if (tevent_req_nomem(subreq
, req
)) {
883 tevent_req_set_callback(subreq
,
884 cli_session_setup_gensec_remote_done
,
888 static void cli_session_setup_gensec_remote_done(struct tevent_req
*subreq
)
890 struct tevent_req
*req
=
891 tevent_req_callback_data(subreq
,
893 struct cli_session_setup_gensec_state
*state
=
895 struct cli_session_setup_gensec_state
);
899 TALLOC_FREE(state
->recv_iov
);
901 status
= cli_sesssetup_blob_recv(subreq
, state
, &state
->blob_in
,
902 &state
->inbuf
, &state
->recv_iov
);
904 data_blob_free(&state
->blob_out
);
905 if (!NT_STATUS_IS_OK(status
) &&
906 !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
))
908 tevent_req_nterror(req
, status
);
912 if (NT_STATUS_IS_OK(status
)) {
913 struct smbXcli_session
*session
= NULL
;
914 bool is_guest
= false;
916 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
917 session
= state
->cli
->smb2
.session
;
919 session
= state
->cli
->smb1
.session
;
922 is_guest
= smbXcli_session_is_guest(session
);
925 * We can't finish the gensec handshake, we don't
926 * have a negotiated session key.
928 * So just pretend we are completely done.
930 * Note that smbXcli_session_is_guest()
931 * always returns false if we require signing.
933 state
->blob_in
= data_blob_null
;
934 state
->local_ready
= true;
937 state
->remote_ready
= true;
940 if (state
->local_ready
&& state
->remote_ready
) {
941 cli_session_setup_gensec_ready(req
);
945 cli_session_setup_gensec_local_next(req
);
948 static void cli_session_setup_gensec_ready(struct tevent_req
*req
)
950 struct cli_session_setup_gensec_state
*state
=
952 struct cli_session_setup_gensec_state
);
953 const char *server_domain
= NULL
;
956 if (state
->blob_in
.length
!= 0) {
957 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
961 if (state
->blob_out
.length
!= 0) {
962 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
967 * gensec_ntlmssp_server_domain() returns NULL
968 * if NTLMSSP is not used.
970 * We can remove this later
971 * and leave the server domain empty for SMB2 and above
972 * in future releases.
974 server_domain
= gensec_ntlmssp_server_domain(
975 state
->auth_generic
->gensec_security
);
977 if (state
->cli
->server_domain
[0] == '\0' && server_domain
!= NULL
) {
978 TALLOC_FREE(state
->cli
->server_domain
);
979 state
->cli
->server_domain
= talloc_strdup(state
->cli
,
981 if (state
->cli
->server_domain
== NULL
) {
982 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
987 if (state
->is_anonymous
) {
989 * Windows server does not set the
990 * SMB2_SESSION_FLAG_IS_NULL flag.
992 * This fix makes sure we do not try
993 * to verify a signature on the final
994 * session setup response.
996 tevent_req_done(req
);
1000 status
= gensec_session_key(state
->auth_generic
->gensec_security
,
1001 state
, &state
->session_key
);
1002 if (tevent_req_nterror(req
, status
)) {
1006 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
1007 struct smbXcli_session
*session
= state
->cli
->smb2
.session
;
1009 status
= smb2cli_session_set_session_key(session
,
1012 if (tevent_req_nterror(req
, status
)) {
1016 struct smbXcli_session
*session
= state
->cli
->smb1
.session
;
1019 status
= smb1cli_session_set_session_key(session
,
1020 state
->session_key
);
1021 if (tevent_req_nterror(req
, status
)) {
1025 active
= smb1cli_conn_activate_signing(state
->cli
->conn
,
1031 ok
= smb1cli_conn_check_signing(state
->cli
->conn
,
1034 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1040 tevent_req_done(req
);
1043 static NTSTATUS
cli_session_setup_gensec_recv(struct tevent_req
*req
)
1045 struct cli_session_setup_gensec_state
*state
=
1046 tevent_req_data(req
,
1047 struct cli_session_setup_gensec_state
);
1050 if (tevent_req_is_nterror(req
, &status
)) {
1051 cli_state_set_uid(state
->cli
, UID_FIELD_INVALID
);
1054 return NT_STATUS_OK
;
1057 static char *cli_session_setup_get_account(TALLOC_CTX
*mem_ctx
,
1058 const char *principal
)
1062 account
= talloc_strdup(mem_ctx
, principal
);
1063 if (account
== NULL
) {
1066 p
= strchr_m(account
, '@');
1073 /****************************************************************************
1074 Do a spnego encrypted session setup.
1076 user_domain: The shortname of the domain the user/machine is a member of.
1077 dest_realm: The realm we're connecting to, if NULL we use our default realm.
1078 ****************************************************************************/
1080 struct cli_session_setup_spnego_state
{
1084 static void cli_session_setup_spnego_done(struct tevent_req
*subreq
);
1086 static struct tevent_req
*cli_session_setup_spnego_send(
1087 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
1088 struct cli_credentials
*creds
)
1090 struct tevent_req
*req
, *subreq
;
1091 struct cli_session_setup_spnego_state
*state
;
1092 const char *user_principal
= NULL
;
1093 const char *user_account
= NULL
;
1094 const char *user_domain
= NULL
;
1095 const char *pass
= NULL
;
1096 const char *target_hostname
= NULL
;
1097 const DATA_BLOB
*server_blob
= NULL
;
1098 enum credentials_use_kerberos krb5_state
;
1099 bool try_kerberos
= false;
1100 bool need_kinit
= false;
1101 bool auth_requested
= true;
1103 req
= tevent_req_create(mem_ctx
, &state
,
1104 struct cli_session_setup_spnego_state
);
1109 target_hostname
= smbXcli_conn_remote_name(cli
->conn
);
1110 server_blob
= smbXcli_conn_server_gss_blob(cli
->conn
);
1112 /* the server might not even do spnego */
1113 if (server_blob
!= NULL
&& server_blob
->length
!= 0) {
1114 char *principal
= NULL
;
1115 char *OIDs
[ASN1_MAX_OIDS
];
1118 /* The server sent us the first part of the SPNEGO exchange in the
1119 * negprot reply. It is WRONG to depend on the principal sent in the
1120 * negprot reply, but right now we do it. If we don't receive one,
1121 * we try to best guess, then fall back to NTLM. */
1122 if (!spnego_parse_negTokenInit(state
, *server_blob
, OIDs
,
1123 &principal
, NULL
) ||
1125 state
->result
= ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
1126 tevent_req_done(req
);
1127 return tevent_req_post(req
, ev
);
1129 TALLOC_FREE(principal
);
1131 /* make sure the server understands kerberos */
1132 for (i
= 0; OIDs
[i
] != NULL
; i
++) {
1134 DEBUG(3,("got OID=%s\n", OIDs
[i
]));
1136 DEBUGADD(3,("got OID=%s\n", OIDs
[i
]));
1139 if (strcmp(OIDs
[i
], OID_KERBEROS5_OLD
) == 0 ||
1140 strcmp(OIDs
[i
], OID_KERBEROS5
) == 0) {
1141 cli
->got_kerberos_mechanism
= True
;
1143 talloc_free(OIDs
[i
]);
1147 auth_requested
= cli_credentials_authentication_requested(creds
);
1148 if (auth_requested
) {
1149 user_principal
= cli_credentials_get_principal(creds
, state
);
1150 if (tevent_req_nomem(user_principal
, req
)) {
1151 return tevent_req_post(req
, ev
);
1154 user_account
= cli_credentials_get_username(creds
);
1155 user_domain
= cli_credentials_get_domain(creds
);
1156 pass
= cli_credentials_get_password(creds
);
1158 krb5_state
= cli_credentials_get_kerberos_state(creds
);
1160 if (krb5_state
!= CRED_DONT_USE_KERBEROS
) {
1161 try_kerberos
= true;
1164 if (target_hostname
== NULL
) {
1165 try_kerberos
= false;
1166 } else if (is_ipaddress(target_hostname
)) {
1167 try_kerberos
= false;
1168 } else if (strequal(target_hostname
, "localhost")) {
1169 try_kerberos
= false;
1170 } else if (strequal(target_hostname
, STAR_SMBSERVER
)) {
1171 try_kerberos
= false;
1172 } else if (!auth_requested
) {
1173 try_kerberos
= false;
1176 if (krb5_state
== CRED_MUST_USE_KERBEROS
&& !try_kerberos
) {
1177 DEBUG(0, ("Kerberos auth with '%s' (%s\\%s) to access "
1178 "'%s' not possible\n",
1179 user_principal
, user_domain
, user_account
,
1181 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1182 return tevent_req_post(req
, ev
);
1185 if (pass
== NULL
|| strlen(pass
) == 0) {
1187 } else if (krb5_state
== CRED_MUST_USE_KERBEROS
) {
1188 need_kinit
= try_kerberos
;
1189 } else if (!cli
->got_kerberos_mechanism
) {
1191 * Most likely the server doesn't support
1192 * Kerberos, don't waste time doing a kinit
1196 need_kinit
= try_kerberos
;
1202 use_in_memory_ccache();
1203 ret
= kerberos_kinit_password(user_principal
, pass
,
1204 0 /* no time correction for now */,
1208 DEBUG(0, ("Kinit for %s to access %s failed: %s\n",
1209 user_principal
, target_hostname
,
1210 error_message(ret
)));
1211 if (krb5_state
== CRED_MUST_USE_KERBEROS
) {
1212 state
->result
= ADS_ERROR_KRB5(ret
);
1213 tevent_req_done(req
);
1214 return tevent_req_post(req
, ev
);
1218 * Ignore the error and hope that NTLM will work
1224 subreq
= cli_session_setup_gensec_send(state
, ev
, cli
, creds
,
1225 "cifs", target_hostname
);
1226 if (tevent_req_nomem(subreq
, req
)) {
1227 return tevent_req_post(req
, ev
);
1229 tevent_req_set_callback(
1230 subreq
, cli_session_setup_spnego_done
, req
);
1234 static void cli_session_setup_spnego_done(struct tevent_req
*subreq
)
1236 struct tevent_req
*req
= tevent_req_callback_data(
1237 subreq
, struct tevent_req
);
1240 status
= cli_session_setup_gensec_recv(subreq
);
1241 TALLOC_FREE(subreq
);
1242 if (tevent_req_nterror(req
, status
)) {
1246 tevent_req_done(req
);
1249 static ADS_STATUS
cli_session_setup_spnego_recv(struct tevent_req
*req
)
1251 struct cli_session_setup_spnego_state
*state
= tevent_req_data(
1252 req
, struct cli_session_setup_spnego_state
);
1255 if (tevent_req_is_nterror(req
, &status
)) {
1256 state
->result
= ADS_ERROR_NT(status
);
1259 return state
->result
;
1262 struct cli_session_setup_creds_state
{
1263 struct cli_state
*cli
;
1264 DATA_BLOB apassword_blob
;
1265 DATA_BLOB upassword_blob
;
1266 DATA_BLOB lm_session_key
;
1267 DATA_BLOB session_key
;
1268 char *out_native_os
;
1269 char *out_native_lm
;
1270 char *out_primary_domain
;
1273 static void cli_session_setup_creds_cleanup(struct tevent_req
*req
,
1274 enum tevent_req_state req_state
)
1276 struct cli_session_setup_creds_state
*state
= tevent_req_data(
1277 req
, struct cli_session_setup_creds_state
);
1279 if (req_state
!= TEVENT_REQ_RECEIVED
) {
1284 * We only call data_blob_clear() as
1285 * some of the blobs point to the same memory.
1287 * We let the talloc hierachy free the memory.
1289 data_blob_clear(&state
->apassword_blob
);
1290 data_blob_clear(&state
->upassword_blob
);
1291 data_blob_clear(&state
->lm_session_key
);
1292 data_blob_clear(&state
->session_key
);
1293 ZERO_STRUCTP(state
);
1296 static void cli_session_setup_creds_done_spnego(struct tevent_req
*subreq
);
1297 static void cli_session_setup_creds_done_nt1(struct tevent_req
*subreq
);
1298 static void cli_session_setup_creds_done_lm21(struct tevent_req
*subreq
);
1300 /****************************************************************************
1301 Send a session setup. The username and workgroup is in UNIX character
1302 format and must be converted to DOS codepage format before sending. If the
1303 password is in plaintext, the same should be done.
1304 ****************************************************************************/
1306 struct tevent_req
*cli_session_setup_creds_send(TALLOC_CTX
*mem_ctx
,
1307 struct tevent_context
*ev
,
1308 struct cli_state
*cli
,
1309 struct cli_credentials
*creds
)
1311 struct tevent_req
*req
, *subreq
;
1312 struct cli_session_setup_creds_state
*state
;
1313 uint16_t sec_mode
= smb1cli_conn_server_security_mode(cli
->conn
);
1314 bool use_spnego
= false;
1316 enum credentials_use_kerberos krb5_state
;
1317 uint32_t gensec_features
;
1318 const char *username
= "";
1319 const char *domain
= "";
1320 DATA_BLOB target_info
= data_blob_null
;
1321 DATA_BLOB challenge
= data_blob_null
;
1322 uint16_t in_buf_size
= 0;
1323 uint16_t in_mpx_max
= 0;
1324 uint16_t in_vc_num
= 0;
1325 uint32_t in_sess_key
= 0;
1326 const char *in_native_os
= NULL
;
1327 const char *in_native_lm
= NULL
;
1330 req
= tevent_req_create(mem_ctx
, &state
,
1331 struct cli_session_setup_creds_state
);
1337 tevent_req_set_cleanup_fn(req
, cli_session_setup_creds_cleanup
);
1339 krb5_state
= cli_credentials_get_kerberos_state(creds
);
1340 gensec_features
= cli_credentials_get_gensec_features(creds
);
1342 switch (krb5_state
) {
1343 case CRED_MUST_USE_KERBEROS
:
1344 cli
->use_kerberos
= true;
1345 cli
->fallback_after_kerberos
= false;
1347 case CRED_AUTO_USE_KERBEROS
:
1348 cli
->use_kerberos
= true;
1349 cli
->fallback_after_kerberos
= true;
1351 case CRED_DONT_USE_KERBEROS
:
1352 cli
->use_kerberos
= false;
1353 cli
->fallback_after_kerberos
= false;
1357 if (gensec_features
& GENSEC_FEATURE_NTLM_CCACHE
) {
1358 cli
->use_ccache
= true;
1360 cli
->use_ccache
= false;
1364 * Now work out what sort of session setup we are going to
1365 * do. I have split this into separate functions to make the flow a bit
1366 * easier to understand (tridge).
1368 if (smbXcli_conn_protocol(cli
->conn
) < PROTOCOL_NT1
) {
1370 } else if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
1372 } else if (smb1cli_conn_capabilities(cli
->conn
) & CAP_EXTENDED_SECURITY
) {
1374 * if the server supports extended security then use SPNEGO
1375 * even for anonymous connections.
1383 subreq
= cli_session_setup_spnego_send(
1384 state
, ev
, cli
, creds
);
1385 if (tevent_req_nomem(subreq
, req
)) {
1386 return tevent_req_post(req
, ev
);
1388 tevent_req_set_callback(subreq
, cli_session_setup_creds_done_spnego
,
1393 if (smbXcli_conn_protocol(cli
->conn
) < PROTOCOL_LANMAN1
) {
1395 * SessionSetupAndX was introduced by LANMAN 1.0. So we skip
1396 * this step against older servers.
1398 tevent_req_done(req
);
1399 return tevent_req_post(req
, ev
);
1402 if (cli_credentials_is_anonymous(creds
)) {
1404 * Do an anonymous session setup
1406 goto non_spnego_creds_done
;
1409 if ((sec_mode
& NEGOTIATE_SECURITY_USER_LEVEL
) == 0) {
1411 * Do an anonymous session setup,
1412 * the password is passed via the tree connect.
1414 goto non_spnego_creds_done
;
1417 cli_credentials_get_ntlm_username_domain(creds
, state
,
1420 if (tevent_req_nomem(username
, req
)) {
1421 return tevent_req_post(req
, ev
);
1423 if (tevent_req_nomem(domain
, req
)) {
1424 return tevent_req_post(req
, ev
);
1427 if ((sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
) == 0) {
1428 bool use_unicode
= smbXcli_conn_use_unicode(cli
->conn
);
1429 uint8_t *bytes
= NULL
;
1430 size_t bytes_len
= 0;
1431 const char *pw
= cli_credentials_get_password(creds
);
1437 pw_len
= strlen(pw
) + 1;
1439 if (!lp_client_plaintext_auth()) {
1440 DEBUG(1, ("Server requested PLAINTEXT password but "
1441 "'client plaintext auth = no'\n"));
1442 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1443 return tevent_req_post(req
, ev
);
1446 bytes
= talloc_array(state
, uint8_t, 0);
1447 bytes
= trans2_bytes_push_str(bytes
, use_unicode
,
1448 pw
, pw_len
, &bytes_len
);
1449 if (tevent_req_nomem(bytes
, req
)) {
1450 return tevent_req_post(req
, ev
);
1455 * CAP_UNICODE, can only be negotiated by NT1.
1457 state
->upassword_blob
= data_blob_const(bytes
,
1460 state
->apassword_blob
= data_blob_const(bytes
,
1464 goto non_spnego_creds_done
;
1467 challenge
= data_blob_const(smb1cli_conn_server_challenge(cli
->conn
), 8);
1469 if (smbXcli_conn_protocol(cli
->conn
) == PROTOCOL_NT1
) {
1470 if (lp_client_ntlmv2_auth() && lp_client_use_spnego()) {
1472 * Don't send an NTLMv2 response without NTLMSSP if we
1473 * want to use spnego support.
1475 DEBUG(1, ("Server does not support EXTENDED_SECURITY "
1476 " but 'client use spnego = yes'"
1477 " and 'client ntlmv2 auth = yes' is set\n"));
1478 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1479 return tevent_req_post(req
, ev
);
1482 if (lp_client_ntlmv2_auth()) {
1483 flags
|= CLI_CRED_NTLMv2_AUTH
;
1486 * note that the 'domain' here is a best
1487 * guess - we don't know the server's domain
1488 * at this point. Windows clients also don't
1491 target_info
= NTLMv2_generate_names_blob(state
,
1494 if (tevent_req_nomem(target_info
.data
, req
)) {
1495 return tevent_req_post(req
, ev
);
1498 flags
|= CLI_CRED_NTLM_AUTH
;
1499 if (lp_client_lanman_auth()) {
1500 flags
|= CLI_CRED_LANMAN_AUTH
;
1504 if (!lp_client_lanman_auth()) {
1505 DEBUG(1, ("Server requested LM password but "
1506 "'client lanman auth = no' "
1507 "or 'client ntlmv2 auth = yes' is set\n"));
1508 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1509 return tevent_req_post(req
, ev
);
1512 flags
|= CLI_CRED_LANMAN_AUTH
;
1515 status
= cli_credentials_get_ntlm_response(creds
, state
, &flags
,
1518 &state
->apassword_blob
,
1519 &state
->upassword_blob
,
1520 &state
->lm_session_key
,
1521 &state
->session_key
);
1522 if (tevent_req_nterror(req
, status
)) {
1523 return tevent_req_post(req
, ev
);
1526 non_spnego_creds_done
:
1528 in_buf_size
= CLI_BUFFER_SIZE
;
1529 in_mpx_max
= smbXcli_conn_max_requests(cli
->conn
);
1530 in_vc_num
= cli_state_get_vc_num(cli
);
1531 in_sess_key
= smb1cli_conn_server_session_key(cli
->conn
);
1532 in_native_os
= "Unix";
1533 in_native_lm
= "Samba";
1535 if (smbXcli_conn_protocol(cli
->conn
) == PROTOCOL_NT1
) {
1536 uint32_t in_capabilities
= 0;
1538 in_capabilities
= cli_session_setup_capabilities(cli
, 0);
1541 * For now we keep the same values as before,
1542 * we may remove these in a separate commit later.
1546 subreq
= smb1cli_session_setup_nt1_send(state
, ev
,
1557 state
->apassword_blob
,
1558 state
->upassword_blob
,
1562 if (tevent_req_nomem(subreq
, req
)) {
1563 return tevent_req_post(req
, ev
);
1565 tevent_req_set_callback(subreq
, cli_session_setup_creds_done_nt1
,
1571 * For now we keep the same values as before,
1572 * we may remove these in a separate commit later.
1577 subreq
= smb1cli_session_setup_lm21_send(state
, ev
,
1588 state
->apassword_blob
,
1591 if (tevent_req_nomem(subreq
, req
)) {
1592 return tevent_req_post(req
, ev
);
1594 tevent_req_set_callback(subreq
, cli_session_setup_creds_done_lm21
,
1599 static void cli_session_setup_creds_done_spnego(struct tevent_req
*subreq
)
1601 struct tevent_req
*req
= tevent_req_callback_data(
1602 subreq
, struct tevent_req
);
1605 status
= cli_session_setup_spnego_recv(subreq
);
1606 TALLOC_FREE(subreq
);
1607 if (!ADS_ERR_OK(status
)) {
1608 DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status
)));
1609 tevent_req_nterror(req
, ads_ntstatus(status
));
1612 tevent_req_done(req
);
1615 static void cli_session_setup_creds_done_nt1(struct tevent_req
*subreq
)
1617 struct tevent_req
*req
= tevent_req_callback_data(
1618 subreq
, struct tevent_req
);
1619 struct cli_session_setup_creds_state
*state
= tevent_req_data(
1620 req
, struct cli_session_setup_creds_state
);
1621 struct cli_state
*cli
= state
->cli
;
1623 struct iovec
*recv_iov
= NULL
;
1624 const uint8_t *inbuf
= NULL
;
1627 status
= smb1cli_session_setup_nt1_recv(subreq
, state
,
1630 &state
->out_native_os
,
1631 &state
->out_native_lm
,
1632 &state
->out_primary_domain
);
1633 TALLOC_FREE(subreq
);
1634 if (!NT_STATUS_IS_OK(status
)) {
1635 DEBUG(3, ("NT1 login failed: %s\n", nt_errstr(status
)));
1636 tevent_req_nterror(req
, status
);
1640 if (cli
->server_os
== NULL
) {
1641 cli
->server_os
= talloc_move(cli
, &state
->out_native_os
);
1643 if (cli
->server_type
== NULL
) {
1644 cli
->server_type
= talloc_move(cli
, &state
->out_native_lm
);
1646 if (cli
->server_domain
== NULL
) {
1647 cli
->server_domain
= talloc_move(cli
, &state
->out_primary_domain
);
1650 ok
= smb1cli_conn_activate_signing(cli
->conn
,
1652 state
->upassword_blob
);
1654 ok
= smb1cli_conn_check_signing(cli
->conn
, inbuf
, 1);
1656 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1661 if (state
->session_key
.data
) {
1662 struct smbXcli_session
*session
= cli
->smb1
.session
;
1664 status
= smb1cli_session_set_session_key(session
,
1665 state
->session_key
);
1666 if (tevent_req_nterror(req
, status
)) {
1671 tevent_req_done(req
);
1674 static void cli_session_setup_creds_done_lm21(struct tevent_req
*subreq
)
1676 struct tevent_req
*req
= tevent_req_callback_data(
1677 subreq
, struct tevent_req
);
1678 struct cli_session_setup_creds_state
*state
= tevent_req_data(
1679 req
, struct cli_session_setup_creds_state
);
1680 struct cli_state
*cli
= state
->cli
;
1683 status
= smb1cli_session_setup_lm21_recv(subreq
, state
,
1684 &state
->out_native_os
,
1685 &state
->out_native_lm
);
1686 TALLOC_FREE(subreq
);
1687 if (!NT_STATUS_IS_OK(status
)) {
1688 DEBUG(3, ("LM21 login failed: %s\n", nt_errstr(status
)));
1689 tevent_req_nterror(req
, status
);
1693 if (cli
->server_os
== NULL
) {
1694 cli
->server_os
= talloc_move(cli
, &state
->out_native_os
);
1696 if (cli
->server_type
== NULL
) {
1697 cli
->server_type
= talloc_move(cli
, &state
->out_native_lm
);
1700 tevent_req_done(req
);
1703 NTSTATUS
cli_session_setup_creds_recv(struct tevent_req
*req
)
1705 return tevent_req_simple_recv_ntstatus(req
);
1708 NTSTATUS
cli_session_setup_creds(struct cli_state
*cli
,
1709 struct cli_credentials
*creds
)
1711 struct tevent_context
*ev
;
1712 struct tevent_req
*req
;
1713 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
1715 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
1716 return NT_STATUS_INVALID_PARAMETER
;
1718 ev
= samba_tevent_context_init(talloc_tos());
1722 req
= cli_session_setup_creds_send(ev
, ev
, cli
, creds
);
1726 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
1729 status
= cli_session_setup_creds_recv(req
);
1735 NTSTATUS
cli_session_setup_anon(struct cli_state
*cli
)
1737 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
1738 struct cli_credentials
*creds
= NULL
;
1740 creds
= cli_credentials_init_anon(cli
);
1741 if (creds
== NULL
) {
1742 return NT_STATUS_NO_MEMORY
;
1745 status
= cli_session_setup_creds(cli
, creds
);
1747 if (!NT_STATUS_IS_OK(status
)) {
1751 return NT_STATUS_OK
;
1754 NTSTATUS
cli_session_setup(struct cli_state
*cli
,
1757 const char *workgroup
)
1759 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
1760 const char *dest_realm
= NULL
;
1761 struct cli_credentials
*creds
= NULL
;
1764 * dest_realm is only valid in the winbindd use case,
1765 * where we also have the account in that realm.
1767 dest_realm
= cli_state_remote_realm(cli
);
1769 creds
= cli_session_creds_init(cli
,
1775 cli
->fallback_after_kerberos
,
1778 if (creds
== NULL
) {
1779 return NT_STATUS_NO_MEMORY
;
1782 status
= cli_session_setup_creds(cli
, creds
);
1784 if (!NT_STATUS_IS_OK(status
)) {
1788 return NT_STATUS_OK
;
1791 /****************************************************************************
1793 *****************************************************************************/
1795 struct cli_ulogoff_state
{
1796 struct cli_state
*cli
;
1800 static void cli_ulogoff_done(struct tevent_req
*subreq
);
1802 static struct tevent_req
*cli_ulogoff_send(TALLOC_CTX
*mem_ctx
,
1803 struct tevent_context
*ev
,
1804 struct cli_state
*cli
)
1806 struct tevent_req
*req
, *subreq
;
1807 struct cli_ulogoff_state
*state
;
1809 req
= tevent_req_create(mem_ctx
, &state
, struct cli_ulogoff_state
);
1815 SCVAL(state
->vwv
+0, 0, 0xFF);
1816 SCVAL(state
->vwv
+1, 0, 0);
1817 SSVAL(state
->vwv
+2, 0, 0);
1819 subreq
= cli_smb_send(state
, ev
, cli
, SMBulogoffX
, 0, 0, 2, state
->vwv
,
1821 if (tevent_req_nomem(subreq
, req
)) {
1822 return tevent_req_post(req
, ev
);
1824 tevent_req_set_callback(subreq
, cli_ulogoff_done
, req
);
1828 static void cli_ulogoff_done(struct tevent_req
*subreq
)
1830 struct tevent_req
*req
= tevent_req_callback_data(
1831 subreq
, struct tevent_req
);
1832 struct cli_ulogoff_state
*state
= tevent_req_data(
1833 req
, struct cli_ulogoff_state
);
1836 status
= cli_smb_recv(subreq
, NULL
, NULL
, 0, NULL
, NULL
, NULL
, NULL
);
1837 if (!NT_STATUS_IS_OK(status
)) {
1838 tevent_req_nterror(req
, status
);
1841 cli_state_set_uid(state
->cli
, UID_FIELD_INVALID
);
1842 tevent_req_done(req
);
1845 static NTSTATUS
cli_ulogoff_recv(struct tevent_req
*req
)
1847 return tevent_req_simple_recv_ntstatus(req
);
1850 NTSTATUS
cli_ulogoff(struct cli_state
*cli
)
1852 struct tevent_context
*ev
;
1853 struct tevent_req
*req
;
1854 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
1856 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
1857 status
= smb2cli_logoff(cli
->conn
,
1860 if (!NT_STATUS_IS_OK(status
)) {
1863 smb2cli_session_set_id_and_flags(cli
->smb2
.session
,
1865 return NT_STATUS_OK
;
1868 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
1869 return NT_STATUS_INVALID_PARAMETER
;
1871 ev
= samba_tevent_context_init(talloc_tos());
1875 req
= cli_ulogoff_send(ev
, ev
, cli
);
1879 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
1882 status
= cli_ulogoff_recv(req
);
1888 /****************************************************************************
1890 ****************************************************************************/
1892 struct cli_tcon_andx_state
{
1893 struct cli_state
*cli
;
1898 static void cli_tcon_andx_done(struct tevent_req
*subreq
);
1900 struct tevent_req
*cli_tcon_andx_create(TALLOC_CTX
*mem_ctx
,
1901 struct tevent_context
*ev
,
1902 struct cli_state
*cli
,
1903 const char *share
, const char *dev
,
1904 const char *pass
, int passlen
,
1905 struct tevent_req
**psmbreq
)
1907 struct tevent_req
*req
, *subreq
;
1908 struct cli_tcon_andx_state
*state
;
1913 uint16_t sec_mode
= smb1cli_conn_server_security_mode(cli
->conn
);
1914 uint16_t tcon_flags
= 0;
1918 req
= tevent_req_create(mem_ctx
, &state
, struct cli_tcon_andx_state
);
1925 cli
->share
= talloc_strdup(cli
, share
);
1930 /* in user level security don't send a password now */
1931 if (sec_mode
& NEGOTIATE_SECURITY_USER_LEVEL
) {
1934 } else if (pass
== NULL
) {
1935 DEBUG(1, ("Server not using user level security and no "
1936 "password supplied.\n"));
1940 if ((sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
) &&
1941 *pass
&& passlen
!= 24) {
1942 if (!lp_client_lanman_auth()) {
1943 DEBUG(1, ("Server requested LANMAN password "
1944 "(share-level security) but "
1945 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
1950 * Non-encrypted passwords - convert to DOS codepage before
1953 SMBencrypt(pass
, smb1cli_conn_server_challenge(cli
->conn
), p24
);
1955 pass
= (const char *)p24
;
1957 if((sec_mode
& (NEGOTIATE_SECURITY_USER_LEVEL
1958 |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
))
1962 if (!lp_client_plaintext_auth() && (*pass
)) {
1963 DEBUG(1, ("Server requested PLAINTEXT "
1965 "'client plaintext auth = no' or 'client ntlmv2 auth = yes'\n"));
1970 * Non-encrypted passwords - convert to DOS codepage
1973 tmp_pass
= talloc_array(talloc_tos(), uint8_t, 0);
1974 if (tevent_req_nomem(tmp_pass
, req
)) {
1975 return tevent_req_post(req
, ev
);
1977 tmp_pass
= trans2_bytes_push_str(tmp_pass
,
1978 false, /* always DOS */
1982 if (tevent_req_nomem(tmp_pass
, req
)) {
1983 return tevent_req_post(req
, ev
);
1985 pass
= (const char *)tmp_pass
;
1986 passlen
= talloc_get_size(tmp_pass
);
1990 tcon_flags
|= TCONX_FLAG_EXTENDED_RESPONSE
;
1991 tcon_flags
|= TCONX_FLAG_EXTENDED_SIGNATURES
;
1993 SCVAL(vwv
+0, 0, 0xFF);
1996 SSVAL(vwv
+2, 0, tcon_flags
);
1997 SSVAL(vwv
+3, 0, passlen
);
1999 if (passlen
&& pass
) {
2000 bytes
= (uint8_t *)talloc_memdup(state
, pass
, passlen
);
2002 bytes
= talloc_array(state
, uint8_t, 0);
2008 tmp
= talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
2009 smbXcli_conn_remote_name(cli
->conn
), share
);
2014 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), tmp
, strlen(tmp
)+1,
2019 * Add the devicetype
2021 tmp
= talloc_strdup_upper(talloc_tos(), dev
);
2026 bytes
= smb_bytes_push_str(bytes
, false, tmp
, strlen(tmp
)+1, NULL
);
2029 if (bytes
== NULL
) {
2034 state
->bytes
.iov_base
= (void *)bytes
;
2035 state
->bytes
.iov_len
= talloc_get_size(bytes
);
2037 subreq
= cli_smb_req_create(state
, ev
, cli
, SMBtconX
, 0, 0, 4, vwv
,
2039 if (subreq
== NULL
) {
2043 tevent_req_set_callback(subreq
, cli_tcon_andx_done
, req
);
2048 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
2049 return tevent_req_post(req
, ev
);
2052 struct tevent_req
*cli_tcon_andx_send(TALLOC_CTX
*mem_ctx
,
2053 struct tevent_context
*ev
,
2054 struct cli_state
*cli
,
2055 const char *share
, const char *dev
,
2056 const char *pass
, int passlen
)
2058 struct tevent_req
*req
, *subreq
;
2061 req
= cli_tcon_andx_create(mem_ctx
, ev
, cli
, share
, dev
, pass
, passlen
,
2066 if (subreq
== NULL
) {
2069 status
= smb1cli_req_chain_submit(&subreq
, 1);
2070 if (!NT_STATUS_IS_OK(status
)) {
2071 tevent_req_nterror(req
, status
);
2072 return tevent_req_post(req
, ev
);
2077 static void cli_tcon_andx_done(struct tevent_req
*subreq
)
2079 struct tevent_req
*req
= tevent_req_callback_data(
2080 subreq
, struct tevent_req
);
2081 struct cli_tcon_andx_state
*state
= tevent_req_data(
2082 req
, struct cli_tcon_andx_state
);
2083 struct cli_state
*cli
= state
->cli
;
2091 uint16_t optional_support
= 0;
2093 status
= cli_smb_recv(subreq
, state
, &in
, 0, &wct
, &vwv
,
2094 &num_bytes
, &bytes
);
2095 TALLOC_FREE(subreq
);
2096 if (!NT_STATUS_IS_OK(status
)) {
2097 tevent_req_nterror(req
, status
);
2101 inhdr
= in
+ NBT_HDR_SIZE
;
2104 if (clistr_pull_talloc(cli
,
2105 (const char *)inhdr
,
2106 SVAL(inhdr
, HDR_FLG2
),
2110 STR_TERMINATE
|STR_ASCII
) == -1) {
2111 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
2115 cli
->dev
= talloc_strdup(cli
, "");
2116 if (cli
->dev
== NULL
) {
2117 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
2122 if ((smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_NT1
) && (num_bytes
== 3)) {
2123 /* almost certainly win95 - enable bug fixes */
2128 * Make sure that we have the optional support 16-bit field. WCT > 2.
2129 * Avoids issues when connecting to Win9x boxes sharing files
2132 if ((wct
> 2) && (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_LANMAN2
)) {
2133 optional_support
= SVAL(vwv
+2, 0);
2136 if (optional_support
& SMB_EXTENDED_SIGNATURES
) {
2137 smb1cli_session_protect_session_key(cli
->smb1
.session
);
2140 smb1cli_tcon_set_values(state
->cli
->smb1
.tcon
,
2141 SVAL(inhdr
, HDR_TID
),
2143 0, /* maximal_access */
2144 0, /* guest_maximal_access */
2146 NULL
); /* fs_type */
2148 tevent_req_done(req
);
2151 NTSTATUS
cli_tcon_andx_recv(struct tevent_req
*req
)
2153 return tevent_req_simple_recv_ntstatus(req
);
2156 NTSTATUS
cli_tcon_andx(struct cli_state
*cli
, const char *share
,
2157 const char *dev
, const char *pass
, int passlen
)
2159 TALLOC_CTX
*frame
= talloc_stackframe();
2160 struct tevent_context
*ev
;
2161 struct tevent_req
*req
;
2162 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2164 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
2166 * Can't use sync call while an async call is in flight
2168 status
= NT_STATUS_INVALID_PARAMETER
;
2172 ev
= samba_tevent_context_init(frame
);
2177 req
= cli_tcon_andx_send(frame
, ev
, cli
, share
, dev
, pass
, passlen
);
2182 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2186 status
= cli_tcon_andx_recv(req
);
2192 struct cli_tree_connect_state
{
2193 struct cli_state
*cli
;
2196 static struct tevent_req
*cli_raw_tcon_send(
2197 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
2198 const char *service
, const char *pass
, const char *dev
);
2199 static NTSTATUS
cli_raw_tcon_recv(struct tevent_req
*req
,
2200 uint16_t *max_xmit
, uint16_t *tid
);
2202 static void cli_tree_connect_smb2_done(struct tevent_req
*subreq
);
2203 static void cli_tree_connect_andx_done(struct tevent_req
*subreq
);
2204 static void cli_tree_connect_raw_done(struct tevent_req
*subreq
);
2206 static struct tevent_req
*cli_tree_connect_send(
2207 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
2208 const char *share
, const char *dev
, const char *pass
, int passlen
)
2210 struct tevent_req
*req
, *subreq
;
2211 struct cli_tree_connect_state
*state
;
2213 req
= tevent_req_create(mem_ctx
, &state
,
2214 struct cli_tree_connect_state
);
2220 cli
->share
= talloc_strdup(cli
, share
);
2221 if (tevent_req_nomem(cli
->share
, req
)) {
2222 return tevent_req_post(req
, ev
);
2225 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
2228 cli
->smb2
.tcon
= smbXcli_tcon_create(cli
);
2229 if (tevent_req_nomem(cli
->smb2
.tcon
, req
)) {
2230 return tevent_req_post(req
, ev
);
2233 unc
= talloc_asprintf(state
, "\\\\%s\\%s",
2234 smbXcli_conn_remote_name(cli
->conn
),
2236 if (tevent_req_nomem(unc
, req
)) {
2237 return tevent_req_post(req
, ev
);
2240 subreq
= smb2cli_tcon_send(state
, ev
, cli
->conn
, cli
->timeout
,
2241 cli
->smb2
.session
, cli
->smb2
.tcon
,
2244 if (tevent_req_nomem(subreq
, req
)) {
2245 return tevent_req_post(req
, ev
);
2247 tevent_req_set_callback(subreq
, cli_tree_connect_smb2_done
,
2252 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_LANMAN1
) {
2253 subreq
= cli_tcon_andx_send(state
, ev
, cli
, share
, dev
,
2255 if (tevent_req_nomem(subreq
, req
)) {
2256 return tevent_req_post(req
, ev
);
2258 tevent_req_set_callback(subreq
, cli_tree_connect_andx_done
,
2263 subreq
= cli_raw_tcon_send(state
, ev
, cli
, share
, pass
, dev
);
2264 if (tevent_req_nomem(subreq
, req
)) {
2265 return tevent_req_post(req
, ev
);
2267 tevent_req_set_callback(subreq
, cli_tree_connect_raw_done
, req
);
2272 static void cli_tree_connect_smb2_done(struct tevent_req
*subreq
)
2274 tevent_req_simple_finish_ntstatus(
2275 subreq
, smb2cli_tcon_recv(subreq
));
2278 static void cli_tree_connect_andx_done(struct tevent_req
*subreq
)
2280 tevent_req_simple_finish_ntstatus(
2281 subreq
, cli_tcon_andx_recv(subreq
));
2284 static void cli_tree_connect_raw_done(struct tevent_req
*subreq
)
2286 struct tevent_req
*req
= tevent_req_callback_data(
2287 subreq
, struct tevent_req
);
2288 struct cli_tree_connect_state
*state
= tevent_req_data(
2289 req
, struct cli_tree_connect_state
);
2291 uint16_t max_xmit
= 0;
2294 status
= cli_raw_tcon_recv(subreq
, &max_xmit
, &tid
);
2295 if (tevent_req_nterror(req
, status
)) {
2299 smb1cli_tcon_set_values(state
->cli
->smb1
.tcon
,
2301 0, /* optional_support */
2302 0, /* maximal_access */
2303 0, /* guest_maximal_access */
2305 NULL
); /* fs_type */
2307 tevent_req_done(req
);
2310 static NTSTATUS
cli_tree_connect_recv(struct tevent_req
*req
)
2312 return tevent_req_simple_recv_ntstatus(req
);
2315 NTSTATUS
cli_tree_connect(struct cli_state
*cli
, const char *share
,
2316 const char *dev
, const char *pass
, int passlen
)
2318 struct tevent_context
*ev
;
2319 struct tevent_req
*req
;
2320 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2322 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
2323 return NT_STATUS_INVALID_PARAMETER
;
2325 ev
= samba_tevent_context_init(talloc_tos());
2329 req
= cli_tree_connect_send(ev
, ev
, cli
, share
, dev
, pass
, passlen
);
2333 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2336 status
= cli_tree_connect_recv(req
);
2342 /****************************************************************************
2343 Send a tree disconnect.
2344 ****************************************************************************/
2346 struct cli_tdis_state
{
2347 struct cli_state
*cli
;
2350 static void cli_tdis_done(struct tevent_req
*subreq
);
2352 static struct tevent_req
*cli_tdis_send(TALLOC_CTX
*mem_ctx
,
2353 struct tevent_context
*ev
,
2354 struct cli_state
*cli
)
2356 struct tevent_req
*req
, *subreq
;
2357 struct cli_tdis_state
*state
;
2359 req
= tevent_req_create(mem_ctx
, &state
, struct cli_tdis_state
);
2365 subreq
= cli_smb_send(state
, ev
, cli
, SMBtdis
, 0, 0, 0, NULL
, 0, NULL
);
2366 if (tevent_req_nomem(subreq
, req
)) {
2367 return tevent_req_post(req
, ev
);
2369 tevent_req_set_callback(subreq
, cli_tdis_done
, req
);
2373 static void cli_tdis_done(struct tevent_req
*subreq
)
2375 struct tevent_req
*req
= tevent_req_callback_data(
2376 subreq
, struct tevent_req
);
2377 struct cli_tdis_state
*state
= tevent_req_data(
2378 req
, struct cli_tdis_state
);
2381 status
= cli_smb_recv(subreq
, NULL
, NULL
, 0, NULL
, NULL
, NULL
, NULL
);
2382 TALLOC_FREE(subreq
);
2383 if (!NT_STATUS_IS_OK(status
)) {
2384 tevent_req_nterror(req
, status
);
2387 cli_state_set_tid(state
->cli
, UINT16_MAX
);
2388 tevent_req_done(req
);
2391 static NTSTATUS
cli_tdis_recv(struct tevent_req
*req
)
2393 return tevent_req_simple_recv_ntstatus(req
);
2396 NTSTATUS
cli_tdis(struct cli_state
*cli
)
2398 struct tevent_context
*ev
;
2399 struct tevent_req
*req
;
2400 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2402 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
2403 return smb2cli_tdis(cli
->conn
,
2409 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
2410 return NT_STATUS_INVALID_PARAMETER
;
2412 ev
= samba_tevent_context_init(talloc_tos());
2416 req
= cli_tdis_send(ev
, ev
, cli
);
2420 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2423 status
= cli_tdis_recv(req
);
2429 struct cli_connect_sock_state
{
2430 const char **called_names
;
2431 const char **calling_names
;
2437 static void cli_connect_sock_done(struct tevent_req
*subreq
);
2440 * Async only if we don't have to look up the name, i.e. "pss" is set with a
2444 static struct tevent_req
*cli_connect_sock_send(
2445 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
2446 const char *host
, int name_type
, const struct sockaddr_storage
*pss
,
2447 const char *myname
, uint16_t port
)
2449 struct tevent_req
*req
, *subreq
;
2450 struct cli_connect_sock_state
*state
;
2452 struct sockaddr_storage
*addrs
;
2453 unsigned i
, num_addrs
;
2456 req
= tevent_req_create(mem_ctx
, &state
,
2457 struct cli_connect_sock_state
);
2462 prog
= getenv("LIBSMB_PROG");
2464 state
->fd
= sock_exec(prog
);
2465 if (state
->fd
== -1) {
2466 status
= map_nt_error_from_unix(errno
);
2467 tevent_req_nterror(req
, status
);
2470 tevent_req_done(req
);
2472 return tevent_req_post(req
, ev
);
2475 if ((pss
== NULL
) || is_zero_addr(pss
)) {
2478 * Here we cheat. resolve_name_list is not async at all. So
2479 * this call will only be really async if the name lookup has
2480 * been done externally.
2483 status
= resolve_name_list(state
, host
, name_type
,
2484 &addrs
, &num_addrs
);
2485 if (!NT_STATUS_IS_OK(status
)) {
2486 tevent_req_nterror(req
, status
);
2487 return tevent_req_post(req
, ev
);
2490 addrs
= talloc_array(state
, struct sockaddr_storage
, 1);
2491 if (tevent_req_nomem(addrs
, req
)) {
2492 return tevent_req_post(req
, ev
);
2498 state
->called_names
= talloc_array(state
, const char *, num_addrs
);
2499 if (tevent_req_nomem(state
->called_names
, req
)) {
2500 return tevent_req_post(req
, ev
);
2502 state
->called_types
= talloc_array(state
, int, num_addrs
);
2503 if (tevent_req_nomem(state
->called_types
, req
)) {
2504 return tevent_req_post(req
, ev
);
2506 state
->calling_names
= talloc_array(state
, const char *, num_addrs
);
2507 if (tevent_req_nomem(state
->calling_names
, req
)) {
2508 return tevent_req_post(req
, ev
);
2510 for (i
=0; i
<num_addrs
; i
++) {
2511 state
->called_names
[i
] = host
;
2512 state
->called_types
[i
] = name_type
;
2513 state
->calling_names
[i
] = myname
;
2516 subreq
= smbsock_any_connect_send(
2517 state
, ev
, addrs
, state
->called_names
, state
->called_types
,
2518 state
->calling_names
, NULL
, num_addrs
, port
);
2519 if (tevent_req_nomem(subreq
, req
)) {
2520 return tevent_req_post(req
, ev
);
2522 tevent_req_set_callback(subreq
, cli_connect_sock_done
, req
);
2526 static void cli_connect_sock_done(struct tevent_req
*subreq
)
2528 struct tevent_req
*req
= tevent_req_callback_data(
2529 subreq
, struct tevent_req
);
2530 struct cli_connect_sock_state
*state
= tevent_req_data(
2531 req
, struct cli_connect_sock_state
);
2534 status
= smbsock_any_connect_recv(subreq
, &state
->fd
, NULL
,
2536 TALLOC_FREE(subreq
);
2537 if (tevent_req_nterror(req
, status
)) {
2540 set_socket_options(state
->fd
, lp_socket_options());
2541 tevent_req_done(req
);
2544 static NTSTATUS
cli_connect_sock_recv(struct tevent_req
*req
,
2545 int *pfd
, uint16_t *pport
)
2547 struct cli_connect_sock_state
*state
= tevent_req_data(
2548 req
, struct cli_connect_sock_state
);
2551 if (tevent_req_is_nterror(req
, &status
)) {
2555 *pport
= state
->port
;
2556 return NT_STATUS_OK
;
2559 struct cli_connect_nb_state
{
2560 const char *desthost
;
2563 struct cli_state
*cli
;
2566 static void cli_connect_nb_done(struct tevent_req
*subreq
);
2568 static struct tevent_req
*cli_connect_nb_send(
2569 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
2570 const char *host
, const struct sockaddr_storage
*dest_ss
,
2571 uint16_t port
, int name_type
, const char *myname
,
2572 int signing_state
, int flags
)
2574 struct tevent_req
*req
, *subreq
;
2575 struct cli_connect_nb_state
*state
;
2577 req
= tevent_req_create(mem_ctx
, &state
, struct cli_connect_nb_state
);
2581 state
->signing_state
= signing_state
;
2582 state
->flags
= flags
;
2585 char *p
= strchr(host
, '#');
2588 name_type
= strtol(p
+1, NULL
, 16);
2589 host
= talloc_strndup(state
, host
, p
- host
);
2590 if (tevent_req_nomem(host
, req
)) {
2591 return tevent_req_post(req
, ev
);
2595 state
->desthost
= host
;
2596 } else if (dest_ss
!= NULL
) {
2597 state
->desthost
= print_canonical_sockaddr(state
, dest_ss
);
2598 if (tevent_req_nomem(state
->desthost
, req
)) {
2599 return tevent_req_post(req
, ev
);
2602 /* No host or dest_ss given. Error out. */
2603 tevent_req_error(req
, EINVAL
);
2604 return tevent_req_post(req
, ev
);
2607 subreq
= cli_connect_sock_send(state
, ev
, host
, name_type
, dest_ss
,
2609 if (tevent_req_nomem(subreq
, req
)) {
2610 return tevent_req_post(req
, ev
);
2612 tevent_req_set_callback(subreq
, cli_connect_nb_done
, req
);
2616 static void cli_connect_nb_done(struct tevent_req
*subreq
)
2618 struct tevent_req
*req
= tevent_req_callback_data(
2619 subreq
, struct tevent_req
);
2620 struct cli_connect_nb_state
*state
= tevent_req_data(
2621 req
, struct cli_connect_nb_state
);
2626 status
= cli_connect_sock_recv(subreq
, &fd
, &port
);
2627 TALLOC_FREE(subreq
);
2628 if (tevent_req_nterror(req
, status
)) {
2632 state
->cli
= cli_state_create(state
, fd
, state
->desthost
, NULL
,
2633 state
->signing_state
, state
->flags
);
2634 if (tevent_req_nomem(state
->cli
, req
)) {
2638 tevent_req_done(req
);
2641 static NTSTATUS
cli_connect_nb_recv(struct tevent_req
*req
,
2642 struct cli_state
**pcli
)
2644 struct cli_connect_nb_state
*state
= tevent_req_data(
2645 req
, struct cli_connect_nb_state
);
2648 if (tevent_req_is_nterror(req
, &status
)) {
2651 *pcli
= talloc_move(NULL
, &state
->cli
);
2652 return NT_STATUS_OK
;
2655 NTSTATUS
cli_connect_nb(const char *host
, const struct sockaddr_storage
*dest_ss
,
2656 uint16_t port
, int name_type
, const char *myname
,
2657 int signing_state
, int flags
, struct cli_state
**pcli
)
2659 struct tevent_context
*ev
;
2660 struct tevent_req
*req
;
2661 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2663 ev
= samba_tevent_context_init(talloc_tos());
2667 req
= cli_connect_nb_send(ev
, ev
, host
, dest_ss
, port
, name_type
,
2668 myname
, signing_state
, flags
);
2672 if (!tevent_req_set_endtime(req
, ev
, timeval_current_ofs(20, 0))) {
2675 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2678 status
= cli_connect_nb_recv(req
, pcli
);
2684 struct cli_start_connection_state
{
2685 struct tevent_context
*ev
;
2686 struct cli_state
*cli
;
2691 static void cli_start_connection_connected(struct tevent_req
*subreq
);
2692 static void cli_start_connection_done(struct tevent_req
*subreq
);
2695 establishes a connection to after the negprot.
2696 @param output_cli A fully initialised cli structure, non-null only on success
2697 @param dest_host The netbios name of the remote host
2698 @param dest_ss (optional) The the destination IP, NULL for name based lookup
2699 @param port (optional) The destination port (0 for default)
2702 static struct tevent_req
*cli_start_connection_send(
2703 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
2704 const char *my_name
, const char *dest_host
,
2705 const struct sockaddr_storage
*dest_ss
, int port
,
2706 int signing_state
, int flags
)
2708 struct tevent_req
*req
, *subreq
;
2709 struct cli_start_connection_state
*state
;
2711 req
= tevent_req_create(mem_ctx
, &state
,
2712 struct cli_start_connection_state
);
2718 if (signing_state
== SMB_SIGNING_IPC_DEFAULT
) {
2719 state
->min_protocol
= lp_client_ipc_min_protocol();
2720 state
->max_protocol
= lp_client_ipc_max_protocol();
2722 state
->min_protocol
= lp_client_min_protocol();
2723 state
->max_protocol
= lp_client_max_protocol();
2726 subreq
= cli_connect_nb_send(state
, ev
, dest_host
, dest_ss
, port
,
2727 0x20, my_name
, signing_state
, flags
);
2728 if (tevent_req_nomem(subreq
, req
)) {
2729 return tevent_req_post(req
, ev
);
2731 tevent_req_set_callback(subreq
, cli_start_connection_connected
, req
);
2735 static void cli_start_connection_connected(struct tevent_req
*subreq
)
2737 struct tevent_req
*req
= tevent_req_callback_data(
2738 subreq
, struct tevent_req
);
2739 struct cli_start_connection_state
*state
= tevent_req_data(
2740 req
, struct cli_start_connection_state
);
2743 status
= cli_connect_nb_recv(subreq
, &state
->cli
);
2744 TALLOC_FREE(subreq
);
2745 if (tevent_req_nterror(req
, status
)) {
2749 subreq
= smbXcli_negprot_send(state
, state
->ev
, state
->cli
->conn
,
2750 state
->cli
->timeout
,
2751 state
->min_protocol
,
2752 state
->max_protocol
);
2753 if (tevent_req_nomem(subreq
, req
)) {
2756 tevent_req_set_callback(subreq
, cli_start_connection_done
, req
);
2759 static void cli_start_connection_done(struct tevent_req
*subreq
)
2761 struct tevent_req
*req
= tevent_req_callback_data(
2762 subreq
, struct tevent_req
);
2763 struct cli_start_connection_state
*state
= tevent_req_data(
2764 req
, struct cli_start_connection_state
);
2767 status
= smbXcli_negprot_recv(subreq
);
2768 TALLOC_FREE(subreq
);
2769 if (tevent_req_nterror(req
, status
)) {
2773 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
2774 /* Ensure we ask for some initial credits. */
2775 smb2cli_conn_set_max_credits(state
->cli
->conn
,
2776 DEFAULT_SMB2_MAX_CREDITS
);
2779 tevent_req_done(req
);
2782 static NTSTATUS
cli_start_connection_recv(struct tevent_req
*req
,
2783 struct cli_state
**output_cli
)
2785 struct cli_start_connection_state
*state
= tevent_req_data(
2786 req
, struct cli_start_connection_state
);
2789 if (tevent_req_is_nterror(req
, &status
)) {
2792 *output_cli
= state
->cli
;
2794 return NT_STATUS_OK
;
2797 NTSTATUS
cli_start_connection(struct cli_state
**output_cli
,
2798 const char *my_name
,
2799 const char *dest_host
,
2800 const struct sockaddr_storage
*dest_ss
, int port
,
2801 int signing_state
, int flags
)
2803 struct tevent_context
*ev
;
2804 struct tevent_req
*req
;
2805 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2807 ev
= samba_tevent_context_init(talloc_tos());
2811 req
= cli_start_connection_send(ev
, ev
, my_name
, dest_host
, dest_ss
,
2812 port
, signing_state
, flags
);
2816 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2819 status
= cli_start_connection_recv(req
, output_cli
);
2826 establishes a connection right up to doing tconX, password specified.
2827 @param output_cli A fully initialised cli structure, non-null only on success
2828 @param dest_host The netbios name of the remote host
2829 @param dest_ip (optional) The the destination IP, NULL for name based lookup
2830 @param port (optional) The destination port (0 for default)
2831 @param service (optional) The share to make the connection to. Should be 'unqualified' in any way.
2832 @param service_type The 'type' of serivice.
2833 @param user Username, unix string
2834 @param domain User's domain
2835 @param password User's password, unencrypted unix string.
2838 struct cli_full_connection_state
{
2839 struct tevent_context
*ev
;
2840 const char *service
;
2841 const char *service_type
;
2844 const char *password
;
2847 struct cli_state
*cli
;
2850 static int cli_full_connection_state_destructor(
2851 struct cli_full_connection_state
*s
);
2852 static void cli_full_connection_started(struct tevent_req
*subreq
);
2853 static void cli_full_connection_sess_set_up(struct tevent_req
*subreq
);
2854 static void cli_full_connection_done(struct tevent_req
*subreq
);
2856 struct tevent_req
*cli_full_connection_send(
2857 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
2858 const char *my_name
, const char *dest_host
,
2859 const struct sockaddr_storage
*dest_ss
, int port
,
2860 const char *service
, const char *service_type
,
2861 const char *user
, const char *domain
,
2862 const char *password
, int flags
, int signing_state
)
2864 struct tevent_req
*req
, *subreq
;
2865 struct cli_full_connection_state
*state
;
2867 req
= tevent_req_create(mem_ctx
, &state
,
2868 struct cli_full_connection_state
);
2872 talloc_set_destructor(state
, cli_full_connection_state_destructor
);
2875 state
->service
= service
;
2876 state
->service_type
= service_type
;
2878 state
->domain
= domain
;
2879 state
->password
= password
;
2880 state
->flags
= flags
;
2882 state
->pw_len
= state
->password
? strlen(state
->password
)+1 : 0;
2883 if (state
->password
== NULL
) {
2884 state
->password
= "";
2887 subreq
= cli_start_connection_send(
2888 state
, ev
, my_name
, dest_host
, dest_ss
, port
,
2889 signing_state
, flags
);
2890 if (tevent_req_nomem(subreq
, req
)) {
2891 return tevent_req_post(req
, ev
);
2893 tevent_req_set_callback(subreq
, cli_full_connection_started
, req
);
2897 static int cli_full_connection_state_destructor(
2898 struct cli_full_connection_state
*s
)
2900 if (s
->cli
!= NULL
) {
2901 cli_shutdown(s
->cli
);
2907 static void cli_full_connection_started(struct tevent_req
*subreq
)
2909 struct tevent_req
*req
= tevent_req_callback_data(
2910 subreq
, struct tevent_req
);
2911 struct cli_full_connection_state
*state
= tevent_req_data(
2912 req
, struct cli_full_connection_state
);
2914 struct cli_credentials
*creds
= NULL
;
2916 status
= cli_start_connection_recv(subreq
, &state
->cli
);
2917 TALLOC_FREE(subreq
);
2918 if (tevent_req_nterror(req
, status
)) {
2922 creds
= cli_session_creds_init(state
,
2925 NULL
, /* realm (use default) */
2927 state
->cli
->use_kerberos
,
2928 state
->cli
->fallback_after_kerberos
,
2929 state
->cli
->use_ccache
,
2930 state
->cli
->pw_nt_hash
);
2931 if (tevent_req_nomem(creds
, req
)) {
2935 subreq
= cli_session_setup_creds_send(
2936 state
, state
->ev
, state
->cli
, creds
);
2937 if (tevent_req_nomem(subreq
, req
)) {
2940 tevent_req_set_callback(subreq
, cli_full_connection_sess_set_up
, req
);
2943 static void cli_full_connection_sess_set_up(struct tevent_req
*subreq
)
2945 struct tevent_req
*req
= tevent_req_callback_data(
2946 subreq
, struct tevent_req
);
2947 struct cli_full_connection_state
*state
= tevent_req_data(
2948 req
, struct cli_full_connection_state
);
2951 status
= cli_session_setup_creds_recv(subreq
);
2952 TALLOC_FREE(subreq
);
2954 if (!NT_STATUS_IS_OK(status
) &&
2955 (state
->flags
& CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK
)) {
2956 struct cli_credentials
*creds
= NULL
;
2958 state
->flags
&= ~CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK
;
2960 creds
= cli_credentials_init_anon(state
);
2961 if (tevent_req_nomem(creds
, req
)) {
2965 subreq
= cli_session_setup_creds_send(
2966 state
, state
->ev
, state
->cli
, creds
);
2967 if (tevent_req_nomem(subreq
, req
)) {
2970 tevent_req_set_callback(
2971 subreq
, cli_full_connection_sess_set_up
, req
);
2975 if (tevent_req_nterror(req
, status
)) {
2979 if (state
->service
!= NULL
) {
2980 subreq
= cli_tree_connect_send(
2981 state
, state
->ev
, state
->cli
,
2982 state
->service
, state
->service_type
,
2983 state
->password
, state
->pw_len
);
2984 if (tevent_req_nomem(subreq
, req
)) {
2987 tevent_req_set_callback(subreq
, cli_full_connection_done
, req
);
2991 tevent_req_done(req
);
2994 static void cli_full_connection_done(struct tevent_req
*subreq
)
2996 struct tevent_req
*req
= tevent_req_callback_data(
2997 subreq
, struct tevent_req
);
3000 status
= cli_tree_connect_recv(subreq
);
3001 TALLOC_FREE(subreq
);
3002 if (tevent_req_nterror(req
, status
)) {
3006 tevent_req_done(req
);
3009 NTSTATUS
cli_full_connection_recv(struct tevent_req
*req
,
3010 struct cli_state
**output_cli
)
3012 struct cli_full_connection_state
*state
= tevent_req_data(
3013 req
, struct cli_full_connection_state
);
3016 if (tevent_req_is_nterror(req
, &status
)) {
3019 *output_cli
= state
->cli
;
3020 talloc_set_destructor(state
, NULL
);
3021 return NT_STATUS_OK
;
3024 NTSTATUS
cli_full_connection(struct cli_state
**output_cli
,
3025 const char *my_name
,
3026 const char *dest_host
,
3027 const struct sockaddr_storage
*dest_ss
, int port
,
3028 const char *service
, const char *service_type
,
3029 const char *user
, const char *domain
,
3030 const char *password
, int flags
,
3033 struct tevent_context
*ev
;
3034 struct tevent_req
*req
;
3035 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
3037 ev
= samba_tevent_context_init(talloc_tos());
3041 req
= cli_full_connection_send(
3042 ev
, ev
, my_name
, dest_host
, dest_ss
, port
, service
,
3043 service_type
, user
, domain
, password
, flags
, signing_state
);
3047 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
3050 status
= cli_full_connection_recv(req
, output_cli
);
3056 /****************************************************************************
3057 Send an old style tcon.
3058 ****************************************************************************/
3059 struct cli_raw_tcon_state
{
3063 static void cli_raw_tcon_done(struct tevent_req
*subreq
);
3065 static struct tevent_req
*cli_raw_tcon_send(
3066 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
3067 const char *service
, const char *pass
, const char *dev
)
3069 struct tevent_req
*req
, *subreq
;
3070 struct cli_raw_tcon_state
*state
;
3073 req
= tevent_req_create(mem_ctx
, &state
, struct cli_raw_tcon_state
);
3078 if (!lp_client_plaintext_auth() && (*pass
)) {
3079 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
3080 " or 'client ntlmv2 auth = yes'\n"));
3081 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
3082 return tevent_req_post(req
, ev
);
3085 bytes
= talloc_array(state
, uint8_t, 0);
3086 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
3087 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
3088 service
, strlen(service
)+1, NULL
);
3089 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
3090 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
3091 pass
, strlen(pass
)+1, NULL
);
3092 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
3093 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
3094 dev
, strlen(dev
)+1, NULL
);
3096 if (tevent_req_nomem(bytes
, req
)) {
3097 return tevent_req_post(req
, ev
);
3100 subreq
= cli_smb_send(state
, ev
, cli
, SMBtcon
, 0, 0, 0, NULL
,
3101 talloc_get_size(bytes
), bytes
);
3102 if (tevent_req_nomem(subreq
, req
)) {
3103 return tevent_req_post(req
, ev
);
3105 tevent_req_set_callback(subreq
, cli_raw_tcon_done
, req
);
3109 static void cli_raw_tcon_done(struct tevent_req
*subreq
)
3111 struct tevent_req
*req
= tevent_req_callback_data(
3112 subreq
, struct tevent_req
);
3113 struct cli_raw_tcon_state
*state
= tevent_req_data(
3114 req
, struct cli_raw_tcon_state
);
3117 status
= cli_smb_recv(subreq
, state
, NULL
, 2, NULL
, &state
->ret_vwv
,
3119 TALLOC_FREE(subreq
);
3120 if (tevent_req_nterror(req
, status
)) {
3123 tevent_req_done(req
);
3126 static NTSTATUS
cli_raw_tcon_recv(struct tevent_req
*req
,
3127 uint16_t *max_xmit
, uint16_t *tid
)
3129 struct cli_raw_tcon_state
*state
= tevent_req_data(
3130 req
, struct cli_raw_tcon_state
);
3133 if (tevent_req_is_nterror(req
, &status
)) {
3136 *max_xmit
= SVAL(state
->ret_vwv
+ 0, 0);
3137 *tid
= SVAL(state
->ret_vwv
+ 1, 0);
3138 return NT_STATUS_OK
;
3141 NTSTATUS
cli_raw_tcon(struct cli_state
*cli
,
3142 const char *service
, const char *pass
, const char *dev
,
3143 uint16_t *max_xmit
, uint16_t *tid
)
3145 struct tevent_context
*ev
;
3146 struct tevent_req
*req
;
3147 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
3149 ev
= samba_tevent_context_init(talloc_tos());
3153 req
= cli_raw_tcon_send(ev
, ev
, cli
, service
, pass
, dev
);
3157 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
3160 status
= cli_raw_tcon_recv(req
, max_xmit
, tid
);
3166 /* Return a cli_state pointing at the IPC$ share for the given server */
3168 struct cli_state
*get_ipc_connect(char *server
,
3169 struct sockaddr_storage
*server_ss
,
3170 const struct user_auth_info
*user_info
)
3172 struct cli_state
*cli
;
3174 uint32_t flags
= CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK
;
3176 if (get_cmdline_auth_info_use_kerberos(user_info
)) {
3177 flags
|= CLI_FULL_CONNECTION_USE_KERBEROS
;
3180 nt_status
= cli_full_connection(&cli
, NULL
, server
, server_ss
, 0, "IPC$", "IPC",
3181 get_cmdline_auth_info_username(user_info
),
3183 get_cmdline_auth_info_password(user_info
),
3185 SMB_SIGNING_DEFAULT
);
3187 if (NT_STATUS_IS_OK(nt_status
)) {
3189 } else if (is_ipaddress(server
)) {
3190 /* windows 9* needs a correct NMB name for connections */
3191 fstring remote_name
;
3193 if (name_status_find("*", 0, 0, server_ss
, remote_name
)) {
3194 cli
= get_ipc_connect(remote_name
, server_ss
, user_info
);
3203 * Given the IP address of a master browser on the network, return its
3204 * workgroup and connect to it.
3206 * This function is provided to allow additional processing beyond what
3207 * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
3208 * browsers and obtain each master browsers' list of domains (in case the
3209 * first master browser is recently on the network and has not yet
3210 * synchronized with other master browsers and therefore does not yet have the
3211 * entire network browse list)
3214 struct cli_state
*get_ipc_connect_master_ip(TALLOC_CTX
*ctx
,
3215 struct sockaddr_storage
*mb_ip
,
3216 const struct user_auth_info
*user_info
,
3217 char **pp_workgroup_out
)
3219 char addr
[INET6_ADDRSTRLEN
];
3221 struct cli_state
*cli
;
3222 struct sockaddr_storage server_ss
;
3224 *pp_workgroup_out
= NULL
;
3226 print_sockaddr(addr
, sizeof(addr
), mb_ip
);
3227 DEBUG(99, ("Looking up name of master browser %s\n",
3231 * Do a name status query to find out the name of the master browser.
3232 * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
3233 * master browser will not respond to a wildcard query (or, at least,
3234 * an NT4 server acting as the domain master browser will not).
3236 * We might be able to use ONLY the query on MSBROWSE, but that's not
3237 * yet been tested with all Windows versions, so until it is, leave
3238 * the original wildcard query as the first choice and fall back to
3239 * MSBROWSE if the wildcard query fails.
3241 if (!name_status_find("*", 0, 0x1d, mb_ip
, name
) &&
3242 !name_status_find(MSBROWSE
, 1, 0x1d, mb_ip
, name
)) {
3244 DEBUG(99, ("Could not retrieve name status for %s\n",
3249 if (!find_master_ip(name
, &server_ss
)) {
3250 DEBUG(99, ("Could not find master ip for %s\n", name
));
3254 *pp_workgroup_out
= talloc_strdup(ctx
, name
);
3256 DEBUG(4, ("found master browser %s, %s\n", name
, addr
));
3258 print_sockaddr(addr
, sizeof(addr
), &server_ss
);
3259 cli
= get_ipc_connect(addr
, &server_ss
, user_info
);
3265 * Return the IP address and workgroup of a master browser on the network, and
3269 struct cli_state
*get_ipc_connect_master_ip_bcast(TALLOC_CTX
*ctx
,
3270 const struct user_auth_info
*user_info
,
3271 char **pp_workgroup_out
)
3273 struct sockaddr_storage
*ip_list
;
3274 struct cli_state
*cli
;
3278 *pp_workgroup_out
= NULL
;
3280 DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
3282 /* Go looking for workgroups by broadcasting on the local network */
3284 status
= name_resolve_bcast(MSBROWSE
, 1, talloc_tos(),
3286 if (!NT_STATUS_IS_OK(status
)) {
3287 DEBUG(99, ("No master browsers responded: %s\n",
3288 nt_errstr(status
)));
3292 for (i
= 0; i
< count
; i
++) {
3293 char addr
[INET6_ADDRSTRLEN
];
3294 print_sockaddr(addr
, sizeof(addr
), &ip_list
[i
]);
3295 DEBUG(99, ("Found master browser %s\n", addr
));
3297 cli
= get_ipc_connect_master_ip(ctx
, &ip_list
[i
],
3298 user_info
, pp_workgroup_out
);