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 "auth_info.h"
27 #include "../libcli/auth/libcli_auth.h"
28 #include "../libcli/auth/spnego.h"
30 #include "auth/credentials/credentials.h"
31 #include "auth/gensec/gensec.h"
32 #include "auth/ntlmssp/ntlmssp.h"
33 #include "auth_generic.h"
34 #include "libads/kerberos_proto.h"
36 #include "../lib/util/tevent_ntstatus.h"
37 #include "async_smb.h"
38 #include "libsmb/nmblib.h"
39 #include "librpc/ndr/libndr.h"
40 #include "../libcli/smb/smbXcli_base.h"
41 #include "../libcli/smb/smb_seal.h"
42 #include "lib/param/param.h"
43 #include "../libcli/smb/smb2_negotiate_context.h"
44 #include "libads/krb5_errs.h"
46 #define STAR_SMBSERVER "*SMBSERVER"
48 static char *cli_session_setup_get_account(TALLOC_CTX *mem_ctx,
49 const char *principal);
51 struct cli_credentials *cli_session_creds_init(TALLOC_CTX *mem_ctx,
57 bool fallback_after_kerberos,
59 bool password_is_nt_hash)
61 struct loadparm_context *lp_ctx = NULL;
62 struct cli_credentials *creds = NULL;
63 const char *principal = NULL;
68 creds = cli_credentials_init(mem_ctx);
73 lp_ctx = loadparm_init_s3(creds, loadparm_s3_helpers());
77 cli_credentials_set_conf(creds, lp_ctx);
79 if (username == NULL) {
83 if (strlen(username) == 0) {
84 if (password != NULL && strlen(password) == 0) {
86 * some callers pass "" as no password
88 * gensec only handles NULL as no password.
92 if (password == NULL) {
93 cli_credentials_set_anonymous(creds);
98 tmp = talloc_strdup(creds, username);
104 /* allow for workgroups as part of the username */
105 if ((p = strchr_m(tmp, '\\')) ||
106 (p = strchr_m(tmp, '/')) ||
107 (p = strchr_m(tmp, *lp_winbind_separator()))) {
113 principal = username;
114 username = cli_session_setup_get_account(creds, principal);
115 if (username == NULL) {
118 ok = strequal(username, principal);
121 * Ok still the same, so it's not a principal
126 if (use_kerberos && fallback_after_kerberos) {
127 cli_credentials_set_kerberos_state(creds,
128 CRED_AUTO_USE_KERBEROS);
129 } else if (use_kerberos) {
130 cli_credentials_set_kerberos_state(creds,
131 CRED_MUST_USE_KERBEROS);
133 cli_credentials_set_kerberos_state(creds,
134 CRED_DONT_USE_KERBEROS);
140 features = cli_credentials_get_gensec_features(creds);
141 features |= GENSEC_FEATURE_NTLM_CCACHE;
142 cli_credentials_set_gensec_features(creds, features);
144 if (password != NULL && strlen(password) == 0) {
146 * some callers pass "" as no password
148 * GENSEC_FEATURE_NTLM_CCACHE only handles
149 * NULL as no password.
155 ok = cli_credentials_set_username(creds,
162 if (domain != NULL) {
163 ok = cli_credentials_set_domain(creds,
171 if (principal != NULL) {
172 ok = cli_credentials_set_principal(creds,
181 ok = cli_credentials_set_realm(creds,
189 if (password != NULL && strlen(password) > 0) {
190 if (password_is_nt_hash) {
191 struct samr_Password nt_hash;
194 converted = strhex_to_str((char *)nt_hash.hash,
195 sizeof(nt_hash.hash),
198 if (converted != sizeof(nt_hash.hash)) {
202 ok = cli_credentials_set_nt_hash(creds,
209 ok = cli_credentials_set_password(creds,
224 NTSTATUS cli_session_creds_prepare_krb5(struct cli_state *cli,
225 struct cli_credentials *creds)
227 TALLOC_CTX *frame = talloc_stackframe();
228 const char *user_principal = NULL;
229 const char *user_account = NULL;
230 const char *user_domain = NULL;
231 const char *pass = NULL;
232 const char *target_hostname = NULL;
233 const DATA_BLOB *server_blob = NULL;
234 bool got_kerberos_mechanism = false;
235 enum credentials_use_kerberos krb5_state;
236 bool try_kerberos = false;
237 bool need_kinit = false;
238 bool auth_requested = true;
241 target_hostname = smbXcli_conn_remote_name(cli->conn);
242 server_blob = smbXcli_conn_server_gss_blob(cli->conn);
244 /* the server might not even do spnego */
245 if (server_blob != NULL && server_blob->length != 0) {
246 char *OIDs[ASN1_MAX_OIDS] = { NULL, };
251 * The server sent us the first part of the SPNEGO exchange in the
252 * negprot reply. It is WRONG to depend on the principal sent in the
253 * negprot reply, but right now we do it. If we don't receive one,
254 * we try to best guess, then fall back to NTLM.
256 ok = spnego_parse_negTokenInit(frame,
263 return NT_STATUS_INVALID_PARAMETER;
265 if (OIDs[0] == NULL) {
267 return NT_STATUS_INVALID_PARAMETER;
270 /* make sure the server understands kerberos */
271 for (i = 0; OIDs[i] != NULL; i++) {
273 DEBUG(3,("got OID=%s\n", OIDs[i]));
275 DEBUGADD(3,("got OID=%s\n", OIDs[i]));
278 if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0 ||
279 strcmp(OIDs[i], OID_KERBEROS5) == 0) {
280 got_kerberos_mechanism = true;
286 auth_requested = cli_credentials_authentication_requested(creds);
287 if (auth_requested) {
289 user_principal = cli_credentials_get_principal(creds, frame);
292 return NT_STATUS_NO_MEMORY;
295 user_account = cli_credentials_get_username(creds);
296 user_domain = cli_credentials_get_domain(creds);
297 pass = cli_credentials_get_password(creds);
299 krb5_state = cli_credentials_get_kerberos_state(creds);
301 if (krb5_state != CRED_DONT_USE_KERBEROS) {
305 if (user_principal == NULL) {
306 try_kerberos = false;
309 if (target_hostname == NULL) {
310 try_kerberos = false;
311 } else if (is_ipaddress(target_hostname)) {
312 try_kerberos = false;
313 } else if (strequal(target_hostname, "localhost")) {
314 try_kerberos = false;
315 } else if (strequal(target_hostname, STAR_SMBSERVER)) {
316 try_kerberos = false;
317 } else if (!auth_requested) {
318 try_kerberos = false;
321 if (krb5_state == CRED_MUST_USE_KERBEROS && !try_kerberos) {
322 DEBUG(0, ("Kerberos auth with '%s' (%s\\%s) to access "
323 "'%s' not possible\n",
324 user_principal, user_domain, user_account,
327 return NT_STATUS_ACCESS_DENIED;
330 if (pass == NULL || strlen(pass) == 0) {
332 } else if (krb5_state == CRED_MUST_USE_KERBEROS) {
333 need_kinit = try_kerberos;
334 } else if (!got_kerberos_mechanism) {
336 * Most likely the server doesn't support
337 * Kerberos, don't waste time doing a kinit
341 need_kinit = try_kerberos;
349 DBG_INFO("Doing kinit for %s to access %s\n",
350 user_principal, target_hostname);
353 * TODO: This should be done within the gensec layer
356 setenv(KRB5_ENV_CCNAME, "MEMORY:cliconnect", 1);
357 ret = kerberos_kinit_password(user_principal, pass,
358 0 /* no time correction for now */,
361 int dbglvl = DBGLVL_NOTICE;
363 if (krb5_state == CRED_MUST_USE_KERBEROS) {
367 DEBUG(dbglvl, ("Kinit for %s to access %s failed: %s\n",
368 user_principal, target_hostname,
369 error_message(ret)));
370 if (krb5_state == CRED_MUST_USE_KERBEROS) {
372 return krb5_to_nt_status(ret);
376 * Ignore the error and hope that NTLM will work
380 DBG_DEBUG("Successfully authenticated as %s to access %s using "
389 static NTSTATUS cli_state_update_after_sesssetup(struct cli_state *cli,
390 const char *native_os,
391 const char *native_lm,
392 const char *primary_domain)
394 #define _VALID_STR(p) ((p) != NULL && (p)[0] != '\0')
396 if (!_VALID_STR(cli->server_os) && _VALID_STR(native_os)) {
397 cli->server_os = talloc_strdup(cli, native_os);
398 if (cli->server_os == NULL) {
399 return NT_STATUS_NO_MEMORY;
403 if (!_VALID_STR(cli->server_type) && _VALID_STR(native_lm)) {
404 cli->server_type = talloc_strdup(cli, native_lm);
405 if (cli->server_type == NULL) {
406 return NT_STATUS_NO_MEMORY;
410 if (!_VALID_STR(cli->server_domain) && _VALID_STR(primary_domain)) {
411 cli->server_domain = talloc_strdup(cli, primary_domain);
412 if (cli->server_domain == NULL) {
413 return NT_STATUS_NO_MEMORY;
421 /********************************************************
422 Utility function to ensure we always return at least
423 a valid char * pointer to an empty string for the
424 cli->server_os, cli->server_type and cli->server_domain
426 *******************************************************/
428 static NTSTATUS smb_bytes_talloc_string(TALLOC_CTX *mem_ctx,
435 *destlen = clistr_pull_talloc(mem_ctx,
442 if (*destlen == -1) {
443 return NT_STATUS_NO_MEMORY;
447 *dest = talloc_strdup(mem_ctx, "");
449 return NT_STATUS_NO_MEMORY;
455 /****************************************************************************
456 Work out suitable capabilities to offer the server.
457 ****************************************************************************/
459 static uint32_t cli_session_setup_capabilities(struct cli_state *cli,
460 uint32_t sesssetup_capabilities)
462 uint32_t client_capabilities = smb1cli_conn_capabilities(cli->conn);
465 * We only send capabilities based on the mask for:
466 * - client only flags
467 * - flags used in both directions
469 * We do not echo the server only flags, except some legacy flags.
471 * SMB_CAP_LEGACY_CLIENT_MASK contains CAP_LARGE_READX and
472 * CAP_LARGE_WRITEX in order to allow us to do large reads
473 * against old Samba releases (<= 3.6.x).
475 client_capabilities &= (SMB_CAP_BOTH_MASK | SMB_CAP_LEGACY_CLIENT_MASK);
478 * Session Setup specific flags CAP_DYNAMIC_REAUTH
479 * and CAP_EXTENDED_SECURITY are passed by the caller.
480 * We need that in order to do guest logins even if
481 * CAP_EXTENDED_SECURITY is negotiated.
483 client_capabilities &= ~(CAP_DYNAMIC_REAUTH|CAP_EXTENDED_SECURITY);
484 sesssetup_capabilities &= (CAP_DYNAMIC_REAUTH|CAP_EXTENDED_SECURITY);
485 client_capabilities |= sesssetup_capabilities;
487 return client_capabilities;
490 /****************************************************************************
491 Do a NT1 guest session setup.
492 ****************************************************************************/
494 struct cli_session_setup_guest_state {
495 struct cli_state *cli;
500 static void cli_session_setup_guest_done(struct tevent_req *subreq);
502 struct tevent_req *cli_session_setup_guest_create(TALLOC_CTX *mem_ctx,
503 struct tevent_context *ev,
504 struct cli_state *cli,
505 struct tevent_req **psmbreq)
507 struct tevent_req *req, *subreq;
508 struct cli_session_setup_guest_state *state;
512 req = tevent_req_create(mem_ctx, &state,
513 struct cli_session_setup_guest_state);
520 SCVAL(vwv+0, 0, 0xFF);
523 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
525 SSVAL(vwv+4, 0, cli_state_get_vc_num(cli));
526 SIVAL(vwv+5, 0, smb1cli_conn_server_session_key(cli->conn));
531 SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli, 0));
533 bytes = talloc_array(state, uint8_t, 0);
535 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "", 1, /* username */
537 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "", 1, /* workgroup */
539 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "Unix", 5, NULL);
540 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "Samba", 6, NULL);
547 state->bytes.iov_base = (void *)bytes;
548 state->bytes.iov_len = talloc_get_size(bytes);
550 subreq = cli_smb_req_create(state, ev, cli, SMBsesssetupX, 0, 0, 13,
551 vwv, 1, &state->bytes);
552 if (subreq == NULL) {
556 tevent_req_set_callback(subreq, cli_session_setup_guest_done, req);
561 struct tevent_req *cli_session_setup_guest_send(TALLOC_CTX *mem_ctx,
562 struct tevent_context *ev,
563 struct cli_state *cli)
565 struct tevent_req *req, *subreq;
568 req = cli_session_setup_guest_create(mem_ctx, ev, cli, &subreq);
573 status = smb1cli_req_chain_submit(&subreq, 1);
574 if (!NT_STATUS_IS_OK(status)) {
575 tevent_req_nterror(req, status);
576 return tevent_req_post(req, ev);
581 static void cli_session_setup_guest_done(struct tevent_req *subreq)
583 struct tevent_req *req = tevent_req_callback_data(
584 subreq, struct tevent_req);
585 struct cli_session_setup_guest_state *state = tevent_req_data(
586 req, struct cli_session_setup_guest_state);
587 struct cli_state *cli = state->cli;
598 status = cli_smb_recv(subreq, state, &in, 3, &wct, &vwv,
601 if (!NT_STATUS_IS_OK(status)) {
602 tevent_req_nterror(req, status);
606 inhdr = in + NBT_HDR_SIZE;
609 cli_state_set_uid(state->cli, SVAL(inhdr, HDR_UID));
610 smb1cli_session_set_action(cli->smb1.session, SVAL(vwv+2, 0));
612 status = smb_bytes_talloc_string(cli,
619 if (!NT_STATUS_IS_OK(status)) {
620 tevent_req_nterror(req, status);
625 status = smb_bytes_talloc_string(cli,
632 if (!NT_STATUS_IS_OK(status)) {
633 tevent_req_nterror(req, status);
638 status = smb_bytes_talloc_string(cli,
645 if (!NT_STATUS_IS_OK(status)) {
646 tevent_req_nterror(req, status);
651 tevent_req_done(req);
654 NTSTATUS cli_session_setup_guest_recv(struct tevent_req *req)
656 return tevent_req_simple_recv_ntstatus(req);
659 /* The following is calculated from :
661 * (smb_wcnt * 2) = 24 (smb_wcnt == 12 in cli_session_setup_blob_send() )
662 * (strlen("Unix") + 1 + strlen("Samba") + 1) * 2 = 22 (unicode strings at
666 #define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22)
668 struct cli_sesssetup_blob_state {
669 struct tevent_context *ev;
670 struct cli_state *cli;
672 uint16_t max_blob_size;
675 struct iovec *recv_iov;
678 const uint8_t *inbuf;
685 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state *state,
686 struct tevent_req **psubreq);
687 static void cli_sesssetup_blob_done(struct tevent_req *subreq);
689 static struct tevent_req *cli_sesssetup_blob_send(TALLOC_CTX *mem_ctx,
690 struct tevent_context *ev,
691 struct cli_state *cli,
694 struct tevent_req *req, *subreq;
695 struct cli_sesssetup_blob_state *state;
696 uint32_t usable_space;
698 req = tevent_req_create(mem_ctx, &state,
699 struct cli_sesssetup_blob_state);
707 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
708 usable_space = UINT16_MAX;
710 usable_space = cli_state_available_size(cli,
711 BASE_SESSSETUP_BLOB_PACKET_SIZE);
714 if (usable_space == 0) {
715 DEBUG(1, ("cli_session_setup_blob: cli->max_xmit too small "
716 "(not possible to send %u bytes)\n",
717 BASE_SESSSETUP_BLOB_PACKET_SIZE + 1));
718 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
719 return tevent_req_post(req, ev);
721 state->max_blob_size = MIN(usable_space, 0xFFFF);
723 if (!cli_sesssetup_blob_next(state, &subreq)) {
724 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
725 return tevent_req_post(req, ev);
727 tevent_req_set_callback(subreq, cli_sesssetup_blob_done, req);
731 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state *state,
732 struct tevent_req **psubreq)
734 struct tevent_req *subreq;
737 thistime = MIN(state->blob.length, state->max_blob_size);
739 state->this_blob.data = state->blob.data;
740 state->this_blob.length = thistime;
742 state->blob.data += thistime;
743 state->blob.length -= thistime;
745 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
746 subreq = smb2cli_session_setup_send(state, state->ev,
749 state->cli->smb2.session,
751 SMB2_CAP_DFS, /* in_capabilities */
753 0, /* in_previous_session_id */
755 if (subreq == NULL) {
759 uint16_t in_buf_size = 0;
760 uint16_t in_mpx_max = 0;
761 uint16_t in_vc_num = 0;
762 uint32_t in_sess_key = 0;
763 uint32_t in_capabilities = 0;
764 const char *in_native_os = NULL;
765 const char *in_native_lm = NULL;
767 in_buf_size = CLI_BUFFER_SIZE;
768 in_mpx_max = smbXcli_conn_max_requests(state->cli->conn);
769 in_vc_num = cli_state_get_vc_num(state->cli);
770 in_sess_key = smb1cli_conn_server_session_key(state->cli->conn);
771 in_capabilities = cli_session_setup_capabilities(state->cli,
772 CAP_EXTENDED_SECURITY);
773 in_native_os = "Unix";
774 in_native_lm = "Samba";
777 * For now we keep the same values as before,
778 * we may remove these in a separate commit later.
784 subreq = smb1cli_session_setup_ext_send(state, state->ev,
787 state->cli->smb1.pid,
788 state->cli->smb1.session,
797 if (subreq == NULL) {
805 static void cli_sesssetup_blob_done(struct tevent_req *subreq)
807 struct tevent_req *req = tevent_req_callback_data(
808 subreq, struct tevent_req);
809 struct cli_sesssetup_blob_state *state = tevent_req_data(
810 req, struct cli_sesssetup_blob_state);
813 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
814 status = smb2cli_session_setup_recv(subreq, state,
818 status = smb1cli_session_setup_ext_recv(subreq, state,
822 &state->out_native_os,
823 &state->out_native_lm);
826 if (!NT_STATUS_IS_OK(status)
827 && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
828 tevent_req_nterror(req, status);
832 state->status = status;
834 status = cli_state_update_after_sesssetup(state->cli,
835 state->out_native_os,
836 state->out_native_lm,
838 if (tevent_req_nterror(req, status)) {
842 if (state->blob.length != 0) {
846 if (!cli_sesssetup_blob_next(state, &subreq)) {
850 tevent_req_set_callback(subreq, cli_sesssetup_blob_done, req);
853 tevent_req_done(req);
856 static NTSTATUS cli_sesssetup_blob_recv(struct tevent_req *req,
859 const uint8_t **pinbuf,
860 struct iovec **precv_iov)
862 struct cli_sesssetup_blob_state *state = tevent_req_data(
863 req, struct cli_sesssetup_blob_state);
865 struct iovec *recv_iov;
867 if (tevent_req_is_nterror(req, &status)) {
868 TALLOC_FREE(state->cli->smb2.session);
869 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
870 tevent_req_received(req);
874 recv_iov = talloc_move(mem_ctx, &state->recv_iov);
876 *pblob = state->ret_blob;
878 if (pinbuf != NULL) {
879 *pinbuf = state->inbuf;
881 if (precv_iov != NULL) {
882 *precv_iov = recv_iov;
884 /* could be NT_STATUS_MORE_PROCESSING_REQUIRED */
885 status = state->status;
886 tevent_req_received(req);
890 /****************************************************************************
891 Do a spnego/NTLMSSP encrypted session setup.
892 ****************************************************************************/
894 struct cli_session_setup_gensec_state {
895 struct tevent_context *ev;
896 struct cli_state *cli;
897 struct auth_generic_state *auth_generic;
900 const uint8_t *inbuf;
901 struct iovec *recv_iov;
905 DATA_BLOB session_key;
908 static int cli_session_setup_gensec_state_destructor(
909 struct cli_session_setup_gensec_state *state)
911 TALLOC_FREE(state->auth_generic);
912 data_blob_clear_free(&state->session_key);
916 static void cli_session_setup_gensec_local_next(struct tevent_req *req);
917 static void cli_session_setup_gensec_local_done(struct tevent_req *subreq);
918 static void cli_session_setup_gensec_remote_next(struct tevent_req *req);
919 static void cli_session_setup_gensec_remote_done(struct tevent_req *subreq);
920 static void cli_session_setup_gensec_ready(struct tevent_req *req);
922 static struct tevent_req *cli_session_setup_gensec_send(
923 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
924 struct cli_credentials *creds,
925 const char *target_service,
926 const char *target_hostname)
928 struct tevent_req *req;
929 struct cli_session_setup_gensec_state *state;
931 const DATA_BLOB *b = NULL;
933 req = tevent_req_create(mem_ctx, &state,
934 struct cli_session_setup_gensec_state);
941 talloc_set_destructor(
942 state, cli_session_setup_gensec_state_destructor);
944 status = auth_generic_client_prepare(state, &state->auth_generic);
945 if (tevent_req_nterror(req, status)) {
946 return tevent_req_post(req, ev);
949 status = auth_generic_set_creds(state->auth_generic, creds);
950 if (tevent_req_nterror(req, status)) {
951 return tevent_req_post(req, ev);
954 gensec_want_feature(state->auth_generic->gensec_security,
955 GENSEC_FEATURE_SESSION_KEY);
957 if (target_service != NULL) {
958 status = gensec_set_target_service(
959 state->auth_generic->gensec_security,
961 if (tevent_req_nterror(req, status)) {
962 return tevent_req_post(req, ev);
966 if (target_hostname != NULL) {
967 status = gensec_set_target_hostname(
968 state->auth_generic->gensec_security,
970 if (tevent_req_nterror(req, status)) {
971 return tevent_req_post(req, ev);
975 b = smbXcli_conn_server_gss_blob(cli->conn);
980 state->is_anonymous = cli_credentials_is_anonymous(state->auth_generic->credentials);
982 status = auth_generic_client_start(state->auth_generic,
984 if (tevent_req_nterror(req, status)) {
985 return tevent_req_post(req, ev);
988 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
989 state->cli->smb2.session = smbXcli_session_create(cli,
991 if (tevent_req_nomem(state->cli->smb2.session, req)) {
992 return tevent_req_post(req, ev);
996 cli_session_setup_gensec_local_next(req);
997 if (!tevent_req_is_in_progress(req)) {
998 return tevent_req_post(req, ev);
1004 static void cli_session_setup_gensec_local_next(struct tevent_req *req)
1006 struct cli_session_setup_gensec_state *state =
1007 tevent_req_data(req,
1008 struct cli_session_setup_gensec_state);
1009 struct tevent_req *subreq = NULL;
1011 if (state->local_ready) {
1012 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1016 subreq = gensec_update_send(state, state->ev,
1017 state->auth_generic->gensec_security,
1019 if (tevent_req_nomem(subreq, req)) {
1022 tevent_req_set_callback(subreq, cli_session_setup_gensec_local_done, req);
1025 static void cli_session_setup_gensec_local_done(struct tevent_req *subreq)
1027 struct tevent_req *req =
1028 tevent_req_callback_data(subreq,
1030 struct cli_session_setup_gensec_state *state =
1031 tevent_req_data(req,
1032 struct cli_session_setup_gensec_state);
1035 status = gensec_update_recv(subreq, state, &state->blob_out);
1036 TALLOC_FREE(subreq);
1037 state->blob_in = data_blob_null;
1038 if (!NT_STATUS_IS_OK(status) &&
1039 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
1041 tevent_req_nterror(req, status);
1045 if (NT_STATUS_IS_OK(status)) {
1046 state->local_ready = true;
1049 if (state->local_ready && state->remote_ready) {
1050 cli_session_setup_gensec_ready(req);
1054 cli_session_setup_gensec_remote_next(req);
1057 static void cli_session_setup_gensec_remote_next(struct tevent_req *req)
1059 struct cli_session_setup_gensec_state *state =
1060 tevent_req_data(req,
1061 struct cli_session_setup_gensec_state);
1062 struct tevent_req *subreq = NULL;
1064 if (state->remote_ready) {
1065 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1069 subreq = cli_sesssetup_blob_send(state, state->ev,
1070 state->cli, state->blob_out);
1071 if (tevent_req_nomem(subreq, req)) {
1074 tevent_req_set_callback(subreq,
1075 cli_session_setup_gensec_remote_done,
1079 static void cli_session_setup_gensec_remote_done(struct tevent_req *subreq)
1081 struct tevent_req *req =
1082 tevent_req_callback_data(subreq,
1084 struct cli_session_setup_gensec_state *state =
1085 tevent_req_data(req,
1086 struct cli_session_setup_gensec_state);
1089 state->inbuf = NULL;
1090 TALLOC_FREE(state->recv_iov);
1092 status = cli_sesssetup_blob_recv(subreq, state, &state->blob_in,
1093 &state->inbuf, &state->recv_iov);
1094 TALLOC_FREE(subreq);
1095 data_blob_free(&state->blob_out);
1096 if (!NT_STATUS_IS_OK(status) &&
1097 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
1099 tevent_req_nterror(req, status);
1103 if (NT_STATUS_IS_OK(status)) {
1104 struct smbXcli_session *session = NULL;
1105 bool is_guest = false;
1107 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
1108 session = state->cli->smb2.session;
1110 session = state->cli->smb1.session;
1113 is_guest = smbXcli_session_is_guest(session);
1116 * We can't finish the gensec handshake, we don't
1117 * have a negotiated session key.
1119 * So just pretend we are completely done,
1120 * we need to continue as anonymous from this point,
1121 * as we can't get a session key.
1123 * Note that smbXcli_session_is_guest()
1124 * always returns false if we require signing.
1126 state->blob_in = data_blob_null;
1127 state->local_ready = true;
1128 state->is_anonymous = true;
1131 state->remote_ready = true;
1134 if (state->local_ready && state->remote_ready) {
1135 cli_session_setup_gensec_ready(req);
1139 cli_session_setup_gensec_local_next(req);
1142 static void cli_session_dump_keys(TALLOC_CTX *mem_ctx,
1143 struct smbXcli_session *session,
1144 DATA_BLOB session_key)
1147 DATA_BLOB sig = data_blob_null;
1148 DATA_BLOB app = data_blob_null;
1149 DATA_BLOB enc = data_blob_null;
1150 DATA_BLOB dec = data_blob_null;
1151 uint64_t sid = smb2cli_session_current_id(session);
1153 status = smb2cli_session_signing_key(session, mem_ctx, &sig);
1154 if (!NT_STATUS_IS_OK(status)) {
1157 status = smbXcli_session_application_key(session, mem_ctx, &app);
1158 if (!NT_STATUS_IS_OK(status)) {
1161 status = smb2cli_session_encryption_key(session, mem_ctx, &enc);
1162 if (!NT_STATUS_IS_OK(status)) {
1165 status = smb2cli_session_decryption_key(session, mem_ctx, &dec);
1166 if (!NT_STATUS_IS_OK(status)) {
1170 DEBUG(0, ("debug encryption: dumping generated session keys\n"));
1171 DEBUGADD(0, ("Session Id "));
1172 dump_data(0, (uint8_t*)&sid, sizeof(sid));
1173 DEBUGADD(0, ("Session Key "));
1174 dump_data(0, session_key.data, session_key.length);
1175 DEBUGADD(0, ("Signing Key "));
1176 dump_data(0, sig.data, sig.length);
1177 DEBUGADD(0, ("App Key "));
1178 dump_data(0, app.data, app.length);
1180 /* In client code, ServerIn is the encryption key */
1182 DEBUGADD(0, ("ServerIn Key "));
1183 dump_data(0, enc.data, enc.length);
1184 DEBUGADD(0, ("ServerOut Key "));
1185 dump_data(0, dec.data, dec.length);
1188 data_blob_clear_free(&sig);
1189 data_blob_clear_free(&app);
1190 data_blob_clear_free(&enc);
1191 data_blob_clear_free(&dec);
1194 static void cli_session_setup_gensec_ready(struct tevent_req *req)
1196 struct cli_session_setup_gensec_state *state =
1197 tevent_req_data(req,
1198 struct cli_session_setup_gensec_state);
1199 const char *server_domain = NULL;
1202 if (state->blob_in.length != 0) {
1203 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1207 if (state->blob_out.length != 0) {
1208 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1213 * gensec_ntlmssp_server_domain() returns NULL
1214 * if NTLMSSP is not used.
1216 * We can remove this later
1217 * and leave the server domain empty for SMB2 and above
1218 * in future releases.
1220 server_domain = gensec_ntlmssp_server_domain(
1221 state->auth_generic->gensec_security);
1223 if (state->cli->server_domain[0] == '\0' && server_domain != NULL) {
1224 TALLOC_FREE(state->cli->server_domain);
1225 state->cli->server_domain = talloc_strdup(state->cli,
1227 if (state->cli->server_domain == NULL) {
1228 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1233 if (state->is_anonymous) {
1235 * Windows server does not set the
1236 * SMB2_SESSION_FLAG_IS_NULL flag.
1238 * This fix makes sure we do not try
1239 * to verify a signature on the final
1240 * session setup response.
1242 tevent_req_done(req);
1246 status = gensec_session_key(state->auth_generic->gensec_security,
1247 state, &state->session_key);
1248 if (tevent_req_nterror(req, status)) {
1252 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
1253 struct smbXcli_session *session = state->cli->smb2.session;
1255 status = smb2cli_session_set_session_key(session,
1258 if (tevent_req_nterror(req, status)) {
1261 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB3_00
1262 && lp_debug_encryption())
1264 cli_session_dump_keys(state, session, state->session_key);
1267 struct smbXcli_session *session = state->cli->smb1.session;
1270 status = smb1cli_session_set_session_key(session,
1271 state->session_key);
1272 if (tevent_req_nterror(req, status)) {
1276 active = smb1cli_conn_activate_signing(state->cli->conn,
1282 ok = smb1cli_conn_check_signing(state->cli->conn,
1285 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1291 tevent_req_done(req);
1294 static NTSTATUS cli_session_setup_gensec_recv(struct tevent_req *req)
1296 struct cli_session_setup_gensec_state *state =
1297 tevent_req_data(req,
1298 struct cli_session_setup_gensec_state);
1301 if (tevent_req_is_nterror(req, &status)) {
1302 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
1305 return NT_STATUS_OK;
1308 static char *cli_session_setup_get_account(TALLOC_CTX *mem_ctx,
1309 const char *principal)
1313 account = talloc_strdup(mem_ctx, principal);
1314 if (account == NULL) {
1317 p = strchr_m(account, '@');
1324 /****************************************************************************
1325 Do a spnego encrypted session setup.
1327 user_domain: The shortname of the domain the user/machine is a member of.
1328 dest_realm: The realm we're connecting to, if NULL we use our default realm.
1329 ****************************************************************************/
1331 struct cli_session_setup_spnego_state {
1335 static void cli_session_setup_spnego_done(struct tevent_req *subreq);
1337 static struct tevent_req *cli_session_setup_spnego_send(
1338 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
1339 struct cli_credentials *creds)
1341 struct tevent_req *req, *subreq;
1342 struct cli_session_setup_spnego_state *state;
1343 const char *target_service = NULL;
1344 const char *target_hostname = NULL;
1347 req = tevent_req_create(mem_ctx, &state,
1348 struct cli_session_setup_spnego_state);
1353 target_service = "cifs";
1354 target_hostname = smbXcli_conn_remote_name(cli->conn);
1356 status = cli_session_creds_prepare_krb5(cli, creds);
1357 if (tevent_req_nterror(req, status)) {
1358 return tevent_req_post(req, ev);
1361 DBG_INFO("Connect to %s as %s using SPNEGO\n",
1363 cli_credentials_get_principal(creds, talloc_tos()));
1365 subreq = cli_session_setup_gensec_send(state, ev, cli, creds,
1366 target_service, target_hostname);
1367 if (tevent_req_nomem(subreq, req)) {
1368 return tevent_req_post(req, ev);
1370 tevent_req_set_callback(
1371 subreq, cli_session_setup_spnego_done, req);
1375 static void cli_session_setup_spnego_done(struct tevent_req *subreq)
1377 struct tevent_req *req = tevent_req_callback_data(
1378 subreq, struct tevent_req);
1381 status = cli_session_setup_gensec_recv(subreq);
1382 TALLOC_FREE(subreq);
1383 if (tevent_req_nterror(req, status)) {
1387 tevent_req_done(req);
1390 static ADS_STATUS cli_session_setup_spnego_recv(struct tevent_req *req)
1392 struct cli_session_setup_spnego_state *state = tevent_req_data(
1393 req, struct cli_session_setup_spnego_state);
1396 if (tevent_req_is_nterror(req, &status)) {
1397 state->result = ADS_ERROR_NT(status);
1400 return state->result;
1403 struct cli_session_setup_creds_state {
1404 struct cli_state *cli;
1405 DATA_BLOB apassword_blob;
1406 DATA_BLOB upassword_blob;
1407 DATA_BLOB lm_session_key;
1408 DATA_BLOB session_key;
1409 char *out_native_os;
1410 char *out_native_lm;
1411 char *out_primary_domain;
1414 static void cli_session_setup_creds_cleanup(struct tevent_req *req,
1415 enum tevent_req_state req_state)
1417 struct cli_session_setup_creds_state *state = tevent_req_data(
1418 req, struct cli_session_setup_creds_state);
1420 if (req_state != TEVENT_REQ_RECEIVED) {
1425 * We only call data_blob_clear() as
1426 * some of the blobs point to the same memory.
1428 * We let the talloc hierachy free the memory.
1430 data_blob_clear(&state->apassword_blob);
1431 data_blob_clear(&state->upassword_blob);
1432 data_blob_clear(&state->lm_session_key);
1433 data_blob_clear(&state->session_key);
1434 ZERO_STRUCTP(state);
1437 static void cli_session_setup_creds_done_spnego(struct tevent_req *subreq);
1438 static void cli_session_setup_creds_done_nt1(struct tevent_req *subreq);
1439 static void cli_session_setup_creds_done_lm21(struct tevent_req *subreq);
1441 /****************************************************************************
1442 Send a session setup. The username and workgroup is in UNIX character
1443 format and must be converted to DOS codepage format before sending. If the
1444 password is in plaintext, the same should be done.
1445 ****************************************************************************/
1447 struct tevent_req *cli_session_setup_creds_send(TALLOC_CTX *mem_ctx,
1448 struct tevent_context *ev,
1449 struct cli_state *cli,
1450 struct cli_credentials *creds)
1452 struct tevent_req *req, *subreq;
1453 struct cli_session_setup_creds_state *state;
1454 uint16_t sec_mode = smb1cli_conn_server_security_mode(cli->conn);
1455 bool use_spnego = false;
1457 enum credentials_use_kerberos krb5_state;
1458 uint32_t gensec_features;
1459 const char *username = "";
1460 const char *domain = "";
1461 DATA_BLOB target_info = data_blob_null;
1462 DATA_BLOB challenge = data_blob_null;
1463 uint16_t in_buf_size = 0;
1464 uint16_t in_mpx_max = 0;
1465 uint16_t in_vc_num = 0;
1466 uint32_t in_sess_key = 0;
1467 const char *in_native_os = NULL;
1468 const char *in_native_lm = NULL;
1471 req = tevent_req_create(mem_ctx, &state,
1472 struct cli_session_setup_creds_state);
1478 tevent_req_set_cleanup_fn(req, cli_session_setup_creds_cleanup);
1480 krb5_state = cli_credentials_get_kerberos_state(creds);
1481 gensec_features = cli_credentials_get_gensec_features(creds);
1483 switch (krb5_state) {
1484 case CRED_MUST_USE_KERBEROS:
1485 cli->use_kerberos = true;
1486 cli->fallback_after_kerberos = false;
1488 case CRED_AUTO_USE_KERBEROS:
1489 cli->use_kerberos = true;
1490 cli->fallback_after_kerberos = true;
1492 case CRED_DONT_USE_KERBEROS:
1493 cli->use_kerberos = false;
1494 cli->fallback_after_kerberos = false;
1498 if (gensec_features & GENSEC_FEATURE_NTLM_CCACHE) {
1499 cli->use_ccache = true;
1501 cli->use_ccache = false;
1505 * Now work out what sort of session setup we are going to
1506 * do. I have split this into separate functions to make the flow a bit
1507 * easier to understand (tridge).
1509 if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_NT1) {
1511 } else if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
1513 } else if (smb1cli_conn_capabilities(cli->conn) & CAP_EXTENDED_SECURITY) {
1515 * if the server supports extended security then use SPNEGO
1516 * even for anonymous connections.
1524 subreq = cli_session_setup_spnego_send(
1525 state, ev, cli, creds);
1526 if (tevent_req_nomem(subreq, req)) {
1527 return tevent_req_post(req, ev);
1529 tevent_req_set_callback(subreq, cli_session_setup_creds_done_spnego,
1534 if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_LANMAN1) {
1536 * SessionSetupAndX was introduced by LANMAN 1.0. So we skip
1537 * this step against older servers.
1539 tevent_req_done(req);
1540 return tevent_req_post(req, ev);
1543 if (cli_credentials_is_anonymous(creds)) {
1545 * Do an anonymous session setup
1547 goto non_spnego_creds_done;
1550 if ((sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0) {
1552 * Do an anonymous session setup,
1553 * the password is passed via the tree connect.
1555 goto non_spnego_creds_done;
1558 cli_credentials_get_ntlm_username_domain(creds, state,
1561 if (tevent_req_nomem(username, req)) {
1562 return tevent_req_post(req, ev);
1564 if (tevent_req_nomem(domain, req)) {
1565 return tevent_req_post(req, ev);
1568 DBG_INFO("Connect to %s as %s using NTLM\n", domain, username);
1570 if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) {
1571 bool use_unicode = smbXcli_conn_use_unicode(cli->conn);
1572 uint8_t *bytes = NULL;
1573 size_t bytes_len = 0;
1574 const char *pw = cli_credentials_get_password(creds);
1580 pw_len = strlen(pw) + 1;
1582 if (!lp_client_plaintext_auth()) {
1583 DEBUG(1, ("Server requested PLAINTEXT password but "
1584 "'client plaintext auth = no'\n"));
1585 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1586 return tevent_req_post(req, ev);
1589 bytes = talloc_array(state, uint8_t, 0);
1590 bytes = trans2_bytes_push_str(bytes, use_unicode,
1591 pw, pw_len, &bytes_len);
1592 if (tevent_req_nomem(bytes, req)) {
1593 return tevent_req_post(req, ev);
1598 * CAP_UNICODE, can only be negotiated by NT1.
1600 state->upassword_blob = data_blob_const(bytes,
1603 state->apassword_blob = data_blob_const(bytes,
1607 goto non_spnego_creds_done;
1610 challenge = data_blob_const(smb1cli_conn_server_challenge(cli->conn), 8);
1612 if (smbXcli_conn_protocol(cli->conn) == PROTOCOL_NT1) {
1613 if (lp_client_ntlmv2_auth() && lp_client_use_spnego()) {
1615 * Don't send an NTLMv2 response without NTLMSSP if we
1616 * want to use spnego support.
1618 DEBUG(1, ("Server does not support EXTENDED_SECURITY "
1619 " but 'client use spnego = yes'"
1620 " and 'client ntlmv2 auth = yes' is set\n"));
1621 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1622 return tevent_req_post(req, ev);
1625 if (lp_client_ntlmv2_auth()) {
1626 flags |= CLI_CRED_NTLMv2_AUTH;
1629 * note that the 'domain' here is a best
1630 * guess - we don't know the server's domain
1631 * at this point. Windows clients also don't
1634 target_info = NTLMv2_generate_names_blob(state,
1637 if (tevent_req_nomem(target_info.data, req)) {
1638 return tevent_req_post(req, ev);
1641 flags |= CLI_CRED_NTLM_AUTH;
1642 if (lp_client_lanman_auth()) {
1643 flags |= CLI_CRED_LANMAN_AUTH;
1647 if (!lp_client_lanman_auth()) {
1648 DEBUG(1, ("Server requested user level LM password but "
1649 "'client lanman auth = no' is set.\n"));
1650 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1651 return tevent_req_post(req, ev);
1654 flags |= CLI_CRED_LANMAN_AUTH;
1657 status = cli_credentials_get_ntlm_response(creds, state, &flags,
1660 &state->apassword_blob,
1661 &state->upassword_blob,
1662 &state->lm_session_key,
1663 &state->session_key);
1664 if (tevent_req_nterror(req, status)) {
1665 return tevent_req_post(req, ev);
1668 non_spnego_creds_done:
1670 in_buf_size = CLI_BUFFER_SIZE;
1671 in_mpx_max = smbXcli_conn_max_requests(cli->conn);
1672 in_vc_num = cli_state_get_vc_num(cli);
1673 in_sess_key = smb1cli_conn_server_session_key(cli->conn);
1674 in_native_os = "Unix";
1675 in_native_lm = "Samba";
1677 if (smbXcli_conn_protocol(cli->conn) == PROTOCOL_NT1) {
1678 uint32_t in_capabilities = 0;
1680 in_capabilities = cli_session_setup_capabilities(cli, 0);
1683 * For now we keep the same values as before,
1684 * we may remove these in a separate commit later.
1688 subreq = smb1cli_session_setup_nt1_send(state, ev,
1699 state->apassword_blob,
1700 state->upassword_blob,
1704 if (tevent_req_nomem(subreq, req)) {
1705 return tevent_req_post(req, ev);
1707 tevent_req_set_callback(subreq, cli_session_setup_creds_done_nt1,
1713 * For now we keep the same values as before,
1714 * we may remove these in a separate commit later.
1719 subreq = smb1cli_session_setup_lm21_send(state, ev,
1730 state->apassword_blob,
1733 if (tevent_req_nomem(subreq, req)) {
1734 return tevent_req_post(req, ev);
1736 tevent_req_set_callback(subreq, cli_session_setup_creds_done_lm21,
1741 static void cli_session_setup_creds_done_spnego(struct tevent_req *subreq)
1743 struct tevent_req *req = tevent_req_callback_data(
1744 subreq, struct tevent_req);
1747 status = cli_session_setup_spnego_recv(subreq);
1748 TALLOC_FREE(subreq);
1749 if (!ADS_ERR_OK(status)) {
1750 DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status)));
1751 tevent_req_nterror(req, ads_ntstatus(status));
1754 tevent_req_done(req);
1757 static void cli_session_setup_creds_done_nt1(struct tevent_req *subreq)
1759 struct tevent_req *req = tevent_req_callback_data(
1760 subreq, struct tevent_req);
1761 struct cli_session_setup_creds_state *state = tevent_req_data(
1762 req, struct cli_session_setup_creds_state);
1763 struct cli_state *cli = state->cli;
1765 struct iovec *recv_iov = NULL;
1766 const uint8_t *inbuf = NULL;
1769 status = smb1cli_session_setup_nt1_recv(subreq, state,
1772 &state->out_native_os,
1773 &state->out_native_lm,
1774 &state->out_primary_domain);
1775 TALLOC_FREE(subreq);
1776 if (!NT_STATUS_IS_OK(status)) {
1777 DEBUG(3, ("NT1 login failed: %s\n", nt_errstr(status)));
1778 tevent_req_nterror(req, status);
1782 status = cli_state_update_after_sesssetup(state->cli,
1783 state->out_native_os,
1784 state->out_native_lm,
1785 state->out_primary_domain);
1786 if (tevent_req_nterror(req, status)) {
1790 ok = smb1cli_conn_activate_signing(cli->conn,
1792 state->upassword_blob);
1794 ok = smb1cli_conn_check_signing(cli->conn, inbuf, 1);
1796 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1801 if (state->session_key.data) {
1802 struct smbXcli_session *session = cli->smb1.session;
1804 status = smb1cli_session_set_session_key(session,
1805 state->session_key);
1806 if (tevent_req_nterror(req, status)) {
1811 tevent_req_done(req);
1814 static void cli_session_setup_creds_done_lm21(struct tevent_req *subreq)
1816 struct tevent_req *req = tevent_req_callback_data(
1817 subreq, struct tevent_req);
1818 struct cli_session_setup_creds_state *state = tevent_req_data(
1819 req, struct cli_session_setup_creds_state);
1822 status = smb1cli_session_setup_lm21_recv(subreq, state,
1823 &state->out_native_os,
1824 &state->out_native_lm);
1825 TALLOC_FREE(subreq);
1826 if (!NT_STATUS_IS_OK(status)) {
1827 DEBUG(3, ("LM21 login failed: %s\n", nt_errstr(status)));
1828 tevent_req_nterror(req, status);
1832 status = cli_state_update_after_sesssetup(state->cli,
1833 state->out_native_os,
1834 state->out_native_lm,
1836 if (tevent_req_nterror(req, status)) {
1840 tevent_req_done(req);
1843 NTSTATUS cli_session_setup_creds_recv(struct tevent_req *req)
1845 return tevent_req_simple_recv_ntstatus(req);
1848 NTSTATUS cli_session_setup_creds(struct cli_state *cli,
1849 struct cli_credentials *creds)
1851 struct tevent_context *ev;
1852 struct tevent_req *req;
1853 NTSTATUS status = NT_STATUS_NO_MEMORY;
1855 if (smbXcli_conn_has_async_calls(cli->conn)) {
1856 return NT_STATUS_INVALID_PARAMETER;
1858 ev = samba_tevent_context_init(talloc_tos());
1862 req = cli_session_setup_creds_send(ev, ev, cli, creds);
1866 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1869 status = cli_session_setup_creds_recv(req);
1875 NTSTATUS cli_session_setup_anon(struct cli_state *cli)
1877 NTSTATUS status = NT_STATUS_NO_MEMORY;
1878 struct cli_credentials *creds = NULL;
1880 creds = cli_credentials_init_anon(cli);
1881 if (creds == NULL) {
1882 return NT_STATUS_NO_MEMORY;
1885 status = cli_session_setup_creds(cli, creds);
1887 if (!NT_STATUS_IS_OK(status)) {
1891 return NT_STATUS_OK;
1894 /****************************************************************************
1896 *****************************************************************************/
1898 struct cli_ulogoff_state {
1899 struct cli_state *cli;
1903 static void cli_ulogoff_done(struct tevent_req *subreq);
1905 static struct tevent_req *cli_ulogoff_send(TALLOC_CTX *mem_ctx,
1906 struct tevent_context *ev,
1907 struct cli_state *cli)
1909 struct tevent_req *req, *subreq;
1910 struct cli_ulogoff_state *state;
1912 req = tevent_req_create(mem_ctx, &state, struct cli_ulogoff_state);
1918 SCVAL(state->vwv+0, 0, 0xFF);
1919 SCVAL(state->vwv+1, 0, 0);
1920 SSVAL(state->vwv+2, 0, 0);
1922 subreq = cli_smb_send(state, ev, cli, SMBulogoffX, 0, 0, 2, state->vwv,
1924 if (tevent_req_nomem(subreq, req)) {
1925 return tevent_req_post(req, ev);
1927 tevent_req_set_callback(subreq, cli_ulogoff_done, req);
1931 static void cli_ulogoff_done(struct tevent_req *subreq)
1933 struct tevent_req *req = tevent_req_callback_data(
1934 subreq, struct tevent_req);
1935 struct cli_ulogoff_state *state = tevent_req_data(
1936 req, struct cli_ulogoff_state);
1939 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
1940 if (!NT_STATUS_IS_OK(status)) {
1941 tevent_req_nterror(req, status);
1944 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
1945 tevent_req_done(req);
1948 static NTSTATUS cli_ulogoff_recv(struct tevent_req *req)
1950 return tevent_req_simple_recv_ntstatus(req);
1953 NTSTATUS cli_ulogoff(struct cli_state *cli)
1955 struct tevent_context *ev;
1956 struct tevent_req *req;
1957 NTSTATUS status = NT_STATUS_NO_MEMORY;
1959 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
1960 status = smb2cli_logoff(cli->conn,
1963 if (!NT_STATUS_IS_OK(status)) {
1966 smb2cli_session_set_id_and_flags(cli->smb2.session,
1968 return NT_STATUS_OK;
1971 if (smbXcli_conn_has_async_calls(cli->conn)) {
1972 return NT_STATUS_INVALID_PARAMETER;
1974 ev = samba_tevent_context_init(talloc_tos());
1978 req = cli_ulogoff_send(ev, ev, cli);
1982 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1985 status = cli_ulogoff_recv(req);
1991 /****************************************************************************
1993 ****************************************************************************/
1995 struct cli_tcon_andx_state {
1996 struct cli_state *cli;
2001 static void cli_tcon_andx_done(struct tevent_req *subreq);
2003 struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx,
2004 struct tevent_context *ev,
2005 struct cli_state *cli,
2006 const char *share, const char *dev,
2007 const char *pass, int passlen,
2008 struct tevent_req **psmbreq)
2010 struct tevent_req *req, *subreq;
2011 struct cli_tcon_andx_state *state;
2016 uint16_t sec_mode = smb1cli_conn_server_security_mode(cli->conn);
2017 uint16_t tcon_flags = 0;
2021 req = tevent_req_create(mem_ctx, &state, struct cli_tcon_andx_state);
2028 TALLOC_FREE(cli->smb1.tcon);
2029 cli->smb1.tcon = smbXcli_tcon_create(cli);
2030 if (tevent_req_nomem(cli->smb1.tcon, req)) {
2031 return tevent_req_post(req, ev);
2033 smb1cli_tcon_set_id(cli->smb1.tcon, UINT16_MAX);
2035 cli->share = talloc_strdup(cli, share);
2040 /* in user level security don't send a password now */
2041 if (sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {
2044 } else if (pass == NULL) {
2045 DEBUG(1, ("Server not using user level security and no "
2046 "password supplied.\n"));
2050 if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) &&
2051 *pass && passlen != 24) {
2052 if (!lp_client_lanman_auth()) {
2053 DEBUG(1, ("Server requested LANMAN password "
2054 "(share-level security) but "
2055 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2060 * Non-encrypted passwords - convert to DOS codepage before
2063 SMBencrypt(pass, smb1cli_conn_server_challenge(cli->conn), p24);
2065 pass = (const char *)p24;
2067 if((sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL
2068 |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE))
2072 if (!lp_client_plaintext_auth() && (*pass)) {
2073 DEBUG(1, ("Server requested PLAINTEXT "
2075 "'client plaintext auth = no' or 'client ntlmv2 auth = yes'\n"));
2080 * Non-encrypted passwords - convert to DOS codepage
2083 tmp_pass = talloc_array(talloc_tos(), uint8_t, 0);
2084 if (tevent_req_nomem(tmp_pass, req)) {
2085 return tevent_req_post(req, ev);
2087 tmp_pass = trans2_bytes_push_str(tmp_pass,
2088 false, /* always DOS */
2092 if (tevent_req_nomem(tmp_pass, req)) {
2093 return tevent_req_post(req, ev);
2095 pass = (const char *)tmp_pass;
2096 passlen = talloc_get_size(tmp_pass);
2100 tcon_flags |= TCONX_FLAG_EXTENDED_RESPONSE;
2101 tcon_flags |= TCONX_FLAG_EXTENDED_SIGNATURES;
2103 SCVAL(vwv+0, 0, 0xFF);
2106 SSVAL(vwv+2, 0, tcon_flags);
2107 SSVAL(vwv+3, 0, passlen);
2109 if (passlen && pass) {
2110 bytes = (uint8_t *)talloc_memdup(state, pass, passlen);
2112 bytes = talloc_array(state, uint8_t, 0);
2118 tmp = talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
2119 smbXcli_conn_remote_name(cli->conn), share);
2124 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), tmp, strlen(tmp)+1,
2129 * Add the devicetype
2131 tmp = talloc_strdup_upper(talloc_tos(), dev);
2136 bytes = smb_bytes_push_str(bytes, false, tmp, strlen(tmp)+1, NULL);
2139 if (bytes == NULL) {
2144 state->bytes.iov_base = (void *)bytes;
2145 state->bytes.iov_len = talloc_get_size(bytes);
2147 subreq = cli_smb_req_create(state, ev, cli, SMBtconX, 0, 0, 4, vwv,
2149 if (subreq == NULL) {
2153 tevent_req_set_callback(subreq, cli_tcon_andx_done, req);
2158 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
2159 return tevent_req_post(req, ev);
2162 struct tevent_req *cli_tcon_andx_send(TALLOC_CTX *mem_ctx,
2163 struct tevent_context *ev,
2164 struct cli_state *cli,
2165 const char *share, const char *dev,
2166 const char *pass, int passlen)
2168 struct tevent_req *req, *subreq;
2171 req = cli_tcon_andx_create(mem_ctx, ev, cli, share, dev, pass, passlen,
2176 if (subreq == NULL) {
2179 status = smb1cli_req_chain_submit(&subreq, 1);
2180 if (!NT_STATUS_IS_OK(status)) {
2181 tevent_req_nterror(req, status);
2182 return tevent_req_post(req, ev);
2187 static void cli_tcon_andx_done(struct tevent_req *subreq)
2189 struct tevent_req *req = tevent_req_callback_data(
2190 subreq, struct tevent_req);
2191 struct cli_tcon_andx_state *state = tevent_req_data(
2192 req, struct cli_tcon_andx_state);
2193 struct cli_state *cli = state->cli;
2201 uint16_t optional_support = 0;
2203 status = cli_smb_recv(subreq, state, &in, 0, &wct, &vwv,
2204 &num_bytes, &bytes);
2205 TALLOC_FREE(subreq);
2206 if (!NT_STATUS_IS_OK(status)) {
2207 tevent_req_nterror(req, status);
2211 inhdr = in + NBT_HDR_SIZE;
2214 if (clistr_pull_talloc(cli,
2215 (const char *)inhdr,
2216 SVAL(inhdr, HDR_FLG2),
2220 STR_TERMINATE|STR_ASCII) == -1) {
2221 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2225 cli->dev = talloc_strdup(cli, "");
2226 if (cli->dev == NULL) {
2227 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2232 if ((smbXcli_conn_protocol(cli->conn) >= PROTOCOL_NT1) && (num_bytes == 3)) {
2233 /* almost certainly win95 - enable bug fixes */
2238 * Make sure that we have the optional support 16-bit field. WCT > 2.
2239 * Avoids issues when connecting to Win9x boxes sharing files
2242 if ((wct > 2) && (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_LANMAN2)) {
2243 optional_support = SVAL(vwv+2, 0);
2246 if (optional_support & SMB_EXTENDED_SIGNATURES) {
2247 smb1cli_session_protect_session_key(cli->smb1.session);
2250 smb1cli_tcon_set_values(state->cli->smb1.tcon,
2251 SVAL(inhdr, HDR_TID),
2253 0, /* maximal_access */
2254 0, /* guest_maximal_access */
2256 NULL); /* fs_type */
2258 tevent_req_done(req);
2261 NTSTATUS cli_tcon_andx_recv(struct tevent_req *req)
2263 return tevent_req_simple_recv_ntstatus(req);
2266 NTSTATUS cli_tcon_andx(struct cli_state *cli, const char *share,
2267 const char *dev, const char *pass, int passlen)
2269 TALLOC_CTX *frame = talloc_stackframe();
2270 struct tevent_context *ev;
2271 struct tevent_req *req;
2272 NTSTATUS status = NT_STATUS_NO_MEMORY;
2274 if (smbXcli_conn_has_async_calls(cli->conn)) {
2276 * Can't use sync call while an async call is in flight
2278 status = NT_STATUS_INVALID_PARAMETER;
2282 ev = samba_tevent_context_init(frame);
2287 req = cli_tcon_andx_send(frame, ev, cli, share, dev, pass, passlen);
2292 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2296 status = cli_tcon_andx_recv(req);
2302 struct cli_tree_connect_state {
2303 struct cli_state *cli;
2306 static struct tevent_req *cli_raw_tcon_send(
2307 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
2308 const char *service, const char *pass, const char *dev);
2309 static NTSTATUS cli_raw_tcon_recv(struct tevent_req *req,
2310 uint16_t *max_xmit, uint16_t *tid);
2312 static void cli_tree_connect_smb2_done(struct tevent_req *subreq);
2313 static void cli_tree_connect_andx_done(struct tevent_req *subreq);
2314 static void cli_tree_connect_raw_done(struct tevent_req *subreq);
2316 static struct tevent_req *cli_tree_connect_send(
2317 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
2318 const char *share, const char *dev, const char *pass)
2320 struct tevent_req *req, *subreq;
2321 struct cli_tree_connect_state *state;
2327 passlen = strlen(pass) + 1;
2329 req = tevent_req_create(mem_ctx, &state,
2330 struct cli_tree_connect_state);
2336 cli->share = talloc_strdup(cli, share);
2337 if (tevent_req_nomem(cli->share, req)) {
2338 return tevent_req_post(req, ev);
2341 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
2344 TALLOC_FREE(cli->smb2.tcon);
2345 cli->smb2.tcon = smbXcli_tcon_create(cli);
2346 if (tevent_req_nomem(cli->smb2.tcon, req)) {
2347 return tevent_req_post(req, ev);
2350 unc = talloc_asprintf(state, "\\\\%s\\%s",
2351 smbXcli_conn_remote_name(cli->conn),
2353 if (tevent_req_nomem(unc, req)) {
2354 return tevent_req_post(req, ev);
2357 subreq = smb2cli_tcon_send(state, ev, cli->conn, cli->timeout,
2358 cli->smb2.session, cli->smb2.tcon,
2361 if (tevent_req_nomem(subreq, req)) {
2362 return tevent_req_post(req, ev);
2364 tevent_req_set_callback(subreq, cli_tree_connect_smb2_done,
2369 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_LANMAN1) {
2370 subreq = cli_tcon_andx_send(state, ev, cli, share, dev,
2372 if (tevent_req_nomem(subreq, req)) {
2373 return tevent_req_post(req, ev);
2375 tevent_req_set_callback(subreq, cli_tree_connect_andx_done,
2380 subreq = cli_raw_tcon_send(state, ev, cli, share, pass, dev);
2381 if (tevent_req_nomem(subreq, req)) {
2382 return tevent_req_post(req, ev);
2384 tevent_req_set_callback(subreq, cli_tree_connect_raw_done, req);
2389 static void cli_tree_connect_smb2_done(struct tevent_req *subreq)
2391 tevent_req_simple_finish_ntstatus(
2392 subreq, smb2cli_tcon_recv(subreq));
2395 static void cli_tree_connect_andx_done(struct tevent_req *subreq)
2397 tevent_req_simple_finish_ntstatus(
2398 subreq, cli_tcon_andx_recv(subreq));
2401 static void cli_tree_connect_raw_done(struct tevent_req *subreq)
2403 struct tevent_req *req = tevent_req_callback_data(
2404 subreq, struct tevent_req);
2405 struct cli_tree_connect_state *state = tevent_req_data(
2406 req, struct cli_tree_connect_state);
2408 uint16_t max_xmit = 0;
2411 status = cli_raw_tcon_recv(subreq, &max_xmit, &tid);
2412 if (tevent_req_nterror(req, status)) {
2416 smb1cli_tcon_set_values(state->cli->smb1.tcon,
2418 0, /* optional_support */
2419 0, /* maximal_access */
2420 0, /* guest_maximal_access */
2422 NULL); /* fs_type */
2424 tevent_req_done(req);
2427 static NTSTATUS cli_tree_connect_recv(struct tevent_req *req)
2429 return tevent_req_simple_recv_ntstatus(req);
2432 NTSTATUS cli_tree_connect(struct cli_state *cli, const char *share,
2433 const char *dev, const char *pass)
2435 struct tevent_context *ev;
2436 struct tevent_req *req;
2437 NTSTATUS status = NT_STATUS_NO_MEMORY;
2439 if (smbXcli_conn_has_async_calls(cli->conn)) {
2440 return NT_STATUS_INVALID_PARAMETER;
2442 ev = samba_tevent_context_init(talloc_tos());
2446 req = cli_tree_connect_send(ev, ev, cli, share, dev, pass);
2450 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2453 status = cli_tree_connect_recv(req);
2459 NTSTATUS cli_tree_connect_creds(struct cli_state *cli,
2460 const char *share, const char *dev,
2461 struct cli_credentials *creds)
2463 const char *pw = NULL;
2465 if (creds != NULL) {
2466 pw = cli_credentials_get_password(creds);
2469 return cli_tree_connect(cli, share, dev, pw);
2472 /****************************************************************************
2473 Send a tree disconnect.
2474 ****************************************************************************/
2476 struct cli_tdis_state {
2477 struct cli_state *cli;
2480 static void cli_tdis_done(struct tevent_req *subreq);
2482 static struct tevent_req *cli_tdis_send(TALLOC_CTX *mem_ctx,
2483 struct tevent_context *ev,
2484 struct cli_state *cli)
2486 struct tevent_req *req, *subreq;
2487 struct cli_tdis_state *state;
2489 req = tevent_req_create(mem_ctx, &state, struct cli_tdis_state);
2495 subreq = cli_smb_send(state, ev, cli, SMBtdis, 0, 0, 0, NULL, 0, NULL);
2496 if (tevent_req_nomem(subreq, req)) {
2497 return tevent_req_post(req, ev);
2499 tevent_req_set_callback(subreq, cli_tdis_done, req);
2503 static void cli_tdis_done(struct tevent_req *subreq)
2505 struct tevent_req *req = tevent_req_callback_data(
2506 subreq, struct tevent_req);
2507 struct cli_tdis_state *state = tevent_req_data(
2508 req, struct cli_tdis_state);
2511 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
2512 TALLOC_FREE(subreq);
2513 if (!NT_STATUS_IS_OK(status)) {
2514 tevent_req_nterror(req, status);
2517 TALLOC_FREE(state->cli->smb1.tcon);
2518 tevent_req_done(req);
2521 static NTSTATUS cli_tdis_recv(struct tevent_req *req)
2523 return tevent_req_simple_recv_ntstatus(req);
2526 NTSTATUS cli_tdis(struct cli_state *cli)
2528 struct tevent_context *ev;
2529 struct tevent_req *req;
2530 NTSTATUS status = NT_STATUS_NO_MEMORY;
2532 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
2533 status = smb2cli_tdis(cli->conn,
2537 if (NT_STATUS_IS_OK(status)) {
2538 TALLOC_FREE(cli->smb2.tcon);
2543 if (smbXcli_conn_has_async_calls(cli->conn)) {
2544 return NT_STATUS_INVALID_PARAMETER;
2546 ev = samba_tevent_context_init(talloc_tos());
2550 req = cli_tdis_send(ev, ev, cli);
2554 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2557 status = cli_tdis_recv(req);
2563 struct cli_connect_sock_state {
2564 const char **called_names;
2565 const char **calling_names;
2571 static void cli_connect_sock_done(struct tevent_req *subreq);
2574 * Async only if we don't have to look up the name, i.e. "pss" is set with a
2578 static struct tevent_req *cli_connect_sock_send(
2579 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2580 const char *host, int name_type, const struct sockaddr_storage *pss,
2581 const char *myname, uint16_t port)
2583 struct tevent_req *req, *subreq;
2584 struct cli_connect_sock_state *state;
2585 struct sockaddr_storage *addrs;
2586 unsigned i, num_addrs;
2589 req = tevent_req_create(mem_ctx, &state,
2590 struct cli_connect_sock_state);
2595 if ((pss == NULL) || is_zero_addr(pss)) {
2598 * Here we cheat. resolve_name_list is not async at all. So
2599 * this call will only be really async if the name lookup has
2600 * been done externally.
2603 status = resolve_name_list(state, host, name_type,
2604 &addrs, &num_addrs);
2605 if (!NT_STATUS_IS_OK(status)) {
2606 tevent_req_nterror(req, status);
2607 return tevent_req_post(req, ev);
2610 addrs = talloc_array(state, struct sockaddr_storage, 1);
2611 if (tevent_req_nomem(addrs, req)) {
2612 return tevent_req_post(req, ev);
2618 state->called_names = talloc_array(state, const char *, num_addrs);
2619 if (tevent_req_nomem(state->called_names, req)) {
2620 return tevent_req_post(req, ev);
2622 state->called_types = talloc_array(state, int, num_addrs);
2623 if (tevent_req_nomem(state->called_types, req)) {
2624 return tevent_req_post(req, ev);
2626 state->calling_names = talloc_array(state, const char *, num_addrs);
2627 if (tevent_req_nomem(state->calling_names, req)) {
2628 return tevent_req_post(req, ev);
2630 for (i=0; i<num_addrs; i++) {
2631 state->called_names[i] = host;
2632 state->called_types[i] = name_type;
2633 state->calling_names[i] = myname;
2636 subreq = smbsock_any_connect_send(
2637 state, ev, addrs, state->called_names, state->called_types,
2638 state->calling_names, NULL, num_addrs, port);
2639 if (tevent_req_nomem(subreq, req)) {
2640 return tevent_req_post(req, ev);
2642 tevent_req_set_callback(subreq, cli_connect_sock_done, req);
2646 static void cli_connect_sock_done(struct tevent_req *subreq)
2648 struct tevent_req *req = tevent_req_callback_data(
2649 subreq, struct tevent_req);
2650 struct cli_connect_sock_state *state = tevent_req_data(
2651 req, struct cli_connect_sock_state);
2654 status = smbsock_any_connect_recv(subreq, &state->fd, NULL,
2656 TALLOC_FREE(subreq);
2657 if (tevent_req_nterror(req, status)) {
2660 set_socket_options(state->fd, lp_socket_options());
2661 tevent_req_done(req);
2664 static NTSTATUS cli_connect_sock_recv(struct tevent_req *req,
2665 int *pfd, uint16_t *pport)
2667 struct cli_connect_sock_state *state = tevent_req_data(
2668 req, struct cli_connect_sock_state);
2671 if (tevent_req_is_nterror(req, &status)) {
2675 *pport = state->port;
2676 return NT_STATUS_OK;
2679 struct cli_connect_nb_state {
2680 const char *desthost;
2683 struct cli_state *cli;
2686 static void cli_connect_nb_done(struct tevent_req *subreq);
2688 static struct tevent_req *cli_connect_nb_send(
2689 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2690 const char *host, const struct sockaddr_storage *dest_ss,
2691 uint16_t port, int name_type, const char *myname,
2692 int signing_state, int flags)
2694 struct tevent_req *req, *subreq;
2695 struct cli_connect_nb_state *state;
2697 req = tevent_req_create(mem_ctx, &state, struct cli_connect_nb_state);
2701 state->signing_state = signing_state;
2702 state->flags = flags;
2705 char *p = strchr(host, '#');
2708 name_type = strtol(p+1, NULL, 16);
2709 host = talloc_strndup(state, host, p - host);
2710 if (tevent_req_nomem(host, req)) {
2711 return tevent_req_post(req, ev);
2715 state->desthost = host;
2716 } else if (dest_ss != NULL) {
2717 state->desthost = print_canonical_sockaddr(state, dest_ss);
2718 if (tevent_req_nomem(state->desthost, req)) {
2719 return tevent_req_post(req, ev);
2722 /* No host or dest_ss given. Error out. */
2723 tevent_req_error(req, EINVAL);
2724 return tevent_req_post(req, ev);
2727 subreq = cli_connect_sock_send(state, ev, host, name_type, dest_ss,
2729 if (tevent_req_nomem(subreq, req)) {
2730 return tevent_req_post(req, ev);
2732 tevent_req_set_callback(subreq, cli_connect_nb_done, req);
2736 static void cli_connect_nb_done(struct tevent_req *subreq)
2738 struct tevent_req *req = tevent_req_callback_data(
2739 subreq, struct tevent_req);
2740 struct cli_connect_nb_state *state = tevent_req_data(
2741 req, struct cli_connect_nb_state);
2746 status = cli_connect_sock_recv(subreq, &fd, &port);
2747 TALLOC_FREE(subreq);
2748 if (tevent_req_nterror(req, status)) {
2752 state->cli = cli_state_create(state, fd, state->desthost,
2753 state->signing_state, state->flags);
2754 if (tevent_req_nomem(state->cli, req)) {
2758 tevent_req_done(req);
2761 static NTSTATUS cli_connect_nb_recv(struct tevent_req *req,
2762 struct cli_state **pcli)
2764 struct cli_connect_nb_state *state = tevent_req_data(
2765 req, struct cli_connect_nb_state);
2768 if (tevent_req_is_nterror(req, &status)) {
2771 *pcli = talloc_move(NULL, &state->cli);
2772 return NT_STATUS_OK;
2775 NTSTATUS cli_connect_nb(const char *host, const struct sockaddr_storage *dest_ss,
2776 uint16_t port, int name_type, const char *myname,
2777 int signing_state, int flags, struct cli_state **pcli)
2779 struct tevent_context *ev;
2780 struct tevent_req *req;
2781 NTSTATUS status = NT_STATUS_NO_MEMORY;
2783 ev = samba_tevent_context_init(talloc_tos());
2787 req = cli_connect_nb_send(ev, ev, host, dest_ss, port, name_type,
2788 myname, signing_state, flags);
2792 if (!tevent_req_set_endtime(req, ev, timeval_current_ofs(20, 0))) {
2795 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2798 status = cli_connect_nb_recv(req, pcli);
2804 struct cli_start_connection_state {
2805 struct tevent_context *ev;
2806 struct cli_state *cli;
2811 static void cli_start_connection_connected(struct tevent_req *subreq);
2812 static void cli_start_connection_done(struct tevent_req *subreq);
2815 establishes a connection to after the negprot.
2816 @param output_cli A fully initialised cli structure, non-null only on success
2817 @param dest_host The netbios name of the remote host
2818 @param dest_ss (optional) The the destination IP, NULL for name based lookup
2819 @param port (optional) The destination port (0 for default)
2822 static struct tevent_req *cli_start_connection_send(
2823 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2824 const char *my_name, const char *dest_host,
2825 const struct sockaddr_storage *dest_ss, int port,
2826 int signing_state, int flags)
2828 struct tevent_req *req, *subreq;
2829 struct cli_start_connection_state *state;
2831 req = tevent_req_create(mem_ctx, &state,
2832 struct cli_start_connection_state);
2838 if (signing_state == SMB_SIGNING_IPC_DEFAULT) {
2839 state->min_protocol = lp_client_ipc_min_protocol();
2840 state->max_protocol = lp_client_ipc_max_protocol();
2842 state->min_protocol = lp_client_min_protocol();
2843 state->max_protocol = lp_client_max_protocol();
2846 if (flags & CLI_FULL_CONNECTION_FORCE_SMB1) {
2847 state->max_protocol = MIN(state->max_protocol, PROTOCOL_NT1);
2850 if (flags & CLI_FULL_CONNECTION_DISABLE_SMB1) {
2851 state->min_protocol = MAX(state->max_protocol, PROTOCOL_SMB2_02);
2852 state->max_protocol = MAX(state->max_protocol, PROTOCOL_LATEST);
2855 subreq = cli_connect_nb_send(state, ev, dest_host, dest_ss, port,
2856 0x20, my_name, signing_state, flags);
2857 if (tevent_req_nomem(subreq, req)) {
2858 return tevent_req_post(req, ev);
2860 tevent_req_set_callback(subreq, cli_start_connection_connected, req);
2864 static void cli_start_connection_connected(struct tevent_req *subreq)
2866 struct tevent_req *req = tevent_req_callback_data(
2867 subreq, struct tevent_req);
2868 struct cli_start_connection_state *state = tevent_req_data(
2869 req, struct cli_start_connection_state);
2872 status = cli_connect_nb_recv(subreq, &state->cli);
2873 TALLOC_FREE(subreq);
2874 if (tevent_req_nterror(req, status)) {
2878 subreq = smbXcli_negprot_send(state, state->ev, state->cli->conn,
2879 state->cli->timeout,
2880 state->min_protocol,
2881 state->max_protocol,
2882 WINDOWS_CLIENT_PURE_SMB2_NEGPROT_INITIAL_CREDIT_ASK);
2883 if (tevent_req_nomem(subreq, req)) {
2886 tevent_req_set_callback(subreq, cli_start_connection_done, req);
2889 static void cli_start_connection_done(struct tevent_req *subreq)
2891 struct tevent_req *req = tevent_req_callback_data(
2892 subreq, struct tevent_req);
2893 struct cli_start_connection_state *state = tevent_req_data(
2894 req, struct cli_start_connection_state);
2897 status = smbXcli_negprot_recv(subreq);
2898 TALLOC_FREE(subreq);
2899 if (tevent_req_nterror(req, status)) {
2903 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
2904 /* Ensure we ask for some initial credits. */
2905 smb2cli_conn_set_max_credits(state->cli->conn,
2906 DEFAULT_SMB2_MAX_CREDITS);
2909 tevent_req_done(req);
2912 static NTSTATUS cli_start_connection_recv(struct tevent_req *req,
2913 struct cli_state **output_cli)
2915 struct cli_start_connection_state *state = tevent_req_data(
2916 req, struct cli_start_connection_state);
2919 if (tevent_req_is_nterror(req, &status)) {
2922 *output_cli = state->cli;
2924 return NT_STATUS_OK;
2927 NTSTATUS cli_start_connection(struct cli_state **output_cli,
2928 const char *my_name,
2929 const char *dest_host,
2930 const struct sockaddr_storage *dest_ss, int port,
2931 int signing_state, int flags)
2933 struct tevent_context *ev;
2934 struct tevent_req *req;
2935 NTSTATUS status = NT_STATUS_NO_MEMORY;
2937 ev = samba_tevent_context_init(talloc_tos());
2941 req = cli_start_connection_send(ev, ev, my_name, dest_host, dest_ss,
2942 port, signing_state, flags);
2946 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2949 status = cli_start_connection_recv(req, output_cli);
2955 struct cli_smb1_setup_encryption_blob_state {
2960 uint16_t enc_ctx_id;
2963 static void cli_smb1_setup_encryption_blob_done(struct tevent_req *subreq);
2965 static struct tevent_req *cli_smb1_setup_encryption_blob_send(TALLOC_CTX *mem_ctx,
2966 struct tevent_context *ev,
2967 struct cli_state *cli,
2970 struct tevent_req *req = NULL;
2971 struct cli_smb1_setup_encryption_blob_state *state = NULL;
2972 struct tevent_req *subreq = NULL;
2974 req = tevent_req_create(mem_ctx, &state,
2975 struct cli_smb1_setup_encryption_blob_state);
2980 if (in.length > CLI_BUFFER_SIZE) {
2981 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
2982 return tevent_req_post(req, ev);
2985 SSVAL(state->setup+0, 0, TRANSACT2_SETFSINFO);
2986 SSVAL(state->param, 0, 0);
2987 SSVAL(state->param, 2, SMB_REQUEST_TRANSPORT_ENCRYPTION);
2989 subreq = smb1cli_trans_send(state, ev, cli->conn,
2997 NULL, /* pipe_name */
3003 in.data, in.length, CLI_BUFFER_SIZE);
3004 if (tevent_req_nomem(subreq, req)) {
3005 return tevent_req_post(req, ev);
3007 tevent_req_set_callback(subreq,
3008 cli_smb1_setup_encryption_blob_done,
3014 static void cli_smb1_setup_encryption_blob_done(struct tevent_req *subreq)
3016 struct tevent_req *req =
3017 tevent_req_callback_data(subreq,
3019 struct cli_smb1_setup_encryption_blob_state *state =
3020 tevent_req_data(req,
3021 struct cli_smb1_setup_encryption_blob_state);
3022 uint8_t *rparam=NULL, *rdata=NULL;
3023 uint32_t num_rparam, num_rdata;
3026 status = smb1cli_trans_recv(subreq, state,
3027 NULL, /* recv_flags */
3028 NULL, 0, NULL, /* rsetup */
3029 &rparam, 0, &num_rparam,
3030 &rdata, 0, &num_rdata);
3031 TALLOC_FREE(subreq);
3032 state->status = status;
3033 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
3034 status = NT_STATUS_OK;
3036 if (tevent_req_nterror(req, status)) {
3040 if (num_rparam == 2) {
3041 state->enc_ctx_id = SVAL(rparam, 0);
3043 TALLOC_FREE(rparam);
3045 state->out = data_blob_const(rdata, num_rdata);
3047 tevent_req_done(req);
3050 static NTSTATUS cli_smb1_setup_encryption_blob_recv(struct tevent_req *req,
3051 TALLOC_CTX *mem_ctx,
3053 uint16_t *enc_ctx_id)
3055 struct cli_smb1_setup_encryption_blob_state *state =
3056 tevent_req_data(req,
3057 struct cli_smb1_setup_encryption_blob_state);
3060 if (tevent_req_is_nterror(req, &status)) {
3061 tevent_req_received(req);
3065 status = state->status;
3068 talloc_steal(mem_ctx, out->data);
3070 *enc_ctx_id = state->enc_ctx_id;
3072 tevent_req_received(req);
3076 struct cli_smb1_setup_encryption_state {
3077 struct tevent_context *ev;
3078 struct cli_state *cli;
3079 struct smb_trans_enc_state *es;
3086 static void cli_smb1_setup_encryption_local_next(struct tevent_req *req);
3087 static void cli_smb1_setup_encryption_local_done(struct tevent_req *subreq);
3088 static void cli_smb1_setup_encryption_remote_next(struct tevent_req *req);
3089 static void cli_smb1_setup_encryption_remote_done(struct tevent_req *subreq);
3090 static void cli_smb1_setup_encryption_ready(struct tevent_req *req);
3092 static struct tevent_req *cli_smb1_setup_encryption_send(TALLOC_CTX *mem_ctx,
3093 struct tevent_context *ev,
3094 struct cli_state *cli,
3095 struct cli_credentials *creds)
3097 struct tevent_req *req = NULL;
3098 struct cli_smb1_setup_encryption_state *state = NULL;
3099 struct auth_generic_state *ags = NULL;
3100 const DATA_BLOB *b = NULL;
3101 bool auth_requested = false;
3102 const char *target_service = NULL;
3103 const char *target_hostname = NULL;
3106 req = tevent_req_create(mem_ctx, &state,
3107 struct cli_smb1_setup_encryption_state);
3114 auth_requested = cli_credentials_authentication_requested(creds);
3115 if (!auth_requested) {
3116 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
3117 return tevent_req_post(req, ev);
3120 target_service = "cifs";
3121 target_hostname = smbXcli_conn_remote_name(cli->conn);
3123 status = cli_session_creds_prepare_krb5(cli, creds);
3124 if (tevent_req_nterror(req, status)) {
3125 return tevent_req_post(req, ev);
3128 state->es = talloc_zero(state, struct smb_trans_enc_state);
3129 if (tevent_req_nomem(state->es, req)) {
3130 return tevent_req_post(req, ev);
3133 status = auth_generic_client_prepare(state->es, &ags);
3134 if (tevent_req_nterror(req, status)) {
3135 return tevent_req_post(req, ev);
3138 gensec_want_feature(ags->gensec_security,
3139 GENSEC_FEATURE_SIGN);
3140 gensec_want_feature(ags->gensec_security,
3141 GENSEC_FEATURE_SEAL);
3143 status = auth_generic_set_creds(ags, creds);
3144 if (tevent_req_nterror(req, status)) {
3145 return tevent_req_post(req, ev);
3148 if (target_service != NULL) {
3149 status = gensec_set_target_service(ags->gensec_security,
3151 if (tevent_req_nterror(req, status)) {
3152 return tevent_req_post(req, ev);
3156 if (target_hostname != NULL) {
3157 status = gensec_set_target_hostname(ags->gensec_security,
3159 if (tevent_req_nterror(req, status)) {
3160 return tevent_req_post(req, ev);
3164 gensec_set_max_update_size(ags->gensec_security,
3167 b = smbXcli_conn_server_gss_blob(state->cli->conn);
3169 state->blob_in = *b;
3172 status = auth_generic_client_start(ags, GENSEC_OID_SPNEGO);
3173 if (tevent_req_nterror(req, status)) {
3174 return tevent_req_post(req, ev);
3178 * We only need the gensec_security part from here.
3180 state->es->gensec_security = talloc_move(state->es,
3181 &ags->gensec_security);
3184 cli_smb1_setup_encryption_local_next(req);
3185 if (!tevent_req_is_in_progress(req)) {
3186 return tevent_req_post(req, ev);
3192 static void cli_smb1_setup_encryption_local_next(struct tevent_req *req)
3194 struct cli_smb1_setup_encryption_state *state =
3195 tevent_req_data(req,
3196 struct cli_smb1_setup_encryption_state);
3197 struct tevent_req *subreq = NULL;
3199 if (state->local_ready) {
3200 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3204 subreq = gensec_update_send(state, state->ev,
3205 state->es->gensec_security,
3207 if (tevent_req_nomem(subreq, req)) {
3210 tevent_req_set_callback(subreq, cli_smb1_setup_encryption_local_done, req);
3213 static void cli_smb1_setup_encryption_local_done(struct tevent_req *subreq)
3215 struct tevent_req *req =
3216 tevent_req_callback_data(subreq,
3218 struct cli_smb1_setup_encryption_state *state =
3219 tevent_req_data(req,
3220 struct cli_smb1_setup_encryption_state);
3223 status = gensec_update_recv(subreq, state, &state->blob_out);
3224 TALLOC_FREE(subreq);
3225 state->blob_in = data_blob_null;
3226 if (!NT_STATUS_IS_OK(status) &&
3227 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
3229 tevent_req_nterror(req, status);
3233 if (NT_STATUS_IS_OK(status)) {
3234 state->local_ready = true;
3238 * We always get NT_STATUS_OK from the server even if it is not ready.
3239 * So guess the server is ready when we are ready and already sent
3240 * our last blob to the server.
3242 if (state->local_ready && state->blob_out.length == 0) {
3243 state->remote_ready = true;
3246 if (state->local_ready && state->remote_ready) {
3247 cli_smb1_setup_encryption_ready(req);
3251 cli_smb1_setup_encryption_remote_next(req);
3254 static void cli_smb1_setup_encryption_remote_next(struct tevent_req *req)
3256 struct cli_smb1_setup_encryption_state *state =
3257 tevent_req_data(req,
3258 struct cli_smb1_setup_encryption_state);
3259 struct tevent_req *subreq = NULL;
3261 if (state->remote_ready) {
3262 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3266 subreq = cli_smb1_setup_encryption_blob_send(state, state->ev,
3267 state->cli, state->blob_out);
3268 if (tevent_req_nomem(subreq, req)) {
3271 tevent_req_set_callback(subreq,
3272 cli_smb1_setup_encryption_remote_done,
3276 static void cli_smb1_setup_encryption_remote_done(struct tevent_req *subreq)
3278 struct tevent_req *req =
3279 tevent_req_callback_data(subreq,
3281 struct cli_smb1_setup_encryption_state *state =
3282 tevent_req_data(req,
3283 struct cli_smb1_setup_encryption_state);
3286 status = cli_smb1_setup_encryption_blob_recv(subreq, state,
3288 &state->es->enc_ctx_num);
3289 TALLOC_FREE(subreq);
3290 data_blob_free(&state->blob_out);
3291 if (!NT_STATUS_IS_OK(status) &&
3292 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
3294 tevent_req_nterror(req, status);
3299 * We always get NT_STATUS_OK even if the server is not ready.
3300 * So guess the server is ready when we are ready and sent
3301 * our last blob to the server.
3303 if (state->local_ready) {
3304 state->remote_ready = true;
3307 if (state->local_ready && state->remote_ready) {
3308 cli_smb1_setup_encryption_ready(req);
3312 cli_smb1_setup_encryption_local_next(req);
3315 static void cli_smb1_setup_encryption_ready(struct tevent_req *req)
3317 struct cli_smb1_setup_encryption_state *state =
3318 tevent_req_data(req,
3319 struct cli_smb1_setup_encryption_state);
3320 struct smb_trans_enc_state *es = NULL;
3322 if (state->blob_in.length != 0) {
3323 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3327 if (state->blob_out.length != 0) {
3328 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3332 es = talloc_move(state->cli->conn, &state->es);
3334 smb1cli_conn_set_encryption(state->cli->conn, es);
3337 tevent_req_done(req);
3340 static NTSTATUS cli_smb1_setup_encryption_recv(struct tevent_req *req)
3342 return tevent_req_simple_recv_ntstatus(req);
3345 NTSTATUS cli_smb1_setup_encryption(struct cli_state *cli,
3346 struct cli_credentials *creds)
3348 struct tevent_context *ev = NULL;
3349 struct tevent_req *req = NULL;
3350 NTSTATUS status = NT_STATUS_NO_MEMORY;
3352 ev = samba_tevent_context_init(talloc_tos());
3356 req = cli_smb1_setup_encryption_send(ev, ev, cli, creds);
3360 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
3363 status = cli_smb1_setup_encryption_recv(req);
3370 establishes a connection right up to doing tconX, password specified.
3371 @param output_cli A fully initialised cli structure, non-null only on success
3372 @param dest_host The netbios name of the remote host
3373 @param dest_ip (optional) The the destination IP, NULL for name based lookup
3374 @param port (optional) The destination port (0 for default)
3375 @param service (optional) The share to make the connection to. Should be 'unqualified' in any way.
3376 @param service_type The 'type' of serivice.
3377 @param creds The used user credentials
3380 struct cli_full_connection_creds_state {
3381 struct tevent_context *ev;
3382 const char *service;
3383 const char *service_type;
3384 struct cli_credentials *creds;
3386 struct cli_state *cli;
3389 static int cli_full_connection_creds_state_destructor(
3390 struct cli_full_connection_creds_state *s)
3392 if (s->cli != NULL) {
3393 cli_shutdown(s->cli);
3399 static void cli_full_connection_creds_conn_done(struct tevent_req *subreq);
3400 static void cli_full_connection_creds_sess_start(struct tevent_req *req);
3401 static void cli_full_connection_creds_sess_done(struct tevent_req *subreq);
3402 static void cli_full_connection_creds_tcon_start(struct tevent_req *req);
3403 static void cli_full_connection_creds_tcon_done(struct tevent_req *subreq);
3405 struct tevent_req *cli_full_connection_creds_send(
3406 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
3407 const char *my_name, const char *dest_host,
3408 const struct sockaddr_storage *dest_ss, int port,
3409 const char *service, const char *service_type,
3410 struct cli_credentials *creds,
3411 int flags, int signing_state)
3413 struct tevent_req *req, *subreq;
3414 struct cli_full_connection_creds_state *state;
3415 enum credentials_use_kerberos krb5_state;
3416 uint32_t gensec_features = 0;
3418 req = tevent_req_create(mem_ctx, &state,
3419 struct cli_full_connection_creds_state);
3423 talloc_set_destructor(state, cli_full_connection_creds_state_destructor);
3425 flags &= ~CLI_FULL_CONNECTION_USE_KERBEROS;
3426 flags &= ~CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS;
3427 flags &= ~CLI_FULL_CONNECTION_USE_CCACHE;
3428 flags &= ~CLI_FULL_CONNECTION_USE_NT_HASH;
3430 krb5_state = cli_credentials_get_kerberos_state(creds);
3431 switch (krb5_state) {
3432 case CRED_MUST_USE_KERBEROS:
3433 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
3434 flags &= ~CLI_FULL_CONNECTION_DONT_SPNEGO;
3436 case CRED_AUTO_USE_KERBEROS:
3437 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
3438 flags |= CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS;
3440 case CRED_DONT_USE_KERBEROS:
3444 gensec_features = cli_credentials_get_gensec_features(creds);
3445 if (gensec_features & GENSEC_FEATURE_NTLM_CCACHE) {
3446 flags |= CLI_FULL_CONNECTION_USE_CCACHE;
3450 state->service = service;
3451 state->service_type = service_type;
3452 state->creds = creds;
3453 state->flags = flags;
3455 subreq = cli_start_connection_send(
3456 state, ev, my_name, dest_host, dest_ss, port,
3457 signing_state, flags);
3458 if (tevent_req_nomem(subreq, req)) {
3459 return tevent_req_post(req, ev);
3461 tevent_req_set_callback(subreq,
3462 cli_full_connection_creds_conn_done,
3467 static void cli_full_connection_creds_conn_done(struct tevent_req *subreq)
3469 struct tevent_req *req = tevent_req_callback_data(
3470 subreq, struct tevent_req);
3471 struct cli_full_connection_creds_state *state = tevent_req_data(
3472 req, struct cli_full_connection_creds_state);
3475 status = cli_start_connection_recv(subreq, &state->cli);
3476 TALLOC_FREE(subreq);
3477 if (tevent_req_nterror(req, status)) {
3481 cli_full_connection_creds_sess_start(req);
3484 static void cli_full_connection_creds_sess_start(struct tevent_req *req)
3486 struct cli_full_connection_creds_state *state = tevent_req_data(
3487 req, struct cli_full_connection_creds_state);
3488 struct tevent_req *subreq = NULL;
3490 subreq = cli_session_setup_creds_send(
3491 state, state->ev, state->cli, state->creds);
3492 if (tevent_req_nomem(subreq, req)) {
3495 tevent_req_set_callback(subreq,
3496 cli_full_connection_creds_sess_done,
3500 static void cli_full_connection_creds_sess_done(struct tevent_req *subreq)
3502 struct tevent_req *req = tevent_req_callback_data(
3503 subreq, struct tevent_req);
3504 struct cli_full_connection_creds_state *state = tevent_req_data(
3505 req, struct cli_full_connection_creds_state);
3508 status = cli_session_setup_creds_recv(subreq);
3509 TALLOC_FREE(subreq);
3511 if (!NT_STATUS_IS_OK(status) &&
3512 (state->flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)) {
3514 state->flags &= ~CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
3516 state->creds = cli_credentials_init_anon(state);
3517 if (tevent_req_nomem(state->creds, req)) {
3521 cli_full_connection_creds_sess_start(req);
3525 if (tevent_req_nterror(req, status)) {
3529 cli_full_connection_creds_tcon_start(req);
3532 static void cli_full_connection_creds_tcon_start(struct tevent_req *req)
3534 struct cli_full_connection_creds_state *state = tevent_req_data(
3535 req, struct cli_full_connection_creds_state);
3536 struct tevent_req *subreq = NULL;
3537 const char *password = NULL;
3539 if (state->service == NULL) {
3540 tevent_req_done(req);
3544 password = cli_credentials_get_password(state->creds);
3546 subreq = cli_tree_connect_send(state, state->ev,
3549 state->service_type,
3551 if (tevent_req_nomem(subreq, req)) {
3554 tevent_req_set_callback(subreq,
3555 cli_full_connection_creds_tcon_done,
3559 static void cli_full_connection_creds_tcon_done(struct tevent_req *subreq)
3561 struct tevent_req *req = tevent_req_callback_data(
3562 subreq, struct tevent_req);
3565 status = cli_tree_connect_recv(subreq);
3566 TALLOC_FREE(subreq);
3567 if (tevent_req_nterror(req, status)) {
3571 tevent_req_done(req);
3574 NTSTATUS cli_full_connection_creds_recv(struct tevent_req *req,
3575 struct cli_state **output_cli)
3577 struct cli_full_connection_creds_state *state = tevent_req_data(
3578 req, struct cli_full_connection_creds_state);
3581 if (tevent_req_is_nterror(req, &status)) {
3584 *output_cli = state->cli;
3585 talloc_set_destructor(state, NULL);
3586 return NT_STATUS_OK;
3589 NTSTATUS cli_full_connection_creds(struct cli_state **output_cli,
3590 const char *my_name,
3591 const char *dest_host,
3592 const struct sockaddr_storage *dest_ss, int port,
3593 const char *service, const char *service_type,
3594 struct cli_credentials *creds,
3598 struct tevent_context *ev;
3599 struct tevent_req *req;
3600 NTSTATUS status = NT_STATUS_NO_MEMORY;
3602 ev = samba_tevent_context_init(talloc_tos());
3606 req = cli_full_connection_creds_send(
3607 ev, ev, my_name, dest_host, dest_ss, port, service,
3608 service_type, creds, flags, signing_state);
3612 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
3615 status = cli_full_connection_creds_recv(req, output_cli);
3621 NTSTATUS cli_full_connection(struct cli_state **output_cli,
3622 const char *my_name,
3623 const char *dest_host,
3624 const struct sockaddr_storage *dest_ss, int port,
3625 const char *service, const char *service_type,
3626 const char *user, const char *domain,
3627 const char *password, int flags,
3630 TALLOC_CTX *frame = talloc_stackframe();
3632 bool use_kerberos = false;
3633 bool fallback_after_kerberos = false;
3634 bool use_ccache = false;
3635 bool pw_nt_hash = false;
3636 struct cli_credentials *creds = NULL;
3638 if (flags & CLI_FULL_CONNECTION_USE_KERBEROS) {
3639 use_kerberos = true;
3642 if (flags & CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS) {
3643 fallback_after_kerberos = true;
3646 if (flags & CLI_FULL_CONNECTION_USE_CCACHE) {
3650 if (flags & CLI_FULL_CONNECTION_USE_NT_HASH) {
3654 creds = cli_session_creds_init(frame,
3657 NULL, /* realm (use default) */
3660 fallback_after_kerberos,
3663 if (creds == NULL) {
3665 return NT_STATUS_NO_MEMORY;
3668 status = cli_full_connection_creds(output_cli, my_name,
3669 dest_host, dest_ss, port,
3670 service, service_type,
3671 creds, flags, signing_state);
3672 if (!NT_STATUS_IS_OK(status)) {
3678 return NT_STATUS_OK;
3681 /****************************************************************************
3682 Send an old style tcon.
3683 ****************************************************************************/
3684 struct cli_raw_tcon_state {
3688 static void cli_raw_tcon_done(struct tevent_req *subreq);
3690 static struct tevent_req *cli_raw_tcon_send(
3691 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
3692 const char *service, const char *pass, const char *dev)
3694 struct tevent_req *req, *subreq;
3695 struct cli_raw_tcon_state *state;
3698 req = tevent_req_create(mem_ctx, &state, struct cli_raw_tcon_state);
3703 if (!lp_client_plaintext_auth() && (*pass)) {
3704 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
3705 " or 'client ntlmv2 auth = yes'\n"));
3706 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
3707 return tevent_req_post(req, ev);
3710 TALLOC_FREE(cli->smb1.tcon);
3711 cli->smb1.tcon = smbXcli_tcon_create(cli);
3712 if (tevent_req_nomem(cli->smb1.tcon, req)) {
3713 return tevent_req_post(req, ev);
3715 smb1cli_tcon_set_id(cli->smb1.tcon, UINT16_MAX);
3717 bytes = talloc_array(state, uint8_t, 0);
3718 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3719 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3720 service, strlen(service)+1, NULL);
3721 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3722 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3723 pass, strlen(pass)+1, NULL);
3724 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3725 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3726 dev, strlen(dev)+1, NULL);
3728 if (tevent_req_nomem(bytes, req)) {
3729 return tevent_req_post(req, ev);
3732 subreq = cli_smb_send(state, ev, cli, SMBtcon, 0, 0, 0, NULL,
3733 talloc_get_size(bytes), bytes);
3734 if (tevent_req_nomem(subreq, req)) {
3735 return tevent_req_post(req, ev);
3737 tevent_req_set_callback(subreq, cli_raw_tcon_done, req);
3741 static void cli_raw_tcon_done(struct tevent_req *subreq)
3743 struct tevent_req *req = tevent_req_callback_data(
3744 subreq, struct tevent_req);
3745 struct cli_raw_tcon_state *state = tevent_req_data(
3746 req, struct cli_raw_tcon_state);
3749 status = cli_smb_recv(subreq, state, NULL, 2, NULL, &state->ret_vwv,
3751 TALLOC_FREE(subreq);
3752 if (tevent_req_nterror(req, status)) {
3755 tevent_req_done(req);
3758 static NTSTATUS cli_raw_tcon_recv(struct tevent_req *req,
3759 uint16_t *max_xmit, uint16_t *tid)
3761 struct cli_raw_tcon_state *state = tevent_req_data(
3762 req, struct cli_raw_tcon_state);
3765 if (tevent_req_is_nterror(req, &status)) {
3768 *max_xmit = SVAL(state->ret_vwv + 0, 0);
3769 *tid = SVAL(state->ret_vwv + 1, 0);
3770 return NT_STATUS_OK;
3773 NTSTATUS cli_raw_tcon(struct cli_state *cli,
3774 const char *service, const char *pass, const char *dev,
3775 uint16_t *max_xmit, uint16_t *tid)
3777 struct tevent_context *ev;
3778 struct tevent_req *req;
3779 NTSTATUS status = NT_STATUS_NO_MEMORY;
3781 ev = samba_tevent_context_init(talloc_tos());
3785 req = cli_raw_tcon_send(ev, ev, cli, service, pass, dev);
3789 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
3792 status = cli_raw_tcon_recv(req, max_xmit, tid);
3798 /* Return a cli_state pointing at the IPC$ share for the given server */
3800 struct cli_state *get_ipc_connect(char *server,
3801 struct sockaddr_storage *server_ss,
3802 const struct user_auth_info *user_info)
3804 struct cli_state *cli;
3806 uint32_t flags = CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
3808 if (get_cmdline_auth_info_use_kerberos(user_info)) {
3809 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
3812 flags |= CLI_FULL_CONNECTION_FORCE_SMB1;
3814 nt_status = cli_full_connection(&cli, NULL, server, server_ss, 0, "IPC$", "IPC",
3815 get_cmdline_auth_info_username(user_info),
3817 get_cmdline_auth_info_password(user_info),
3819 SMB_SIGNING_DEFAULT);
3821 if (NT_STATUS_IS_OK(nt_status)) {
3823 } else if (is_ipaddress(server)) {
3824 /* windows 9* needs a correct NMB name for connections */
3825 fstring remote_name;
3827 if (name_status_find("*", 0, 0, server_ss, remote_name)) {
3828 cli = get_ipc_connect(remote_name, server_ss, user_info);
3837 * Given the IP address of a master browser on the network, return its
3838 * workgroup and connect to it.
3840 * This function is provided to allow additional processing beyond what
3841 * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
3842 * browsers and obtain each master browsers' list of domains (in case the
3843 * first master browser is recently on the network and has not yet
3844 * synchronized with other master browsers and therefore does not yet have the
3845 * entire network browse list)
3848 struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx,
3849 struct sockaddr_storage *mb_ip,
3850 const struct user_auth_info *user_info,
3851 char **pp_workgroup_out)
3853 char addr[INET6_ADDRSTRLEN];
3855 struct cli_state *cli;
3856 struct sockaddr_storage server_ss;
3858 *pp_workgroup_out = NULL;
3860 print_sockaddr(addr, sizeof(addr), mb_ip);
3861 DEBUG(99, ("Looking up name of master browser %s\n",
3865 * Do a name status query to find out the name of the master browser.
3866 * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
3867 * master browser will not respond to a wildcard query (or, at least,
3868 * an NT4 server acting as the domain master browser will not).
3870 * We might be able to use ONLY the query on MSBROWSE, but that's not
3871 * yet been tested with all Windows versions, so until it is, leave
3872 * the original wildcard query as the first choice and fall back to
3873 * MSBROWSE if the wildcard query fails.
3875 if (!name_status_find("*", 0, 0x1d, mb_ip, name) &&
3876 !name_status_find(MSBROWSE, 1, 0x1d, mb_ip, name)) {
3878 DEBUG(99, ("Could not retrieve name status for %s\n",
3883 if (!find_master_ip(name, &server_ss)) {
3884 DEBUG(99, ("Could not find master ip for %s\n", name));
3888 *pp_workgroup_out = talloc_strdup(ctx, name);
3890 DEBUG(4, ("found master browser %s, %s\n", name, addr));
3892 print_sockaddr(addr, sizeof(addr), &server_ss);
3893 cli = get_ipc_connect(addr, &server_ss, user_info);
3899 * Return the IP address and workgroup of a master browser on the network, and
3903 struct cli_state *get_ipc_connect_master_ip_bcast(TALLOC_CTX *ctx,
3904 const struct user_auth_info *user_info,
3905 char **pp_workgroup_out)
3907 struct sockaddr_storage *ip_list;
3908 struct cli_state *cli;
3912 *pp_workgroup_out = NULL;
3914 DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
3916 /* Go looking for workgroups by broadcasting on the local network */
3918 status = name_resolve_bcast(MSBROWSE, 1, talloc_tos(),
3920 if (!NT_STATUS_IS_OK(status)) {
3921 DEBUG(99, ("No master browsers responded: %s\n",
3922 nt_errstr(status)));
3926 for (i = 0; i < count; i++) {
3927 char addr[INET6_ADDRSTRLEN];
3928 print_sockaddr(addr, sizeof(addr), &ip_list[i]);
3929 DEBUG(99, ("Found master browser %s\n", addr));
3931 cli = get_ipc_connect_master_ip(ctx, &ip_list[i],
3932 user_info, pp_workgroup_out);