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) {
128 * Keep what we learned from the
129 * "client use kerberos" option.
131 enum credentials_use_kerberos current_krb5 =
132 cli_credentials_get_kerberos_state(creds);
133 cli_credentials_set_kerberos_state(creds,
136 } else if (use_kerberos) {
137 cli_credentials_set_kerberos_state(creds,
138 CRED_USE_KERBEROS_REQUIRED,
141 cli_credentials_set_kerberos_state(creds,
142 CRED_USE_KERBEROS_DISABLED,
149 features = cli_credentials_get_gensec_features(creds);
150 features |= GENSEC_FEATURE_NTLM_CCACHE;
151 cli_credentials_set_gensec_features(creds,
155 if (password != NULL && strlen(password) == 0) {
157 * some callers pass "" as no password
159 * GENSEC_FEATURE_NTLM_CCACHE only handles
160 * NULL as no password.
166 ok = cli_credentials_set_username(creds,
173 if (domain != NULL) {
174 ok = cli_credentials_set_domain(creds,
182 if (principal != NULL) {
183 ok = cli_credentials_set_principal(creds,
192 ok = cli_credentials_set_realm(creds,
200 if (password != NULL && strlen(password) > 0) {
201 if (password_is_nt_hash) {
202 struct samr_Password nt_hash;
205 converted = strhex_to_str((char *)nt_hash.hash,
206 sizeof(nt_hash.hash),
209 if (converted != sizeof(nt_hash.hash)) {
213 ok = cli_credentials_set_nt_hash(creds,
220 ok = cli_credentials_set_password(creds,
235 NTSTATUS cli_session_creds_prepare_krb5(struct cli_state *cli,
236 struct cli_credentials *creds)
238 TALLOC_CTX *frame = talloc_stackframe();
239 const char *user_principal = NULL;
240 const char *user_account = NULL;
241 const char *user_domain = NULL;
242 const char *pass = NULL;
243 char *canon_principal = NULL;
244 char *canon_realm = NULL;
245 const char *target_hostname = NULL;
246 enum credentials_use_kerberos krb5_state;
247 bool try_kerberos = false;
248 bool need_kinit = false;
249 bool auth_requested = true;
253 target_hostname = smbXcli_conn_remote_name(cli->conn);
255 auth_requested = cli_credentials_authentication_requested(creds);
256 if (auth_requested) {
258 user_principal = cli_credentials_get_principal(creds, frame);
261 return NT_STATUS_NO_MEMORY;
264 user_account = cli_credentials_get_username(creds);
265 user_domain = cli_credentials_get_domain(creds);
266 pass = cli_credentials_get_password(creds);
268 krb5_state = cli_credentials_get_kerberos_state(creds);
270 if (krb5_state != CRED_USE_KERBEROS_DISABLED) {
274 if (user_principal == NULL) {
275 try_kerberos = false;
278 if (target_hostname == NULL) {
279 try_kerberos = false;
280 } else if (is_ipaddress(target_hostname)) {
281 try_kerberos = false;
282 } else if (strequal(target_hostname, "localhost")) {
283 try_kerberos = false;
284 } else if (strequal(target_hostname, STAR_SMBSERVER)) {
285 try_kerberos = false;
286 } else if (!auth_requested) {
287 try_kerberos = false;
290 if (krb5_state == CRED_USE_KERBEROS_REQUIRED && !try_kerberos) {
291 DEBUG(0, ("Kerberos auth with '%s' (%s\\%s) to access "
292 "'%s' not possible\n",
293 user_principal, user_domain, user_account,
296 return NT_STATUS_ACCESS_DENIED;
299 if (pass == NULL || strlen(pass) == 0) {
301 } else if (krb5_state == CRED_USE_KERBEROS_REQUIRED) {
302 need_kinit = try_kerberos;
304 need_kinit = try_kerberos;
312 DBG_INFO("Doing kinit for %s to access %s\n",
313 user_principal, target_hostname);
316 * TODO: This should be done within the gensec layer
319 setenv(KRB5_ENV_CCNAME, "MEMORY:cliconnect", 1);
320 ret = kerberos_kinit_password_ext(user_principal,
334 int dbglvl = DBGLVL_NOTICE;
336 if (krb5_state == CRED_USE_KERBEROS_REQUIRED) {
340 DEBUG(dbglvl, ("Kinit for %s to access %s failed: %s\n",
341 user_principal, target_hostname,
342 error_message(ret)));
343 if (krb5_state == CRED_USE_KERBEROS_REQUIRED) {
345 return krb5_to_nt_status(ret);
349 * Ignore the error and hope that NTLM will work
355 ok = cli_credentials_set_principal(creds,
360 return NT_STATUS_NO_MEMORY;
363 ok = cli_credentials_set_realm(creds,
368 return NT_STATUS_NO_MEMORY;
371 DBG_DEBUG("Successfully authenticated as %s (%s) to access %s using "
381 static NTSTATUS cli_state_update_after_sesssetup(struct cli_state *cli,
382 const char *native_os,
383 const char *native_lm,
384 const char *primary_domain)
386 #define _VALID_STR(p) ((p) != NULL && (p)[0] != '\0')
388 if (!_VALID_STR(cli->server_os) && _VALID_STR(native_os)) {
389 cli->server_os = talloc_strdup(cli, native_os);
390 if (cli->server_os == NULL) {
391 return NT_STATUS_NO_MEMORY;
395 if (!_VALID_STR(cli->server_type) && _VALID_STR(native_lm)) {
396 cli->server_type = talloc_strdup(cli, native_lm);
397 if (cli->server_type == NULL) {
398 return NT_STATUS_NO_MEMORY;
402 if (!_VALID_STR(cli->server_domain) && _VALID_STR(primary_domain)) {
403 cli->server_domain = talloc_strdup(cli, primary_domain);
404 if (cli->server_domain == NULL) {
405 return NT_STATUS_NO_MEMORY;
413 /********************************************************
414 Utility function to ensure we always return at least
415 a valid char * pointer to an empty string for the
416 cli->server_os, cli->server_type and cli->server_domain
418 *******************************************************/
420 static NTSTATUS smb_bytes_talloc_string(TALLOC_CTX *mem_ctx,
427 *destlen = pull_string_talloc(mem_ctx,
434 if (*destlen == -1) {
435 return NT_STATUS_NO_MEMORY;
439 *dest = talloc_strdup(mem_ctx, "");
441 return NT_STATUS_NO_MEMORY;
447 /****************************************************************************
448 Work out suitable capabilities to offer the server.
449 ****************************************************************************/
451 static uint32_t cli_session_setup_capabilities(struct cli_state *cli,
452 uint32_t sesssetup_capabilities)
454 uint32_t client_capabilities = smb1cli_conn_capabilities(cli->conn);
457 * We only send capabilities based on the mask for:
458 * - client only flags
459 * - flags used in both directions
461 * We do not echo the server only flags, except some legacy flags.
463 * SMB_CAP_LEGACY_CLIENT_MASK contains CAP_LARGE_READX and
464 * CAP_LARGE_WRITEX in order to allow us to do large reads
465 * against old Samba releases (<= 3.6.x).
467 client_capabilities &= (SMB_CAP_BOTH_MASK | SMB_CAP_LEGACY_CLIENT_MASK);
470 * Session Setup specific flags CAP_DYNAMIC_REAUTH
471 * and CAP_EXTENDED_SECURITY are passed by the caller.
472 * We need that in order to do guest logins even if
473 * CAP_EXTENDED_SECURITY is negotiated.
475 client_capabilities &= ~(CAP_DYNAMIC_REAUTH|CAP_EXTENDED_SECURITY);
476 sesssetup_capabilities &= (CAP_DYNAMIC_REAUTH|CAP_EXTENDED_SECURITY);
477 client_capabilities |= sesssetup_capabilities;
479 return client_capabilities;
482 /****************************************************************************
483 Do a NT1 guest session setup.
484 ****************************************************************************/
486 struct cli_session_setup_guest_state {
487 struct cli_state *cli;
492 static void cli_session_setup_guest_done(struct tevent_req *subreq);
494 struct tevent_req *cli_session_setup_guest_create(TALLOC_CTX *mem_ctx,
495 struct tevent_context *ev,
496 struct cli_state *cli,
497 struct tevent_req **psmbreq)
499 struct tevent_req *req, *subreq;
500 struct cli_session_setup_guest_state *state;
504 req = tevent_req_create(mem_ctx, &state,
505 struct cli_session_setup_guest_state);
512 SCVAL(vwv+0, 0, 0xFF);
515 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
517 SSVAL(vwv+4, 0, cli_state_get_vc_num(cli));
518 SIVAL(vwv+5, 0, smb1cli_conn_server_session_key(cli->conn));
523 SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli, 0));
525 bytes = talloc_array(state, uint8_t, 0);
527 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "", 1, /* username */
529 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "", 1, /* workgroup */
531 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "Unix", 5, NULL);
532 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "Samba", 6, NULL);
539 state->bytes.iov_base = (void *)bytes;
540 state->bytes.iov_len = talloc_get_size(bytes);
542 subreq = cli_smb_req_create(state, ev, cli, SMBsesssetupX, 0, 0, 13,
543 vwv, 1, &state->bytes);
544 if (subreq == NULL) {
548 tevent_req_set_callback(subreq, cli_session_setup_guest_done, req);
553 struct tevent_req *cli_session_setup_guest_send(TALLOC_CTX *mem_ctx,
554 struct tevent_context *ev,
555 struct cli_state *cli)
557 struct tevent_req *req, *subreq;
560 req = cli_session_setup_guest_create(mem_ctx, ev, cli, &subreq);
565 status = smb1cli_req_chain_submit(&subreq, 1);
566 if (!NT_STATUS_IS_OK(status)) {
567 tevent_req_nterror(req, status);
568 return tevent_req_post(req, ev);
573 static void cli_session_setup_guest_done(struct tevent_req *subreq)
575 struct tevent_req *req = tevent_req_callback_data(
576 subreq, struct tevent_req);
577 struct cli_session_setup_guest_state *state = tevent_req_data(
578 req, struct cli_session_setup_guest_state);
579 struct cli_state *cli = state->cli;
590 status = cli_smb_recv(subreq, state, &in, 3, &wct, &vwv,
593 if (!NT_STATUS_IS_OK(status)) {
594 tevent_req_nterror(req, status);
598 inhdr = in + NBT_HDR_SIZE;
601 cli_state_set_uid(state->cli, SVAL(inhdr, HDR_UID));
602 smb1cli_session_set_action(cli->smb1.session, SVAL(vwv+2, 0));
604 status = smb_bytes_talloc_string(cli,
611 if (!NT_STATUS_IS_OK(status)) {
612 tevent_req_nterror(req, status);
617 status = smb_bytes_talloc_string(cli,
624 if (!NT_STATUS_IS_OK(status)) {
625 tevent_req_nterror(req, status);
630 status = smb_bytes_talloc_string(cli,
637 if (!NT_STATUS_IS_OK(status)) {
638 tevent_req_nterror(req, status);
642 tevent_req_done(req);
645 NTSTATUS cli_session_setup_guest_recv(struct tevent_req *req)
647 return tevent_req_simple_recv_ntstatus(req);
650 /* The following is calculated from :
652 * (smb_wcnt * 2) = 24 (smb_wcnt == 12 in cli_session_setup_blob_send() )
653 * (strlen("Unix") + 1 + strlen("Samba") + 1) * 2 = 22 (unicode strings at
657 #define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22)
659 struct cli_sesssetup_blob_state {
660 struct tevent_context *ev;
661 struct cli_state *cli;
663 uint16_t max_blob_size;
666 struct iovec *recv_iov;
669 const uint8_t *inbuf;
676 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state *state,
677 struct tevent_req **psubreq);
678 static void cli_sesssetup_blob_done(struct tevent_req *subreq);
680 static struct tevent_req *cli_sesssetup_blob_send(TALLOC_CTX *mem_ctx,
681 struct tevent_context *ev,
682 struct cli_state *cli,
685 struct tevent_req *req, *subreq;
686 struct cli_sesssetup_blob_state *state;
687 uint32_t usable_space;
689 req = tevent_req_create(mem_ctx, &state,
690 struct cli_sesssetup_blob_state);
698 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
699 usable_space = UINT16_MAX;
701 usable_space = cli_state_available_size(cli,
702 BASE_SESSSETUP_BLOB_PACKET_SIZE);
705 if (usable_space == 0) {
706 DEBUG(1, ("cli_session_setup_blob: cli->max_xmit too small "
707 "(not possible to send %u bytes)\n",
708 BASE_SESSSETUP_BLOB_PACKET_SIZE + 1));
709 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
710 return tevent_req_post(req, ev);
712 state->max_blob_size = MIN(usable_space, 0xFFFF);
714 if (!cli_sesssetup_blob_next(state, &subreq)) {
715 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
716 return tevent_req_post(req, ev);
718 tevent_req_set_callback(subreq, cli_sesssetup_blob_done, req);
722 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state *state,
723 struct tevent_req **psubreq)
725 struct tevent_req *subreq;
728 thistime = MIN(state->blob.length, state->max_blob_size);
730 state->this_blob.data = state->blob.data;
731 state->this_blob.length = thistime;
733 state->blob.data += thistime;
734 state->blob.length -= thistime;
736 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
737 subreq = smb2cli_session_setup_send(state, state->ev,
740 state->cli->smb2.session,
742 SMB2_CAP_DFS, /* in_capabilities */
744 0, /* in_previous_session_id */
746 if (subreq == NULL) {
750 uint16_t in_buf_size = 0;
751 uint16_t in_mpx_max = 0;
752 uint16_t in_vc_num = 0;
753 uint32_t in_sess_key = 0;
754 uint32_t in_capabilities = 0;
755 const char *in_native_os = NULL;
756 const char *in_native_lm = NULL;
758 in_buf_size = CLI_BUFFER_SIZE;
759 in_mpx_max = smbXcli_conn_max_requests(state->cli->conn);
760 in_vc_num = cli_state_get_vc_num(state->cli);
761 in_sess_key = smb1cli_conn_server_session_key(state->cli->conn);
762 in_capabilities = cli_session_setup_capabilities(state->cli,
763 CAP_EXTENDED_SECURITY);
764 in_native_os = "Unix";
765 in_native_lm = "Samba";
768 * For now we keep the same values as before,
769 * we may remove these in a separate commit later.
775 subreq = smb1cli_session_setup_ext_send(state, state->ev,
778 state->cli->smb1.pid,
779 state->cli->smb1.session,
788 if (subreq == NULL) {
796 static void cli_sesssetup_blob_done(struct tevent_req *subreq)
798 struct tevent_req *req = tevent_req_callback_data(
799 subreq, struct tevent_req);
800 struct cli_sesssetup_blob_state *state = tevent_req_data(
801 req, struct cli_sesssetup_blob_state);
804 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
805 status = smb2cli_session_setup_recv(subreq, state,
809 status = smb1cli_session_setup_ext_recv(subreq, state,
813 &state->out_native_os,
814 &state->out_native_lm);
817 if (!NT_STATUS_IS_OK(status)
818 && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
819 tevent_req_nterror(req, status);
823 state->status = status;
825 status = cli_state_update_after_sesssetup(state->cli,
826 state->out_native_os,
827 state->out_native_lm,
829 if (tevent_req_nterror(req, status)) {
833 if (state->blob.length != 0) {
837 if (!cli_sesssetup_blob_next(state, &subreq)) {
841 tevent_req_set_callback(subreq, cli_sesssetup_blob_done, req);
844 tevent_req_done(req);
847 static NTSTATUS cli_sesssetup_blob_recv(struct tevent_req *req,
850 const uint8_t **pinbuf,
851 struct iovec **precv_iov)
853 struct cli_sesssetup_blob_state *state = tevent_req_data(
854 req, struct cli_sesssetup_blob_state);
856 struct iovec *recv_iov;
858 if (tevent_req_is_nterror(req, &status)) {
859 TALLOC_FREE(state->cli->smb2.session);
860 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
861 tevent_req_received(req);
865 recv_iov = talloc_move(mem_ctx, &state->recv_iov);
867 *pblob = state->ret_blob;
869 if (pinbuf != NULL) {
870 *pinbuf = state->inbuf;
872 if (precv_iov != NULL) {
873 *precv_iov = recv_iov;
875 /* could be NT_STATUS_MORE_PROCESSING_REQUIRED */
876 status = state->status;
877 tevent_req_received(req);
881 /****************************************************************************
882 Do a spnego/NTLMSSP encrypted session setup.
883 ****************************************************************************/
885 struct cli_session_setup_gensec_state {
886 struct tevent_context *ev;
887 struct cli_state *cli;
888 struct auth_generic_state *auth_generic;
891 const uint8_t *inbuf;
892 struct iovec *recv_iov;
896 DATA_BLOB session_key;
899 static int cli_session_setup_gensec_state_destructor(
900 struct cli_session_setup_gensec_state *state)
902 TALLOC_FREE(state->auth_generic);
903 data_blob_clear_free(&state->session_key);
907 static void cli_session_setup_gensec_local_next(struct tevent_req *req);
908 static void cli_session_setup_gensec_local_done(struct tevent_req *subreq);
909 static void cli_session_setup_gensec_remote_next(struct tevent_req *req);
910 static void cli_session_setup_gensec_remote_done(struct tevent_req *subreq);
911 static void cli_session_setup_gensec_ready(struct tevent_req *req);
913 static struct tevent_req *cli_session_setup_gensec_send(
914 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
915 struct cli_credentials *creds,
916 const char *target_service,
917 const char *target_hostname)
919 struct tevent_req *req;
920 struct cli_session_setup_gensec_state *state;
922 const DATA_BLOB *b = NULL;
924 req = tevent_req_create(mem_ctx, &state,
925 struct cli_session_setup_gensec_state);
932 talloc_set_destructor(
933 state, cli_session_setup_gensec_state_destructor);
935 status = auth_generic_client_prepare(state, &state->auth_generic);
936 if (tevent_req_nterror(req, status)) {
937 return tevent_req_post(req, ev);
940 status = auth_generic_set_creds(state->auth_generic, creds);
941 if (tevent_req_nterror(req, status)) {
942 return tevent_req_post(req, ev);
945 gensec_want_feature(state->auth_generic->gensec_security,
946 GENSEC_FEATURE_SESSION_KEY);
948 if (target_service != NULL) {
949 status = gensec_set_target_service(
950 state->auth_generic->gensec_security,
952 if (tevent_req_nterror(req, status)) {
953 return tevent_req_post(req, ev);
957 if (target_hostname != NULL) {
958 status = gensec_set_target_hostname(
959 state->auth_generic->gensec_security,
961 if (tevent_req_nterror(req, status)) {
962 return tevent_req_post(req, ev);
966 b = smbXcli_conn_server_gss_blob(cli->conn);
971 state->is_anonymous = cli_credentials_is_anonymous(state->auth_generic->credentials);
973 status = auth_generic_client_start(state->auth_generic,
975 if (tevent_req_nterror(req, status)) {
976 return tevent_req_post(req, ev);
979 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
980 state->cli->smb2.session = smbXcli_session_create(cli,
982 if (tevent_req_nomem(state->cli->smb2.session, req)) {
983 return tevent_req_post(req, ev);
987 cli_session_setup_gensec_local_next(req);
988 if (!tevent_req_is_in_progress(req)) {
989 return tevent_req_post(req, ev);
995 static void cli_session_setup_gensec_local_next(struct tevent_req *req)
997 struct cli_session_setup_gensec_state *state =
999 struct cli_session_setup_gensec_state);
1000 struct tevent_req *subreq = NULL;
1002 if (state->local_ready) {
1003 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1007 subreq = gensec_update_send(state, state->ev,
1008 state->auth_generic->gensec_security,
1010 if (tevent_req_nomem(subreq, req)) {
1013 tevent_req_set_callback(subreq, cli_session_setup_gensec_local_done, req);
1016 static void cli_session_setup_gensec_local_done(struct tevent_req *subreq)
1018 struct tevent_req *req =
1019 tevent_req_callback_data(subreq,
1021 struct cli_session_setup_gensec_state *state =
1022 tevent_req_data(req,
1023 struct cli_session_setup_gensec_state);
1026 status = gensec_update_recv(subreq, state, &state->blob_out);
1027 TALLOC_FREE(subreq);
1028 state->blob_in = data_blob_null;
1029 if (!NT_STATUS_IS_OK(status) &&
1030 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
1032 tevent_req_nterror(req, status);
1036 if (NT_STATUS_IS_OK(status)) {
1037 state->local_ready = true;
1040 if (state->local_ready && state->remote_ready) {
1041 cli_session_setup_gensec_ready(req);
1045 cli_session_setup_gensec_remote_next(req);
1048 static void cli_session_setup_gensec_remote_next(struct tevent_req *req)
1050 struct cli_session_setup_gensec_state *state =
1051 tevent_req_data(req,
1052 struct cli_session_setup_gensec_state);
1053 struct tevent_req *subreq = NULL;
1055 if (state->remote_ready) {
1056 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1060 subreq = cli_sesssetup_blob_send(state, state->ev,
1061 state->cli, state->blob_out);
1062 if (tevent_req_nomem(subreq, req)) {
1065 tevent_req_set_callback(subreq,
1066 cli_session_setup_gensec_remote_done,
1070 static void cli_session_setup_gensec_remote_done(struct tevent_req *subreq)
1072 struct tevent_req *req =
1073 tevent_req_callback_data(subreq,
1075 struct cli_session_setup_gensec_state *state =
1076 tevent_req_data(req,
1077 struct cli_session_setup_gensec_state);
1080 state->inbuf = NULL;
1081 TALLOC_FREE(state->recv_iov);
1083 status = cli_sesssetup_blob_recv(subreq, state, &state->blob_in,
1084 &state->inbuf, &state->recv_iov);
1085 TALLOC_FREE(subreq);
1086 data_blob_free(&state->blob_out);
1087 if (!NT_STATUS_IS_OK(status) &&
1088 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
1090 tevent_req_nterror(req, status);
1094 if (NT_STATUS_IS_OK(status)) {
1095 struct smbXcli_session *session = NULL;
1096 bool is_guest = false;
1098 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
1099 session = state->cli->smb2.session;
1101 session = state->cli->smb1.session;
1104 is_guest = smbXcli_session_is_guest(session);
1107 * We can't finish the gensec handshake, we don't
1108 * have a negotiated session key.
1110 * So just pretend we are completely done,
1111 * we need to continue as anonymous from this point,
1112 * as we can't get a session key.
1114 * Note that smbXcli_session_is_guest()
1115 * always returns false if we require signing.
1117 state->blob_in = data_blob_null;
1118 state->local_ready = true;
1119 state->is_anonymous = true;
1122 state->remote_ready = true;
1125 if (state->local_ready && state->remote_ready) {
1126 cli_session_setup_gensec_ready(req);
1130 cli_session_setup_gensec_local_next(req);
1133 static void cli_session_dump_keys(TALLOC_CTX *mem_ctx,
1134 struct smbXcli_session *session,
1135 DATA_BLOB session_key)
1138 DATA_BLOB sig = data_blob_null;
1139 DATA_BLOB app = data_blob_null;
1140 DATA_BLOB enc = data_blob_null;
1141 DATA_BLOB dec = data_blob_null;
1142 uint64_t sid = smb2cli_session_current_id(session);
1144 status = smb2cli_session_signing_key(session, mem_ctx, &sig);
1145 if (!NT_STATUS_IS_OK(status)) {
1148 status = smbXcli_session_application_key(session, mem_ctx, &app);
1149 if (!NT_STATUS_IS_OK(status)) {
1152 status = smb2cli_session_encryption_key(session, mem_ctx, &enc);
1153 if (!NT_STATUS_IS_OK(status)) {
1156 status = smb2cli_session_decryption_key(session, mem_ctx, &dec);
1157 if (!NT_STATUS_IS_OK(status)) {
1161 DEBUG(0, ("debug encryption: dumping generated session keys\n"));
1162 DEBUGADD(0, ("Session Id "));
1163 dump_data(0, (uint8_t*)&sid, sizeof(sid));
1164 DEBUGADD(0, ("Session Key "));
1165 dump_data(0, session_key.data, session_key.length);
1166 DEBUGADD(0, ("Signing Key "));
1167 dump_data(0, sig.data, sig.length);
1168 DEBUGADD(0, ("App Key "));
1169 dump_data(0, app.data, app.length);
1171 /* In client code, ServerIn is the encryption key */
1173 DEBUGADD(0, ("ServerIn Key "));
1174 dump_data(0, enc.data, enc.length);
1175 DEBUGADD(0, ("ServerOut Key "));
1176 dump_data(0, dec.data, dec.length);
1179 data_blob_clear_free(&sig);
1180 data_blob_clear_free(&app);
1181 data_blob_clear_free(&enc);
1182 data_blob_clear_free(&dec);
1185 static void cli_session_setup_gensec_ready(struct tevent_req *req)
1187 struct cli_session_setup_gensec_state *state =
1188 tevent_req_data(req,
1189 struct cli_session_setup_gensec_state);
1190 const char *server_domain = NULL;
1193 if (state->blob_in.length != 0) {
1194 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1198 if (state->blob_out.length != 0) {
1199 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1204 * gensec_ntlmssp_server_domain() returns NULL
1205 * if NTLMSSP is not used.
1207 * We can remove this later
1208 * and leave the server domain empty for SMB2 and above
1209 * in future releases.
1211 server_domain = gensec_ntlmssp_server_domain(
1212 state->auth_generic->gensec_security);
1214 if (state->cli->server_domain[0] == '\0' && server_domain != NULL) {
1215 TALLOC_FREE(state->cli->server_domain);
1216 state->cli->server_domain = talloc_strdup(state->cli,
1218 if (state->cli->server_domain == NULL) {
1219 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1224 if (state->is_anonymous) {
1226 * Windows server does not set the
1227 * SMB2_SESSION_FLAG_IS_NULL flag.
1229 * This fix makes sure we do not try
1230 * to verify a signature on the final
1231 * session setup response.
1233 tevent_req_done(req);
1237 status = gensec_session_key(state->auth_generic->gensec_security,
1238 state, &state->session_key);
1239 if (tevent_req_nterror(req, status)) {
1243 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
1244 struct smbXcli_session *session = state->cli->smb2.session;
1246 status = smb2cli_session_set_session_key(session,
1249 if (tevent_req_nterror(req, status)) {
1252 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB3_00
1253 && lp_debug_encryption())
1255 cli_session_dump_keys(state, session, state->session_key);
1258 struct smbXcli_session *session = state->cli->smb1.session;
1261 status = smb1cli_session_set_session_key(session,
1262 state->session_key);
1263 if (tevent_req_nterror(req, status)) {
1267 active = smb1cli_conn_activate_signing(state->cli->conn,
1273 ok = smb1cli_conn_check_signing(state->cli->conn,
1276 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1282 tevent_req_done(req);
1285 static NTSTATUS cli_session_setup_gensec_recv(struct tevent_req *req)
1287 struct cli_session_setup_gensec_state *state =
1288 tevent_req_data(req,
1289 struct cli_session_setup_gensec_state);
1292 if (tevent_req_is_nterror(req, &status)) {
1293 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
1296 return NT_STATUS_OK;
1299 static char *cli_session_setup_get_account(TALLOC_CTX *mem_ctx,
1300 const char *principal)
1304 account = talloc_strdup(mem_ctx, principal);
1305 if (account == NULL) {
1308 p = strchr_m(account, '@');
1315 /****************************************************************************
1316 Do a spnego encrypted session setup.
1318 user_domain: The shortname of the domain the user/machine is a member of.
1319 dest_realm: The realm we're connecting to, if NULL we use our default realm.
1320 ****************************************************************************/
1322 struct cli_session_setup_spnego_state {
1326 static void cli_session_setup_spnego_done(struct tevent_req *subreq);
1328 static struct tevent_req *cli_session_setup_spnego_send(
1329 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
1330 struct cli_credentials *creds)
1332 struct tevent_req *req, *subreq;
1333 struct cli_session_setup_spnego_state *state;
1334 const char *target_service = NULL;
1335 const char *target_hostname = NULL;
1338 req = tevent_req_create(mem_ctx, &state,
1339 struct cli_session_setup_spnego_state);
1344 target_service = "cifs";
1345 target_hostname = smbXcli_conn_remote_name(cli->conn);
1347 status = cli_session_creds_prepare_krb5(cli, creds);
1348 if (tevent_req_nterror(req, status)) {
1349 return tevent_req_post(req, ev);
1352 DBG_INFO("Connect to %s as %s using SPNEGO\n",
1354 cli_credentials_get_principal(creds, talloc_tos()));
1356 subreq = cli_session_setup_gensec_send(state, ev, cli, creds,
1357 target_service, target_hostname);
1358 if (tevent_req_nomem(subreq, req)) {
1359 return tevent_req_post(req, ev);
1361 tevent_req_set_callback(
1362 subreq, cli_session_setup_spnego_done, req);
1366 static void cli_session_setup_spnego_done(struct tevent_req *subreq)
1368 struct tevent_req *req = tevent_req_callback_data(
1369 subreq, struct tevent_req);
1372 status = cli_session_setup_gensec_recv(subreq);
1373 TALLOC_FREE(subreq);
1374 if (tevent_req_nterror(req, status)) {
1378 tevent_req_done(req);
1381 static ADS_STATUS cli_session_setup_spnego_recv(struct tevent_req *req)
1383 struct cli_session_setup_spnego_state *state = tevent_req_data(
1384 req, struct cli_session_setup_spnego_state);
1387 if (tevent_req_is_nterror(req, &status)) {
1388 state->result = ADS_ERROR_NT(status);
1391 return state->result;
1394 struct cli_session_setup_creds_state {
1395 struct cli_state *cli;
1396 DATA_BLOB apassword_blob;
1397 DATA_BLOB upassword_blob;
1398 DATA_BLOB lm_session_key;
1399 DATA_BLOB session_key;
1400 char *out_native_os;
1401 char *out_native_lm;
1402 char *out_primary_domain;
1405 static void cli_session_setup_creds_cleanup(struct tevent_req *req,
1406 enum tevent_req_state req_state)
1408 struct cli_session_setup_creds_state *state = tevent_req_data(
1409 req, struct cli_session_setup_creds_state);
1411 if (req_state != TEVENT_REQ_RECEIVED) {
1416 * We only call data_blob_clear() as
1417 * some of the blobs point to the same memory.
1419 * We let the talloc hierarchy free the memory.
1421 data_blob_clear(&state->apassword_blob);
1422 data_blob_clear(&state->upassword_blob);
1423 data_blob_clear(&state->lm_session_key);
1424 data_blob_clear(&state->session_key);
1425 ZERO_STRUCTP(state);
1428 static void cli_session_setup_creds_done_spnego(struct tevent_req *subreq);
1429 static void cli_session_setup_creds_done_nt1(struct tevent_req *subreq);
1430 static void cli_session_setup_creds_done_lm21(struct tevent_req *subreq);
1432 /****************************************************************************
1433 Send a session setup. The username and workgroup is in UNIX character
1434 format and must be converted to DOS codepage format before sending. If the
1435 password is in plaintext, the same should be done.
1436 ****************************************************************************/
1438 struct tevent_req *cli_session_setup_creds_send(TALLOC_CTX *mem_ctx,
1439 struct tevent_context *ev,
1440 struct cli_state *cli,
1441 struct cli_credentials *creds)
1443 struct tevent_req *req, *subreq;
1444 struct cli_session_setup_creds_state *state;
1445 uint16_t sec_mode = smb1cli_conn_server_security_mode(cli->conn);
1446 bool use_spnego = false;
1448 const char *username = "";
1449 const char *domain = "";
1450 DATA_BLOB target_info = data_blob_null;
1451 DATA_BLOB challenge = data_blob_null;
1452 uint16_t in_buf_size = 0;
1453 uint16_t in_mpx_max = 0;
1454 uint16_t in_vc_num = 0;
1455 uint32_t in_sess_key = 0;
1456 const char *in_native_os = NULL;
1457 const char *in_native_lm = NULL;
1458 enum credentials_use_kerberos krb5_state =
1459 cli_credentials_get_kerberos_state(creds);
1462 req = tevent_req_create(mem_ctx, &state,
1463 struct cli_session_setup_creds_state);
1469 tevent_req_set_cleanup_fn(req, cli_session_setup_creds_cleanup);
1472 * Now work out what sort of session setup we are going to
1473 * do. I have split this into separate functions to make the flow a bit
1474 * easier to understand (tridge).
1476 if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_NT1) {
1478 } else if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
1480 } else if (smb1cli_conn_capabilities(cli->conn) & CAP_EXTENDED_SECURITY) {
1482 * if the server supports extended security then use SPNEGO
1483 * even for anonymous connections.
1491 subreq = cli_session_setup_spnego_send(
1492 state, ev, cli, creds);
1493 if (tevent_req_nomem(subreq, req)) {
1494 return tevent_req_post(req, ev);
1496 tevent_req_set_callback(subreq, cli_session_setup_creds_done_spnego,
1501 if (krb5_state == CRED_USE_KERBEROS_REQUIRED) {
1502 DBG_WARNING("Kerberos authentication requested, but "
1503 "the server does not support SPNEGO authentication\n");
1504 tevent_req_nterror(req, NT_STATUS_NETWORK_CREDENTIAL_CONFLICT);
1505 return tevent_req_post(req, ev);
1508 if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_LANMAN1) {
1510 * SessionSetupAndX was introduced by LANMAN 1.0. So we skip
1511 * this step against older servers.
1513 tevent_req_done(req);
1514 return tevent_req_post(req, ev);
1517 if (cli_credentials_is_anonymous(creds)) {
1519 * Do an anonymous session setup
1521 goto non_spnego_creds_done;
1524 if ((sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0) {
1526 * Do an anonymous session setup,
1527 * the password is passed via the tree connect.
1529 goto non_spnego_creds_done;
1532 cli_credentials_get_ntlm_username_domain(creds, state,
1535 if (tevent_req_nomem(username, req)) {
1536 return tevent_req_post(req, ev);
1538 if (tevent_req_nomem(domain, req)) {
1539 return tevent_req_post(req, ev);
1542 DBG_INFO("Connect to %s as %s using NTLM\n", domain, username);
1544 if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) {
1545 bool use_unicode = smbXcli_conn_use_unicode(cli->conn);
1546 uint8_t *bytes = NULL;
1547 size_t bytes_len = 0;
1548 const char *pw = cli_credentials_get_password(creds);
1554 pw_len = strlen(pw) + 1;
1556 if (!lp_client_plaintext_auth()) {
1557 DEBUG(1, ("Server requested PLAINTEXT password but "
1558 "'client plaintext auth = no'\n"));
1559 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1560 return tevent_req_post(req, ev);
1563 bytes = talloc_array(state, uint8_t, 0);
1564 bytes = trans2_bytes_push_str(bytes, use_unicode,
1565 pw, pw_len, &bytes_len);
1566 if (tevent_req_nomem(bytes, req)) {
1567 return tevent_req_post(req, ev);
1572 * CAP_UNICODE, can only be negotiated by NT1.
1574 state->upassword_blob = data_blob_const(bytes,
1577 state->apassword_blob = data_blob_const(bytes,
1581 goto non_spnego_creds_done;
1584 challenge = data_blob_const(smb1cli_conn_server_challenge(cli->conn), 8);
1586 if (smbXcli_conn_protocol(cli->conn) == PROTOCOL_NT1) {
1587 if (lp_client_ntlmv2_auth() && lp_client_use_spnego()) {
1589 * Don't send an NTLMv2 response without NTLMSSP if we
1590 * want to use spnego support.
1592 DEBUG(1, ("Server does not support EXTENDED_SECURITY "
1593 " but 'client use spnego = yes'"
1594 " and 'client ntlmv2 auth = yes' is set\n"));
1595 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1596 return tevent_req_post(req, ev);
1599 if (lp_client_ntlmv2_auth()) {
1600 flags |= CLI_CRED_NTLMv2_AUTH;
1603 * note that the 'domain' here is a best
1604 * guess - we don't know the server's domain
1605 * at this point. Windows clients also don't
1608 target_info = NTLMv2_generate_names_blob(state,
1611 if (tevent_req_nomem(target_info.data, req)) {
1612 return tevent_req_post(req, ev);
1615 flags |= CLI_CRED_NTLM_AUTH;
1616 if (lp_client_lanman_auth()) {
1617 flags |= CLI_CRED_LANMAN_AUTH;
1621 if (!lp_client_lanman_auth()) {
1622 DEBUG(1, ("Server requested user level LM password but "
1623 "'client lanman auth = no' is set.\n"));
1624 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1625 return tevent_req_post(req, ev);
1628 flags |= CLI_CRED_LANMAN_AUTH;
1631 status = cli_credentials_get_ntlm_response(creds, state, &flags,
1634 &state->apassword_blob,
1635 &state->upassword_blob,
1636 &state->lm_session_key,
1637 &state->session_key);
1638 if (tevent_req_nterror(req, status)) {
1639 return tevent_req_post(req, ev);
1642 non_spnego_creds_done:
1644 in_buf_size = CLI_BUFFER_SIZE;
1645 in_mpx_max = smbXcli_conn_max_requests(cli->conn);
1646 in_vc_num = cli_state_get_vc_num(cli);
1647 in_sess_key = smb1cli_conn_server_session_key(cli->conn);
1648 in_native_os = "Unix";
1649 in_native_lm = "Samba";
1651 if (smbXcli_conn_protocol(cli->conn) == PROTOCOL_NT1) {
1652 uint32_t in_capabilities = 0;
1654 in_capabilities = cli_session_setup_capabilities(cli, 0);
1657 * For now we keep the same values as before,
1658 * we may remove these in a separate commit later.
1662 subreq = smb1cli_session_setup_nt1_send(state, ev,
1673 state->apassword_blob,
1674 state->upassword_blob,
1678 if (tevent_req_nomem(subreq, req)) {
1679 return tevent_req_post(req, ev);
1681 tevent_req_set_callback(subreq, cli_session_setup_creds_done_nt1,
1687 * For now we keep the same values as before,
1688 * we may remove these in a separate commit later.
1693 subreq = smb1cli_session_setup_lm21_send(state, ev,
1704 state->apassword_blob,
1707 if (tevent_req_nomem(subreq, req)) {
1708 return tevent_req_post(req, ev);
1710 tevent_req_set_callback(subreq, cli_session_setup_creds_done_lm21,
1715 static void cli_session_setup_creds_done_spnego(struct tevent_req *subreq)
1717 struct tevent_req *req = tevent_req_callback_data(
1718 subreq, struct tevent_req);
1721 status = cli_session_setup_spnego_recv(subreq);
1722 TALLOC_FREE(subreq);
1723 if (!ADS_ERR_OK(status)) {
1724 DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status)));
1725 tevent_req_nterror(req, ads_ntstatus(status));
1728 tevent_req_done(req);
1731 static void cli_session_setup_creds_done_nt1(struct tevent_req *subreq)
1733 struct tevent_req *req = tevent_req_callback_data(
1734 subreq, struct tevent_req);
1735 struct cli_session_setup_creds_state *state = tevent_req_data(
1736 req, struct cli_session_setup_creds_state);
1737 struct cli_state *cli = state->cli;
1739 struct iovec *recv_iov = NULL;
1740 const uint8_t *inbuf = NULL;
1743 status = smb1cli_session_setup_nt1_recv(subreq, state,
1746 &state->out_native_os,
1747 &state->out_native_lm,
1748 &state->out_primary_domain);
1749 TALLOC_FREE(subreq);
1750 if (tevent_req_nterror(req, status)) {
1751 DEBUG(3, ("NT1 login failed: %s\n", nt_errstr(status)));
1755 status = cli_state_update_after_sesssetup(state->cli,
1756 state->out_native_os,
1757 state->out_native_lm,
1758 state->out_primary_domain);
1759 if (tevent_req_nterror(req, status)) {
1763 ok = smb1cli_conn_activate_signing(cli->conn,
1765 state->upassword_blob);
1767 ok = smb1cli_conn_check_signing(cli->conn, inbuf, 1);
1769 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1774 if (state->session_key.data) {
1775 struct smbXcli_session *session = cli->smb1.session;
1777 status = smb1cli_session_set_session_key(session,
1778 state->session_key);
1779 if (tevent_req_nterror(req, status)) {
1784 tevent_req_done(req);
1787 static void cli_session_setup_creds_done_lm21(struct tevent_req *subreq)
1789 struct tevent_req *req = tevent_req_callback_data(
1790 subreq, struct tevent_req);
1791 struct cli_session_setup_creds_state *state = tevent_req_data(
1792 req, struct cli_session_setup_creds_state);
1795 status = smb1cli_session_setup_lm21_recv(subreq, state,
1796 &state->out_native_os,
1797 &state->out_native_lm);
1798 TALLOC_FREE(subreq);
1799 if (tevent_req_nterror(req, status)) {
1800 DEBUG(3, ("LM21 login failed: %s\n", nt_errstr(status)));
1804 status = cli_state_update_after_sesssetup(state->cli,
1805 state->out_native_os,
1806 state->out_native_lm,
1808 if (tevent_req_nterror(req, status)) {
1812 tevent_req_done(req);
1815 NTSTATUS cli_session_setup_creds_recv(struct tevent_req *req)
1817 return tevent_req_simple_recv_ntstatus(req);
1820 NTSTATUS cli_session_setup_creds(struct cli_state *cli,
1821 struct cli_credentials *creds)
1823 struct tevent_context *ev;
1824 struct tevent_req *req;
1825 NTSTATUS status = NT_STATUS_NO_MEMORY;
1827 if (smbXcli_conn_has_async_calls(cli->conn)) {
1828 return NT_STATUS_INVALID_PARAMETER;
1830 ev = samba_tevent_context_init(talloc_tos());
1834 req = cli_session_setup_creds_send(ev, ev, cli, creds);
1838 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1841 status = cli_session_setup_creds_recv(req);
1847 NTSTATUS cli_session_setup_anon(struct cli_state *cli)
1850 struct cli_credentials *creds = NULL;
1852 creds = cli_credentials_init_anon(cli);
1853 if (creds == NULL) {
1854 return NT_STATUS_NO_MEMORY;
1857 status = cli_session_setup_creds(cli, creds);
1859 if (!NT_STATUS_IS_OK(status)) {
1863 return NT_STATUS_OK;
1866 /****************************************************************************
1868 *****************************************************************************/
1870 struct cli_ulogoff_state {
1871 struct cli_state *cli;
1875 static void cli_ulogoff_done(struct tevent_req *subreq);
1877 static struct tevent_req *cli_ulogoff_send(TALLOC_CTX *mem_ctx,
1878 struct tevent_context *ev,
1879 struct cli_state *cli)
1881 struct tevent_req *req, *subreq;
1882 struct cli_ulogoff_state *state;
1884 req = tevent_req_create(mem_ctx, &state, struct cli_ulogoff_state);
1890 SCVAL(state->vwv+0, 0, 0xFF);
1891 SCVAL(state->vwv+1, 0, 0);
1892 SSVAL(state->vwv+2, 0, 0);
1894 subreq = cli_smb_send(state, ev, cli, SMBulogoffX, 0, 0, 2, state->vwv,
1896 if (tevent_req_nomem(subreq, req)) {
1897 return tevent_req_post(req, ev);
1899 tevent_req_set_callback(subreq, cli_ulogoff_done, req);
1903 static void cli_ulogoff_done(struct tevent_req *subreq)
1905 struct tevent_req *req = tevent_req_callback_data(
1906 subreq, struct tevent_req);
1907 struct cli_ulogoff_state *state = tevent_req_data(
1908 req, struct cli_ulogoff_state);
1911 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
1912 if (tevent_req_nterror(req, status)) {
1915 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
1916 tevent_req_done(req);
1919 static NTSTATUS cli_ulogoff_recv(struct tevent_req *req)
1921 return tevent_req_simple_recv_ntstatus(req);
1924 NTSTATUS cli_ulogoff(struct cli_state *cli)
1926 struct tevent_context *ev;
1927 struct tevent_req *req;
1928 NTSTATUS status = NT_STATUS_NO_MEMORY;
1930 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
1931 status = smb2cli_logoff(cli->conn,
1934 if (!NT_STATUS_IS_OK(status)) {
1937 smb2cli_session_set_id_and_flags(cli->smb2.session,
1939 return NT_STATUS_OK;
1942 if (smbXcli_conn_has_async_calls(cli->conn)) {
1943 return NT_STATUS_INVALID_PARAMETER;
1945 ev = samba_tevent_context_init(talloc_tos());
1949 req = cli_ulogoff_send(ev, ev, cli);
1953 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1956 status = cli_ulogoff_recv(req);
1962 /****************************************************************************
1964 ****************************************************************************/
1966 struct cli_tcon_andx_state {
1967 struct cli_state *cli;
1972 static void cli_tcon_andx_done(struct tevent_req *subreq);
1974 struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx,
1975 struct tevent_context *ev,
1976 struct cli_state *cli,
1977 const char *share, const char *dev,
1978 const char *pass, int passlen,
1979 struct tevent_req **psmbreq)
1981 struct tevent_req *req, *subreq;
1982 struct cli_tcon_andx_state *state;
1987 uint16_t sec_mode = smb1cli_conn_server_security_mode(cli->conn);
1988 uint16_t tcon_flags = 0;
1992 req = tevent_req_create(mem_ctx, &state, struct cli_tcon_andx_state);
1999 TALLOC_FREE(cli->smb1.tcon);
2000 cli->smb1.tcon = smbXcli_tcon_create(cli);
2001 if (tevent_req_nomem(cli->smb1.tcon, req)) {
2002 return tevent_req_post(req, ev);
2004 smb1cli_tcon_set_id(cli->smb1.tcon, UINT16_MAX);
2006 cli->share = talloc_strdup(cli, share);
2011 /* in user level security don't send a password now */
2012 if (sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {
2015 } else if (pass == NULL) {
2016 DEBUG(1, ("Server not using user level security and no "
2017 "password supplied.\n"));
2021 if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) &&
2022 *pass && passlen != 24) {
2023 if (!lp_client_lanman_auth()) {
2024 DEBUG(1, ("Server requested LANMAN password "
2025 "(share-level security) but "
2026 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2031 * Non-encrypted passwords - convert to DOS codepage before
2034 SMBencrypt(pass, smb1cli_conn_server_challenge(cli->conn), p24);
2036 pass = (const char *)p24;
2038 if((sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL
2039 |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE))
2043 if (!lp_client_plaintext_auth() && (*pass)) {
2044 DEBUG(1, ("Server requested PLAINTEXT "
2046 "'client plaintext auth = no' or 'client ntlmv2 auth = yes'\n"));
2051 * Non-encrypted passwords - convert to DOS codepage
2054 tmp_pass = talloc_array(talloc_tos(), uint8_t, 0);
2055 if (tevent_req_nomem(tmp_pass, req)) {
2056 return tevent_req_post(req, ev);
2058 tmp_pass = trans2_bytes_push_str(tmp_pass,
2059 false, /* always DOS */
2063 if (tevent_req_nomem(tmp_pass, req)) {
2064 return tevent_req_post(req, ev);
2066 pass = (const char *)tmp_pass;
2067 passlen = talloc_get_size(tmp_pass);
2071 tcon_flags |= TCONX_FLAG_EXTENDED_RESPONSE;
2072 tcon_flags |= TCONX_FLAG_EXTENDED_SIGNATURES;
2074 SCVAL(vwv+0, 0, 0xFF);
2077 SSVAL(vwv+2, 0, tcon_flags);
2078 SSVAL(vwv+3, 0, passlen);
2080 if (passlen && pass) {
2081 bytes = (uint8_t *)talloc_memdup(state, pass, passlen);
2083 bytes = talloc_array(state, uint8_t, 0);
2089 tmp = talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
2090 smbXcli_conn_remote_name(cli->conn), share);
2095 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), tmp, strlen(tmp)+1,
2100 * Add the devicetype
2102 tmp = talloc_strdup_upper(talloc_tos(), dev);
2107 bytes = smb_bytes_push_str(bytes, false, tmp, strlen(tmp)+1, NULL);
2110 if (bytes == NULL) {
2115 state->bytes.iov_base = (void *)bytes;
2116 state->bytes.iov_len = talloc_get_size(bytes);
2118 subreq = cli_smb_req_create(state, ev, cli, SMBtconX, 0, 0, 4, vwv,
2120 if (subreq == NULL) {
2124 tevent_req_set_callback(subreq, cli_tcon_andx_done, req);
2129 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
2130 return tevent_req_post(req, ev);
2133 struct tevent_req *cli_tcon_andx_send(TALLOC_CTX *mem_ctx,
2134 struct tevent_context *ev,
2135 struct cli_state *cli,
2136 const char *share, const char *dev,
2137 const char *pass, int passlen)
2139 struct tevent_req *req, *subreq;
2142 req = cli_tcon_andx_create(mem_ctx, ev, cli, share, dev, pass, passlen,
2147 if (subreq == NULL) {
2150 status = smb1cli_req_chain_submit(&subreq, 1);
2151 if (tevent_req_nterror(req, status)) {
2152 return tevent_req_post(req, ev);
2157 static void cli_tcon_andx_done(struct tevent_req *subreq)
2159 struct tevent_req *req = tevent_req_callback_data(
2160 subreq, struct tevent_req);
2161 struct cli_tcon_andx_state *state = tevent_req_data(
2162 req, struct cli_tcon_andx_state);
2163 struct cli_state *cli = state->cli;
2171 uint16_t optional_support = 0;
2173 status = cli_smb_recv(subreq, state, &in, 0, &wct, &vwv,
2174 &num_bytes, &bytes);
2175 TALLOC_FREE(subreq);
2176 if (tevent_req_nterror(req, status)) {
2180 inhdr = in + NBT_HDR_SIZE;
2183 if (pull_string_talloc(cli,
2184 (const char *)inhdr,
2185 SVAL(inhdr, HDR_FLG2),
2189 STR_TERMINATE|STR_ASCII) == -1) {
2190 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2194 cli->dev = talloc_strdup(cli, "");
2195 if (cli->dev == NULL) {
2196 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2201 if ((smbXcli_conn_protocol(cli->conn) >= PROTOCOL_NT1) && (num_bytes == 3)) {
2202 /* almost certainly win95 - enable bug fixes */
2207 * Make sure that we have the optional support 16-bit field. WCT > 2.
2208 * Avoids issues when connecting to Win9x boxes sharing files
2211 if ((wct > 2) && (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_LANMAN2)) {
2212 optional_support = SVAL(vwv+2, 0);
2215 if (optional_support & SMB_EXTENDED_SIGNATURES) {
2216 smb1cli_session_protect_session_key(cli->smb1.session);
2219 smb1cli_tcon_set_values(state->cli->smb1.tcon,
2220 SVAL(inhdr, HDR_TID),
2222 0, /* maximal_access */
2223 0, /* guest_maximal_access */
2225 NULL); /* fs_type */
2227 tevent_req_done(req);
2230 NTSTATUS cli_tcon_andx_recv(struct tevent_req *req)
2232 return tevent_req_simple_recv_ntstatus(req);
2235 NTSTATUS cli_tcon_andx(struct cli_state *cli, const char *share,
2236 const char *dev, const char *pass, int passlen)
2238 TALLOC_CTX *frame = talloc_stackframe();
2239 struct tevent_context *ev;
2240 struct tevent_req *req;
2241 NTSTATUS status = NT_STATUS_NO_MEMORY;
2243 if (smbXcli_conn_has_async_calls(cli->conn)) {
2245 * Can't use sync call while an async call is in flight
2247 status = NT_STATUS_INVALID_PARAMETER;
2251 ev = samba_tevent_context_init(frame);
2256 req = cli_tcon_andx_send(frame, ev, cli, share, dev, pass, passlen);
2261 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2265 status = cli_tcon_andx_recv(req);
2271 struct cli_tree_connect_state {
2272 struct cli_state *cli;
2275 static struct tevent_req *cli_raw_tcon_send(
2276 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
2277 const char *service, const char *pass, const char *dev);
2278 static NTSTATUS cli_raw_tcon_recv(struct tevent_req *req,
2279 uint16_t *max_xmit, uint16_t *tid);
2281 static void cli_tree_connect_smb2_done(struct tevent_req *subreq);
2282 static void cli_tree_connect_andx_done(struct tevent_req *subreq);
2283 static void cli_tree_connect_raw_done(struct tevent_req *subreq);
2285 static struct tevent_req *cli_tree_connect_send(
2286 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
2287 const char *share, const char *dev, const char *pass)
2289 struct tevent_req *req, *subreq;
2290 struct cli_tree_connect_state *state;
2296 passlen = strlen(pass) + 1;
2298 req = tevent_req_create(mem_ctx, &state,
2299 struct cli_tree_connect_state);
2305 cli->share = talloc_strdup(cli, share);
2306 if (tevent_req_nomem(cli->share, req)) {
2307 return tevent_req_post(req, ev);
2310 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
2313 TALLOC_FREE(cli->smb2.tcon);
2314 cli->smb2.tcon = smbXcli_tcon_create(cli);
2315 if (tevent_req_nomem(cli->smb2.tcon, req)) {
2316 return tevent_req_post(req, ev);
2319 unc = talloc_asprintf(state, "\\\\%s\\%s",
2320 smbXcli_conn_remote_name(cli->conn),
2322 if (tevent_req_nomem(unc, req)) {
2323 return tevent_req_post(req, ev);
2326 subreq = smb2cli_tcon_send(state, ev, cli->conn, cli->timeout,
2327 cli->smb2.session, cli->smb2.tcon,
2330 if (tevent_req_nomem(subreq, req)) {
2331 return tevent_req_post(req, ev);
2333 tevent_req_set_callback(subreq, cli_tree_connect_smb2_done,
2338 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_LANMAN1) {
2339 subreq = cli_tcon_andx_send(state, ev, cli, share, dev,
2341 if (tevent_req_nomem(subreq, req)) {
2342 return tevent_req_post(req, ev);
2344 tevent_req_set_callback(subreq, cli_tree_connect_andx_done,
2349 subreq = cli_raw_tcon_send(state, ev, cli, share, pass, dev);
2350 if (tevent_req_nomem(subreq, req)) {
2351 return tevent_req_post(req, ev);
2353 tevent_req_set_callback(subreq, cli_tree_connect_raw_done, req);
2358 static void cli_tree_connect_smb2_done(struct tevent_req *subreq)
2360 NTSTATUS status = smb2cli_tcon_recv(subreq);
2361 tevent_req_simple_finish_ntstatus(subreq, status);
2364 static void cli_tree_connect_andx_done(struct tevent_req *subreq)
2366 NTSTATUS status = cli_tcon_andx_recv(subreq);
2367 tevent_req_simple_finish_ntstatus(subreq, status);
2370 static void cli_tree_connect_raw_done(struct tevent_req *subreq)
2372 struct tevent_req *req = tevent_req_callback_data(
2373 subreq, struct tevent_req);
2374 struct cli_tree_connect_state *state = tevent_req_data(
2375 req, struct cli_tree_connect_state);
2377 uint16_t max_xmit = 0;
2380 status = cli_raw_tcon_recv(subreq, &max_xmit, &tid);
2381 if (tevent_req_nterror(req, status)) {
2385 smb1cli_tcon_set_values(state->cli->smb1.tcon,
2387 0, /* optional_support */
2388 0, /* maximal_access */
2389 0, /* guest_maximal_access */
2391 NULL); /* fs_type */
2393 tevent_req_done(req);
2396 static NTSTATUS cli_tree_connect_recv(struct tevent_req *req)
2398 return tevent_req_simple_recv_ntstatus(req);
2401 NTSTATUS cli_tree_connect(struct cli_state *cli, const char *share,
2402 const char *dev, const char *pass)
2404 struct tevent_context *ev;
2405 struct tevent_req *req;
2406 NTSTATUS status = NT_STATUS_NO_MEMORY;
2408 if (smbXcli_conn_has_async_calls(cli->conn)) {
2409 return NT_STATUS_INVALID_PARAMETER;
2411 ev = samba_tevent_context_init(talloc_tos());
2415 req = cli_tree_connect_send(ev, ev, cli, share, dev, pass);
2419 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2422 status = cli_tree_connect_recv(req);
2428 NTSTATUS cli_tree_connect_creds(struct cli_state *cli,
2429 const char *share, const char *dev,
2430 struct cli_credentials *creds)
2432 bool need_pass = false;
2433 const char *pw = NULL;
2436 * We should work out if the protocol
2437 * will make use of a password for share level
2438 * authentication before we may cause
2439 * the password prompt to be called.
2441 if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_SMB2_02) {
2442 uint16_t sec_mode = smb1cli_conn_server_security_mode(cli->conn);
2444 /* in user level security don't send a password now */
2445 if (!(sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) {
2450 if (need_pass && creds != NULL) {
2451 pw = cli_credentials_get_password(creds);
2454 return cli_tree_connect(cli, share, dev, pw);
2457 /****************************************************************************
2458 Send a tree disconnect.
2459 ****************************************************************************/
2461 struct cli_tdis_state {
2462 struct cli_state *cli;
2465 static void cli_tdis_done(struct tevent_req *subreq);
2467 static struct tevent_req *cli_tdis_send(TALLOC_CTX *mem_ctx,
2468 struct tevent_context *ev,
2469 struct cli_state *cli)
2471 struct tevent_req *req, *subreq;
2472 struct cli_tdis_state *state;
2474 req = tevent_req_create(mem_ctx, &state, struct cli_tdis_state);
2480 subreq = cli_smb_send(state, ev, cli, SMBtdis, 0, 0, 0, NULL, 0, NULL);
2481 if (tevent_req_nomem(subreq, req)) {
2482 return tevent_req_post(req, ev);
2484 tevent_req_set_callback(subreq, cli_tdis_done, req);
2488 static void cli_tdis_done(struct tevent_req *subreq)
2490 struct tevent_req *req = tevent_req_callback_data(
2491 subreq, struct tevent_req);
2492 struct cli_tdis_state *state = tevent_req_data(
2493 req, struct cli_tdis_state);
2496 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
2497 TALLOC_FREE(subreq);
2498 if (tevent_req_nterror(req, status)) {
2501 TALLOC_FREE(state->cli->smb1.tcon);
2502 tevent_req_done(req);
2505 static NTSTATUS cli_tdis_recv(struct tevent_req *req)
2507 return tevent_req_simple_recv_ntstatus(req);
2510 NTSTATUS cli_tdis(struct cli_state *cli)
2512 struct tevent_context *ev;
2513 struct tevent_req *req;
2514 NTSTATUS status = NT_STATUS_NO_MEMORY;
2516 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
2517 status = smb2cli_tdis(cli->conn,
2521 if (NT_STATUS_IS_OK(status)) {
2522 TALLOC_FREE(cli->smb2.tcon);
2527 if (smbXcli_conn_has_async_calls(cli->conn)) {
2528 return NT_STATUS_INVALID_PARAMETER;
2530 ev = samba_tevent_context_init(talloc_tos());
2534 req = cli_tdis_send(ev, ev, cli);
2538 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2541 status = cli_tdis_recv(req);
2547 struct cli_connect_sock_state {
2548 const char **called_names;
2549 const char **calling_names;
2555 static void cli_connect_sock_done(struct tevent_req *subreq);
2558 * Async only if we don't have to look up the name, i.e. "pss" is set with a
2562 static struct tevent_req *cli_connect_sock_send(
2563 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2564 const char *host, int name_type, const struct sockaddr_storage *pss,
2565 const char *myname, uint16_t port)
2567 struct tevent_req *req, *subreq;
2568 struct cli_connect_sock_state *state;
2569 struct sockaddr_storage *addrs = NULL;
2571 unsigned num_addrs = 0;
2574 req = tevent_req_create(mem_ctx, &state,
2575 struct cli_connect_sock_state);
2580 if ((pss == NULL) || is_zero_addr(pss)) {
2583 * Here we cheat. resolve_name_list is not async at all. So
2584 * this call will only be really async if the name lookup has
2585 * been done externally.
2588 status = resolve_name_list(state, host, name_type,
2589 &addrs, &num_addrs);
2590 if (tevent_req_nterror(req, status)) {
2591 return tevent_req_post(req, ev);
2594 addrs = talloc_array(state, struct sockaddr_storage, 1);
2595 if (tevent_req_nomem(addrs, req)) {
2596 return tevent_req_post(req, ev);
2602 state->called_names = talloc_array(state, const char *, num_addrs);
2603 if (tevent_req_nomem(state->called_names, req)) {
2604 return tevent_req_post(req, ev);
2606 state->called_types = talloc_array(state, int, num_addrs);
2607 if (tevent_req_nomem(state->called_types, req)) {
2608 return tevent_req_post(req, ev);
2610 state->calling_names = talloc_array(state, const char *, num_addrs);
2611 if (tevent_req_nomem(state->calling_names, req)) {
2612 return tevent_req_post(req, ev);
2614 for (i=0; i<num_addrs; i++) {
2615 state->called_names[i] = host;
2616 state->called_types[i] = name_type;
2617 state->calling_names[i] = myname;
2620 subreq = smbsock_any_connect_send(
2621 state, ev, addrs, state->called_names, state->called_types,
2622 state->calling_names, NULL, num_addrs, port);
2623 if (tevent_req_nomem(subreq, req)) {
2624 return tevent_req_post(req, ev);
2626 tevent_req_set_callback(subreq, cli_connect_sock_done, req);
2630 static void cli_connect_sock_done(struct tevent_req *subreq)
2632 struct tevent_req *req = tevent_req_callback_data(
2633 subreq, struct tevent_req);
2634 struct cli_connect_sock_state *state = tevent_req_data(
2635 req, struct cli_connect_sock_state);
2638 status = smbsock_any_connect_recv(subreq, &state->fd, NULL,
2640 TALLOC_FREE(subreq);
2641 if (tevent_req_nterror(req, status)) {
2644 set_socket_options(state->fd, lp_socket_options());
2645 tevent_req_done(req);
2648 static NTSTATUS cli_connect_sock_recv(struct tevent_req *req,
2649 int *pfd, uint16_t *pport)
2651 struct cli_connect_sock_state *state = tevent_req_data(
2652 req, struct cli_connect_sock_state);
2655 if (tevent_req_is_nterror(req, &status)) {
2659 *pport = state->port;
2660 return NT_STATUS_OK;
2663 struct cli_connect_nb_state {
2664 const char *desthost;
2665 enum smb_signing_setting signing_state;
2667 struct cli_state *cli;
2670 static void cli_connect_nb_done(struct tevent_req *subreq);
2672 static struct tevent_req *cli_connect_nb_send(
2673 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2674 const char *host, const struct sockaddr_storage *dest_ss,
2675 uint16_t port, int name_type, const char *myname,
2676 enum smb_signing_setting signing_state, int flags)
2678 struct tevent_req *req, *subreq;
2679 struct cli_connect_nb_state *state;
2681 req = tevent_req_create(mem_ctx, &state, struct cli_connect_nb_state);
2685 state->signing_state = signing_state;
2686 state->flags = flags;
2689 char *p = strchr(host, '#');
2692 name_type = strtol(p+1, NULL, 16);
2693 host = talloc_strndup(state, host, p - host);
2694 if (tevent_req_nomem(host, req)) {
2695 return tevent_req_post(req, ev);
2699 state->desthost = host;
2700 } else if (dest_ss != NULL) {
2701 state->desthost = print_canonical_sockaddr(state, dest_ss);
2702 if (tevent_req_nomem(state->desthost, req)) {
2703 return tevent_req_post(req, ev);
2706 /* No host or dest_ss given. Error out. */
2707 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
2708 return tevent_req_post(req, ev);
2711 subreq = cli_connect_sock_send(state, ev, host, name_type, dest_ss,
2713 if (tevent_req_nomem(subreq, req)) {
2714 return tevent_req_post(req, ev);
2716 tevent_req_set_callback(subreq, cli_connect_nb_done, req);
2720 static void cli_connect_nb_done(struct tevent_req *subreq)
2722 struct tevent_req *req = tevent_req_callback_data(
2723 subreq, struct tevent_req);
2724 struct cli_connect_nb_state *state = tevent_req_data(
2725 req, struct cli_connect_nb_state);
2730 status = cli_connect_sock_recv(subreq, &fd, &port);
2731 TALLOC_FREE(subreq);
2732 if (tevent_req_nterror(req, status)) {
2736 state->cli = cli_state_create(state, fd, state->desthost,
2737 state->signing_state, state->flags);
2738 if (tevent_req_nomem(state->cli, req)) {
2742 tevent_req_done(req);
2745 static NTSTATUS cli_connect_nb_recv(struct tevent_req *req,
2746 TALLOC_CTX *mem_ctx,
2747 struct cli_state **pcli)
2749 struct cli_connect_nb_state *state = tevent_req_data(
2750 req, struct cli_connect_nb_state);
2753 if (tevent_req_is_nterror(req, &status)) {
2756 *pcli = talloc_move(mem_ctx, &state->cli);
2757 return NT_STATUS_OK;
2760 NTSTATUS cli_connect_nb(TALLOC_CTX *mem_ctx,
2762 const struct sockaddr_storage *dest_ss,
2766 enum smb_signing_setting signing_state,
2768 struct cli_state **pcli)
2770 struct tevent_context *ev;
2771 struct tevent_req *req;
2772 NTSTATUS status = NT_STATUS_NO_MEMORY;
2774 ev = samba_tevent_context_init(mem_ctx);
2778 req = cli_connect_nb_send(ev, ev, host, dest_ss, port, name_type,
2779 myname, signing_state, flags);
2783 if (!tevent_req_set_endtime(req, ev, timeval_current_ofs(20, 0))) {
2786 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2789 status = cli_connect_nb_recv(req, mem_ctx, pcli);
2795 struct cli_start_connection_state {
2796 struct tevent_context *ev;
2797 struct cli_state *cli;
2800 struct smb2_negotiate_contexts *negotiate_contexts;
2803 static void cli_start_connection_connected(struct tevent_req *subreq);
2804 static void cli_start_connection_done(struct tevent_req *subreq);
2807 establishes a connection to after the negprot.
2808 @param output_cli A fully initialised cli structure, non-null only on success
2809 @param dest_host The netbios name of the remote host
2810 @param dest_ss (optional) The destination IP, NULL for name based lookup
2811 @param port (optional) The destination port (0 for default)
2814 static struct tevent_req *cli_start_connection_send(
2815 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2816 const char *my_name, const char *dest_host,
2817 const struct sockaddr_storage *dest_ss, int port,
2818 enum smb_signing_setting signing_state, int flags,
2819 struct smb2_negotiate_contexts *negotiate_contexts)
2821 struct tevent_req *req, *subreq;
2822 struct cli_start_connection_state *state;
2824 req = tevent_req_create(mem_ctx, &state,
2825 struct cli_start_connection_state);
2831 if (flags & CLI_FULL_CONNECTION_IPC) {
2832 state->min_protocol = lp_client_ipc_min_protocol();
2833 state->max_protocol = lp_client_ipc_max_protocol();
2835 state->min_protocol = lp_client_min_protocol();
2836 state->max_protocol = lp_client_max_protocol();
2839 if (flags & CLI_FULL_CONNECTION_FORCE_SMB1) {
2840 state->max_protocol = MIN(state->max_protocol,
2842 state->min_protocol = MIN(state->min_protocol,
2843 state->max_protocol);
2846 if (flags & CLI_FULL_CONNECTION_DISABLE_SMB1) {
2847 state->min_protocol = MAX(state->min_protocol,
2849 state->max_protocol = MAX(state->max_protocol,
2850 state->min_protocol);
2853 state->negotiate_contexts = talloc_zero(
2854 state, struct smb2_negotiate_contexts);
2855 if (tevent_req_nomem(state->negotiate_contexts, req)) {
2856 return tevent_req_post(req, ev);
2859 if (flags & CLI_FULL_CONNECTION_REQUEST_POSIX) {
2862 status = smb2_negotiate_context_add(
2863 state->negotiate_contexts,
2864 state->negotiate_contexts,
2865 SMB2_POSIX_EXTENSIONS_AVAILABLE,
2866 (const uint8_t *)SMB2_CREATE_TAG_POSIX,
2867 strlen(SMB2_CREATE_TAG_POSIX));
2868 if (tevent_req_nterror(req, status)) {
2869 return tevent_req_post(req, ev);
2873 if (negotiate_contexts != NULL) {
2876 for (i=0; i<negotiate_contexts->num_contexts; i++) {
2877 struct smb2_negotiate_context *ctx =
2878 &negotiate_contexts->contexts[i];
2881 status = smb2_negotiate_context_add(
2882 state->negotiate_contexts,
2883 state->negotiate_contexts,
2887 if (tevent_req_nterror(req, status)) {
2888 return tevent_req_post(req, ev);
2893 subreq = cli_connect_nb_send(state, ev, dest_host, dest_ss, port,
2894 0x20, my_name, signing_state, flags);
2895 if (tevent_req_nomem(subreq, req)) {
2896 return tevent_req_post(req, ev);
2898 tevent_req_set_callback(subreq, cli_start_connection_connected, req);
2902 static void cli_start_connection_connected(struct tevent_req *subreq)
2904 struct tevent_req *req = tevent_req_callback_data(
2905 subreq, struct tevent_req);
2906 struct cli_start_connection_state *state = tevent_req_data(
2907 req, struct cli_start_connection_state);
2910 status = cli_connect_nb_recv(subreq, state, &state->cli);
2911 TALLOC_FREE(subreq);
2912 if (tevent_req_nterror(req, status)) {
2916 subreq = smbXcli_negprot_send(
2920 state->cli->timeout,
2921 state->min_protocol,
2922 state->max_protocol,
2923 WINDOWS_CLIENT_PURE_SMB2_NEGPROT_INITIAL_CREDIT_ASK,
2924 state->negotiate_contexts);
2925 if (tevent_req_nomem(subreq, req)) {
2928 tevent_req_set_callback(subreq, cli_start_connection_done, req);
2931 static void cli_start_connection_done(struct tevent_req *subreq)
2933 struct tevent_req *req = tevent_req_callback_data(
2934 subreq, struct tevent_req);
2935 struct cli_start_connection_state *state = tevent_req_data(
2936 req, struct cli_start_connection_state);
2939 status = smbXcli_negprot_recv(subreq, NULL, NULL);
2940 TALLOC_FREE(subreq);
2941 if (tevent_req_nterror(req, status)) {
2945 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
2946 /* Ensure we ask for some initial credits. */
2947 smb2cli_conn_set_max_credits(state->cli->conn,
2948 DEFAULT_SMB2_MAX_CREDITS);
2951 tevent_req_done(req);
2954 static NTSTATUS cli_start_connection_recv(struct tevent_req *req,
2955 TALLOC_CTX *mem_ctx,
2956 struct cli_state **output_cli)
2958 struct cli_start_connection_state *state = tevent_req_data(
2959 req, struct cli_start_connection_state);
2962 if (tevent_req_is_nterror(req, &status)) {
2965 *output_cli = talloc_move(mem_ctx, &state->cli);
2967 return NT_STATUS_OK;
2970 NTSTATUS cli_start_connection(TALLOC_CTX *mem_ctx,
2971 struct cli_state **output_cli,
2972 const char *my_name,
2973 const char *dest_host,
2974 const struct sockaddr_storage *dest_ss, int port,
2975 enum smb_signing_setting signing_state, int flags)
2977 struct tevent_context *ev;
2978 struct tevent_req *req;
2979 NTSTATUS status = NT_STATUS_NO_MEMORY;
2981 ev = samba_tevent_context_init(mem_ctx);
2985 req = cli_start_connection_send(ev, ev, my_name, dest_host, dest_ss,
2986 port, signing_state, flags, NULL);
2990 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2993 status = cli_start_connection_recv(req, mem_ctx, output_cli);
2999 struct cli_smb1_setup_encryption_blob_state {
3004 uint16_t enc_ctx_id;
3007 static void cli_smb1_setup_encryption_blob_done(struct tevent_req *subreq);
3009 static struct tevent_req *cli_smb1_setup_encryption_blob_send(TALLOC_CTX *mem_ctx,
3010 struct tevent_context *ev,
3011 struct cli_state *cli,
3014 struct tevent_req *req = NULL;
3015 struct cli_smb1_setup_encryption_blob_state *state = NULL;
3016 struct tevent_req *subreq = NULL;
3018 req = tevent_req_create(mem_ctx, &state,
3019 struct cli_smb1_setup_encryption_blob_state);
3024 if (in.length > CLI_BUFFER_SIZE) {
3025 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
3026 return tevent_req_post(req, ev);
3029 SSVAL(state->setup+0, 0, TRANSACT2_SETFSINFO);
3030 SSVAL(state->param, 0, 0);
3031 SSVAL(state->param, 2, SMB_REQUEST_TRANSPORT_ENCRYPTION);
3033 subreq = smb1cli_trans_send(state, ev, cli->conn,
3041 NULL, /* pipe_name */
3047 in.data, in.length, CLI_BUFFER_SIZE);
3048 if (tevent_req_nomem(subreq, req)) {
3049 return tevent_req_post(req, ev);
3051 tevent_req_set_callback(subreq,
3052 cli_smb1_setup_encryption_blob_done,
3058 static void cli_smb1_setup_encryption_blob_done(struct tevent_req *subreq)
3060 struct tevent_req *req =
3061 tevent_req_callback_data(subreq,
3063 struct cli_smb1_setup_encryption_blob_state *state =
3064 tevent_req_data(req,
3065 struct cli_smb1_setup_encryption_blob_state);
3066 uint8_t *rparam=NULL, *rdata=NULL;
3067 uint32_t num_rparam, num_rdata;
3070 status = smb1cli_trans_recv(subreq, state,
3071 NULL, /* recv_flags */
3072 NULL, 0, NULL, /* rsetup */
3073 &rparam, 0, &num_rparam,
3074 &rdata, 0, &num_rdata);
3075 TALLOC_FREE(subreq);
3076 state->status = status;
3077 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
3078 status = NT_STATUS_OK;
3080 if (tevent_req_nterror(req, status)) {
3084 if (num_rparam == 2) {
3085 state->enc_ctx_id = SVAL(rparam, 0);
3087 TALLOC_FREE(rparam);
3089 state->out = data_blob_const(rdata, num_rdata);
3091 tevent_req_done(req);
3094 static NTSTATUS cli_smb1_setup_encryption_blob_recv(struct tevent_req *req,
3095 TALLOC_CTX *mem_ctx,
3097 uint16_t *enc_ctx_id)
3099 struct cli_smb1_setup_encryption_blob_state *state =
3100 tevent_req_data(req,
3101 struct cli_smb1_setup_encryption_blob_state);
3104 if (tevent_req_is_nterror(req, &status)) {
3105 tevent_req_received(req);
3109 status = state->status;
3112 talloc_steal(mem_ctx, out->data);
3114 *enc_ctx_id = state->enc_ctx_id;
3116 tevent_req_received(req);
3120 struct cli_smb1_setup_encryption_state {
3121 struct tevent_context *ev;
3122 struct cli_state *cli;
3123 struct smb_trans_enc_state *es;
3130 static void cli_smb1_setup_encryption_local_next(struct tevent_req *req);
3131 static void cli_smb1_setup_encryption_local_done(struct tevent_req *subreq);
3132 static void cli_smb1_setup_encryption_remote_next(struct tevent_req *req);
3133 static void cli_smb1_setup_encryption_remote_done(struct tevent_req *subreq);
3134 static void cli_smb1_setup_encryption_ready(struct tevent_req *req);
3136 static struct tevent_req *cli_smb1_setup_encryption_send(TALLOC_CTX *mem_ctx,
3137 struct tevent_context *ev,
3138 struct cli_state *cli,
3139 struct cli_credentials *creds)
3141 struct tevent_req *req = NULL;
3142 struct cli_smb1_setup_encryption_state *state = NULL;
3143 struct auth_generic_state *ags = NULL;
3144 const DATA_BLOB *b = NULL;
3145 bool auth_requested = false;
3146 const char *target_service = NULL;
3147 const char *target_hostname = NULL;
3150 req = tevent_req_create(mem_ctx, &state,
3151 struct cli_smb1_setup_encryption_state);
3158 auth_requested = cli_credentials_authentication_requested(creds);
3159 if (!auth_requested) {
3160 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
3161 return tevent_req_post(req, ev);
3164 target_service = "cifs";
3165 target_hostname = smbXcli_conn_remote_name(cli->conn);
3167 status = cli_session_creds_prepare_krb5(cli, creds);
3168 if (tevent_req_nterror(req, status)) {
3169 return tevent_req_post(req, ev);
3172 state->es = talloc_zero(state, struct smb_trans_enc_state);
3173 if (tevent_req_nomem(state->es, req)) {
3174 return tevent_req_post(req, ev);
3177 status = auth_generic_client_prepare(state->es, &ags);
3178 if (tevent_req_nterror(req, status)) {
3179 return tevent_req_post(req, ev);
3182 gensec_want_feature(ags->gensec_security,
3183 GENSEC_FEATURE_SIGN);
3184 gensec_want_feature(ags->gensec_security,
3185 GENSEC_FEATURE_SEAL);
3187 status = auth_generic_set_creds(ags, creds);
3188 if (tevent_req_nterror(req, status)) {
3189 return tevent_req_post(req, ev);
3192 if (target_service != NULL) {
3193 status = gensec_set_target_service(ags->gensec_security,
3195 if (tevent_req_nterror(req, status)) {
3196 return tevent_req_post(req, ev);
3200 if (target_hostname != NULL) {
3201 status = gensec_set_target_hostname(ags->gensec_security,
3203 if (tevent_req_nterror(req, status)) {
3204 return tevent_req_post(req, ev);
3208 gensec_set_max_update_size(ags->gensec_security,
3211 b = smbXcli_conn_server_gss_blob(state->cli->conn);
3213 state->blob_in = *b;
3216 status = auth_generic_client_start(ags, GENSEC_OID_SPNEGO);
3217 if (tevent_req_nterror(req, status)) {
3218 return tevent_req_post(req, ev);
3222 * We only need the gensec_security part from here.
3224 state->es->gensec_security = talloc_move(state->es,
3225 &ags->gensec_security);
3228 cli_smb1_setup_encryption_local_next(req);
3229 if (!tevent_req_is_in_progress(req)) {
3230 return tevent_req_post(req, ev);
3236 static void cli_smb1_setup_encryption_local_next(struct tevent_req *req)
3238 struct cli_smb1_setup_encryption_state *state =
3239 tevent_req_data(req,
3240 struct cli_smb1_setup_encryption_state);
3241 struct tevent_req *subreq = NULL;
3243 if (state->local_ready) {
3244 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3248 subreq = gensec_update_send(state, state->ev,
3249 state->es->gensec_security,
3251 if (tevent_req_nomem(subreq, req)) {
3254 tevent_req_set_callback(subreq, cli_smb1_setup_encryption_local_done, req);
3257 static void cli_smb1_setup_encryption_local_done(struct tevent_req *subreq)
3259 struct tevent_req *req =
3260 tevent_req_callback_data(subreq,
3262 struct cli_smb1_setup_encryption_state *state =
3263 tevent_req_data(req,
3264 struct cli_smb1_setup_encryption_state);
3267 status = gensec_update_recv(subreq, state, &state->blob_out);
3268 TALLOC_FREE(subreq);
3269 state->blob_in = data_blob_null;
3270 if (!NT_STATUS_IS_OK(status) &&
3271 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
3273 tevent_req_nterror(req, status);
3277 if (NT_STATUS_IS_OK(status)) {
3278 state->local_ready = true;
3282 * We always get NT_STATUS_OK from the server even if it is not ready.
3283 * So guess the server is ready when we are ready and already sent
3284 * our last blob to the server.
3286 if (state->local_ready && state->blob_out.length == 0) {
3287 state->remote_ready = true;
3290 if (state->local_ready && state->remote_ready) {
3291 cli_smb1_setup_encryption_ready(req);
3295 cli_smb1_setup_encryption_remote_next(req);
3298 static void cli_smb1_setup_encryption_remote_next(struct tevent_req *req)
3300 struct cli_smb1_setup_encryption_state *state =
3301 tevent_req_data(req,
3302 struct cli_smb1_setup_encryption_state);
3303 struct tevent_req *subreq = NULL;
3305 if (state->remote_ready) {
3306 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3310 subreq = cli_smb1_setup_encryption_blob_send(state, state->ev,
3311 state->cli, state->blob_out);
3312 if (tevent_req_nomem(subreq, req)) {
3315 tevent_req_set_callback(subreq,
3316 cli_smb1_setup_encryption_remote_done,
3320 static void cli_smb1_setup_encryption_remote_done(struct tevent_req *subreq)
3322 struct tevent_req *req =
3323 tevent_req_callback_data(subreq,
3325 struct cli_smb1_setup_encryption_state *state =
3326 tevent_req_data(req,
3327 struct cli_smb1_setup_encryption_state);
3330 status = cli_smb1_setup_encryption_blob_recv(subreq, state,
3332 &state->es->enc_ctx_num);
3333 TALLOC_FREE(subreq);
3334 data_blob_free(&state->blob_out);
3335 if (!NT_STATUS_IS_OK(status) &&
3336 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
3338 tevent_req_nterror(req, status);
3343 * We always get NT_STATUS_OK even if the server is not ready.
3344 * So guess the server is ready when we are ready and sent
3345 * our last blob to the server.
3347 if (state->local_ready) {
3348 state->remote_ready = true;
3351 if (state->local_ready && state->remote_ready) {
3352 cli_smb1_setup_encryption_ready(req);
3356 cli_smb1_setup_encryption_local_next(req);
3359 static void cli_smb1_setup_encryption_ready(struct tevent_req *req)
3361 struct cli_smb1_setup_encryption_state *state =
3362 tevent_req_data(req,
3363 struct cli_smb1_setup_encryption_state);
3364 struct smb_trans_enc_state *es = NULL;
3366 if (state->blob_in.length != 0) {
3367 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3371 if (state->blob_out.length != 0) {
3372 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3376 es = talloc_move(state->cli->conn, &state->es);
3378 smb1cli_conn_set_encryption(state->cli->conn, es);
3381 tevent_req_done(req);
3384 static NTSTATUS cli_smb1_setup_encryption_recv(struct tevent_req *req)
3386 return tevent_req_simple_recv_ntstatus(req);
3389 NTSTATUS cli_smb1_setup_encryption(struct cli_state *cli,
3390 struct cli_credentials *creds)
3392 struct tevent_context *ev = NULL;
3393 struct tevent_req *req = NULL;
3394 NTSTATUS status = NT_STATUS_NO_MEMORY;
3396 ev = samba_tevent_context_init(talloc_tos());
3400 req = cli_smb1_setup_encryption_send(ev, ev, cli, creds);
3404 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
3407 status = cli_smb1_setup_encryption_recv(req);
3414 establishes a connection right up to doing tconX, password specified.
3415 @param output_cli A fully initialised cli structure, non-null only on success
3416 @param dest_host The netbios name of the remote host
3417 @param dest_ip (optional) The the destination IP, NULL for name based lookup
3418 @param port (optional) The destination port (0 for default)
3419 @param service (optional) The share to make the connection to. Should be 'unqualified' in any way.
3420 @param service_type The 'type' of service.
3421 @param creds The used user credentials
3424 struct cli_full_connection_creds_state {
3425 struct tevent_context *ev;
3426 const char *service;
3427 const char *service_type;
3428 struct cli_credentials *creds;
3430 struct cli_state *cli;
3433 static int cli_full_connection_creds_state_destructor(
3434 struct cli_full_connection_creds_state *s)
3436 if (s->cli != NULL) {
3437 cli_shutdown(s->cli);
3443 static void cli_full_connection_creds_conn_done(struct tevent_req *subreq);
3444 static void cli_full_connection_creds_sess_done(struct tevent_req *subreq);
3445 static void cli_full_connection_creds_enc_start(struct tevent_req *req);
3446 static void cli_full_connection_creds_enc_tcon(struct tevent_req *subreq);
3447 static void cli_full_connection_creds_enc_ver(struct tevent_req *subreq);
3448 static void cli_full_connection_creds_enc_done(struct tevent_req *subreq);
3449 static void cli_full_connection_creds_enc_tdis(struct tevent_req *req);
3450 static void cli_full_connection_creds_enc_finished(struct tevent_req *subreq);
3451 static void cli_full_connection_creds_tcon_start(struct tevent_req *req);
3452 static void cli_full_connection_creds_tcon_done(struct tevent_req *subreq);
3454 struct tevent_req *cli_full_connection_creds_send(
3455 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
3456 const char *my_name, const char *dest_host,
3457 const struct sockaddr_storage *dest_ss, int port,
3458 const char *service, const char *service_type,
3459 struct cli_credentials *creds,
3461 struct smb2_negotiate_contexts *negotiate_contexts)
3463 struct tevent_req *req, *subreq;
3464 struct cli_full_connection_creds_state *state;
3465 enum smb_signing_setting signing_state;
3466 enum smb_encryption_setting encryption_state =
3467 cli_credentials_get_smb_encryption(creds);
3469 req = tevent_req_create(mem_ctx, &state,
3470 struct cli_full_connection_creds_state);
3474 talloc_set_destructor(state, cli_full_connection_creds_state_destructor);
3477 state->service = service;
3478 state->service_type = service_type;
3479 state->creds = creds;
3480 state->flags = flags;
3482 if (flags & CLI_FULL_CONNECTION_IPC) {
3483 signing_state = cli_credentials_get_smb_ipc_signing(creds);
3485 signing_state = cli_credentials_get_smb_signing(creds);
3488 if (encryption_state == SMB_ENCRYPTION_REQUIRED) {
3489 if (flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK) {
3490 encryption_state = SMB_ENCRYPTION_DESIRED;
3494 if (encryption_state >= SMB_ENCRYPTION_DESIRED) {
3495 signing_state = SMB_SIGNING_REQUIRED;
3498 subreq = cli_start_connection_send(
3499 state, ev, my_name, dest_host, dest_ss, port,
3500 signing_state, flags,
3501 negotiate_contexts);
3502 if (tevent_req_nomem(subreq, req)) {
3503 return tevent_req_post(req, ev);
3505 tevent_req_set_callback(subreq,
3506 cli_full_connection_creds_conn_done,
3511 static void cli_full_connection_creds_conn_done(struct tevent_req *subreq)
3513 struct tevent_req *req = tevent_req_callback_data(
3514 subreq, struct tevent_req);
3515 struct cli_full_connection_creds_state *state = tevent_req_data(
3516 req, struct cli_full_connection_creds_state);
3519 status = cli_start_connection_recv(subreq, state, &state->cli);
3520 TALLOC_FREE(subreq);
3521 if (tevent_req_nterror(req, status)) {
3525 subreq = cli_session_setup_creds_send(
3526 state, state->ev, state->cli, state->creds);
3527 if (tevent_req_nomem(subreq, req)) {
3530 tevent_req_set_callback(subreq,
3531 cli_full_connection_creds_sess_done,
3535 static void cli_full_connection_creds_sess_done(struct tevent_req *subreq)
3537 struct tevent_req *req = tevent_req_callback_data(
3538 subreq, struct tevent_req);
3539 struct cli_full_connection_creds_state *state = tevent_req_data(
3540 req, struct cli_full_connection_creds_state);
3543 status = cli_session_setup_creds_recv(subreq);
3544 TALLOC_FREE(subreq);
3546 if (!NT_STATUS_IS_OK(status) &&
3547 (state->flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)) {
3549 state->flags &= ~CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
3551 state->creds = cli_credentials_init_anon(state);
3552 if (tevent_req_nomem(state->creds, req)) {
3556 subreq = cli_session_setup_creds_send(
3557 state, state->ev, state->cli, state->creds);
3558 if (tevent_req_nomem(subreq, req)) {
3561 tevent_req_set_callback(subreq,
3562 cli_full_connection_creds_sess_done,
3567 if (tevent_req_nterror(req, status)) {
3571 cli_full_connection_creds_enc_start(req);
3574 static void cli_full_connection_creds_enc_start(struct tevent_req *req)
3576 struct cli_full_connection_creds_state *state = tevent_req_data(
3577 req, struct cli_full_connection_creds_state);
3578 enum smb_encryption_setting encryption_state =
3579 cli_credentials_get_smb_encryption(state->creds);
3580 struct tevent_req *subreq = NULL;
3583 if (encryption_state < SMB_ENCRYPTION_DESIRED) {
3584 cli_full_connection_creds_tcon_start(req);
3588 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
3589 status = smb2cli_session_encryption_on(state->cli->smb2.session);
3590 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
3591 if (encryption_state < SMB_ENCRYPTION_REQUIRED) {
3592 cli_full_connection_creds_tcon_start(req);
3595 d_printf("Encryption required and "
3596 "server doesn't support "
3597 "SMB3 encryption - failing connect\n");
3598 tevent_req_nterror(req, status);
3600 } else if (!NT_STATUS_IS_OK(status)) {
3601 d_printf("Encryption required and "
3602 "setup failed with error %s.\n",
3604 tevent_req_nterror(req, status);
3608 cli_full_connection_creds_tcon_start(req);
3612 if (!SERVER_HAS_UNIX_CIFS(state->cli)) {
3613 if (encryption_state < SMB_ENCRYPTION_REQUIRED) {
3614 cli_full_connection_creds_tcon_start(req);
3618 status = NT_STATUS_NOT_SUPPORTED;
3619 d_printf("Encryption required and "
3620 "server doesn't support "
3621 "SMB1 Unix Extensions - failing connect\n");
3622 tevent_req_nterror(req, status);
3627 * We do a tcon on IPC$ just to setup the encryption,
3628 * the real tcon will be encrypted then.
3630 subreq = cli_tree_connect_send(state, state->ev, state->cli,
3631 "IPC$", "IPC", NULL);
3632 if (tevent_req_nomem(subreq, req)) {
3635 tevent_req_set_callback(subreq, cli_full_connection_creds_enc_tcon, req);
3638 static void cli_full_connection_creds_enc_tcon(struct tevent_req *subreq)
3640 struct tevent_req *req = tevent_req_callback_data(
3641 subreq, struct tevent_req);
3642 struct cli_full_connection_creds_state *state = tevent_req_data(
3643 req, struct cli_full_connection_creds_state);
3646 status = cli_tree_connect_recv(subreq);
3647 TALLOC_FREE(subreq);
3648 if (tevent_req_nterror(req, status)) {
3652 subreq = cli_unix_extensions_version_send(state, state->ev, state->cli);
3653 if (tevent_req_nomem(subreq, req)) {
3656 tevent_req_set_callback(subreq, cli_full_connection_creds_enc_ver, req);
3659 static void cli_full_connection_creds_enc_ver(struct tevent_req *subreq)
3661 struct tevent_req *req = tevent_req_callback_data(
3662 subreq, struct tevent_req);
3663 struct cli_full_connection_creds_state *state = tevent_req_data(
3664 req, struct cli_full_connection_creds_state);
3665 enum smb_encryption_setting encryption_state =
3666 cli_credentials_get_smb_encryption(state->creds);
3667 uint16_t major, minor;
3668 uint32_t caplow, caphigh;
3671 status = cli_unix_extensions_version_recv(subreq,
3675 TALLOC_FREE(subreq);
3676 if (!NT_STATUS_IS_OK(status)) {
3677 if (encryption_state < SMB_ENCRYPTION_REQUIRED) {
3678 /* disconnect ipc$ followed by the real tree connect */
3679 cli_full_connection_creds_enc_tdis(req);
3682 DEBUG(10, ("%s: cli_unix_extensions_version "
3683 "returned %s\n", __func__, nt_errstr(status)));
3684 tevent_req_nterror(req, NT_STATUS_UNKNOWN_REVISION);
3688 if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
3689 if (encryption_state < SMB_ENCRYPTION_REQUIRED) {
3690 /* disconnect ipc$ followed by the real tree connect */
3691 cli_full_connection_creds_enc_tdis(req);
3694 DEBUG(10, ("%s: CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP "
3695 "not supported\n", __func__));
3696 tevent_req_nterror(req, NT_STATUS_UNSUPPORTED_COMPRESSION);
3700 subreq = cli_smb1_setup_encryption_send(state, state->ev,
3703 if (tevent_req_nomem(subreq, req)) {
3706 tevent_req_set_callback(subreq,
3707 cli_full_connection_creds_enc_done,
3711 static void cli_full_connection_creds_enc_done(struct tevent_req *subreq)
3713 struct tevent_req *req = tevent_req_callback_data(
3714 subreq, struct tevent_req);
3717 status = cli_smb1_setup_encryption_recv(subreq);
3718 TALLOC_FREE(subreq);
3719 if (tevent_req_nterror(req, status)) {
3723 /* disconnect ipc$ followed by the real tree connect */
3724 cli_full_connection_creds_enc_tdis(req);
3727 static void cli_full_connection_creds_enc_tdis(struct tevent_req *req)
3729 struct cli_full_connection_creds_state *state = tevent_req_data(
3730 req, struct cli_full_connection_creds_state);
3731 struct tevent_req *subreq = NULL;
3733 subreq = cli_tdis_send(state, state->ev, state->cli);
3734 if (tevent_req_nomem(subreq, req)) {
3737 tevent_req_set_callback(subreq,
3738 cli_full_connection_creds_enc_finished,
3742 static void cli_full_connection_creds_enc_finished(struct tevent_req *subreq)
3744 struct tevent_req *req = tevent_req_callback_data(
3745 subreq, struct tevent_req);
3748 status = cli_tdis_recv(subreq);
3749 TALLOC_FREE(subreq);
3750 if (tevent_req_nterror(req, status)) {
3754 cli_full_connection_creds_tcon_start(req);
3757 static void cli_full_connection_creds_tcon_start(struct tevent_req *req)
3759 struct cli_full_connection_creds_state *state = tevent_req_data(
3760 req, struct cli_full_connection_creds_state);
3761 struct tevent_req *subreq = NULL;
3762 const char *password = NULL;
3764 if (state->service == NULL) {
3765 tevent_req_done(req);
3769 password = cli_credentials_get_password(state->creds);
3771 subreq = cli_tree_connect_send(state, state->ev,
3774 state->service_type,
3776 if (tevent_req_nomem(subreq, req)) {
3779 tevent_req_set_callback(subreq,
3780 cli_full_connection_creds_tcon_done,
3784 static void cli_full_connection_creds_tcon_done(struct tevent_req *subreq)
3786 struct tevent_req *req = tevent_req_callback_data(
3787 subreq, struct tevent_req);
3790 status = cli_tree_connect_recv(subreq);
3791 TALLOC_FREE(subreq);
3792 if (tevent_req_nterror(req, status)) {
3796 tevent_req_done(req);
3799 NTSTATUS cli_full_connection_creds_recv(struct tevent_req *req,
3800 TALLOC_CTX *mem_ctx,
3801 struct cli_state **output_cli)
3803 struct cli_full_connection_creds_state *state = tevent_req_data(
3804 req, struct cli_full_connection_creds_state);
3807 if (tevent_req_is_nterror(req, &status)) {
3810 *output_cli = talloc_move(mem_ctx, &state->cli);
3811 talloc_set_destructor(state, NULL);
3812 return NT_STATUS_OK;
3815 NTSTATUS cli_full_connection_creds(TALLOC_CTX *mem_ctx,
3816 struct cli_state **output_cli,
3817 const char *my_name,
3818 const char *dest_host,
3819 const struct sockaddr_storage *dest_ss, int port,
3820 const char *service, const char *service_type,
3821 struct cli_credentials *creds,
3824 struct tevent_context *ev;
3825 struct tevent_req *req;
3826 NTSTATUS status = NT_STATUS_NO_MEMORY;
3828 ev = samba_tevent_context_init(mem_ctx);
3832 req = cli_full_connection_creds_send(
3833 ev, ev, my_name, dest_host, dest_ss, port, service,
3834 service_type, creds, flags,
3839 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
3842 status = cli_full_connection_creds_recv(req, mem_ctx, output_cli);
3848 /****************************************************************************
3849 Send an old style tcon.
3850 ****************************************************************************/
3851 struct cli_raw_tcon_state {
3855 static void cli_raw_tcon_done(struct tevent_req *subreq);
3857 static struct tevent_req *cli_raw_tcon_send(
3858 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
3859 const char *service, const char *pass, const char *dev)
3861 struct tevent_req *req, *subreq;
3862 struct cli_raw_tcon_state *state;
3865 req = tevent_req_create(mem_ctx, &state, struct cli_raw_tcon_state);
3870 if (!lp_client_plaintext_auth() && (*pass)) {
3871 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
3872 " or 'client ntlmv2 auth = yes'\n"));
3873 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
3874 return tevent_req_post(req, ev);
3877 TALLOC_FREE(cli->smb1.tcon);
3878 cli->smb1.tcon = smbXcli_tcon_create(cli);
3879 if (tevent_req_nomem(cli->smb1.tcon, req)) {
3880 return tevent_req_post(req, ev);
3882 smb1cli_tcon_set_id(cli->smb1.tcon, UINT16_MAX);
3884 bytes = talloc_array(state, uint8_t, 0);
3885 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3886 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3887 service, strlen(service)+1, NULL);
3888 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3889 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3890 pass, strlen(pass)+1, NULL);
3891 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3892 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3893 dev, strlen(dev)+1, NULL);
3895 if (tevent_req_nomem(bytes, req)) {
3896 return tevent_req_post(req, ev);
3899 subreq = cli_smb_send(state, ev, cli, SMBtcon, 0, 0, 0, NULL,
3900 talloc_get_size(bytes), bytes);
3901 if (tevent_req_nomem(subreq, req)) {
3902 return tevent_req_post(req, ev);
3904 tevent_req_set_callback(subreq, cli_raw_tcon_done, req);
3908 static void cli_raw_tcon_done(struct tevent_req *subreq)
3910 struct tevent_req *req = tevent_req_callback_data(
3911 subreq, struct tevent_req);
3912 struct cli_raw_tcon_state *state = tevent_req_data(
3913 req, struct cli_raw_tcon_state);
3916 status = cli_smb_recv(subreq, state, NULL, 2, NULL, &state->ret_vwv,
3918 TALLOC_FREE(subreq);
3919 if (tevent_req_nterror(req, status)) {
3922 tevent_req_done(req);
3925 static NTSTATUS cli_raw_tcon_recv(struct tevent_req *req,
3926 uint16_t *max_xmit, uint16_t *tid)
3928 struct cli_raw_tcon_state *state = tevent_req_data(
3929 req, struct cli_raw_tcon_state);
3932 if (tevent_req_is_nterror(req, &status)) {
3935 *max_xmit = SVAL(state->ret_vwv + 0, 0);
3936 *tid = SVAL(state->ret_vwv + 1, 0);
3937 return NT_STATUS_OK;
3940 NTSTATUS cli_raw_tcon(struct cli_state *cli,
3941 const char *service, const char *pass, const char *dev,
3942 uint16_t *max_xmit, uint16_t *tid)
3944 struct tevent_context *ev;
3945 struct tevent_req *req;
3946 NTSTATUS status = NT_STATUS_NO_MEMORY;
3948 ev = samba_tevent_context_init(talloc_tos());
3952 req = cli_raw_tcon_send(ev, ev, cli, service, pass, dev);
3956 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
3959 status = cli_raw_tcon_recv(req, max_xmit, tid);
3965 /* Return a cli_state pointing at the IPC$ share for the given server */
3967 static struct cli_state *get_ipc_connect(TALLOC_CTX *mem_ctx,
3969 struct sockaddr_storage *server_ss,
3970 struct cli_credentials *creds)
3972 struct cli_state *cli;
3974 uint32_t flags = CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
3976 flags |= CLI_FULL_CONNECTION_FORCE_SMB1;
3977 flags |= CLI_FULL_CONNECTION_IPC;
3979 nt_status = cli_full_connection_creds(mem_ctx,
3990 if (NT_STATUS_IS_OK(nt_status)) {
3993 if (is_ipaddress(server)) {
3994 /* windows 9* needs a correct NMB name for connections */
3995 fstring remote_name;
3997 if (name_status_find("*", 0, 0, server_ss, remote_name)) {
3998 cli = get_ipc_connect(mem_ctx, remote_name, server_ss, creds);
4007 * Given the IP address of a master browser on the network, return its
4008 * workgroup and connect to it.
4010 * This function is provided to allow additional processing beyond what
4011 * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
4012 * browsers and obtain each master browsers' list of domains (in case the
4013 * first master browser is recently on the network and has not yet
4014 * synchronized with other master browsers and therefore does not yet have the
4015 * entire network browse list)
4018 struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx,
4019 struct sockaddr_storage *mb_ip,
4020 struct cli_credentials *creds,
4021 char **pp_workgroup_out)
4023 char addr[INET6_ADDRSTRLEN];
4025 struct cli_state *cli;
4026 struct sockaddr_storage server_ss;
4028 *pp_workgroup_out = NULL;
4030 print_sockaddr(addr, sizeof(addr), mb_ip);
4031 DEBUG(99, ("Looking up name of master browser %s\n",
4035 * Do a name status query to find out the name of the master browser.
4036 * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
4037 * master browser will not respond to a wildcard query (or, at least,
4038 * an NT4 server acting as the domain master browser will not).
4040 * We might be able to use ONLY the query on MSBROWSE, but that's not
4041 * yet been tested with all Windows versions, so until it is, leave
4042 * the original wildcard query as the first choice and fall back to
4043 * MSBROWSE if the wildcard query fails.
4045 if (!name_status_find("*", 0, 0x1d, mb_ip, name) &&
4046 !name_status_find(MSBROWSE, 1, 0x1d, mb_ip, name)) {
4048 DEBUG(99, ("Could not retrieve name status for %s\n",
4053 if (!find_master_ip(name, &server_ss)) {
4054 DEBUG(99, ("Could not find master ip for %s\n", name));
4058 *pp_workgroup_out = talloc_strdup(ctx, name);
4060 DEBUG(4, ("found master browser %s, %s\n", name, addr));
4062 print_sockaddr(addr, sizeof(addr), &server_ss);
4063 cli = get_ipc_connect(ctx, addr, &server_ss, creds);