2 Unix SMB/CIFS implementation.
3 client connect/disconnect routines
4 Copyright (C) Andrew Tridgell 1994-1998
5 Copyright (C) Andrew Bartlett 2001-2003
6 Copyright (C) Volker Lendecke 2011
7 Copyright (C) Jeremy Allison 2011
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "libsmb/libsmb.h"
25 #include "libsmb/namequery.h"
26 #include "../libcli/auth/libcli_auth.h"
28 #include "auth/credentials/credentials.h"
29 #include "auth/gensec/gensec.h"
30 #include "auth/ntlmssp/ntlmssp.h"
31 #include "auth_generic.h"
32 #include "libads/kerberos_proto.h"
34 #include "../lib/util/tevent_ntstatus.h"
35 #include "async_smb.h"
36 #include "libsmb/nmblib.h"
37 #include "librpc/ndr/libndr.h"
38 #include "../libcli/smb/smbXcli_base.h"
39 #include "../libcli/smb/smb_seal.h"
40 #include "lib/param/param.h"
41 #include "../libcli/smb/smb2_negotiate_context.h"
43 #define STAR_SMBSERVER "*SMBSERVER"
45 static char *cli_session_setup_get_account(TALLOC_CTX *mem_ctx,
46 const char *principal);
48 struct cli_credentials *cli_session_creds_init(TALLOC_CTX *mem_ctx,
54 bool fallback_after_kerberos,
56 bool password_is_nt_hash)
58 struct loadparm_context *lp_ctx = NULL;
59 struct cli_credentials *creds = NULL;
60 const char *principal = NULL;
65 creds = cli_credentials_init(mem_ctx);
70 lp_ctx = loadparm_init_s3(creds, loadparm_s3_helpers());
74 ok = 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_USE_KERBEROS_DESIRED,
130 } else if (use_kerberos) {
131 cli_credentials_set_kerberos_state(creds,
132 CRED_USE_KERBEROS_REQUIRED,
135 cli_credentials_set_kerberos_state(creds,
136 CRED_USE_KERBEROS_DISABLED,
143 features = cli_credentials_get_gensec_features(creds);
144 features |= GENSEC_FEATURE_NTLM_CCACHE;
145 cli_credentials_set_gensec_features(creds,
149 if (password != NULL && strlen(password) == 0) {
151 * some callers pass "" as no password
153 * GENSEC_FEATURE_NTLM_CCACHE only handles
154 * NULL as no password.
160 ok = cli_credentials_set_username(creds,
167 if (domain != NULL) {
168 ok = cli_credentials_set_domain(creds,
176 if (principal != NULL) {
177 ok = cli_credentials_set_principal(creds,
186 ok = cli_credentials_set_realm(creds,
194 if (password != NULL && strlen(password) > 0) {
195 if (password_is_nt_hash) {
196 struct samr_Password nt_hash;
199 converted = strhex_to_str((char *)nt_hash.hash,
200 sizeof(nt_hash.hash),
203 if (converted != sizeof(nt_hash.hash)) {
207 ok = cli_credentials_set_nt_hash(creds,
214 ok = cli_credentials_set_password(creds,
229 NTSTATUS cli_session_creds_prepare_krb5(struct cli_state *cli,
230 struct cli_credentials *creds)
232 TALLOC_CTX *frame = talloc_stackframe();
233 const char *user_principal = NULL;
234 const char *user_account = NULL;
235 const char *user_domain = NULL;
236 const char *pass = NULL;
237 char *canon_principal = NULL;
238 char *canon_realm = NULL;
239 const char *target_hostname = NULL;
240 enum credentials_use_kerberos krb5_state;
241 bool try_kerberos = false;
242 bool need_kinit = false;
243 bool auth_requested = true;
247 target_hostname = smbXcli_conn_remote_name(cli->conn);
249 auth_requested = cli_credentials_authentication_requested(creds);
250 if (auth_requested) {
252 user_principal = cli_credentials_get_principal(creds, frame);
255 return NT_STATUS_NO_MEMORY;
258 user_account = cli_credentials_get_username(creds);
259 user_domain = cli_credentials_get_domain(creds);
260 pass = cli_credentials_get_password(creds);
262 krb5_state = cli_credentials_get_kerberos_state(creds);
264 if (krb5_state != CRED_USE_KERBEROS_DISABLED) {
268 if (user_principal == NULL) {
269 try_kerberos = false;
272 if (target_hostname == NULL) {
273 try_kerberos = false;
274 } else if (is_ipaddress(target_hostname)) {
275 try_kerberos = false;
276 } else if (strequal(target_hostname, "localhost")) {
277 try_kerberos = false;
278 } else if (strequal(target_hostname, STAR_SMBSERVER)) {
279 try_kerberos = false;
280 } else if (!auth_requested) {
281 try_kerberos = false;
284 if (krb5_state == CRED_USE_KERBEROS_REQUIRED && !try_kerberos) {
285 DEBUG(0, ("Kerberos auth with '%s' (%s\\%s) to access "
286 "'%s' not possible\n",
287 user_principal, user_domain, user_account,
290 return NT_STATUS_ACCESS_DENIED;
293 if (pass == NULL || strlen(pass) == 0) {
295 } else if (krb5_state == CRED_USE_KERBEROS_REQUIRED) {
296 need_kinit = try_kerberos;
298 need_kinit = try_kerberos;
306 DBG_INFO("Doing kinit for %s to access %s\n",
307 user_principal, target_hostname);
310 * TODO: This should be done within the gensec layer
313 setenv(KRB5_ENV_CCNAME, "MEMORY:cliconnect", 1);
314 ret = kerberos_kinit_password_ext(user_principal,
328 int dbglvl = DBGLVL_NOTICE;
330 if (krb5_state == CRED_USE_KERBEROS_REQUIRED) {
334 DEBUG(dbglvl, ("Kinit for %s to access %s failed: %s\n",
335 user_principal, target_hostname,
336 error_message(ret)));
337 if (krb5_state == CRED_USE_KERBEROS_REQUIRED) {
339 return krb5_to_nt_status(ret);
343 * Ignore the error and hope that NTLM will work
349 ok = cli_credentials_set_principal(creds,
354 return NT_STATUS_NO_MEMORY;
357 ok = cli_credentials_set_realm(creds,
362 return NT_STATUS_NO_MEMORY;
365 DBG_DEBUG("Successfully authenticated as %s (%s) to access %s using "
375 static NTSTATUS cli_state_update_after_sesssetup(struct cli_state *cli,
376 const char *native_os,
377 const char *native_lm,
378 const char *primary_domain)
380 #define _VALID_STR(p) ((p) != NULL && (p)[0] != '\0')
382 if (!_VALID_STR(cli->server_os) && _VALID_STR(native_os)) {
383 cli->server_os = talloc_strdup(cli, native_os);
384 if (cli->server_os == NULL) {
385 return NT_STATUS_NO_MEMORY;
389 if (!_VALID_STR(cli->server_type) && _VALID_STR(native_lm)) {
390 cli->server_type = talloc_strdup(cli, native_lm);
391 if (cli->server_type == NULL) {
392 return NT_STATUS_NO_MEMORY;
396 if (!_VALID_STR(cli->server_domain) && _VALID_STR(primary_domain)) {
397 cli->server_domain = talloc_strdup(cli, primary_domain);
398 if (cli->server_domain == NULL) {
399 return NT_STATUS_NO_MEMORY;
407 /********************************************************
408 Utility function to ensure we always return at least
409 a valid char * pointer to an empty string for the
410 cli->server_os, cli->server_type and cli->server_domain
412 *******************************************************/
414 static NTSTATUS smb_bytes_talloc_string(TALLOC_CTX *mem_ctx,
421 *destlen = pull_string_talloc(mem_ctx,
428 if (*destlen == -1) {
429 return NT_STATUS_NO_MEMORY;
433 *dest = talloc_strdup(mem_ctx, "");
435 return NT_STATUS_NO_MEMORY;
441 /****************************************************************************
442 Work out suitable capabilities to offer the server.
443 ****************************************************************************/
445 static uint32_t cli_session_setup_capabilities(struct cli_state *cli,
446 uint32_t sesssetup_capabilities)
448 uint32_t client_capabilities = smb1cli_conn_capabilities(cli->conn);
451 * We only send capabilities based on the mask for:
452 * - client only flags
453 * - flags used in both directions
455 * We do not echo the server only flags, except some legacy flags.
457 * SMB_CAP_LEGACY_CLIENT_MASK contains CAP_LARGE_READX and
458 * CAP_LARGE_WRITEX in order to allow us to do large reads
459 * against old Samba releases (<= 3.6.x).
461 client_capabilities &= (SMB_CAP_BOTH_MASK | SMB_CAP_LEGACY_CLIENT_MASK);
464 * Session Setup specific flags CAP_DYNAMIC_REAUTH
465 * and CAP_EXTENDED_SECURITY are passed by the caller.
466 * We need that in order to do guest logins even if
467 * CAP_EXTENDED_SECURITY is negotiated.
469 client_capabilities &= ~(CAP_DYNAMIC_REAUTH|CAP_EXTENDED_SECURITY);
470 sesssetup_capabilities &= (CAP_DYNAMIC_REAUTH|CAP_EXTENDED_SECURITY);
471 client_capabilities |= sesssetup_capabilities;
473 return client_capabilities;
476 /****************************************************************************
477 Do a NT1 guest session setup.
478 ****************************************************************************/
480 struct cli_session_setup_guest_state {
481 struct cli_state *cli;
486 static void cli_session_setup_guest_done(struct tevent_req *subreq);
488 struct tevent_req *cli_session_setup_guest_create(TALLOC_CTX *mem_ctx,
489 struct tevent_context *ev,
490 struct cli_state *cli,
491 struct tevent_req **psmbreq)
493 struct tevent_req *req, *subreq;
494 struct cli_session_setup_guest_state *state;
498 req = tevent_req_create(mem_ctx, &state,
499 struct cli_session_setup_guest_state);
506 SCVAL(vwv+0, 0, 0xFF);
509 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
511 SSVAL(vwv+4, 0, cli_state_get_vc_num(cli));
512 SIVAL(vwv+5, 0, smb1cli_conn_server_session_key(cli->conn));
517 SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli, 0));
519 bytes = talloc_array(state, uint8_t, 0);
521 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "", 1, /* username */
523 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "", 1, /* workgroup */
525 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "Unix", 5, NULL);
526 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "Samba", 6, NULL);
533 state->bytes.iov_base = (void *)bytes;
534 state->bytes.iov_len = talloc_get_size(bytes);
536 subreq = cli_smb_req_create(state, ev, cli, SMBsesssetupX, 0, 0, 13,
537 vwv, 1, &state->bytes);
538 if (subreq == NULL) {
542 tevent_req_set_callback(subreq, cli_session_setup_guest_done, req);
547 struct tevent_req *cli_session_setup_guest_send(TALLOC_CTX *mem_ctx,
548 struct tevent_context *ev,
549 struct cli_state *cli)
551 struct tevent_req *req, *subreq;
554 req = cli_session_setup_guest_create(mem_ctx, ev, cli, &subreq);
559 status = smb1cli_req_chain_submit(&subreq, 1);
560 if (!NT_STATUS_IS_OK(status)) {
561 tevent_req_nterror(req, status);
562 return tevent_req_post(req, ev);
567 static void cli_session_setup_guest_done(struct tevent_req *subreq)
569 struct tevent_req *req = tevent_req_callback_data(
570 subreq, struct tevent_req);
571 struct cli_session_setup_guest_state *state = tevent_req_data(
572 req, struct cli_session_setup_guest_state);
573 struct cli_state *cli = state->cli;
584 status = cli_smb_recv(subreq, state, &in, 3, &wct, &vwv,
587 if (!NT_STATUS_IS_OK(status)) {
588 tevent_req_nterror(req, status);
592 inhdr = in + NBT_HDR_SIZE;
595 cli_state_set_uid(state->cli, SVAL(inhdr, HDR_UID));
596 smb1cli_session_set_action(cli->smb1.session, SVAL(vwv+2, 0));
598 status = smb_bytes_talloc_string(cli,
605 if (!NT_STATUS_IS_OK(status)) {
606 tevent_req_nterror(req, status);
611 status = smb_bytes_talloc_string(cli,
618 if (!NT_STATUS_IS_OK(status)) {
619 tevent_req_nterror(req, status);
624 status = smb_bytes_talloc_string(cli,
631 if (!NT_STATUS_IS_OK(status)) {
632 tevent_req_nterror(req, status);
636 tevent_req_done(req);
639 NTSTATUS cli_session_setup_guest_recv(struct tevent_req *req)
641 return tevent_req_simple_recv_ntstatus(req);
644 /* The following is calculated from :
646 * (smb_wcnt * 2) = 24 (smb_wcnt == 12 in cli_session_setup_blob_send() )
647 * (strlen("Unix") + 1 + strlen("Samba") + 1) * 2 = 22 (unicode strings at
651 #define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22)
653 struct cli_sesssetup_blob_state {
654 struct tevent_context *ev;
655 struct cli_state *cli;
657 uint16_t max_blob_size;
660 struct iovec *recv_iov;
663 const uint8_t *inbuf;
670 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state *state,
671 struct tevent_req **psubreq);
672 static void cli_sesssetup_blob_done(struct tevent_req *subreq);
674 static struct tevent_req *cli_sesssetup_blob_send(TALLOC_CTX *mem_ctx,
675 struct tevent_context *ev,
676 struct cli_state *cli,
679 struct tevent_req *req, *subreq;
680 struct cli_sesssetup_blob_state *state;
681 uint32_t usable_space;
683 req = tevent_req_create(mem_ctx, &state,
684 struct cli_sesssetup_blob_state);
692 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
693 usable_space = UINT16_MAX;
695 usable_space = cli_state_available_size(cli,
696 BASE_SESSSETUP_BLOB_PACKET_SIZE);
699 if (usable_space == 0) {
700 DEBUG(1, ("cli_session_setup_blob: cli->max_xmit too small "
701 "(not possible to send %u bytes)\n",
702 BASE_SESSSETUP_BLOB_PACKET_SIZE + 1));
703 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
704 return tevent_req_post(req, ev);
706 state->max_blob_size = MIN(usable_space, 0xFFFF);
708 if (!cli_sesssetup_blob_next(state, &subreq)) {
709 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
710 return tevent_req_post(req, ev);
712 tevent_req_set_callback(subreq, cli_sesssetup_blob_done, req);
716 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state *state,
717 struct tevent_req **psubreq)
719 struct tevent_req *subreq;
722 thistime = MIN(state->blob.length, state->max_blob_size);
724 state->this_blob.data = state->blob.data;
725 state->this_blob.length = thistime;
727 state->blob.data += thistime;
728 state->blob.length -= thistime;
730 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
731 subreq = smb2cli_session_setup_send(state, state->ev,
734 state->cli->smb2.session,
736 SMB2_CAP_DFS, /* in_capabilities */
738 0, /* in_previous_session_id */
740 if (subreq == NULL) {
744 uint16_t in_buf_size = 0;
745 uint16_t in_mpx_max = 0;
746 uint16_t in_vc_num = 0;
747 uint32_t in_sess_key = 0;
748 uint32_t in_capabilities = 0;
749 const char *in_native_os = NULL;
750 const char *in_native_lm = NULL;
752 in_buf_size = CLI_BUFFER_SIZE;
753 in_mpx_max = smbXcli_conn_max_requests(state->cli->conn);
754 in_vc_num = cli_state_get_vc_num(state->cli);
755 in_sess_key = smb1cli_conn_server_session_key(state->cli->conn);
756 in_capabilities = cli_session_setup_capabilities(state->cli,
757 CAP_EXTENDED_SECURITY);
758 in_native_os = "Unix";
759 in_native_lm = "Samba";
762 * For now we keep the same values as before,
763 * we may remove these in a separate commit later.
769 subreq = smb1cli_session_setup_ext_send(state, state->ev,
772 state->cli->smb1.pid,
773 state->cli->smb1.session,
782 if (subreq == NULL) {
790 static void cli_sesssetup_blob_done(struct tevent_req *subreq)
792 struct tevent_req *req = tevent_req_callback_data(
793 subreq, struct tevent_req);
794 struct cli_sesssetup_blob_state *state = tevent_req_data(
795 req, struct cli_sesssetup_blob_state);
798 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
799 status = smb2cli_session_setup_recv(subreq, state,
803 status = smb1cli_session_setup_ext_recv(subreq, state,
807 &state->out_native_os,
808 &state->out_native_lm);
811 if (!NT_STATUS_IS_OK(status)
812 && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
813 tevent_req_nterror(req, status);
817 state->status = status;
819 status = cli_state_update_after_sesssetup(state->cli,
820 state->out_native_os,
821 state->out_native_lm,
823 if (tevent_req_nterror(req, status)) {
827 if (state->blob.length != 0) {
831 if (!cli_sesssetup_blob_next(state, &subreq)) {
835 tevent_req_set_callback(subreq, cli_sesssetup_blob_done, req);
838 tevent_req_done(req);
841 static NTSTATUS cli_sesssetup_blob_recv(struct tevent_req *req,
844 const uint8_t **pinbuf,
845 struct iovec **precv_iov)
847 struct cli_sesssetup_blob_state *state = tevent_req_data(
848 req, struct cli_sesssetup_blob_state);
850 struct iovec *recv_iov;
852 if (tevent_req_is_nterror(req, &status)) {
853 TALLOC_FREE(state->cli->smb2.session);
854 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
855 tevent_req_received(req);
859 recv_iov = talloc_move(mem_ctx, &state->recv_iov);
861 *pblob = state->ret_blob;
863 if (pinbuf != NULL) {
864 *pinbuf = state->inbuf;
866 if (precv_iov != NULL) {
867 *precv_iov = recv_iov;
869 /* could be NT_STATUS_MORE_PROCESSING_REQUIRED */
870 status = state->status;
871 tevent_req_received(req);
875 /****************************************************************************
876 Do a spnego/NTLMSSP encrypted session setup.
877 ****************************************************************************/
879 struct cli_session_setup_gensec_state {
880 struct tevent_context *ev;
881 struct cli_state *cli;
882 struct auth_generic_state *auth_generic;
885 const uint8_t *inbuf;
886 struct iovec *recv_iov;
890 DATA_BLOB session_key;
893 static int cli_session_setup_gensec_state_destructor(
894 struct cli_session_setup_gensec_state *state)
896 TALLOC_FREE(state->auth_generic);
897 data_blob_clear_free(&state->session_key);
901 static void cli_session_setup_gensec_local_next(struct tevent_req *req);
902 static void cli_session_setup_gensec_local_done(struct tevent_req *subreq);
903 static void cli_session_setup_gensec_remote_next(struct tevent_req *req);
904 static void cli_session_setup_gensec_remote_done(struct tevent_req *subreq);
905 static void cli_session_setup_gensec_ready(struct tevent_req *req);
907 static struct tevent_req *cli_session_setup_gensec_send(
908 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
909 struct cli_credentials *creds,
910 const char *target_service,
911 const char *target_hostname)
913 struct tevent_req *req;
914 struct cli_session_setup_gensec_state *state;
916 const DATA_BLOB *b = NULL;
918 req = tevent_req_create(mem_ctx, &state,
919 struct cli_session_setup_gensec_state);
926 talloc_set_destructor(
927 state, cli_session_setup_gensec_state_destructor);
929 status = auth_generic_client_prepare(state, &state->auth_generic);
930 if (tevent_req_nterror(req, status)) {
931 return tevent_req_post(req, ev);
934 status = auth_generic_set_creds(state->auth_generic, creds);
935 if (tevent_req_nterror(req, status)) {
936 return tevent_req_post(req, ev);
939 gensec_want_feature(state->auth_generic->gensec_security,
940 GENSEC_FEATURE_SESSION_KEY);
942 if (target_service != NULL) {
943 status = gensec_set_target_service(
944 state->auth_generic->gensec_security,
946 if (tevent_req_nterror(req, status)) {
947 return tevent_req_post(req, ev);
951 if (target_hostname != NULL) {
952 status = gensec_set_target_hostname(
953 state->auth_generic->gensec_security,
955 if (tevent_req_nterror(req, status)) {
956 return tevent_req_post(req, ev);
960 b = smbXcli_conn_server_gss_blob(cli->conn);
965 state->is_anonymous = cli_credentials_is_anonymous(state->auth_generic->credentials);
967 status = auth_generic_client_start(state->auth_generic,
969 if (tevent_req_nterror(req, status)) {
970 return tevent_req_post(req, ev);
973 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
974 state->cli->smb2.session = smbXcli_session_create(cli,
976 if (tevent_req_nomem(state->cli->smb2.session, req)) {
977 return tevent_req_post(req, ev);
981 cli_session_setup_gensec_local_next(req);
982 if (!tevent_req_is_in_progress(req)) {
983 return tevent_req_post(req, ev);
989 static void cli_session_setup_gensec_local_next(struct tevent_req *req)
991 struct cli_session_setup_gensec_state *state =
993 struct cli_session_setup_gensec_state);
994 struct tevent_req *subreq = NULL;
996 if (state->local_ready) {
997 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1001 subreq = gensec_update_send(state, state->ev,
1002 state->auth_generic->gensec_security,
1004 if (tevent_req_nomem(subreq, req)) {
1007 tevent_req_set_callback(subreq, cli_session_setup_gensec_local_done, req);
1010 static void cli_session_setup_gensec_local_done(struct tevent_req *subreq)
1012 struct tevent_req *req =
1013 tevent_req_callback_data(subreq,
1015 struct cli_session_setup_gensec_state *state =
1016 tevent_req_data(req,
1017 struct cli_session_setup_gensec_state);
1020 status = gensec_update_recv(subreq, state, &state->blob_out);
1021 TALLOC_FREE(subreq);
1022 state->blob_in = data_blob_null;
1023 if (!NT_STATUS_IS_OK(status) &&
1024 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
1026 tevent_req_nterror(req, status);
1030 if (NT_STATUS_IS_OK(status)) {
1031 state->local_ready = true;
1034 if (state->local_ready && state->remote_ready) {
1035 cli_session_setup_gensec_ready(req);
1039 cli_session_setup_gensec_remote_next(req);
1042 static void cli_session_setup_gensec_remote_next(struct tevent_req *req)
1044 struct cli_session_setup_gensec_state *state =
1045 tevent_req_data(req,
1046 struct cli_session_setup_gensec_state);
1047 struct tevent_req *subreq = NULL;
1049 if (state->remote_ready) {
1050 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1054 subreq = cli_sesssetup_blob_send(state, state->ev,
1055 state->cli, state->blob_out);
1056 if (tevent_req_nomem(subreq, req)) {
1059 tevent_req_set_callback(subreq,
1060 cli_session_setup_gensec_remote_done,
1064 static void cli_session_setup_gensec_remote_done(struct tevent_req *subreq)
1066 struct tevent_req *req =
1067 tevent_req_callback_data(subreq,
1069 struct cli_session_setup_gensec_state *state =
1070 tevent_req_data(req,
1071 struct cli_session_setup_gensec_state);
1074 state->inbuf = NULL;
1075 TALLOC_FREE(state->recv_iov);
1077 status = cli_sesssetup_blob_recv(subreq, state, &state->blob_in,
1078 &state->inbuf, &state->recv_iov);
1079 TALLOC_FREE(subreq);
1080 data_blob_free(&state->blob_out);
1081 if (!NT_STATUS_IS_OK(status) &&
1082 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
1084 tevent_req_nterror(req, status);
1088 if (NT_STATUS_IS_OK(status)) {
1089 struct smbXcli_session *session = NULL;
1090 bool is_guest = false;
1092 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
1093 session = state->cli->smb2.session;
1095 session = state->cli->smb1.session;
1098 is_guest = smbXcli_session_is_guest(session);
1101 * We can't finish the gensec handshake, we don't
1102 * have a negotiated session key.
1104 * So just pretend we are completely done,
1105 * we need to continue as anonymous from this point,
1106 * as we can't get a session key.
1108 * Note that smbXcli_session_is_guest()
1109 * always returns false if we require signing.
1111 state->blob_in = data_blob_null;
1112 state->local_ready = true;
1113 state->is_anonymous = true;
1116 state->remote_ready = true;
1119 if (state->local_ready && state->remote_ready) {
1120 cli_session_setup_gensec_ready(req);
1124 cli_session_setup_gensec_local_next(req);
1127 static void cli_session_dump_keys(TALLOC_CTX *mem_ctx,
1128 struct smbXcli_session *session,
1129 DATA_BLOB session_key)
1132 DATA_BLOB sig = data_blob_null;
1133 DATA_BLOB app = data_blob_null;
1134 DATA_BLOB enc = data_blob_null;
1135 DATA_BLOB dec = data_blob_null;
1136 uint64_t sid = smb2cli_session_current_id(session);
1138 status = smb2cli_session_signing_key(session, mem_ctx, &sig);
1139 if (!NT_STATUS_IS_OK(status)) {
1142 status = smbXcli_session_application_key(session, mem_ctx, &app);
1143 if (!NT_STATUS_IS_OK(status)) {
1146 status = smb2cli_session_encryption_key(session, mem_ctx, &enc);
1147 if (!NT_STATUS_IS_OK(status)) {
1150 status = smb2cli_session_decryption_key(session, mem_ctx, &dec);
1151 if (!NT_STATUS_IS_OK(status)) {
1155 DEBUG(0, ("debug encryption: dumping generated session keys\n"));
1156 DEBUGADD(0, ("Session Id "));
1157 dump_data(0, (uint8_t*)&sid, sizeof(sid));
1158 DEBUGADD(0, ("Session Key "));
1159 dump_data(0, session_key.data, session_key.length);
1160 DEBUGADD(0, ("Signing Key "));
1161 dump_data(0, sig.data, sig.length);
1162 DEBUGADD(0, ("App Key "));
1163 dump_data(0, app.data, app.length);
1165 /* In client code, ServerIn is the encryption key */
1167 DEBUGADD(0, ("ServerIn Key "));
1168 dump_data(0, enc.data, enc.length);
1169 DEBUGADD(0, ("ServerOut Key "));
1170 dump_data(0, dec.data, dec.length);
1173 data_blob_clear_free(&sig);
1174 data_blob_clear_free(&app);
1175 data_blob_clear_free(&enc);
1176 data_blob_clear_free(&dec);
1179 static void cli_session_setup_gensec_ready(struct tevent_req *req)
1181 struct cli_session_setup_gensec_state *state =
1182 tevent_req_data(req,
1183 struct cli_session_setup_gensec_state);
1184 const char *server_domain = NULL;
1187 if (state->blob_in.length != 0) {
1188 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1192 if (state->blob_out.length != 0) {
1193 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1198 * gensec_ntlmssp_server_domain() returns NULL
1199 * if NTLMSSP is not used.
1201 * We can remove this later
1202 * and leave the server domain empty for SMB2 and above
1203 * in future releases.
1205 server_domain = gensec_ntlmssp_server_domain(
1206 state->auth_generic->gensec_security);
1208 if (state->cli->server_domain[0] == '\0' && server_domain != NULL) {
1209 TALLOC_FREE(state->cli->server_domain);
1210 state->cli->server_domain = talloc_strdup(state->cli,
1212 if (state->cli->server_domain == NULL) {
1213 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1218 if (state->is_anonymous) {
1220 * Windows server does not set the
1221 * SMB2_SESSION_FLAG_IS_NULL flag.
1223 * This fix makes sure we do not try
1224 * to verify a signature on the final
1225 * session setup response.
1227 tevent_req_done(req);
1231 status = gensec_session_key(state->auth_generic->gensec_security,
1232 state, &state->session_key);
1233 if (tevent_req_nterror(req, status)) {
1237 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
1238 struct smbXcli_session *session = state->cli->smb2.session;
1240 status = smb2cli_session_set_session_key(session,
1243 if (tevent_req_nterror(req, status)) {
1246 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB3_00
1247 && lp_debug_encryption())
1249 cli_session_dump_keys(state, session, state->session_key);
1252 struct smbXcli_session *session = state->cli->smb1.session;
1255 status = smb1cli_session_set_session_key(session,
1256 state->session_key);
1257 if (tevent_req_nterror(req, status)) {
1261 active = smb1cli_conn_activate_signing(state->cli->conn,
1267 ok = smb1cli_conn_check_signing(state->cli->conn,
1270 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1276 tevent_req_done(req);
1279 static NTSTATUS cli_session_setup_gensec_recv(struct tevent_req *req)
1281 struct cli_session_setup_gensec_state *state =
1282 tevent_req_data(req,
1283 struct cli_session_setup_gensec_state);
1286 if (tevent_req_is_nterror(req, &status)) {
1287 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
1290 return NT_STATUS_OK;
1293 static char *cli_session_setup_get_account(TALLOC_CTX *mem_ctx,
1294 const char *principal)
1298 account = talloc_strdup(mem_ctx, principal);
1299 if (account == NULL) {
1302 p = strchr_m(account, '@');
1309 /****************************************************************************
1310 Do a spnego encrypted session setup.
1312 user_domain: The shortname of the domain the user/machine is a member of.
1313 dest_realm: The realm we're connecting to, if NULL we use our default realm.
1314 ****************************************************************************/
1316 struct cli_session_setup_spnego_state {
1320 static void cli_session_setup_spnego_done(struct tevent_req *subreq);
1322 static struct tevent_req *cli_session_setup_spnego_send(
1323 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
1324 struct cli_credentials *creds)
1326 struct tevent_req *req, *subreq;
1327 struct cli_session_setup_spnego_state *state;
1328 const char *target_service = NULL;
1329 const char *target_hostname = NULL;
1332 req = tevent_req_create(mem_ctx, &state,
1333 struct cli_session_setup_spnego_state);
1338 target_service = "cifs";
1339 target_hostname = smbXcli_conn_remote_name(cli->conn);
1341 status = cli_session_creds_prepare_krb5(cli, creds);
1342 if (tevent_req_nterror(req, status)) {
1343 return tevent_req_post(req, ev);
1346 DBG_INFO("Connect to %s as %s using SPNEGO\n",
1348 cli_credentials_get_principal(creds, talloc_tos()));
1350 subreq = cli_session_setup_gensec_send(state, ev, cli, creds,
1351 target_service, target_hostname);
1352 if (tevent_req_nomem(subreq, req)) {
1353 return tevent_req_post(req, ev);
1355 tevent_req_set_callback(
1356 subreq, cli_session_setup_spnego_done, req);
1360 static void cli_session_setup_spnego_done(struct tevent_req *subreq)
1362 struct tevent_req *req = tevent_req_callback_data(
1363 subreq, struct tevent_req);
1366 status = cli_session_setup_gensec_recv(subreq);
1367 TALLOC_FREE(subreq);
1368 if (tevent_req_nterror(req, status)) {
1372 tevent_req_done(req);
1375 static ADS_STATUS cli_session_setup_spnego_recv(struct tevent_req *req)
1377 struct cli_session_setup_spnego_state *state = tevent_req_data(
1378 req, struct cli_session_setup_spnego_state);
1381 if (tevent_req_is_nterror(req, &status)) {
1382 state->result = ADS_ERROR_NT(status);
1385 return state->result;
1388 struct cli_session_setup_creds_state {
1389 struct cli_state *cli;
1390 DATA_BLOB apassword_blob;
1391 DATA_BLOB upassword_blob;
1392 DATA_BLOB lm_session_key;
1393 DATA_BLOB session_key;
1394 char *out_native_os;
1395 char *out_native_lm;
1396 char *out_primary_domain;
1399 static void cli_session_setup_creds_cleanup(struct tevent_req *req,
1400 enum tevent_req_state req_state)
1402 struct cli_session_setup_creds_state *state = tevent_req_data(
1403 req, struct cli_session_setup_creds_state);
1405 if (req_state != TEVENT_REQ_RECEIVED) {
1410 * We only call data_blob_clear() as
1411 * some of the blobs point to the same memory.
1413 * We let the talloc hierarchy free the memory.
1415 data_blob_clear(&state->apassword_blob);
1416 data_blob_clear(&state->upassword_blob);
1417 data_blob_clear(&state->lm_session_key);
1418 data_blob_clear(&state->session_key);
1419 ZERO_STRUCTP(state);
1422 static void cli_session_setup_creds_done_spnego(struct tevent_req *subreq);
1423 static void cli_session_setup_creds_done_nt1(struct tevent_req *subreq);
1424 static void cli_session_setup_creds_done_lm21(struct tevent_req *subreq);
1426 /****************************************************************************
1427 Send a session setup. The username and workgroup is in UNIX character
1428 format and must be converted to DOS codepage format before sending. If the
1429 password is in plaintext, the same should be done.
1430 ****************************************************************************/
1432 struct tevent_req *cli_session_setup_creds_send(TALLOC_CTX *mem_ctx,
1433 struct tevent_context *ev,
1434 struct cli_state *cli,
1435 struct cli_credentials *creds)
1437 struct tevent_req *req, *subreq;
1438 struct cli_session_setup_creds_state *state;
1439 uint16_t sec_mode = smb1cli_conn_server_security_mode(cli->conn);
1440 bool use_spnego = false;
1442 const char *username = "";
1443 const char *domain = "";
1444 DATA_BLOB target_info = data_blob_null;
1445 DATA_BLOB challenge = data_blob_null;
1446 uint16_t in_buf_size = 0;
1447 uint16_t in_mpx_max = 0;
1448 uint16_t in_vc_num = 0;
1449 uint32_t in_sess_key = 0;
1450 const char *in_native_os = NULL;
1451 const char *in_native_lm = NULL;
1452 enum credentials_use_kerberos krb5_state =
1453 cli_credentials_get_kerberos_state(creds);
1456 req = tevent_req_create(mem_ctx, &state,
1457 struct cli_session_setup_creds_state);
1463 tevent_req_set_cleanup_fn(req, cli_session_setup_creds_cleanup);
1466 * Now work out what sort of session setup we are going to
1467 * do. I have split this into separate functions to make the flow a bit
1468 * easier to understand (tridge).
1470 if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_NT1) {
1472 } else if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
1474 } else if (smb1cli_conn_capabilities(cli->conn) & CAP_EXTENDED_SECURITY) {
1476 * if the server supports extended security then use SPNEGO
1477 * even for anonymous connections.
1485 subreq = cli_session_setup_spnego_send(
1486 state, ev, cli, creds);
1487 if (tevent_req_nomem(subreq, req)) {
1488 return tevent_req_post(req, ev);
1490 tevent_req_set_callback(subreq, cli_session_setup_creds_done_spnego,
1495 if (krb5_state == CRED_USE_KERBEROS_REQUIRED) {
1496 DBG_WARNING("Kerberos authentication requested, but "
1497 "the server does not support SPNEGO authentication\n");
1498 tevent_req_nterror(req, NT_STATUS_NETWORK_CREDENTIAL_CONFLICT);
1499 return tevent_req_post(req, ev);
1502 if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_LANMAN1) {
1504 * SessionSetupAndX was introduced by LANMAN 1.0. So we skip
1505 * this step against older servers.
1507 tevent_req_done(req);
1508 return tevent_req_post(req, ev);
1511 if (cli_credentials_is_anonymous(creds)) {
1513 * Do an anonymous session setup
1515 goto non_spnego_creds_done;
1518 if ((sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0) {
1520 * Do an anonymous session setup,
1521 * the password is passed via the tree connect.
1523 goto non_spnego_creds_done;
1526 cli_credentials_get_ntlm_username_domain(creds, state,
1529 if (tevent_req_nomem(username, req)) {
1530 return tevent_req_post(req, ev);
1532 if (tevent_req_nomem(domain, req)) {
1533 return tevent_req_post(req, ev);
1536 DBG_INFO("Connect to %s as %s using NTLM\n", domain, username);
1538 if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) {
1539 bool use_unicode = smbXcli_conn_use_unicode(cli->conn);
1540 uint8_t *bytes = NULL;
1541 size_t bytes_len = 0;
1542 const char *pw = cli_credentials_get_password(creds);
1548 pw_len = strlen(pw) + 1;
1550 if (!lp_client_plaintext_auth()) {
1551 DEBUG(1, ("Server requested PLAINTEXT password but "
1552 "'client plaintext auth = no'\n"));
1553 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1554 return tevent_req_post(req, ev);
1557 bytes = talloc_array(state, uint8_t, 0);
1558 bytes = trans2_bytes_push_str(bytes, use_unicode,
1559 pw, pw_len, &bytes_len);
1560 if (tevent_req_nomem(bytes, req)) {
1561 return tevent_req_post(req, ev);
1566 * CAP_UNICODE, can only be negotiated by NT1.
1568 state->upassword_blob = data_blob_const(bytes,
1571 state->apassword_blob = data_blob_const(bytes,
1575 goto non_spnego_creds_done;
1578 challenge = data_blob_const(smb1cli_conn_server_challenge(cli->conn), 8);
1580 if (smbXcli_conn_protocol(cli->conn) == PROTOCOL_NT1) {
1581 if (lp_client_ntlmv2_auth() && lp_client_use_spnego()) {
1583 * Don't send an NTLMv2 response without NTLMSSP if we
1584 * want to use spnego support.
1586 DEBUG(1, ("Server does not support EXTENDED_SECURITY "
1587 " but 'client use spnego = yes'"
1588 " and 'client ntlmv2 auth = yes' is set\n"));
1589 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1590 return tevent_req_post(req, ev);
1593 if (lp_client_ntlmv2_auth()) {
1594 flags |= CLI_CRED_NTLMv2_AUTH;
1597 * note that the 'domain' here is a best
1598 * guess - we don't know the server's domain
1599 * at this point. Windows clients also don't
1602 target_info = NTLMv2_generate_names_blob(state,
1605 if (tevent_req_nomem(target_info.data, req)) {
1606 return tevent_req_post(req, ev);
1609 flags |= CLI_CRED_NTLM_AUTH;
1610 if (lp_client_lanman_auth()) {
1611 flags |= CLI_CRED_LANMAN_AUTH;
1615 if (!lp_client_lanman_auth()) {
1616 DEBUG(1, ("Server requested user level LM password but "
1617 "'client lanman auth = no' is set.\n"));
1618 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1619 return tevent_req_post(req, ev);
1622 flags |= CLI_CRED_LANMAN_AUTH;
1625 status = cli_credentials_get_ntlm_response(creds, state, &flags,
1628 &state->apassword_blob,
1629 &state->upassword_blob,
1630 &state->lm_session_key,
1631 &state->session_key);
1632 if (tevent_req_nterror(req, status)) {
1633 return tevent_req_post(req, ev);
1636 non_spnego_creds_done:
1638 in_buf_size = CLI_BUFFER_SIZE;
1639 in_mpx_max = smbXcli_conn_max_requests(cli->conn);
1640 in_vc_num = cli_state_get_vc_num(cli);
1641 in_sess_key = smb1cli_conn_server_session_key(cli->conn);
1642 in_native_os = "Unix";
1643 in_native_lm = "Samba";
1645 if (smbXcli_conn_protocol(cli->conn) == PROTOCOL_NT1) {
1646 uint32_t in_capabilities = 0;
1648 in_capabilities = cli_session_setup_capabilities(cli, 0);
1651 * For now we keep the same values as before,
1652 * we may remove these in a separate commit later.
1656 subreq = smb1cli_session_setup_nt1_send(state, ev,
1667 state->apassword_blob,
1668 state->upassword_blob,
1672 if (tevent_req_nomem(subreq, req)) {
1673 return tevent_req_post(req, ev);
1675 tevent_req_set_callback(subreq, cli_session_setup_creds_done_nt1,
1681 * For now we keep the same values as before,
1682 * we may remove these in a separate commit later.
1687 subreq = smb1cli_session_setup_lm21_send(state, ev,
1698 state->apassword_blob,
1701 if (tevent_req_nomem(subreq, req)) {
1702 return tevent_req_post(req, ev);
1704 tevent_req_set_callback(subreq, cli_session_setup_creds_done_lm21,
1709 static void cli_session_setup_creds_done_spnego(struct tevent_req *subreq)
1711 struct tevent_req *req = tevent_req_callback_data(
1712 subreq, struct tevent_req);
1715 status = cli_session_setup_spnego_recv(subreq);
1716 TALLOC_FREE(subreq);
1717 if (!ADS_ERR_OK(status)) {
1718 DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status)));
1719 tevent_req_nterror(req, ads_ntstatus(status));
1722 tevent_req_done(req);
1725 static void cli_session_setup_creds_done_nt1(struct tevent_req *subreq)
1727 struct tevent_req *req = tevent_req_callback_data(
1728 subreq, struct tevent_req);
1729 struct cli_session_setup_creds_state *state = tevent_req_data(
1730 req, struct cli_session_setup_creds_state);
1731 struct cli_state *cli = state->cli;
1733 struct iovec *recv_iov = NULL;
1734 const uint8_t *inbuf = NULL;
1737 status = smb1cli_session_setup_nt1_recv(subreq, state,
1740 &state->out_native_os,
1741 &state->out_native_lm,
1742 &state->out_primary_domain);
1743 TALLOC_FREE(subreq);
1744 if (tevent_req_nterror(req, status)) {
1745 DEBUG(3, ("NT1 login failed: %s\n", nt_errstr(status)));
1749 status = cli_state_update_after_sesssetup(state->cli,
1750 state->out_native_os,
1751 state->out_native_lm,
1752 state->out_primary_domain);
1753 if (tevent_req_nterror(req, status)) {
1757 ok = smb1cli_conn_activate_signing(cli->conn,
1759 state->upassword_blob);
1761 ok = smb1cli_conn_check_signing(cli->conn, inbuf, 1);
1763 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1768 if (state->session_key.data) {
1769 struct smbXcli_session *session = cli->smb1.session;
1771 status = smb1cli_session_set_session_key(session,
1772 state->session_key);
1773 if (tevent_req_nterror(req, status)) {
1778 tevent_req_done(req);
1781 static void cli_session_setup_creds_done_lm21(struct tevent_req *subreq)
1783 struct tevent_req *req = tevent_req_callback_data(
1784 subreq, struct tevent_req);
1785 struct cli_session_setup_creds_state *state = tevent_req_data(
1786 req, struct cli_session_setup_creds_state);
1789 status = smb1cli_session_setup_lm21_recv(subreq, state,
1790 &state->out_native_os,
1791 &state->out_native_lm);
1792 TALLOC_FREE(subreq);
1793 if (tevent_req_nterror(req, status)) {
1794 DEBUG(3, ("LM21 login failed: %s\n", nt_errstr(status)));
1798 status = cli_state_update_after_sesssetup(state->cli,
1799 state->out_native_os,
1800 state->out_native_lm,
1802 if (tevent_req_nterror(req, status)) {
1806 tevent_req_done(req);
1809 NTSTATUS cli_session_setup_creds_recv(struct tevent_req *req)
1811 return tevent_req_simple_recv_ntstatus(req);
1814 NTSTATUS cli_session_setup_creds(struct cli_state *cli,
1815 struct cli_credentials *creds)
1817 struct tevent_context *ev;
1818 struct tevent_req *req;
1819 NTSTATUS status = NT_STATUS_NO_MEMORY;
1821 if (smbXcli_conn_has_async_calls(cli->conn)) {
1822 return NT_STATUS_INVALID_PARAMETER;
1824 ev = samba_tevent_context_init(talloc_tos());
1828 req = cli_session_setup_creds_send(ev, ev, cli, creds);
1832 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1835 status = cli_session_setup_creds_recv(req);
1841 NTSTATUS cli_session_setup_anon(struct cli_state *cli)
1844 struct cli_credentials *creds = NULL;
1846 creds = cli_credentials_init_anon(cli);
1847 if (creds == NULL) {
1848 return NT_STATUS_NO_MEMORY;
1851 status = cli_session_setup_creds(cli, creds);
1853 if (!NT_STATUS_IS_OK(status)) {
1857 return NT_STATUS_OK;
1860 /****************************************************************************
1862 *****************************************************************************/
1864 struct cli_ulogoff_state {
1865 struct cli_state *cli;
1869 static void cli_ulogoff_done(struct tevent_req *subreq);
1871 static struct tevent_req *cli_ulogoff_send(TALLOC_CTX *mem_ctx,
1872 struct tevent_context *ev,
1873 struct cli_state *cli)
1875 struct tevent_req *req, *subreq;
1876 struct cli_ulogoff_state *state;
1878 req = tevent_req_create(mem_ctx, &state, struct cli_ulogoff_state);
1884 SCVAL(state->vwv+0, 0, 0xFF);
1885 SCVAL(state->vwv+1, 0, 0);
1886 SSVAL(state->vwv+2, 0, 0);
1888 subreq = cli_smb_send(state, ev, cli, SMBulogoffX, 0, 0, 2, state->vwv,
1890 if (tevent_req_nomem(subreq, req)) {
1891 return tevent_req_post(req, ev);
1893 tevent_req_set_callback(subreq, cli_ulogoff_done, req);
1897 static void cli_ulogoff_done(struct tevent_req *subreq)
1899 struct tevent_req *req = tevent_req_callback_data(
1900 subreq, struct tevent_req);
1901 struct cli_ulogoff_state *state = tevent_req_data(
1902 req, struct cli_ulogoff_state);
1905 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
1906 if (tevent_req_nterror(req, status)) {
1909 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
1910 tevent_req_done(req);
1913 static NTSTATUS cli_ulogoff_recv(struct tevent_req *req)
1915 return tevent_req_simple_recv_ntstatus(req);
1918 NTSTATUS cli_ulogoff(struct cli_state *cli)
1920 struct tevent_context *ev;
1921 struct tevent_req *req;
1922 NTSTATUS status = NT_STATUS_NO_MEMORY;
1924 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
1925 status = smb2cli_logoff(cli->conn,
1928 if (!NT_STATUS_IS_OK(status)) {
1931 smb2cli_session_set_id_and_flags(cli->smb2.session,
1933 return NT_STATUS_OK;
1936 if (smbXcli_conn_has_async_calls(cli->conn)) {
1937 return NT_STATUS_INVALID_PARAMETER;
1939 ev = samba_tevent_context_init(talloc_tos());
1943 req = cli_ulogoff_send(ev, ev, cli);
1947 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1950 status = cli_ulogoff_recv(req);
1956 /****************************************************************************
1958 ****************************************************************************/
1960 struct cli_tcon_andx_state {
1961 struct cli_state *cli;
1966 static void cli_tcon_andx_done(struct tevent_req *subreq);
1968 struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx,
1969 struct tevent_context *ev,
1970 struct cli_state *cli,
1971 const char *share, const char *dev,
1972 const char *pass, int passlen,
1973 struct tevent_req **psmbreq)
1975 struct tevent_req *req, *subreq;
1976 struct cli_tcon_andx_state *state;
1981 uint16_t sec_mode = smb1cli_conn_server_security_mode(cli->conn);
1982 uint16_t tcon_flags = 0;
1986 req = tevent_req_create(mem_ctx, &state, struct cli_tcon_andx_state);
1993 TALLOC_FREE(cli->smb1.tcon);
1994 cli->smb1.tcon = smbXcli_tcon_create(cli);
1995 if (tevent_req_nomem(cli->smb1.tcon, req)) {
1996 return tevent_req_post(req, ev);
1998 smb1cli_tcon_set_id(cli->smb1.tcon, UINT16_MAX);
2000 cli->share = talloc_strdup(cli, share);
2005 /* in user level security don't send a password now */
2006 if (sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {
2009 } else if (pass == NULL) {
2010 DEBUG(1, ("Server not using user level security and no "
2011 "password supplied.\n"));
2015 if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) &&
2016 *pass && passlen != 24) {
2017 if (!lp_client_lanman_auth()) {
2018 DEBUG(1, ("Server requested LANMAN password "
2019 "(share-level security) but "
2020 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2025 * Non-encrypted passwords - convert to DOS codepage before
2028 SMBencrypt(pass, smb1cli_conn_server_challenge(cli->conn), p24);
2030 pass = (const char *)p24;
2032 if((sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL
2033 |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE))
2037 if (!lp_client_plaintext_auth() && (*pass)) {
2038 DEBUG(1, ("Server requested PLAINTEXT "
2040 "'client plaintext auth = no' or 'client ntlmv2 auth = yes'\n"));
2045 * Non-encrypted passwords - convert to DOS codepage
2048 tmp_pass = talloc_array(talloc_tos(), uint8_t, 0);
2049 if (tevent_req_nomem(tmp_pass, req)) {
2050 return tevent_req_post(req, ev);
2052 tmp_pass = trans2_bytes_push_str(tmp_pass,
2053 false, /* always DOS */
2057 if (tevent_req_nomem(tmp_pass, req)) {
2058 return tevent_req_post(req, ev);
2060 pass = (const char *)tmp_pass;
2061 passlen = talloc_get_size(tmp_pass);
2065 tcon_flags |= TCONX_FLAG_EXTENDED_RESPONSE;
2066 tcon_flags |= TCONX_FLAG_EXTENDED_SIGNATURES;
2068 SCVAL(vwv+0, 0, 0xFF);
2071 SSVAL(vwv+2, 0, tcon_flags);
2072 SSVAL(vwv+3, 0, passlen);
2074 if (passlen && pass) {
2075 bytes = (uint8_t *)talloc_memdup(state, pass, passlen);
2077 bytes = talloc_array(state, uint8_t, 0);
2083 tmp = talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
2084 smbXcli_conn_remote_name(cli->conn), share);
2089 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), tmp, strlen(tmp)+1,
2094 * Add the devicetype
2096 tmp = talloc_strdup_upper(talloc_tos(), dev);
2101 bytes = smb_bytes_push_str(bytes, false, tmp, strlen(tmp)+1, NULL);
2104 if (bytes == NULL) {
2109 state->bytes.iov_base = (void *)bytes;
2110 state->bytes.iov_len = talloc_get_size(bytes);
2112 subreq = cli_smb_req_create(state, ev, cli, SMBtconX, 0, 0, 4, vwv,
2114 if (subreq == NULL) {
2118 tevent_req_set_callback(subreq, cli_tcon_andx_done, req);
2123 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
2124 return tevent_req_post(req, ev);
2127 struct tevent_req *cli_tcon_andx_send(TALLOC_CTX *mem_ctx,
2128 struct tevent_context *ev,
2129 struct cli_state *cli,
2130 const char *share, const char *dev,
2131 const char *pass, int passlen)
2133 struct tevent_req *req, *subreq;
2136 req = cli_tcon_andx_create(mem_ctx, ev, cli, share, dev, pass, passlen,
2141 if (subreq == NULL) {
2144 status = smb1cli_req_chain_submit(&subreq, 1);
2145 if (tevent_req_nterror(req, status)) {
2146 return tevent_req_post(req, ev);
2151 static void cli_tcon_andx_done(struct tevent_req *subreq)
2153 struct tevent_req *req = tevent_req_callback_data(
2154 subreq, struct tevent_req);
2155 struct cli_tcon_andx_state *state = tevent_req_data(
2156 req, struct cli_tcon_andx_state);
2157 struct cli_state *cli = state->cli;
2165 uint16_t optional_support = 0;
2167 status = cli_smb_recv(subreq, state, &in, 0, &wct, &vwv,
2168 &num_bytes, &bytes);
2169 TALLOC_FREE(subreq);
2170 if (tevent_req_nterror(req, status)) {
2174 inhdr = in + NBT_HDR_SIZE;
2177 if (pull_string_talloc(cli,
2178 (const char *)inhdr,
2179 SVAL(inhdr, HDR_FLG2),
2183 STR_TERMINATE|STR_ASCII) == -1) {
2184 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2188 cli->dev = talloc_strdup(cli, "");
2189 if (cli->dev == NULL) {
2190 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2195 if ((smbXcli_conn_protocol(cli->conn) >= PROTOCOL_NT1) && (num_bytes == 3)) {
2196 /* almost certainly win95 - enable bug fixes */
2201 * Make sure that we have the optional support 16-bit field. WCT > 2.
2202 * Avoids issues when connecting to Win9x boxes sharing files
2205 if ((wct > 2) && (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_LANMAN2)) {
2206 optional_support = SVAL(vwv+2, 0);
2209 if (optional_support & SMB_EXTENDED_SIGNATURES) {
2210 smb1cli_session_protect_session_key(cli->smb1.session);
2213 smb1cli_tcon_set_values(state->cli->smb1.tcon,
2214 SVAL(inhdr, HDR_TID),
2216 0, /* maximal_access */
2217 0, /* guest_maximal_access */
2219 NULL); /* fs_type */
2221 tevent_req_done(req);
2224 NTSTATUS cli_tcon_andx_recv(struct tevent_req *req)
2226 return tevent_req_simple_recv_ntstatus(req);
2229 NTSTATUS cli_tcon_andx(struct cli_state *cli, const char *share,
2230 const char *dev, const char *pass, int passlen)
2232 TALLOC_CTX *frame = talloc_stackframe();
2233 struct tevent_context *ev;
2234 struct tevent_req *req;
2235 NTSTATUS status = NT_STATUS_NO_MEMORY;
2237 if (smbXcli_conn_has_async_calls(cli->conn)) {
2239 * Can't use sync call while an async call is in flight
2241 status = NT_STATUS_INVALID_PARAMETER;
2245 ev = samba_tevent_context_init(frame);
2250 req = cli_tcon_andx_send(frame, ev, cli, share, dev, pass, passlen);
2255 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2259 status = cli_tcon_andx_recv(req);
2265 struct cli_tree_connect_state {
2266 struct cli_state *cli;
2269 static struct tevent_req *cli_raw_tcon_send(
2270 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
2271 const char *service, const char *pass, const char *dev);
2272 static NTSTATUS cli_raw_tcon_recv(struct tevent_req *req,
2273 uint16_t *max_xmit, uint16_t *tid);
2275 static void cli_tree_connect_smb2_done(struct tevent_req *subreq);
2276 static void cli_tree_connect_andx_done(struct tevent_req *subreq);
2277 static void cli_tree_connect_raw_done(struct tevent_req *subreq);
2279 static struct tevent_req *cli_tree_connect_send(
2280 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
2281 const char *share, const char *dev, const char *pass)
2283 struct tevent_req *req, *subreq;
2284 struct cli_tree_connect_state *state;
2290 passlen = strlen(pass) + 1;
2292 req = tevent_req_create(mem_ctx, &state,
2293 struct cli_tree_connect_state);
2299 cli->share = talloc_strdup(cli, share);
2300 if (tevent_req_nomem(cli->share, req)) {
2301 return tevent_req_post(req, ev);
2304 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
2307 TALLOC_FREE(cli->smb2.tcon);
2308 cli->smb2.tcon = smbXcli_tcon_create(cli);
2309 if (tevent_req_nomem(cli->smb2.tcon, req)) {
2310 return tevent_req_post(req, ev);
2313 unc = talloc_asprintf(state, "\\\\%s\\%s",
2314 smbXcli_conn_remote_name(cli->conn),
2316 if (tevent_req_nomem(unc, req)) {
2317 return tevent_req_post(req, ev);
2320 subreq = smb2cli_tcon_send(state, ev, cli->conn, cli->timeout,
2321 cli->smb2.session, cli->smb2.tcon,
2324 if (tevent_req_nomem(subreq, req)) {
2325 return tevent_req_post(req, ev);
2327 tevent_req_set_callback(subreq, cli_tree_connect_smb2_done,
2332 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_LANMAN1) {
2333 subreq = cli_tcon_andx_send(state, ev, cli, share, dev,
2335 if (tevent_req_nomem(subreq, req)) {
2336 return tevent_req_post(req, ev);
2338 tevent_req_set_callback(subreq, cli_tree_connect_andx_done,
2343 subreq = cli_raw_tcon_send(state, ev, cli, share, pass, dev);
2344 if (tevent_req_nomem(subreq, req)) {
2345 return tevent_req_post(req, ev);
2347 tevent_req_set_callback(subreq, cli_tree_connect_raw_done, req);
2352 static void cli_tree_connect_smb2_done(struct tevent_req *subreq)
2354 NTSTATUS status = smb2cli_tcon_recv(subreq);
2355 tevent_req_simple_finish_ntstatus(subreq, status);
2358 static void cli_tree_connect_andx_done(struct tevent_req *subreq)
2360 NTSTATUS status = cli_tcon_andx_recv(subreq);
2361 tevent_req_simple_finish_ntstatus(subreq, status);
2364 static void cli_tree_connect_raw_done(struct tevent_req *subreq)
2366 struct tevent_req *req = tevent_req_callback_data(
2367 subreq, struct tevent_req);
2368 struct cli_tree_connect_state *state = tevent_req_data(
2369 req, struct cli_tree_connect_state);
2371 uint16_t max_xmit = 0;
2374 status = cli_raw_tcon_recv(subreq, &max_xmit, &tid);
2375 if (tevent_req_nterror(req, status)) {
2379 smb1cli_tcon_set_values(state->cli->smb1.tcon,
2381 0, /* optional_support */
2382 0, /* maximal_access */
2383 0, /* guest_maximal_access */
2385 NULL); /* fs_type */
2387 tevent_req_done(req);
2390 static NTSTATUS cli_tree_connect_recv(struct tevent_req *req)
2392 return tevent_req_simple_recv_ntstatus(req);
2395 NTSTATUS cli_tree_connect(struct cli_state *cli, const char *share,
2396 const char *dev, const char *pass)
2398 struct tevent_context *ev;
2399 struct tevent_req *req;
2400 NTSTATUS status = NT_STATUS_NO_MEMORY;
2402 if (smbXcli_conn_has_async_calls(cli->conn)) {
2403 return NT_STATUS_INVALID_PARAMETER;
2405 ev = samba_tevent_context_init(talloc_tos());
2409 req = cli_tree_connect_send(ev, ev, cli, share, dev, pass);
2413 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2416 status = cli_tree_connect_recv(req);
2422 NTSTATUS cli_tree_connect_creds(struct cli_state *cli,
2423 const char *share, const char *dev,
2424 struct cli_credentials *creds)
2426 bool need_pass = false;
2427 const char *pw = NULL;
2430 * We should work out if the protocol
2431 * will make use of a password for share level
2432 * authentication before we may cause
2433 * the password prompt to be called.
2435 if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_SMB2_02) {
2436 uint16_t sec_mode = smb1cli_conn_server_security_mode(cli->conn);
2438 /* in user level security don't send a password now */
2439 if (!(sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) {
2444 if (need_pass && creds != NULL) {
2445 pw = cli_credentials_get_password(creds);
2448 return cli_tree_connect(cli, share, dev, pw);
2451 /****************************************************************************
2452 Send a tree disconnect.
2453 ****************************************************************************/
2455 struct cli_tdis_state {
2456 struct cli_state *cli;
2459 static void cli_tdis_done(struct tevent_req *subreq);
2461 static struct tevent_req *cli_tdis_send(TALLOC_CTX *mem_ctx,
2462 struct tevent_context *ev,
2463 struct cli_state *cli)
2465 struct tevent_req *req, *subreq;
2466 struct cli_tdis_state *state;
2468 req = tevent_req_create(mem_ctx, &state, struct cli_tdis_state);
2474 subreq = cli_smb_send(state, ev, cli, SMBtdis, 0, 0, 0, NULL, 0, NULL);
2475 if (tevent_req_nomem(subreq, req)) {
2476 return tevent_req_post(req, ev);
2478 tevent_req_set_callback(subreq, cli_tdis_done, req);
2482 static void cli_tdis_done(struct tevent_req *subreq)
2484 struct tevent_req *req = tevent_req_callback_data(
2485 subreq, struct tevent_req);
2486 struct cli_tdis_state *state = tevent_req_data(
2487 req, struct cli_tdis_state);
2490 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
2491 TALLOC_FREE(subreq);
2492 if (tevent_req_nterror(req, status)) {
2495 TALLOC_FREE(state->cli->smb1.tcon);
2496 tevent_req_done(req);
2499 static NTSTATUS cli_tdis_recv(struct tevent_req *req)
2501 return tevent_req_simple_recv_ntstatus(req);
2504 NTSTATUS cli_tdis(struct cli_state *cli)
2506 struct tevent_context *ev;
2507 struct tevent_req *req;
2508 NTSTATUS status = NT_STATUS_NO_MEMORY;
2510 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
2511 status = smb2cli_tdis(cli->conn,
2515 if (NT_STATUS_IS_OK(status)) {
2516 TALLOC_FREE(cli->smb2.tcon);
2521 if (smbXcli_conn_has_async_calls(cli->conn)) {
2522 return NT_STATUS_INVALID_PARAMETER;
2524 ev = samba_tevent_context_init(talloc_tos());
2528 req = cli_tdis_send(ev, ev, cli);
2532 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2535 status = cli_tdis_recv(req);
2541 struct cli_connect_sock_state {
2542 const char **called_names;
2543 const char **calling_names;
2549 static void cli_connect_sock_done(struct tevent_req *subreq);
2552 * Async only if we don't have to look up the name, i.e. "pss" is set with a
2556 static struct tevent_req *cli_connect_sock_send(
2557 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2558 const char *host, int name_type, const struct sockaddr_storage *pss,
2559 const char *myname, uint16_t port)
2561 struct tevent_req *req, *subreq;
2562 struct cli_connect_sock_state *state;
2563 struct sockaddr_storage *addrs = NULL;
2565 unsigned num_addrs = 0;
2568 req = tevent_req_create(mem_ctx, &state,
2569 struct cli_connect_sock_state);
2574 if ((pss == NULL) || is_zero_addr(pss)) {
2577 * Here we cheat. resolve_name_list is not async at all. So
2578 * this call will only be really async if the name lookup has
2579 * been done externally.
2582 status = resolve_name_list(state, host, name_type,
2583 &addrs, &num_addrs);
2584 if (tevent_req_nterror(req, status)) {
2585 return tevent_req_post(req, ev);
2588 addrs = talloc_array(state, struct sockaddr_storage, 1);
2589 if (tevent_req_nomem(addrs, req)) {
2590 return tevent_req_post(req, ev);
2596 state->called_names = talloc_array(state, const char *, num_addrs);
2597 if (tevent_req_nomem(state->called_names, req)) {
2598 return tevent_req_post(req, ev);
2600 state->called_types = talloc_array(state, int, num_addrs);
2601 if (tevent_req_nomem(state->called_types, req)) {
2602 return tevent_req_post(req, ev);
2604 state->calling_names = talloc_array(state, const char *, num_addrs);
2605 if (tevent_req_nomem(state->calling_names, req)) {
2606 return tevent_req_post(req, ev);
2608 for (i=0; i<num_addrs; i++) {
2609 state->called_names[i] = host;
2610 state->called_types[i] = name_type;
2611 state->calling_names[i] = myname;
2614 subreq = smbsock_any_connect_send(
2615 state, ev, addrs, state->called_names, state->called_types,
2616 state->calling_names, NULL, num_addrs, port);
2617 if (tevent_req_nomem(subreq, req)) {
2618 return tevent_req_post(req, ev);
2620 tevent_req_set_callback(subreq, cli_connect_sock_done, req);
2624 static void cli_connect_sock_done(struct tevent_req *subreq)
2626 struct tevent_req *req = tevent_req_callback_data(
2627 subreq, struct tevent_req);
2628 struct cli_connect_sock_state *state = tevent_req_data(
2629 req, struct cli_connect_sock_state);
2632 status = smbsock_any_connect_recv(subreq, &state->fd, NULL,
2634 TALLOC_FREE(subreq);
2635 if (tevent_req_nterror(req, status)) {
2638 set_socket_options(state->fd, lp_socket_options());
2639 tevent_req_done(req);
2642 static NTSTATUS cli_connect_sock_recv(struct tevent_req *req,
2643 int *pfd, uint16_t *pport)
2645 struct cli_connect_sock_state *state = tevent_req_data(
2646 req, struct cli_connect_sock_state);
2649 if (tevent_req_is_nterror(req, &status)) {
2653 *pport = state->port;
2654 return NT_STATUS_OK;
2657 struct cli_connect_nb_state {
2658 const char *desthost;
2659 enum smb_signing_setting signing_state;
2661 struct cli_state *cli;
2664 static void cli_connect_nb_done(struct tevent_req *subreq);
2666 static struct tevent_req *cli_connect_nb_send(
2667 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2668 const char *host, const struct sockaddr_storage *dest_ss,
2669 uint16_t port, int name_type, const char *myname,
2670 enum smb_signing_setting signing_state, int flags)
2672 struct tevent_req *req, *subreq;
2673 struct cli_connect_nb_state *state;
2675 req = tevent_req_create(mem_ctx, &state, struct cli_connect_nb_state);
2679 state->signing_state = signing_state;
2680 state->flags = flags;
2683 char *p = strchr(host, '#');
2686 name_type = strtol(p+1, NULL, 16);
2687 host = talloc_strndup(state, host, p - host);
2688 if (tevent_req_nomem(host, req)) {
2689 return tevent_req_post(req, ev);
2693 state->desthost = host;
2694 } else if (dest_ss != NULL) {
2695 state->desthost = print_canonical_sockaddr(state, dest_ss);
2696 if (tevent_req_nomem(state->desthost, req)) {
2697 return tevent_req_post(req, ev);
2700 /* No host or dest_ss given. Error out. */
2701 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
2702 return tevent_req_post(req, ev);
2705 subreq = cli_connect_sock_send(state, ev, host, name_type, dest_ss,
2707 if (tevent_req_nomem(subreq, req)) {
2708 return tevent_req_post(req, ev);
2710 tevent_req_set_callback(subreq, cli_connect_nb_done, req);
2714 static void cli_connect_nb_done(struct tevent_req *subreq)
2716 struct tevent_req *req = tevent_req_callback_data(
2717 subreq, struct tevent_req);
2718 struct cli_connect_nb_state *state = tevent_req_data(
2719 req, struct cli_connect_nb_state);
2724 status = cli_connect_sock_recv(subreq, &fd, &port);
2725 TALLOC_FREE(subreq);
2726 if (tevent_req_nterror(req, status)) {
2730 state->cli = cli_state_create(state, fd, state->desthost,
2731 state->signing_state, state->flags);
2732 if (tevent_req_nomem(state->cli, req)) {
2736 tevent_req_done(req);
2739 static NTSTATUS cli_connect_nb_recv(struct tevent_req *req,
2740 TALLOC_CTX *mem_ctx,
2741 struct cli_state **pcli)
2743 struct cli_connect_nb_state *state = tevent_req_data(
2744 req, struct cli_connect_nb_state);
2747 if (tevent_req_is_nterror(req, &status)) {
2750 *pcli = talloc_move(mem_ctx, &state->cli);
2751 return NT_STATUS_OK;
2754 NTSTATUS cli_connect_nb(TALLOC_CTX *mem_ctx,
2756 const struct sockaddr_storage *dest_ss,
2760 enum smb_signing_setting signing_state,
2762 struct cli_state **pcli)
2764 struct tevent_context *ev;
2765 struct tevent_req *req;
2766 NTSTATUS status = NT_STATUS_NO_MEMORY;
2768 ev = samba_tevent_context_init(mem_ctx);
2772 req = cli_connect_nb_send(ev, ev, host, dest_ss, port, name_type,
2773 myname, signing_state, flags);
2777 if (!tevent_req_set_endtime(req, ev, timeval_current_ofs(20, 0))) {
2780 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2783 status = cli_connect_nb_recv(req, mem_ctx, pcli);
2789 struct cli_start_connection_state {
2790 struct tevent_context *ev;
2791 struct cli_state *cli;
2794 struct smb2_negotiate_contexts *negotiate_contexts;
2797 static void cli_start_connection_connected(struct tevent_req *subreq);
2798 static void cli_start_connection_done(struct tevent_req *subreq);
2801 establishes a connection to after the negprot.
2802 @param output_cli A fully initialised cli structure, non-null only on success
2803 @param dest_host The netbios name of the remote host
2804 @param dest_ss (optional) The destination IP, NULL for name based lookup
2805 @param port (optional) The destination port (0 for default)
2808 static struct tevent_req *cli_start_connection_send(
2809 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2810 const char *my_name, const char *dest_host,
2811 const struct sockaddr_storage *dest_ss, int port,
2812 enum smb_signing_setting signing_state, int flags,
2813 struct smb2_negotiate_contexts *negotiate_contexts)
2815 struct tevent_req *req, *subreq;
2816 struct cli_start_connection_state *state;
2818 req = tevent_req_create(mem_ctx, &state,
2819 struct cli_start_connection_state);
2825 if (flags & CLI_FULL_CONNECTION_IPC) {
2826 state->min_protocol = lp_client_ipc_min_protocol();
2827 state->max_protocol = lp_client_ipc_max_protocol();
2829 state->min_protocol = lp_client_min_protocol();
2830 state->max_protocol = lp_client_max_protocol();
2833 if (flags & CLI_FULL_CONNECTION_FORCE_SMB1) {
2834 state->max_protocol = MIN(state->max_protocol,
2836 state->min_protocol = MIN(state->min_protocol,
2837 state->max_protocol);
2840 if (flags & CLI_FULL_CONNECTION_DISABLE_SMB1) {
2841 state->min_protocol = MAX(state->min_protocol,
2843 state->max_protocol = MAX(state->max_protocol,
2844 state->min_protocol);
2847 state->negotiate_contexts = talloc_zero(
2848 state, struct smb2_negotiate_contexts);
2849 if (tevent_req_nomem(state->negotiate_contexts, req)) {
2850 return tevent_req_post(req, ev);
2853 if (flags & CLI_FULL_CONNECTION_REQUEST_POSIX) {
2856 status = smb2_negotiate_context_add(
2857 state->negotiate_contexts,
2858 state->negotiate_contexts,
2859 SMB2_POSIX_EXTENSIONS_AVAILABLE,
2860 (const uint8_t *)SMB2_CREATE_TAG_POSIX,
2861 strlen(SMB2_CREATE_TAG_POSIX));
2862 if (tevent_req_nterror(req, status)) {
2863 return tevent_req_post(req, ev);
2867 if (negotiate_contexts != NULL) {
2870 for (i=0; i<negotiate_contexts->num_contexts; i++) {
2871 struct smb2_negotiate_context *ctx =
2872 &negotiate_contexts->contexts[i];
2875 status = smb2_negotiate_context_add(
2876 state->negotiate_contexts,
2877 state->negotiate_contexts,
2881 if (tevent_req_nterror(req, status)) {
2882 return tevent_req_post(req, ev);
2887 subreq = cli_connect_nb_send(state, ev, dest_host, dest_ss, port,
2888 0x20, my_name, signing_state, flags);
2889 if (tevent_req_nomem(subreq, req)) {
2890 return tevent_req_post(req, ev);
2892 tevent_req_set_callback(subreq, cli_start_connection_connected, req);
2896 static void cli_start_connection_connected(struct tevent_req *subreq)
2898 struct tevent_req *req = tevent_req_callback_data(
2899 subreq, struct tevent_req);
2900 struct cli_start_connection_state *state = tevent_req_data(
2901 req, struct cli_start_connection_state);
2904 status = cli_connect_nb_recv(subreq, state, &state->cli);
2905 TALLOC_FREE(subreq);
2906 if (tevent_req_nterror(req, status)) {
2910 subreq = smbXcli_negprot_send(
2914 state->cli->timeout,
2915 state->min_protocol,
2916 state->max_protocol,
2917 WINDOWS_CLIENT_PURE_SMB2_NEGPROT_INITIAL_CREDIT_ASK,
2918 state->negotiate_contexts);
2919 if (tevent_req_nomem(subreq, req)) {
2922 tevent_req_set_callback(subreq, cli_start_connection_done, req);
2925 static void cli_start_connection_done(struct tevent_req *subreq)
2927 struct tevent_req *req = tevent_req_callback_data(
2928 subreq, struct tevent_req);
2929 struct cli_start_connection_state *state = tevent_req_data(
2930 req, struct cli_start_connection_state);
2933 status = smbXcli_negprot_recv(subreq, NULL, NULL);
2934 TALLOC_FREE(subreq);
2935 if (tevent_req_nterror(req, status)) {
2939 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
2940 /* Ensure we ask for some initial credits. */
2941 smb2cli_conn_set_max_credits(state->cli->conn,
2942 DEFAULT_SMB2_MAX_CREDITS);
2945 tevent_req_done(req);
2948 static NTSTATUS cli_start_connection_recv(struct tevent_req *req,
2949 TALLOC_CTX *mem_ctx,
2950 struct cli_state **output_cli)
2952 struct cli_start_connection_state *state = tevent_req_data(
2953 req, struct cli_start_connection_state);
2956 if (tevent_req_is_nterror(req, &status)) {
2959 *output_cli = talloc_move(mem_ctx, &state->cli);
2961 return NT_STATUS_OK;
2964 NTSTATUS cli_start_connection(TALLOC_CTX *mem_ctx,
2965 struct cli_state **output_cli,
2966 const char *my_name,
2967 const char *dest_host,
2968 const struct sockaddr_storage *dest_ss, int port,
2969 enum smb_signing_setting signing_state, int flags)
2971 struct tevent_context *ev;
2972 struct tevent_req *req;
2973 NTSTATUS status = NT_STATUS_NO_MEMORY;
2975 ev = samba_tevent_context_init(mem_ctx);
2979 req = cli_start_connection_send(ev, ev, my_name, dest_host, dest_ss,
2980 port, signing_state, flags, NULL);
2984 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2987 status = cli_start_connection_recv(req, mem_ctx, output_cli);
2993 struct cli_smb1_setup_encryption_blob_state {
2998 uint16_t enc_ctx_id;
3001 static void cli_smb1_setup_encryption_blob_done(struct tevent_req *subreq);
3003 static struct tevent_req *cli_smb1_setup_encryption_blob_send(TALLOC_CTX *mem_ctx,
3004 struct tevent_context *ev,
3005 struct cli_state *cli,
3008 struct tevent_req *req = NULL;
3009 struct cli_smb1_setup_encryption_blob_state *state = NULL;
3010 struct tevent_req *subreq = NULL;
3012 req = tevent_req_create(mem_ctx, &state,
3013 struct cli_smb1_setup_encryption_blob_state);
3018 if (in.length > CLI_BUFFER_SIZE) {
3019 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
3020 return tevent_req_post(req, ev);
3023 SSVAL(state->setup+0, 0, TRANSACT2_SETFSINFO);
3024 SSVAL(state->param, 0, 0);
3025 SSVAL(state->param, 2, SMB_REQUEST_TRANSPORT_ENCRYPTION);
3027 subreq = smb1cli_trans_send(state, ev, cli->conn,
3035 NULL, /* pipe_name */
3041 in.data, in.length, CLI_BUFFER_SIZE);
3042 if (tevent_req_nomem(subreq, req)) {
3043 return tevent_req_post(req, ev);
3045 tevent_req_set_callback(subreq,
3046 cli_smb1_setup_encryption_blob_done,
3052 static void cli_smb1_setup_encryption_blob_done(struct tevent_req *subreq)
3054 struct tevent_req *req =
3055 tevent_req_callback_data(subreq,
3057 struct cli_smb1_setup_encryption_blob_state *state =
3058 tevent_req_data(req,
3059 struct cli_smb1_setup_encryption_blob_state);
3060 uint8_t *rparam=NULL, *rdata=NULL;
3061 uint32_t num_rparam, num_rdata;
3064 status = smb1cli_trans_recv(subreq, state,
3065 NULL, /* recv_flags */
3066 NULL, 0, NULL, /* rsetup */
3067 &rparam, 0, &num_rparam,
3068 &rdata, 0, &num_rdata);
3069 TALLOC_FREE(subreq);
3070 state->status = status;
3071 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
3072 status = NT_STATUS_OK;
3074 if (tevent_req_nterror(req, status)) {
3078 if (num_rparam == 2) {
3079 state->enc_ctx_id = SVAL(rparam, 0);
3081 TALLOC_FREE(rparam);
3083 state->out = data_blob_const(rdata, num_rdata);
3085 tevent_req_done(req);
3088 static NTSTATUS cli_smb1_setup_encryption_blob_recv(struct tevent_req *req,
3089 TALLOC_CTX *mem_ctx,
3091 uint16_t *enc_ctx_id)
3093 struct cli_smb1_setup_encryption_blob_state *state =
3094 tevent_req_data(req,
3095 struct cli_smb1_setup_encryption_blob_state);
3098 if (tevent_req_is_nterror(req, &status)) {
3099 tevent_req_received(req);
3103 status = state->status;
3106 talloc_steal(mem_ctx, out->data);
3108 *enc_ctx_id = state->enc_ctx_id;
3110 tevent_req_received(req);
3114 struct cli_smb1_setup_encryption_state {
3115 struct tevent_context *ev;
3116 struct cli_state *cli;
3117 struct smb_trans_enc_state *es;
3124 static void cli_smb1_setup_encryption_local_next(struct tevent_req *req);
3125 static void cli_smb1_setup_encryption_local_done(struct tevent_req *subreq);
3126 static void cli_smb1_setup_encryption_remote_next(struct tevent_req *req);
3127 static void cli_smb1_setup_encryption_remote_done(struct tevent_req *subreq);
3128 static void cli_smb1_setup_encryption_ready(struct tevent_req *req);
3130 static struct tevent_req *cli_smb1_setup_encryption_send(TALLOC_CTX *mem_ctx,
3131 struct tevent_context *ev,
3132 struct cli_state *cli,
3133 struct cli_credentials *creds)
3135 struct tevent_req *req = NULL;
3136 struct cli_smb1_setup_encryption_state *state = NULL;
3137 struct auth_generic_state *ags = NULL;
3138 const DATA_BLOB *b = NULL;
3139 bool auth_requested = false;
3140 const char *target_service = NULL;
3141 const char *target_hostname = NULL;
3144 req = tevent_req_create(mem_ctx, &state,
3145 struct cli_smb1_setup_encryption_state);
3152 auth_requested = cli_credentials_authentication_requested(creds);
3153 if (!auth_requested) {
3154 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
3155 return tevent_req_post(req, ev);
3158 target_service = "cifs";
3159 target_hostname = smbXcli_conn_remote_name(cli->conn);
3161 status = cli_session_creds_prepare_krb5(cli, creds);
3162 if (tevent_req_nterror(req, status)) {
3163 return tevent_req_post(req, ev);
3166 state->es = talloc_zero(state, struct smb_trans_enc_state);
3167 if (tevent_req_nomem(state->es, req)) {
3168 return tevent_req_post(req, ev);
3171 status = auth_generic_client_prepare(state->es, &ags);
3172 if (tevent_req_nterror(req, status)) {
3173 return tevent_req_post(req, ev);
3176 gensec_want_feature(ags->gensec_security,
3177 GENSEC_FEATURE_SIGN);
3178 gensec_want_feature(ags->gensec_security,
3179 GENSEC_FEATURE_SEAL);
3181 status = auth_generic_set_creds(ags, creds);
3182 if (tevent_req_nterror(req, status)) {
3183 return tevent_req_post(req, ev);
3186 if (target_service != NULL) {
3187 status = gensec_set_target_service(ags->gensec_security,
3189 if (tevent_req_nterror(req, status)) {
3190 return tevent_req_post(req, ev);
3194 if (target_hostname != NULL) {
3195 status = gensec_set_target_hostname(ags->gensec_security,
3197 if (tevent_req_nterror(req, status)) {
3198 return tevent_req_post(req, ev);
3202 gensec_set_max_update_size(ags->gensec_security,
3205 b = smbXcli_conn_server_gss_blob(state->cli->conn);
3207 state->blob_in = *b;
3210 status = auth_generic_client_start(ags, GENSEC_OID_SPNEGO);
3211 if (tevent_req_nterror(req, status)) {
3212 return tevent_req_post(req, ev);
3216 * We only need the gensec_security part from here.
3218 state->es->gensec_security = talloc_move(state->es,
3219 &ags->gensec_security);
3222 cli_smb1_setup_encryption_local_next(req);
3223 if (!tevent_req_is_in_progress(req)) {
3224 return tevent_req_post(req, ev);
3230 static void cli_smb1_setup_encryption_local_next(struct tevent_req *req)
3232 struct cli_smb1_setup_encryption_state *state =
3233 tevent_req_data(req,
3234 struct cli_smb1_setup_encryption_state);
3235 struct tevent_req *subreq = NULL;
3237 if (state->local_ready) {
3238 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3242 subreq = gensec_update_send(state, state->ev,
3243 state->es->gensec_security,
3245 if (tevent_req_nomem(subreq, req)) {
3248 tevent_req_set_callback(subreq, cli_smb1_setup_encryption_local_done, req);
3251 static void cli_smb1_setup_encryption_local_done(struct tevent_req *subreq)
3253 struct tevent_req *req =
3254 tevent_req_callback_data(subreq,
3256 struct cli_smb1_setup_encryption_state *state =
3257 tevent_req_data(req,
3258 struct cli_smb1_setup_encryption_state);
3261 status = gensec_update_recv(subreq, state, &state->blob_out);
3262 TALLOC_FREE(subreq);
3263 state->blob_in = data_blob_null;
3264 if (!NT_STATUS_IS_OK(status) &&
3265 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
3267 tevent_req_nterror(req, status);
3271 if (NT_STATUS_IS_OK(status)) {
3272 state->local_ready = true;
3276 * We always get NT_STATUS_OK from the server even if it is not ready.
3277 * So guess the server is ready when we are ready and already sent
3278 * our last blob to the server.
3280 if (state->local_ready && state->blob_out.length == 0) {
3281 state->remote_ready = true;
3284 if (state->local_ready && state->remote_ready) {
3285 cli_smb1_setup_encryption_ready(req);
3289 cli_smb1_setup_encryption_remote_next(req);
3292 static void cli_smb1_setup_encryption_remote_next(struct tevent_req *req)
3294 struct cli_smb1_setup_encryption_state *state =
3295 tevent_req_data(req,
3296 struct cli_smb1_setup_encryption_state);
3297 struct tevent_req *subreq = NULL;
3299 if (state->remote_ready) {
3300 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3304 subreq = cli_smb1_setup_encryption_blob_send(state, state->ev,
3305 state->cli, state->blob_out);
3306 if (tevent_req_nomem(subreq, req)) {
3309 tevent_req_set_callback(subreq,
3310 cli_smb1_setup_encryption_remote_done,
3314 static void cli_smb1_setup_encryption_remote_done(struct tevent_req *subreq)
3316 struct tevent_req *req =
3317 tevent_req_callback_data(subreq,
3319 struct cli_smb1_setup_encryption_state *state =
3320 tevent_req_data(req,
3321 struct cli_smb1_setup_encryption_state);
3324 status = cli_smb1_setup_encryption_blob_recv(subreq, state,
3326 &state->es->enc_ctx_num);
3327 TALLOC_FREE(subreq);
3328 data_blob_free(&state->blob_out);
3329 if (!NT_STATUS_IS_OK(status) &&
3330 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
3332 tevent_req_nterror(req, status);
3337 * We always get NT_STATUS_OK even if the server is not ready.
3338 * So guess the server is ready when we are ready and sent
3339 * our last blob to the server.
3341 if (state->local_ready) {
3342 state->remote_ready = true;
3345 if (state->local_ready && state->remote_ready) {
3346 cli_smb1_setup_encryption_ready(req);
3350 cli_smb1_setup_encryption_local_next(req);
3353 static void cli_smb1_setup_encryption_ready(struct tevent_req *req)
3355 struct cli_smb1_setup_encryption_state *state =
3356 tevent_req_data(req,
3357 struct cli_smb1_setup_encryption_state);
3358 struct smb_trans_enc_state *es = NULL;
3360 if (state->blob_in.length != 0) {
3361 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3365 if (state->blob_out.length != 0) {
3366 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3370 es = talloc_move(state->cli->conn, &state->es);
3372 smb1cli_conn_set_encryption(state->cli->conn, es);
3375 tevent_req_done(req);
3378 static NTSTATUS cli_smb1_setup_encryption_recv(struct tevent_req *req)
3380 return tevent_req_simple_recv_ntstatus(req);
3383 NTSTATUS cli_smb1_setup_encryption(struct cli_state *cli,
3384 struct cli_credentials *creds)
3386 struct tevent_context *ev = NULL;
3387 struct tevent_req *req = NULL;
3388 NTSTATUS status = NT_STATUS_NO_MEMORY;
3390 ev = samba_tevent_context_init(talloc_tos());
3394 req = cli_smb1_setup_encryption_send(ev, ev, cli, creds);
3398 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
3401 status = cli_smb1_setup_encryption_recv(req);
3408 establishes a connection right up to doing tconX, password specified.
3409 @param output_cli A fully initialised cli structure, non-null only on success
3410 @param dest_host The netbios name of the remote host
3411 @param dest_ip (optional) The the destination IP, NULL for name based lookup
3412 @param port (optional) The destination port (0 for default)
3413 @param service (optional) The share to make the connection to. Should be 'unqualified' in any way.
3414 @param service_type The 'type' of service.
3415 @param creds The used user credentials
3418 struct cli_full_connection_creds_state {
3419 struct tevent_context *ev;
3420 const char *service;
3421 const char *service_type;
3422 struct cli_credentials *creds;
3424 struct cli_state *cli;
3427 static int cli_full_connection_creds_state_destructor(
3428 struct cli_full_connection_creds_state *s)
3430 if (s->cli != NULL) {
3431 cli_shutdown(s->cli);
3437 static void cli_full_connection_creds_conn_done(struct tevent_req *subreq);
3438 static void cli_full_connection_creds_sess_done(struct tevent_req *subreq);
3439 static void cli_full_connection_creds_enc_start(struct tevent_req *req);
3440 static void cli_full_connection_creds_enc_tcon(struct tevent_req *subreq);
3441 static void cli_full_connection_creds_enc_ver(struct tevent_req *subreq);
3442 static void cli_full_connection_creds_enc_done(struct tevent_req *subreq);
3443 static void cli_full_connection_creds_enc_tdis(struct tevent_req *req);
3444 static void cli_full_connection_creds_enc_finished(struct tevent_req *subreq);
3445 static void cli_full_connection_creds_tcon_start(struct tevent_req *req);
3446 static void cli_full_connection_creds_tcon_done(struct tevent_req *subreq);
3448 struct tevent_req *cli_full_connection_creds_send(
3449 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
3450 const char *my_name, const char *dest_host,
3451 const struct sockaddr_storage *dest_ss, int port,
3452 const char *service, const char *service_type,
3453 struct cli_credentials *creds,
3455 struct smb2_negotiate_contexts *negotiate_contexts)
3457 struct tevent_req *req, *subreq;
3458 struct cli_full_connection_creds_state *state;
3459 enum smb_signing_setting signing_state;
3460 enum smb_encryption_setting encryption_state =
3461 cli_credentials_get_smb_encryption(creds);
3463 req = tevent_req_create(mem_ctx, &state,
3464 struct cli_full_connection_creds_state);
3468 talloc_set_destructor(state, cli_full_connection_creds_state_destructor);
3471 state->service = service;
3472 state->service_type = service_type;
3473 state->creds = creds;
3474 state->flags = flags;
3476 if (flags & CLI_FULL_CONNECTION_IPC) {
3477 signing_state = cli_credentials_get_smb_ipc_signing(creds);
3479 signing_state = cli_credentials_get_smb_signing(creds);
3482 if (encryption_state == SMB_ENCRYPTION_REQUIRED) {
3483 if (flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK) {
3484 encryption_state = SMB_ENCRYPTION_DESIRED;
3488 if (encryption_state >= SMB_ENCRYPTION_DESIRED) {
3489 signing_state = SMB_SIGNING_REQUIRED;
3492 subreq = cli_start_connection_send(
3493 state, ev, my_name, dest_host, dest_ss, port,
3494 signing_state, flags,
3495 negotiate_contexts);
3496 if (tevent_req_nomem(subreq, req)) {
3497 return tevent_req_post(req, ev);
3499 tevent_req_set_callback(subreq,
3500 cli_full_connection_creds_conn_done,
3505 static void cli_full_connection_creds_conn_done(struct tevent_req *subreq)
3507 struct tevent_req *req = tevent_req_callback_data(
3508 subreq, struct tevent_req);
3509 struct cli_full_connection_creds_state *state = tevent_req_data(
3510 req, struct cli_full_connection_creds_state);
3513 status = cli_start_connection_recv(subreq, state, &state->cli);
3514 TALLOC_FREE(subreq);
3515 if (tevent_req_nterror(req, status)) {
3519 subreq = cli_session_setup_creds_send(
3520 state, state->ev, state->cli, state->creds);
3521 if (tevent_req_nomem(subreq, req)) {
3524 tevent_req_set_callback(subreq,
3525 cli_full_connection_creds_sess_done,
3529 static void cli_full_connection_creds_sess_done(struct tevent_req *subreq)
3531 struct tevent_req *req = tevent_req_callback_data(
3532 subreq, struct tevent_req);
3533 struct cli_full_connection_creds_state *state = tevent_req_data(
3534 req, struct cli_full_connection_creds_state);
3537 status = cli_session_setup_creds_recv(subreq);
3538 TALLOC_FREE(subreq);
3540 if (!NT_STATUS_IS_OK(status) &&
3541 (state->flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)) {
3543 state->flags &= ~CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
3545 state->creds = cli_credentials_init_anon(state);
3546 if (tevent_req_nomem(state->creds, req)) {
3550 subreq = cli_session_setup_creds_send(
3551 state, state->ev, state->cli, state->creds);
3552 if (tevent_req_nomem(subreq, req)) {
3555 tevent_req_set_callback(subreq,
3556 cli_full_connection_creds_sess_done,
3561 if (tevent_req_nterror(req, status)) {
3565 cli_full_connection_creds_enc_start(req);
3568 static void cli_full_connection_creds_enc_start(struct tevent_req *req)
3570 struct cli_full_connection_creds_state *state = tevent_req_data(
3571 req, struct cli_full_connection_creds_state);
3572 enum smb_encryption_setting encryption_state =
3573 cli_credentials_get_smb_encryption(state->creds);
3574 struct tevent_req *subreq = NULL;
3577 if (encryption_state < SMB_ENCRYPTION_DESIRED) {
3578 cli_full_connection_creds_tcon_start(req);
3582 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
3583 status = smb2cli_session_encryption_on(state->cli->smb2.session);
3584 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
3585 if (encryption_state < SMB_ENCRYPTION_REQUIRED) {
3586 cli_full_connection_creds_tcon_start(req);
3589 d_printf("Encryption required and "
3590 "server doesn't support "
3591 "SMB3 encryption - failing connect\n");
3592 tevent_req_nterror(req, status);
3594 } else if (!NT_STATUS_IS_OK(status)) {
3595 d_printf("Encryption required and "
3596 "setup failed with error %s.\n",
3598 tevent_req_nterror(req, status);
3602 cli_full_connection_creds_tcon_start(req);
3606 if (!SERVER_HAS_UNIX_CIFS(state->cli)) {
3607 if (encryption_state < SMB_ENCRYPTION_REQUIRED) {
3608 cli_full_connection_creds_tcon_start(req);
3612 status = NT_STATUS_NOT_SUPPORTED;
3613 d_printf("Encryption required and "
3614 "server doesn't support "
3615 "SMB1 Unix Extensions - failing connect\n");
3616 tevent_req_nterror(req, status);
3621 * We do a tcon on IPC$ just to setup the encryption,
3622 * the real tcon will be encrypted then.
3624 subreq = cli_tree_connect_send(state, state->ev, state->cli,
3625 "IPC$", "IPC", NULL);
3626 if (tevent_req_nomem(subreq, req)) {
3629 tevent_req_set_callback(subreq, cli_full_connection_creds_enc_tcon, req);
3632 static void cli_full_connection_creds_enc_tcon(struct tevent_req *subreq)
3634 struct tevent_req *req = tevent_req_callback_data(
3635 subreq, struct tevent_req);
3636 struct cli_full_connection_creds_state *state = tevent_req_data(
3637 req, struct cli_full_connection_creds_state);
3640 status = cli_tree_connect_recv(subreq);
3641 TALLOC_FREE(subreq);
3642 if (tevent_req_nterror(req, status)) {
3646 subreq = cli_unix_extensions_version_send(state, state->ev, state->cli);
3647 if (tevent_req_nomem(subreq, req)) {
3650 tevent_req_set_callback(subreq, cli_full_connection_creds_enc_ver, req);
3653 static void cli_full_connection_creds_enc_ver(struct tevent_req *subreq)
3655 struct tevent_req *req = tevent_req_callback_data(
3656 subreq, struct tevent_req);
3657 struct cli_full_connection_creds_state *state = tevent_req_data(
3658 req, struct cli_full_connection_creds_state);
3659 enum smb_encryption_setting encryption_state =
3660 cli_credentials_get_smb_encryption(state->creds);
3661 uint16_t major, minor;
3662 uint32_t caplow, caphigh;
3665 status = cli_unix_extensions_version_recv(subreq,
3669 TALLOC_FREE(subreq);
3670 if (!NT_STATUS_IS_OK(status)) {
3671 if (encryption_state < SMB_ENCRYPTION_REQUIRED) {
3672 /* disconnect ipc$ followed by the real tree connect */
3673 cli_full_connection_creds_enc_tdis(req);
3676 DEBUG(10, ("%s: cli_unix_extensions_version "
3677 "returned %s\n", __func__, nt_errstr(status)));
3678 tevent_req_nterror(req, NT_STATUS_UNKNOWN_REVISION);
3682 if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
3683 if (encryption_state < SMB_ENCRYPTION_REQUIRED) {
3684 /* disconnect ipc$ followed by the real tree connect */
3685 cli_full_connection_creds_enc_tdis(req);
3688 DEBUG(10, ("%s: CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP "
3689 "not supported\n", __func__));
3690 tevent_req_nterror(req, NT_STATUS_UNSUPPORTED_COMPRESSION);
3694 subreq = cli_smb1_setup_encryption_send(state, state->ev,
3697 if (tevent_req_nomem(subreq, req)) {
3700 tevent_req_set_callback(subreq,
3701 cli_full_connection_creds_enc_done,
3705 static void cli_full_connection_creds_enc_done(struct tevent_req *subreq)
3707 struct tevent_req *req = tevent_req_callback_data(
3708 subreq, struct tevent_req);
3711 status = cli_smb1_setup_encryption_recv(subreq);
3712 TALLOC_FREE(subreq);
3713 if (tevent_req_nterror(req, status)) {
3717 /* disconnect ipc$ followed by the real tree connect */
3718 cli_full_connection_creds_enc_tdis(req);
3721 static void cli_full_connection_creds_enc_tdis(struct tevent_req *req)
3723 struct cli_full_connection_creds_state *state = tevent_req_data(
3724 req, struct cli_full_connection_creds_state);
3725 struct tevent_req *subreq = NULL;
3727 subreq = cli_tdis_send(state, state->ev, state->cli);
3728 if (tevent_req_nomem(subreq, req)) {
3731 tevent_req_set_callback(subreq,
3732 cli_full_connection_creds_enc_finished,
3736 static void cli_full_connection_creds_enc_finished(struct tevent_req *subreq)
3738 struct tevent_req *req = tevent_req_callback_data(
3739 subreq, struct tevent_req);
3742 status = cli_tdis_recv(subreq);
3743 TALLOC_FREE(subreq);
3744 if (tevent_req_nterror(req, status)) {
3748 cli_full_connection_creds_tcon_start(req);
3751 static void cli_full_connection_creds_tcon_start(struct tevent_req *req)
3753 struct cli_full_connection_creds_state *state = tevent_req_data(
3754 req, struct cli_full_connection_creds_state);
3755 struct tevent_req *subreq = NULL;
3756 const char *password = NULL;
3758 if (state->service == NULL) {
3759 tevent_req_done(req);
3763 password = cli_credentials_get_password(state->creds);
3765 subreq = cli_tree_connect_send(state, state->ev,
3768 state->service_type,
3770 if (tevent_req_nomem(subreq, req)) {
3773 tevent_req_set_callback(subreq,
3774 cli_full_connection_creds_tcon_done,
3778 static void cli_full_connection_creds_tcon_done(struct tevent_req *subreq)
3780 struct tevent_req *req = tevent_req_callback_data(
3781 subreq, struct tevent_req);
3784 status = cli_tree_connect_recv(subreq);
3785 TALLOC_FREE(subreq);
3786 if (tevent_req_nterror(req, status)) {
3790 tevent_req_done(req);
3793 NTSTATUS cli_full_connection_creds_recv(struct tevent_req *req,
3794 TALLOC_CTX *mem_ctx,
3795 struct cli_state **output_cli)
3797 struct cli_full_connection_creds_state *state = tevent_req_data(
3798 req, struct cli_full_connection_creds_state);
3801 if (tevent_req_is_nterror(req, &status)) {
3804 *output_cli = talloc_move(mem_ctx, &state->cli);
3805 talloc_set_destructor(state, NULL);
3806 return NT_STATUS_OK;
3809 NTSTATUS cli_full_connection_creds(TALLOC_CTX *mem_ctx,
3810 struct cli_state **output_cli,
3811 const char *my_name,
3812 const char *dest_host,
3813 const struct sockaddr_storage *dest_ss, int port,
3814 const char *service, const char *service_type,
3815 struct cli_credentials *creds,
3818 struct tevent_context *ev;
3819 struct tevent_req *req;
3820 NTSTATUS status = NT_STATUS_NO_MEMORY;
3822 ev = samba_tevent_context_init(mem_ctx);
3826 req = cli_full_connection_creds_send(
3827 ev, ev, my_name, dest_host, dest_ss, port, service,
3828 service_type, creds, flags,
3833 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
3836 status = cli_full_connection_creds_recv(req, mem_ctx, output_cli);
3842 /****************************************************************************
3843 Send an old style tcon.
3844 ****************************************************************************/
3845 struct cli_raw_tcon_state {
3849 static void cli_raw_tcon_done(struct tevent_req *subreq);
3851 static struct tevent_req *cli_raw_tcon_send(
3852 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
3853 const char *service, const char *pass, const char *dev)
3855 struct tevent_req *req, *subreq;
3856 struct cli_raw_tcon_state *state;
3859 req = tevent_req_create(mem_ctx, &state, struct cli_raw_tcon_state);
3864 if (!lp_client_plaintext_auth() && (*pass)) {
3865 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
3866 " or 'client ntlmv2 auth = yes'\n"));
3867 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
3868 return tevent_req_post(req, ev);
3871 TALLOC_FREE(cli->smb1.tcon);
3872 cli->smb1.tcon = smbXcli_tcon_create(cli);
3873 if (tevent_req_nomem(cli->smb1.tcon, req)) {
3874 return tevent_req_post(req, ev);
3876 smb1cli_tcon_set_id(cli->smb1.tcon, UINT16_MAX);
3878 bytes = talloc_array(state, uint8_t, 0);
3879 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3880 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3881 service, strlen(service)+1, NULL);
3882 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3883 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3884 pass, strlen(pass)+1, NULL);
3885 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3886 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3887 dev, strlen(dev)+1, NULL);
3889 if (tevent_req_nomem(bytes, req)) {
3890 return tevent_req_post(req, ev);
3893 subreq = cli_smb_send(state, ev, cli, SMBtcon, 0, 0, 0, NULL,
3894 talloc_get_size(bytes), bytes);
3895 if (tevent_req_nomem(subreq, req)) {
3896 return tevent_req_post(req, ev);
3898 tevent_req_set_callback(subreq, cli_raw_tcon_done, req);
3902 static void cli_raw_tcon_done(struct tevent_req *subreq)
3904 struct tevent_req *req = tevent_req_callback_data(
3905 subreq, struct tevent_req);
3906 struct cli_raw_tcon_state *state = tevent_req_data(
3907 req, struct cli_raw_tcon_state);
3910 status = cli_smb_recv(subreq, state, NULL, 2, NULL, &state->ret_vwv,
3912 TALLOC_FREE(subreq);
3913 if (tevent_req_nterror(req, status)) {
3916 tevent_req_done(req);
3919 static NTSTATUS cli_raw_tcon_recv(struct tevent_req *req,
3920 uint16_t *max_xmit, uint16_t *tid)
3922 struct cli_raw_tcon_state *state = tevent_req_data(
3923 req, struct cli_raw_tcon_state);
3926 if (tevent_req_is_nterror(req, &status)) {
3929 *max_xmit = SVAL(state->ret_vwv + 0, 0);
3930 *tid = SVAL(state->ret_vwv + 1, 0);
3931 return NT_STATUS_OK;
3934 NTSTATUS cli_raw_tcon(struct cli_state *cli,
3935 const char *service, const char *pass, const char *dev,
3936 uint16_t *max_xmit, uint16_t *tid)
3938 struct tevent_context *ev;
3939 struct tevent_req *req;
3940 NTSTATUS status = NT_STATUS_NO_MEMORY;
3942 ev = samba_tevent_context_init(talloc_tos());
3946 req = cli_raw_tcon_send(ev, ev, cli, service, pass, dev);
3950 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
3953 status = cli_raw_tcon_recv(req, max_xmit, tid);
3959 /* Return a cli_state pointing at the IPC$ share for the given server */
3961 static struct cli_state *get_ipc_connect(TALLOC_CTX *mem_ctx,
3963 struct sockaddr_storage *server_ss,
3964 struct cli_credentials *creds)
3966 struct cli_state *cli;
3968 uint32_t flags = CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
3970 flags |= CLI_FULL_CONNECTION_FORCE_SMB1;
3971 flags |= CLI_FULL_CONNECTION_IPC;
3973 nt_status = cli_full_connection_creds(mem_ctx,
3984 if (NT_STATUS_IS_OK(nt_status)) {
3987 if (is_ipaddress(server)) {
3988 /* windows 9* needs a correct NMB name for connections */
3989 fstring remote_name;
3991 if (name_status_find("*", 0, 0, server_ss, remote_name)) {
3992 cli = get_ipc_connect(mem_ctx, remote_name, server_ss, creds);
4001 * Given the IP address of a master browser on the network, return its
4002 * workgroup and connect to it.
4004 * This function is provided to allow additional processing beyond what
4005 * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
4006 * browsers and obtain each master browsers' list of domains (in case the
4007 * first master browser is recently on the network and has not yet
4008 * synchronized with other master browsers and therefore does not yet have the
4009 * entire network browse list)
4012 struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx,
4013 struct sockaddr_storage *mb_ip,
4014 struct cli_credentials *creds,
4015 char **pp_workgroup_out)
4017 char addr[INET6_ADDRSTRLEN];
4019 struct cli_state *cli;
4020 struct sockaddr_storage server_ss;
4022 *pp_workgroup_out = NULL;
4024 print_sockaddr(addr, sizeof(addr), mb_ip);
4025 DEBUG(99, ("Looking up name of master browser %s\n",
4029 * Do a name status query to find out the name of the master browser.
4030 * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
4031 * master browser will not respond to a wildcard query (or, at least,
4032 * an NT4 server acting as the domain master browser will not).
4034 * We might be able to use ONLY the query on MSBROWSE, but that's not
4035 * yet been tested with all Windows versions, so until it is, leave
4036 * the original wildcard query as the first choice and fall back to
4037 * MSBROWSE if the wildcard query fails.
4039 if (!name_status_find("*", 0, 0x1d, mb_ip, name) &&
4040 !name_status_find(MSBROWSE, 1, 0x1d, mb_ip, name)) {
4042 DEBUG(99, ("Could not retrieve name status for %s\n",
4047 if (!find_master_ip(name, &server_ss)) {
4048 DEBUG(99, ("Could not find master ip for %s\n", name));
4052 *pp_workgroup_out = talloc_strdup(ctx, name);
4054 DEBUG(4, ("found master browser %s, %s\n", name, addr));
4056 print_sockaddr(addr, sizeof(addr), &server_ss);
4057 cli = get_ipc_connect(ctx, addr, &server_ss, creds);