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 static 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(struct cli_state
*cli
,
1738 const char *workgroup
)
1740 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
1741 const char *dest_realm
= NULL
;
1742 struct cli_credentials
*creds
= NULL
;
1745 * dest_realm is only valid in the winbindd use case,
1746 * where we also have the account in that realm.
1748 dest_realm
= cli_state_remote_realm(cli
);
1750 creds
= cli_session_creds_init(cli
,
1756 cli
->fallback_after_kerberos
,
1759 if (creds
== NULL
) {
1760 return NT_STATUS_NO_MEMORY
;
1763 status
= cli_session_setup_creds(cli
, creds
);
1765 if (!NT_STATUS_IS_OK(status
)) {
1769 return NT_STATUS_OK
;
1772 /****************************************************************************
1774 *****************************************************************************/
1776 struct cli_ulogoff_state
{
1777 struct cli_state
*cli
;
1781 static void cli_ulogoff_done(struct tevent_req
*subreq
);
1783 static struct tevent_req
*cli_ulogoff_send(TALLOC_CTX
*mem_ctx
,
1784 struct tevent_context
*ev
,
1785 struct cli_state
*cli
)
1787 struct tevent_req
*req
, *subreq
;
1788 struct cli_ulogoff_state
*state
;
1790 req
= tevent_req_create(mem_ctx
, &state
, struct cli_ulogoff_state
);
1796 SCVAL(state
->vwv
+0, 0, 0xFF);
1797 SCVAL(state
->vwv
+1, 0, 0);
1798 SSVAL(state
->vwv
+2, 0, 0);
1800 subreq
= cli_smb_send(state
, ev
, cli
, SMBulogoffX
, 0, 0, 2, state
->vwv
,
1802 if (tevent_req_nomem(subreq
, req
)) {
1803 return tevent_req_post(req
, ev
);
1805 tevent_req_set_callback(subreq
, cli_ulogoff_done
, req
);
1809 static void cli_ulogoff_done(struct tevent_req
*subreq
)
1811 struct tevent_req
*req
= tevent_req_callback_data(
1812 subreq
, struct tevent_req
);
1813 struct cli_ulogoff_state
*state
= tevent_req_data(
1814 req
, struct cli_ulogoff_state
);
1817 status
= cli_smb_recv(subreq
, NULL
, NULL
, 0, NULL
, NULL
, NULL
, NULL
);
1818 if (!NT_STATUS_IS_OK(status
)) {
1819 tevent_req_nterror(req
, status
);
1822 cli_state_set_uid(state
->cli
, UID_FIELD_INVALID
);
1823 tevent_req_done(req
);
1826 static NTSTATUS
cli_ulogoff_recv(struct tevent_req
*req
)
1828 return tevent_req_simple_recv_ntstatus(req
);
1831 NTSTATUS
cli_ulogoff(struct cli_state
*cli
)
1833 struct tevent_context
*ev
;
1834 struct tevent_req
*req
;
1835 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
1837 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
1838 status
= smb2cli_logoff(cli
->conn
,
1841 if (!NT_STATUS_IS_OK(status
)) {
1844 smb2cli_session_set_id_and_flags(cli
->smb2
.session
,
1846 return NT_STATUS_OK
;
1849 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
1850 return NT_STATUS_INVALID_PARAMETER
;
1852 ev
= samba_tevent_context_init(talloc_tos());
1856 req
= cli_ulogoff_send(ev
, ev
, cli
);
1860 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
1863 status
= cli_ulogoff_recv(req
);
1869 /****************************************************************************
1871 ****************************************************************************/
1873 struct cli_tcon_andx_state
{
1874 struct cli_state
*cli
;
1879 static void cli_tcon_andx_done(struct tevent_req
*subreq
);
1881 struct tevent_req
*cli_tcon_andx_create(TALLOC_CTX
*mem_ctx
,
1882 struct tevent_context
*ev
,
1883 struct cli_state
*cli
,
1884 const char *share
, const char *dev
,
1885 const char *pass
, int passlen
,
1886 struct tevent_req
**psmbreq
)
1888 struct tevent_req
*req
, *subreq
;
1889 struct cli_tcon_andx_state
*state
;
1894 uint16_t sec_mode
= smb1cli_conn_server_security_mode(cli
->conn
);
1895 uint16_t tcon_flags
= 0;
1899 req
= tevent_req_create(mem_ctx
, &state
, struct cli_tcon_andx_state
);
1906 cli
->share
= talloc_strdup(cli
, share
);
1911 /* in user level security don't send a password now */
1912 if (sec_mode
& NEGOTIATE_SECURITY_USER_LEVEL
) {
1915 } else if (pass
== NULL
) {
1916 DEBUG(1, ("Server not using user level security and no "
1917 "password supplied.\n"));
1921 if ((sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
) &&
1922 *pass
&& passlen
!= 24) {
1923 if (!lp_client_lanman_auth()) {
1924 DEBUG(1, ("Server requested LANMAN password "
1925 "(share-level security) but "
1926 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
1931 * Non-encrypted passwords - convert to DOS codepage before
1934 SMBencrypt(pass
, smb1cli_conn_server_challenge(cli
->conn
), p24
);
1936 pass
= (const char *)p24
;
1938 if((sec_mode
& (NEGOTIATE_SECURITY_USER_LEVEL
1939 |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
))
1943 if (!lp_client_plaintext_auth() && (*pass
)) {
1944 DEBUG(1, ("Server requested PLAINTEXT "
1946 "'client plaintext auth = no' or 'client ntlmv2 auth = yes'\n"));
1951 * Non-encrypted passwords - convert to DOS codepage
1954 tmp_pass
= talloc_array(talloc_tos(), uint8_t, 0);
1955 if (tevent_req_nomem(tmp_pass
, req
)) {
1956 return tevent_req_post(req
, ev
);
1958 tmp_pass
= trans2_bytes_push_str(tmp_pass
,
1959 false, /* always DOS */
1963 if (tevent_req_nomem(tmp_pass
, req
)) {
1964 return tevent_req_post(req
, ev
);
1966 pass
= (const char *)tmp_pass
;
1967 passlen
= talloc_get_size(tmp_pass
);
1971 tcon_flags
|= TCONX_FLAG_EXTENDED_RESPONSE
;
1972 tcon_flags
|= TCONX_FLAG_EXTENDED_SIGNATURES
;
1974 SCVAL(vwv
+0, 0, 0xFF);
1977 SSVAL(vwv
+2, 0, tcon_flags
);
1978 SSVAL(vwv
+3, 0, passlen
);
1980 if (passlen
&& pass
) {
1981 bytes
= (uint8_t *)talloc_memdup(state
, pass
, passlen
);
1983 bytes
= talloc_array(state
, uint8_t, 0);
1989 tmp
= talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
1990 smbXcli_conn_remote_name(cli
->conn
), share
);
1995 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), tmp
, strlen(tmp
)+1,
2000 * Add the devicetype
2002 tmp
= talloc_strdup_upper(talloc_tos(), dev
);
2007 bytes
= smb_bytes_push_str(bytes
, false, tmp
, strlen(tmp
)+1, NULL
);
2010 if (bytes
== NULL
) {
2015 state
->bytes
.iov_base
= (void *)bytes
;
2016 state
->bytes
.iov_len
= talloc_get_size(bytes
);
2018 subreq
= cli_smb_req_create(state
, ev
, cli
, SMBtconX
, 0, 0, 4, vwv
,
2020 if (subreq
== NULL
) {
2024 tevent_req_set_callback(subreq
, cli_tcon_andx_done
, req
);
2029 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
2030 return tevent_req_post(req
, ev
);
2033 struct tevent_req
*cli_tcon_andx_send(TALLOC_CTX
*mem_ctx
,
2034 struct tevent_context
*ev
,
2035 struct cli_state
*cli
,
2036 const char *share
, const char *dev
,
2037 const char *pass
, int passlen
)
2039 struct tevent_req
*req
, *subreq
;
2042 req
= cli_tcon_andx_create(mem_ctx
, ev
, cli
, share
, dev
, pass
, passlen
,
2047 if (subreq
== NULL
) {
2050 status
= smb1cli_req_chain_submit(&subreq
, 1);
2051 if (!NT_STATUS_IS_OK(status
)) {
2052 tevent_req_nterror(req
, status
);
2053 return tevent_req_post(req
, ev
);
2058 static void cli_tcon_andx_done(struct tevent_req
*subreq
)
2060 struct tevent_req
*req
= tevent_req_callback_data(
2061 subreq
, struct tevent_req
);
2062 struct cli_tcon_andx_state
*state
= tevent_req_data(
2063 req
, struct cli_tcon_andx_state
);
2064 struct cli_state
*cli
= state
->cli
;
2072 uint16_t optional_support
= 0;
2074 status
= cli_smb_recv(subreq
, state
, &in
, 0, &wct
, &vwv
,
2075 &num_bytes
, &bytes
);
2076 TALLOC_FREE(subreq
);
2077 if (!NT_STATUS_IS_OK(status
)) {
2078 tevent_req_nterror(req
, status
);
2082 inhdr
= in
+ NBT_HDR_SIZE
;
2085 if (clistr_pull_talloc(cli
,
2086 (const char *)inhdr
,
2087 SVAL(inhdr
, HDR_FLG2
),
2091 STR_TERMINATE
|STR_ASCII
) == -1) {
2092 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
2096 cli
->dev
= talloc_strdup(cli
, "");
2097 if (cli
->dev
== NULL
) {
2098 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
2103 if ((smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_NT1
) && (num_bytes
== 3)) {
2104 /* almost certainly win95 - enable bug fixes */
2109 * Make sure that we have the optional support 16-bit field. WCT > 2.
2110 * Avoids issues when connecting to Win9x boxes sharing files
2113 if ((wct
> 2) && (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_LANMAN2
)) {
2114 optional_support
= SVAL(vwv
+2, 0);
2117 if (optional_support
& SMB_EXTENDED_SIGNATURES
) {
2118 smb1cli_session_protect_session_key(cli
->smb1
.session
);
2121 smb1cli_tcon_set_values(state
->cli
->smb1
.tcon
,
2122 SVAL(inhdr
, HDR_TID
),
2124 0, /* maximal_access */
2125 0, /* guest_maximal_access */
2127 NULL
); /* fs_type */
2129 tevent_req_done(req
);
2132 NTSTATUS
cli_tcon_andx_recv(struct tevent_req
*req
)
2134 return tevent_req_simple_recv_ntstatus(req
);
2137 NTSTATUS
cli_tcon_andx(struct cli_state
*cli
, const char *share
,
2138 const char *dev
, const char *pass
, int passlen
)
2140 TALLOC_CTX
*frame
= talloc_stackframe();
2141 struct tevent_context
*ev
;
2142 struct tevent_req
*req
;
2143 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2145 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
2147 * Can't use sync call while an async call is in flight
2149 status
= NT_STATUS_INVALID_PARAMETER
;
2153 ev
= samba_tevent_context_init(frame
);
2158 req
= cli_tcon_andx_send(frame
, ev
, cli
, share
, dev
, pass
, passlen
);
2163 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2167 status
= cli_tcon_andx_recv(req
);
2173 struct cli_tree_connect_state
{
2174 struct cli_state
*cli
;
2177 static struct tevent_req
*cli_raw_tcon_send(
2178 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
2179 const char *service
, const char *pass
, const char *dev
);
2180 static NTSTATUS
cli_raw_tcon_recv(struct tevent_req
*req
,
2181 uint16_t *max_xmit
, uint16_t *tid
);
2183 static void cli_tree_connect_smb2_done(struct tevent_req
*subreq
);
2184 static void cli_tree_connect_andx_done(struct tevent_req
*subreq
);
2185 static void cli_tree_connect_raw_done(struct tevent_req
*subreq
);
2187 static struct tevent_req
*cli_tree_connect_send(
2188 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
2189 const char *share
, const char *dev
, const char *pass
, int passlen
)
2191 struct tevent_req
*req
, *subreq
;
2192 struct cli_tree_connect_state
*state
;
2194 req
= tevent_req_create(mem_ctx
, &state
,
2195 struct cli_tree_connect_state
);
2201 cli
->share
= talloc_strdup(cli
, share
);
2202 if (tevent_req_nomem(cli
->share
, req
)) {
2203 return tevent_req_post(req
, ev
);
2206 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
2209 cli
->smb2
.tcon
= smbXcli_tcon_create(cli
);
2210 if (tevent_req_nomem(cli
->smb2
.tcon
, req
)) {
2211 return tevent_req_post(req
, ev
);
2214 unc
= talloc_asprintf(state
, "\\\\%s\\%s",
2215 smbXcli_conn_remote_name(cli
->conn
),
2217 if (tevent_req_nomem(unc
, req
)) {
2218 return tevent_req_post(req
, ev
);
2221 subreq
= smb2cli_tcon_send(state
, ev
, cli
->conn
, cli
->timeout
,
2222 cli
->smb2
.session
, cli
->smb2
.tcon
,
2225 if (tevent_req_nomem(subreq
, req
)) {
2226 return tevent_req_post(req
, ev
);
2228 tevent_req_set_callback(subreq
, cli_tree_connect_smb2_done
,
2233 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_LANMAN1
) {
2234 subreq
= cli_tcon_andx_send(state
, ev
, cli
, share
, dev
,
2236 if (tevent_req_nomem(subreq
, req
)) {
2237 return tevent_req_post(req
, ev
);
2239 tevent_req_set_callback(subreq
, cli_tree_connect_andx_done
,
2244 subreq
= cli_raw_tcon_send(state
, ev
, cli
, share
, pass
, dev
);
2245 if (tevent_req_nomem(subreq
, req
)) {
2246 return tevent_req_post(req
, ev
);
2248 tevent_req_set_callback(subreq
, cli_tree_connect_raw_done
, req
);
2253 static void cli_tree_connect_smb2_done(struct tevent_req
*subreq
)
2255 tevent_req_simple_finish_ntstatus(
2256 subreq
, smb2cli_tcon_recv(subreq
));
2259 static void cli_tree_connect_andx_done(struct tevent_req
*subreq
)
2261 tevent_req_simple_finish_ntstatus(
2262 subreq
, cli_tcon_andx_recv(subreq
));
2265 static void cli_tree_connect_raw_done(struct tevent_req
*subreq
)
2267 struct tevent_req
*req
= tevent_req_callback_data(
2268 subreq
, struct tevent_req
);
2269 struct cli_tree_connect_state
*state
= tevent_req_data(
2270 req
, struct cli_tree_connect_state
);
2272 uint16_t max_xmit
= 0;
2275 status
= cli_raw_tcon_recv(subreq
, &max_xmit
, &tid
);
2276 if (tevent_req_nterror(req
, status
)) {
2280 smb1cli_tcon_set_values(state
->cli
->smb1
.tcon
,
2282 0, /* optional_support */
2283 0, /* maximal_access */
2284 0, /* guest_maximal_access */
2286 NULL
); /* fs_type */
2288 tevent_req_done(req
);
2291 static NTSTATUS
cli_tree_connect_recv(struct tevent_req
*req
)
2293 return tevent_req_simple_recv_ntstatus(req
);
2296 NTSTATUS
cli_tree_connect(struct cli_state
*cli
, const char *share
,
2297 const char *dev
, const char *pass
, int passlen
)
2299 struct tevent_context
*ev
;
2300 struct tevent_req
*req
;
2301 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2303 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
2304 return NT_STATUS_INVALID_PARAMETER
;
2306 ev
= samba_tevent_context_init(talloc_tos());
2310 req
= cli_tree_connect_send(ev
, ev
, cli
, share
, dev
, pass
, passlen
);
2314 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2317 status
= cli_tree_connect_recv(req
);
2323 /****************************************************************************
2324 Send a tree disconnect.
2325 ****************************************************************************/
2327 struct cli_tdis_state
{
2328 struct cli_state
*cli
;
2331 static void cli_tdis_done(struct tevent_req
*subreq
);
2333 static struct tevent_req
*cli_tdis_send(TALLOC_CTX
*mem_ctx
,
2334 struct tevent_context
*ev
,
2335 struct cli_state
*cli
)
2337 struct tevent_req
*req
, *subreq
;
2338 struct cli_tdis_state
*state
;
2340 req
= tevent_req_create(mem_ctx
, &state
, struct cli_tdis_state
);
2346 subreq
= cli_smb_send(state
, ev
, cli
, SMBtdis
, 0, 0, 0, NULL
, 0, NULL
);
2347 if (tevent_req_nomem(subreq
, req
)) {
2348 return tevent_req_post(req
, ev
);
2350 tevent_req_set_callback(subreq
, cli_tdis_done
, req
);
2354 static void cli_tdis_done(struct tevent_req
*subreq
)
2356 struct tevent_req
*req
= tevent_req_callback_data(
2357 subreq
, struct tevent_req
);
2358 struct cli_tdis_state
*state
= tevent_req_data(
2359 req
, struct cli_tdis_state
);
2362 status
= cli_smb_recv(subreq
, NULL
, NULL
, 0, NULL
, NULL
, NULL
, NULL
);
2363 TALLOC_FREE(subreq
);
2364 if (!NT_STATUS_IS_OK(status
)) {
2365 tevent_req_nterror(req
, status
);
2368 cli_state_set_tid(state
->cli
, UINT16_MAX
);
2369 tevent_req_done(req
);
2372 static NTSTATUS
cli_tdis_recv(struct tevent_req
*req
)
2374 return tevent_req_simple_recv_ntstatus(req
);
2377 NTSTATUS
cli_tdis(struct cli_state
*cli
)
2379 struct tevent_context
*ev
;
2380 struct tevent_req
*req
;
2381 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2383 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
2384 return smb2cli_tdis(cli
->conn
,
2390 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
2391 return NT_STATUS_INVALID_PARAMETER
;
2393 ev
= samba_tevent_context_init(talloc_tos());
2397 req
= cli_tdis_send(ev
, ev
, cli
);
2401 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2404 status
= cli_tdis_recv(req
);
2410 struct cli_connect_sock_state
{
2411 const char **called_names
;
2412 const char **calling_names
;
2418 static void cli_connect_sock_done(struct tevent_req
*subreq
);
2421 * Async only if we don't have to look up the name, i.e. "pss" is set with a
2425 static struct tevent_req
*cli_connect_sock_send(
2426 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
2427 const char *host
, int name_type
, const struct sockaddr_storage
*pss
,
2428 const char *myname
, uint16_t port
)
2430 struct tevent_req
*req
, *subreq
;
2431 struct cli_connect_sock_state
*state
;
2433 struct sockaddr_storage
*addrs
;
2434 unsigned i
, num_addrs
;
2437 req
= tevent_req_create(mem_ctx
, &state
,
2438 struct cli_connect_sock_state
);
2443 prog
= getenv("LIBSMB_PROG");
2445 state
->fd
= sock_exec(prog
);
2446 if (state
->fd
== -1) {
2447 status
= map_nt_error_from_unix(errno
);
2448 tevent_req_nterror(req
, status
);
2451 tevent_req_done(req
);
2453 return tevent_req_post(req
, ev
);
2456 if ((pss
== NULL
) || is_zero_addr(pss
)) {
2459 * Here we cheat. resolve_name_list is not async at all. So
2460 * this call will only be really async if the name lookup has
2461 * been done externally.
2464 status
= resolve_name_list(state
, host
, name_type
,
2465 &addrs
, &num_addrs
);
2466 if (!NT_STATUS_IS_OK(status
)) {
2467 tevent_req_nterror(req
, status
);
2468 return tevent_req_post(req
, ev
);
2471 addrs
= talloc_array(state
, struct sockaddr_storage
, 1);
2472 if (tevent_req_nomem(addrs
, req
)) {
2473 return tevent_req_post(req
, ev
);
2479 state
->called_names
= talloc_array(state
, const char *, num_addrs
);
2480 if (tevent_req_nomem(state
->called_names
, req
)) {
2481 return tevent_req_post(req
, ev
);
2483 state
->called_types
= talloc_array(state
, int, num_addrs
);
2484 if (tevent_req_nomem(state
->called_types
, req
)) {
2485 return tevent_req_post(req
, ev
);
2487 state
->calling_names
= talloc_array(state
, const char *, num_addrs
);
2488 if (tevent_req_nomem(state
->calling_names
, req
)) {
2489 return tevent_req_post(req
, ev
);
2491 for (i
=0; i
<num_addrs
; i
++) {
2492 state
->called_names
[i
] = host
;
2493 state
->called_types
[i
] = name_type
;
2494 state
->calling_names
[i
] = myname
;
2497 subreq
= smbsock_any_connect_send(
2498 state
, ev
, addrs
, state
->called_names
, state
->called_types
,
2499 state
->calling_names
, NULL
, num_addrs
, port
);
2500 if (tevent_req_nomem(subreq
, req
)) {
2501 return tevent_req_post(req
, ev
);
2503 tevent_req_set_callback(subreq
, cli_connect_sock_done
, req
);
2507 static void cli_connect_sock_done(struct tevent_req
*subreq
)
2509 struct tevent_req
*req
= tevent_req_callback_data(
2510 subreq
, struct tevent_req
);
2511 struct cli_connect_sock_state
*state
= tevent_req_data(
2512 req
, struct cli_connect_sock_state
);
2515 status
= smbsock_any_connect_recv(subreq
, &state
->fd
, NULL
,
2517 TALLOC_FREE(subreq
);
2518 if (tevent_req_nterror(req
, status
)) {
2521 set_socket_options(state
->fd
, lp_socket_options());
2522 tevent_req_done(req
);
2525 static NTSTATUS
cli_connect_sock_recv(struct tevent_req
*req
,
2526 int *pfd
, uint16_t *pport
)
2528 struct cli_connect_sock_state
*state
= tevent_req_data(
2529 req
, struct cli_connect_sock_state
);
2532 if (tevent_req_is_nterror(req
, &status
)) {
2536 *pport
= state
->port
;
2537 return NT_STATUS_OK
;
2540 struct cli_connect_nb_state
{
2541 const char *desthost
;
2544 struct cli_state
*cli
;
2547 static void cli_connect_nb_done(struct tevent_req
*subreq
);
2549 static struct tevent_req
*cli_connect_nb_send(
2550 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
2551 const char *host
, const struct sockaddr_storage
*dest_ss
,
2552 uint16_t port
, int name_type
, const char *myname
,
2553 int signing_state
, int flags
)
2555 struct tevent_req
*req
, *subreq
;
2556 struct cli_connect_nb_state
*state
;
2558 req
= tevent_req_create(mem_ctx
, &state
, struct cli_connect_nb_state
);
2562 state
->signing_state
= signing_state
;
2563 state
->flags
= flags
;
2566 char *p
= strchr(host
, '#');
2569 name_type
= strtol(p
+1, NULL
, 16);
2570 host
= talloc_strndup(state
, host
, p
- host
);
2571 if (tevent_req_nomem(host
, req
)) {
2572 return tevent_req_post(req
, ev
);
2576 state
->desthost
= host
;
2577 } else if (dest_ss
!= NULL
) {
2578 state
->desthost
= print_canonical_sockaddr(state
, dest_ss
);
2579 if (tevent_req_nomem(state
->desthost
, req
)) {
2580 return tevent_req_post(req
, ev
);
2583 /* No host or dest_ss given. Error out. */
2584 tevent_req_error(req
, EINVAL
);
2585 return tevent_req_post(req
, ev
);
2588 subreq
= cli_connect_sock_send(state
, ev
, host
, name_type
, dest_ss
,
2590 if (tevent_req_nomem(subreq
, req
)) {
2591 return tevent_req_post(req
, ev
);
2593 tevent_req_set_callback(subreq
, cli_connect_nb_done
, req
);
2597 static void cli_connect_nb_done(struct tevent_req
*subreq
)
2599 struct tevent_req
*req
= tevent_req_callback_data(
2600 subreq
, struct tevent_req
);
2601 struct cli_connect_nb_state
*state
= tevent_req_data(
2602 req
, struct cli_connect_nb_state
);
2607 status
= cli_connect_sock_recv(subreq
, &fd
, &port
);
2608 TALLOC_FREE(subreq
);
2609 if (tevent_req_nterror(req
, status
)) {
2613 state
->cli
= cli_state_create(state
, fd
, state
->desthost
, NULL
,
2614 state
->signing_state
, state
->flags
);
2615 if (tevent_req_nomem(state
->cli
, req
)) {
2619 tevent_req_done(req
);
2622 static NTSTATUS
cli_connect_nb_recv(struct tevent_req
*req
,
2623 struct cli_state
**pcli
)
2625 struct cli_connect_nb_state
*state
= tevent_req_data(
2626 req
, struct cli_connect_nb_state
);
2629 if (tevent_req_is_nterror(req
, &status
)) {
2632 *pcli
= talloc_move(NULL
, &state
->cli
);
2633 return NT_STATUS_OK
;
2636 NTSTATUS
cli_connect_nb(const char *host
, const struct sockaddr_storage
*dest_ss
,
2637 uint16_t port
, int name_type
, const char *myname
,
2638 int signing_state
, int flags
, struct cli_state
**pcli
)
2640 struct tevent_context
*ev
;
2641 struct tevent_req
*req
;
2642 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2644 ev
= samba_tevent_context_init(talloc_tos());
2648 req
= cli_connect_nb_send(ev
, ev
, host
, dest_ss
, port
, name_type
,
2649 myname
, signing_state
, flags
);
2653 if (!tevent_req_set_endtime(req
, ev
, timeval_current_ofs(20, 0))) {
2656 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2659 status
= cli_connect_nb_recv(req
, pcli
);
2665 struct cli_start_connection_state
{
2666 struct tevent_context
*ev
;
2667 struct cli_state
*cli
;
2672 static void cli_start_connection_connected(struct tevent_req
*subreq
);
2673 static void cli_start_connection_done(struct tevent_req
*subreq
);
2676 establishes a connection to after the negprot.
2677 @param output_cli A fully initialised cli structure, non-null only on success
2678 @param dest_host The netbios name of the remote host
2679 @param dest_ss (optional) The the destination IP, NULL for name based lookup
2680 @param port (optional) The destination port (0 for default)
2683 static struct tevent_req
*cli_start_connection_send(
2684 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
2685 const char *my_name
, const char *dest_host
,
2686 const struct sockaddr_storage
*dest_ss
, int port
,
2687 int signing_state
, int flags
)
2689 struct tevent_req
*req
, *subreq
;
2690 struct cli_start_connection_state
*state
;
2692 req
= tevent_req_create(mem_ctx
, &state
,
2693 struct cli_start_connection_state
);
2699 if (signing_state
== SMB_SIGNING_IPC_DEFAULT
) {
2700 state
->min_protocol
= lp_client_ipc_min_protocol();
2701 state
->max_protocol
= lp_client_ipc_max_protocol();
2703 state
->min_protocol
= lp_client_min_protocol();
2704 state
->max_protocol
= lp_client_max_protocol();
2707 subreq
= cli_connect_nb_send(state
, ev
, dest_host
, dest_ss
, port
,
2708 0x20, my_name
, signing_state
, flags
);
2709 if (tevent_req_nomem(subreq
, req
)) {
2710 return tevent_req_post(req
, ev
);
2712 tevent_req_set_callback(subreq
, cli_start_connection_connected
, req
);
2716 static void cli_start_connection_connected(struct tevent_req
*subreq
)
2718 struct tevent_req
*req
= tevent_req_callback_data(
2719 subreq
, struct tevent_req
);
2720 struct cli_start_connection_state
*state
= tevent_req_data(
2721 req
, struct cli_start_connection_state
);
2724 status
= cli_connect_nb_recv(subreq
, &state
->cli
);
2725 TALLOC_FREE(subreq
);
2726 if (tevent_req_nterror(req
, status
)) {
2730 subreq
= smbXcli_negprot_send(state
, state
->ev
, state
->cli
->conn
,
2731 state
->cli
->timeout
,
2732 state
->min_protocol
,
2733 state
->max_protocol
);
2734 if (tevent_req_nomem(subreq
, req
)) {
2737 tevent_req_set_callback(subreq
, cli_start_connection_done
, req
);
2740 static void cli_start_connection_done(struct tevent_req
*subreq
)
2742 struct tevent_req
*req
= tevent_req_callback_data(
2743 subreq
, struct tevent_req
);
2744 struct cli_start_connection_state
*state
= tevent_req_data(
2745 req
, struct cli_start_connection_state
);
2748 status
= smbXcli_negprot_recv(subreq
);
2749 TALLOC_FREE(subreq
);
2750 if (tevent_req_nterror(req
, status
)) {
2754 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
2755 /* Ensure we ask for some initial credits. */
2756 smb2cli_conn_set_max_credits(state
->cli
->conn
,
2757 DEFAULT_SMB2_MAX_CREDITS
);
2760 tevent_req_done(req
);
2763 static NTSTATUS
cli_start_connection_recv(struct tevent_req
*req
,
2764 struct cli_state
**output_cli
)
2766 struct cli_start_connection_state
*state
= tevent_req_data(
2767 req
, struct cli_start_connection_state
);
2770 if (tevent_req_is_nterror(req
, &status
)) {
2773 *output_cli
= state
->cli
;
2775 return NT_STATUS_OK
;
2778 NTSTATUS
cli_start_connection(struct cli_state
**output_cli
,
2779 const char *my_name
,
2780 const char *dest_host
,
2781 const struct sockaddr_storage
*dest_ss
, int port
,
2782 int signing_state
, int flags
)
2784 struct tevent_context
*ev
;
2785 struct tevent_req
*req
;
2786 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2788 ev
= samba_tevent_context_init(talloc_tos());
2792 req
= cli_start_connection_send(ev
, ev
, my_name
, dest_host
, dest_ss
,
2793 port
, signing_state
, flags
);
2797 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2800 status
= cli_start_connection_recv(req
, output_cli
);
2807 establishes a connection right up to doing tconX, password specified.
2808 @param output_cli A fully initialised cli structure, non-null only on success
2809 @param dest_host The netbios name of the remote host
2810 @param dest_ip (optional) The the destination IP, NULL for name based lookup
2811 @param port (optional) The destination port (0 for default)
2812 @param service (optional) The share to make the connection to. Should be 'unqualified' in any way.
2813 @param service_type The 'type' of serivice.
2814 @param user Username, unix string
2815 @param domain User's domain
2816 @param password User's password, unencrypted unix string.
2819 struct cli_full_connection_state
{
2820 struct tevent_context
*ev
;
2821 const char *service
;
2822 const char *service_type
;
2825 const char *password
;
2828 struct cli_state
*cli
;
2831 static int cli_full_connection_state_destructor(
2832 struct cli_full_connection_state
*s
);
2833 static void cli_full_connection_started(struct tevent_req
*subreq
);
2834 static void cli_full_connection_sess_set_up(struct tevent_req
*subreq
);
2835 static void cli_full_connection_done(struct tevent_req
*subreq
);
2837 struct tevent_req
*cli_full_connection_send(
2838 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
2839 const char *my_name
, const char *dest_host
,
2840 const struct sockaddr_storage
*dest_ss
, int port
,
2841 const char *service
, const char *service_type
,
2842 const char *user
, const char *domain
,
2843 const char *password
, int flags
, int signing_state
)
2845 struct tevent_req
*req
, *subreq
;
2846 struct cli_full_connection_state
*state
;
2848 req
= tevent_req_create(mem_ctx
, &state
,
2849 struct cli_full_connection_state
);
2853 talloc_set_destructor(state
, cli_full_connection_state_destructor
);
2856 state
->service
= service
;
2857 state
->service_type
= service_type
;
2859 state
->domain
= domain
;
2860 state
->password
= password
;
2861 state
->flags
= flags
;
2863 state
->pw_len
= state
->password
? strlen(state
->password
)+1 : 0;
2864 if (state
->password
== NULL
) {
2865 state
->password
= "";
2868 subreq
= cli_start_connection_send(
2869 state
, ev
, my_name
, dest_host
, dest_ss
, port
,
2870 signing_state
, flags
);
2871 if (tevent_req_nomem(subreq
, req
)) {
2872 return tevent_req_post(req
, ev
);
2874 tevent_req_set_callback(subreq
, cli_full_connection_started
, req
);
2878 static int cli_full_connection_state_destructor(
2879 struct cli_full_connection_state
*s
)
2881 if (s
->cli
!= NULL
) {
2882 cli_shutdown(s
->cli
);
2888 static void cli_full_connection_started(struct tevent_req
*subreq
)
2890 struct tevent_req
*req
= tevent_req_callback_data(
2891 subreq
, struct tevent_req
);
2892 struct cli_full_connection_state
*state
= tevent_req_data(
2893 req
, struct cli_full_connection_state
);
2895 struct cli_credentials
*creds
= NULL
;
2897 status
= cli_start_connection_recv(subreq
, &state
->cli
);
2898 TALLOC_FREE(subreq
);
2899 if (tevent_req_nterror(req
, status
)) {
2903 creds
= cli_session_creds_init(state
,
2906 NULL
, /* realm (use default) */
2908 state
->cli
->use_kerberos
,
2909 state
->cli
->fallback_after_kerberos
,
2910 state
->cli
->use_ccache
,
2911 state
->cli
->pw_nt_hash
);
2912 if (tevent_req_nomem(creds
, req
)) {
2916 subreq
= cli_session_setup_creds_send(
2917 state
, state
->ev
, state
->cli
, creds
);
2918 if (tevent_req_nomem(subreq
, req
)) {
2921 tevent_req_set_callback(subreq
, cli_full_connection_sess_set_up
, req
);
2924 static void cli_full_connection_sess_set_up(struct tevent_req
*subreq
)
2926 struct tevent_req
*req
= tevent_req_callback_data(
2927 subreq
, struct tevent_req
);
2928 struct cli_full_connection_state
*state
= tevent_req_data(
2929 req
, struct cli_full_connection_state
);
2932 status
= cli_session_setup_creds_recv(subreq
);
2933 TALLOC_FREE(subreq
);
2935 if (!NT_STATUS_IS_OK(status
) &&
2936 (state
->flags
& CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK
)) {
2937 struct cli_credentials
*creds
= NULL
;
2939 state
->flags
&= ~CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK
;
2941 creds
= cli_credentials_init_anon(state
);
2942 if (tevent_req_nomem(creds
, req
)) {
2946 subreq
= cli_session_setup_creds_send(
2947 state
, state
->ev
, state
->cli
, creds
);
2948 if (tevent_req_nomem(subreq
, req
)) {
2951 tevent_req_set_callback(
2952 subreq
, cli_full_connection_sess_set_up
, req
);
2956 if (tevent_req_nterror(req
, status
)) {
2960 if (state
->service
!= NULL
) {
2961 subreq
= cli_tree_connect_send(
2962 state
, state
->ev
, state
->cli
,
2963 state
->service
, state
->service_type
,
2964 state
->password
, state
->pw_len
);
2965 if (tevent_req_nomem(subreq
, req
)) {
2968 tevent_req_set_callback(subreq
, cli_full_connection_done
, req
);
2972 tevent_req_done(req
);
2975 static void cli_full_connection_done(struct tevent_req
*subreq
)
2977 struct tevent_req
*req
= tevent_req_callback_data(
2978 subreq
, struct tevent_req
);
2981 status
= cli_tree_connect_recv(subreq
);
2982 TALLOC_FREE(subreq
);
2983 if (tevent_req_nterror(req
, status
)) {
2987 tevent_req_done(req
);
2990 NTSTATUS
cli_full_connection_recv(struct tevent_req
*req
,
2991 struct cli_state
**output_cli
)
2993 struct cli_full_connection_state
*state
= tevent_req_data(
2994 req
, struct cli_full_connection_state
);
2997 if (tevent_req_is_nterror(req
, &status
)) {
3000 *output_cli
= state
->cli
;
3001 talloc_set_destructor(state
, NULL
);
3002 return NT_STATUS_OK
;
3005 NTSTATUS
cli_full_connection(struct cli_state
**output_cli
,
3006 const char *my_name
,
3007 const char *dest_host
,
3008 const struct sockaddr_storage
*dest_ss
, int port
,
3009 const char *service
, const char *service_type
,
3010 const char *user
, const char *domain
,
3011 const char *password
, int flags
,
3014 struct tevent_context
*ev
;
3015 struct tevent_req
*req
;
3016 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
3018 ev
= samba_tevent_context_init(talloc_tos());
3022 req
= cli_full_connection_send(
3023 ev
, ev
, my_name
, dest_host
, dest_ss
, port
, service
,
3024 service_type
, user
, domain
, password
, flags
, signing_state
);
3028 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
3031 status
= cli_full_connection_recv(req
, output_cli
);
3037 /****************************************************************************
3038 Send an old style tcon.
3039 ****************************************************************************/
3040 struct cli_raw_tcon_state
{
3044 static void cli_raw_tcon_done(struct tevent_req
*subreq
);
3046 static struct tevent_req
*cli_raw_tcon_send(
3047 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
3048 const char *service
, const char *pass
, const char *dev
)
3050 struct tevent_req
*req
, *subreq
;
3051 struct cli_raw_tcon_state
*state
;
3054 req
= tevent_req_create(mem_ctx
, &state
, struct cli_raw_tcon_state
);
3059 if (!lp_client_plaintext_auth() && (*pass
)) {
3060 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
3061 " or 'client ntlmv2 auth = yes'\n"));
3062 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
3063 return tevent_req_post(req
, ev
);
3066 bytes
= talloc_array(state
, uint8_t, 0);
3067 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
3068 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
3069 service
, strlen(service
)+1, NULL
);
3070 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
3071 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
3072 pass
, strlen(pass
)+1, NULL
);
3073 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
3074 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
3075 dev
, strlen(dev
)+1, NULL
);
3077 if (tevent_req_nomem(bytes
, req
)) {
3078 return tevent_req_post(req
, ev
);
3081 subreq
= cli_smb_send(state
, ev
, cli
, SMBtcon
, 0, 0, 0, NULL
,
3082 talloc_get_size(bytes
), bytes
);
3083 if (tevent_req_nomem(subreq
, req
)) {
3084 return tevent_req_post(req
, ev
);
3086 tevent_req_set_callback(subreq
, cli_raw_tcon_done
, req
);
3090 static void cli_raw_tcon_done(struct tevent_req
*subreq
)
3092 struct tevent_req
*req
= tevent_req_callback_data(
3093 subreq
, struct tevent_req
);
3094 struct cli_raw_tcon_state
*state
= tevent_req_data(
3095 req
, struct cli_raw_tcon_state
);
3098 status
= cli_smb_recv(subreq
, state
, NULL
, 2, NULL
, &state
->ret_vwv
,
3100 TALLOC_FREE(subreq
);
3101 if (tevent_req_nterror(req
, status
)) {
3104 tevent_req_done(req
);
3107 static NTSTATUS
cli_raw_tcon_recv(struct tevent_req
*req
,
3108 uint16_t *max_xmit
, uint16_t *tid
)
3110 struct cli_raw_tcon_state
*state
= tevent_req_data(
3111 req
, struct cli_raw_tcon_state
);
3114 if (tevent_req_is_nterror(req
, &status
)) {
3117 *max_xmit
= SVAL(state
->ret_vwv
+ 0, 0);
3118 *tid
= SVAL(state
->ret_vwv
+ 1, 0);
3119 return NT_STATUS_OK
;
3122 NTSTATUS
cli_raw_tcon(struct cli_state
*cli
,
3123 const char *service
, const char *pass
, const char *dev
,
3124 uint16_t *max_xmit
, uint16_t *tid
)
3126 struct tevent_context
*ev
;
3127 struct tevent_req
*req
;
3128 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
3130 ev
= samba_tevent_context_init(talloc_tos());
3134 req
= cli_raw_tcon_send(ev
, ev
, cli
, service
, pass
, dev
);
3138 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
3141 status
= cli_raw_tcon_recv(req
, max_xmit
, tid
);
3147 /* Return a cli_state pointing at the IPC$ share for the given server */
3149 struct cli_state
*get_ipc_connect(char *server
,
3150 struct sockaddr_storage
*server_ss
,
3151 const struct user_auth_info
*user_info
)
3153 struct cli_state
*cli
;
3155 uint32_t flags
= CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK
;
3157 if (get_cmdline_auth_info_use_kerberos(user_info
)) {
3158 flags
|= CLI_FULL_CONNECTION_USE_KERBEROS
;
3161 nt_status
= cli_full_connection(&cli
, NULL
, server
, server_ss
, 0, "IPC$", "IPC",
3162 get_cmdline_auth_info_username(user_info
),
3164 get_cmdline_auth_info_password(user_info
),
3166 SMB_SIGNING_DEFAULT
);
3168 if (NT_STATUS_IS_OK(nt_status
)) {
3170 } else if (is_ipaddress(server
)) {
3171 /* windows 9* needs a correct NMB name for connections */
3172 fstring remote_name
;
3174 if (name_status_find("*", 0, 0, server_ss
, remote_name
)) {
3175 cli
= get_ipc_connect(remote_name
, server_ss
, user_info
);
3184 * Given the IP address of a master browser on the network, return its
3185 * workgroup and connect to it.
3187 * This function is provided to allow additional processing beyond what
3188 * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
3189 * browsers and obtain each master browsers' list of domains (in case the
3190 * first master browser is recently on the network and has not yet
3191 * synchronized with other master browsers and therefore does not yet have the
3192 * entire network browse list)
3195 struct cli_state
*get_ipc_connect_master_ip(TALLOC_CTX
*ctx
,
3196 struct sockaddr_storage
*mb_ip
,
3197 const struct user_auth_info
*user_info
,
3198 char **pp_workgroup_out
)
3200 char addr
[INET6_ADDRSTRLEN
];
3202 struct cli_state
*cli
;
3203 struct sockaddr_storage server_ss
;
3205 *pp_workgroup_out
= NULL
;
3207 print_sockaddr(addr
, sizeof(addr
), mb_ip
);
3208 DEBUG(99, ("Looking up name of master browser %s\n",
3212 * Do a name status query to find out the name of the master browser.
3213 * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
3214 * master browser will not respond to a wildcard query (or, at least,
3215 * an NT4 server acting as the domain master browser will not).
3217 * We might be able to use ONLY the query on MSBROWSE, but that's not
3218 * yet been tested with all Windows versions, so until it is, leave
3219 * the original wildcard query as the first choice and fall back to
3220 * MSBROWSE if the wildcard query fails.
3222 if (!name_status_find("*", 0, 0x1d, mb_ip
, name
) &&
3223 !name_status_find(MSBROWSE
, 1, 0x1d, mb_ip
, name
)) {
3225 DEBUG(99, ("Could not retrieve name status for %s\n",
3230 if (!find_master_ip(name
, &server_ss
)) {
3231 DEBUG(99, ("Could not find master ip for %s\n", name
));
3235 *pp_workgroup_out
= talloc_strdup(ctx
, name
);
3237 DEBUG(4, ("found master browser %s, %s\n", name
, addr
));
3239 print_sockaddr(addr
, sizeof(addr
), &server_ss
);
3240 cli
= get_ipc_connect(addr
, &server_ss
, user_info
);
3246 * Return the IP address and workgroup of a master browser on the network, and
3250 struct cli_state
*get_ipc_connect_master_ip_bcast(TALLOC_CTX
*ctx
,
3251 const struct user_auth_info
*user_info
,
3252 char **pp_workgroup_out
)
3254 struct sockaddr_storage
*ip_list
;
3255 struct cli_state
*cli
;
3259 *pp_workgroup_out
= NULL
;
3261 DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
3263 /* Go looking for workgroups by broadcasting on the local network */
3265 status
= name_resolve_bcast(MSBROWSE
, 1, talloc_tos(),
3267 if (!NT_STATUS_IS_OK(status
)) {
3268 DEBUG(99, ("No master browsers responded: %s\n",
3269 nt_errstr(status
)));
3273 for (i
= 0; i
< count
; i
++) {
3274 char addr
[INET6_ADDRSTRLEN
];
3275 print_sockaddr(addr
, sizeof(addr
), &ip_list
[i
]);
3276 DEBUG(99, ("Found master browser %s\n", addr
));
3278 cli
= get_ipc_connect_master_ip(ctx
, &ip_list
[i
],
3279 user_info
, pp_workgroup_out
);