2 Unix SMB/CIFS implementation.
3 client connect/disconnect routines
4 Copyright (C) Andrew Tridgell 1994-1998
5 Copyright (C) Andrew Bartlett 2001-2003
6 Copyright (C) Volker Lendecke 2011
7 Copyright (C) Jeremy Allison 2011
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "libsmb/libsmb.h"
25 #include "auth_info.h"
26 #include "../libcli/auth/libcli_auth.h"
27 #include "../libcli/auth/spnego.h"
29 #include "auth/credentials/credentials.h"
30 #include "auth/gensec/gensec.h"
31 #include "auth/ntlmssp/ntlmssp.h"
32 #include "auth_generic.h"
33 #include "libads/kerberos_proto.h"
35 #include "../lib/util/tevent_ntstatus.h"
36 #include "async_smb.h"
37 #include "libsmb/nmblib.h"
38 #include "librpc/ndr/libndr.h"
39 #include "../libcli/smb/smbXcli_base.h"
40 #include "../libcli/smb/smb_seal.h"
41 #include "lib/param/param.h"
42 #include "../libcli/smb/smb2_negotiate_context.h"
44 #define STAR_SMBSERVER "*SMBSERVER"
46 static char *cli_session_setup_get_account(TALLOC_CTX *mem_ctx,
47 const char *principal);
49 struct cli_credentials *cli_session_creds_init(TALLOC_CTX *mem_ctx,
55 bool fallback_after_kerberos,
57 bool password_is_nt_hash)
59 struct loadparm_context *lp_ctx = NULL;
60 struct cli_credentials *creds = NULL;
61 const char *principal = NULL;
66 creds = cli_credentials_init(mem_ctx);
71 lp_ctx = loadparm_init_s3(creds, loadparm_s3_helpers());
75 cli_credentials_set_conf(creds, lp_ctx);
77 if (username == NULL) {
81 if (strlen(username) == 0) {
82 if (password != NULL && strlen(password) == 0) {
84 * some callers pass "" as no password
86 * gensec only handles NULL as no password.
90 if (password == NULL) {
91 cli_credentials_set_anonymous(creds);
96 tmp = talloc_strdup(creds, username);
102 /* allow for workgroups as part of the username */
103 if ((p = strchr_m(tmp, '\\')) ||
104 (p = strchr_m(tmp, '/')) ||
105 (p = strchr_m(tmp, *lp_winbind_separator()))) {
111 principal = username;
112 username = cli_session_setup_get_account(creds, principal);
113 if (username == NULL) {
116 ok = strequal(username, principal);
119 * Ok still the same, so it's not a principal
124 if (use_kerberos && fallback_after_kerberos) {
125 cli_credentials_set_kerberos_state(creds,
126 CRED_AUTO_USE_KERBEROS);
127 } else if (use_kerberos) {
128 cli_credentials_set_kerberos_state(creds,
129 CRED_MUST_USE_KERBEROS);
131 cli_credentials_set_kerberos_state(creds,
132 CRED_DONT_USE_KERBEROS);
138 features = cli_credentials_get_gensec_features(creds);
139 features |= GENSEC_FEATURE_NTLM_CCACHE;
140 cli_credentials_set_gensec_features(creds, features);
142 if (password != NULL && strlen(password) == 0) {
144 * some callers pass "" as no password
146 * GENSEC_FEATURE_NTLM_CCACHE only handles
147 * NULL as no password.
153 ok = cli_credentials_set_username(creds,
160 if (domain != NULL) {
161 ok = cli_credentials_set_domain(creds,
169 if (principal != NULL) {
170 ok = cli_credentials_set_principal(creds,
179 ok = cli_credentials_set_realm(creds,
187 if (password != NULL && strlen(password) > 0) {
188 if (password_is_nt_hash) {
189 struct samr_Password nt_hash;
192 converted = strhex_to_str((char *)nt_hash.hash,
193 sizeof(nt_hash.hash),
196 if (converted != sizeof(nt_hash.hash)) {
200 ok = cli_credentials_set_nt_hash(creds,
207 ok = cli_credentials_set_password(creds,
222 NTSTATUS cli_session_creds_prepare_krb5(struct cli_state *cli,
223 struct cli_credentials *creds)
225 TALLOC_CTX *frame = talloc_stackframe();
226 const char *user_principal = NULL;
227 const char *user_account = NULL;
228 const char *user_domain = NULL;
229 const char *pass = NULL;
230 const char *target_hostname = NULL;
231 const DATA_BLOB *server_blob = NULL;
232 bool got_kerberos_mechanism = false;
233 enum credentials_use_kerberos krb5_state;
234 bool try_kerberos = false;
235 bool need_kinit = false;
236 bool auth_requested = true;
239 target_hostname = smbXcli_conn_remote_name(cli->conn);
240 server_blob = smbXcli_conn_server_gss_blob(cli->conn);
242 /* the server might not even do spnego */
243 if (server_blob != NULL && server_blob->length != 0) {
244 char *OIDs[ASN1_MAX_OIDS] = { NULL, };
249 * The server sent us the first part of the SPNEGO exchange in the
250 * negprot reply. It is WRONG to depend on the principal sent in the
251 * negprot reply, but right now we do it. If we don't receive one,
252 * we try to best guess, then fall back to NTLM.
254 ok = spnego_parse_negTokenInit(frame,
261 return NT_STATUS_INVALID_PARAMETER;
263 if (OIDs[0] == NULL) {
265 return NT_STATUS_INVALID_PARAMETER;
268 /* make sure the server understands kerberos */
269 for (i = 0; OIDs[i] != NULL; i++) {
271 DEBUG(3,("got OID=%s\n", OIDs[i]));
273 DEBUGADD(3,("got OID=%s\n", OIDs[i]));
276 if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0 ||
277 strcmp(OIDs[i], OID_KERBEROS5) == 0) {
278 got_kerberos_mechanism = true;
284 auth_requested = cli_credentials_authentication_requested(creds);
285 if (auth_requested) {
286 user_principal = cli_credentials_get_principal(creds, frame);
287 if (user_principal == NULL) {
289 return NT_STATUS_NO_MEMORY;
292 user_account = cli_credentials_get_username(creds);
293 user_domain = cli_credentials_get_domain(creds);
294 pass = cli_credentials_get_password(creds);
296 krb5_state = cli_credentials_get_kerberos_state(creds);
298 if (krb5_state != CRED_DONT_USE_KERBEROS) {
302 if (target_hostname == NULL) {
303 try_kerberos = false;
304 } else if (is_ipaddress(target_hostname)) {
305 try_kerberos = false;
306 } else if (strequal(target_hostname, "localhost")) {
307 try_kerberos = false;
308 } else if (strequal(target_hostname, STAR_SMBSERVER)) {
309 try_kerberos = false;
310 } else if (!auth_requested) {
311 try_kerberos = false;
314 if (krb5_state == CRED_MUST_USE_KERBEROS && !try_kerberos) {
315 DEBUG(0, ("Kerberos auth with '%s' (%s\\%s) to access "
316 "'%s' not possible\n",
317 user_principal, user_domain, user_account,
320 return NT_STATUS_ACCESS_DENIED;
323 if (pass == NULL || strlen(pass) == 0) {
325 } else if (krb5_state == CRED_MUST_USE_KERBEROS) {
326 need_kinit = try_kerberos;
327 } else if (!got_kerberos_mechanism) {
329 * Most likely the server doesn't support
330 * Kerberos, don't waste time doing a kinit
334 need_kinit = try_kerberos;
344 * TODO: This should be done within the gensec layer
347 setenv(KRB5_ENV_CCNAME, "MEMORY:cliconnect", 1);
348 ret = kerberos_kinit_password(user_principal, pass,
349 0 /* no time correction for now */,
352 int dbglvl = DBGLVL_WARNING;
354 if (krb5_state == CRED_MUST_USE_KERBEROS) {
358 DEBUG(dbglvl, ("Kinit for %s to access %s failed: %s\n",
359 user_principal, target_hostname,
360 error_message(ret)));
361 if (krb5_state == CRED_MUST_USE_KERBEROS) {
363 return krb5_to_nt_status(ret);
367 * Ignore the error and hope that NTLM will work
375 static NTSTATUS cli_state_update_after_sesssetup(struct cli_state *cli,
376 const char *native_os,
377 const char *native_lm,
378 const char *primary_domain)
380 #define _VALID_STR(p) ((p) != NULL && (p)[0] != '\0')
382 if (!_VALID_STR(cli->server_os) && _VALID_STR(native_os)) {
383 cli->server_os = talloc_strdup(cli, native_os);
384 if (cli->server_os == NULL) {
385 return NT_STATUS_NO_MEMORY;
389 if (!_VALID_STR(cli->server_type) && _VALID_STR(native_lm)) {
390 cli->server_type = talloc_strdup(cli, native_lm);
391 if (cli->server_type == NULL) {
392 return NT_STATUS_NO_MEMORY;
396 if (!_VALID_STR(cli->server_domain) && _VALID_STR(primary_domain)) {
397 cli->server_domain = talloc_strdup(cli, primary_domain);
398 if (cli->server_domain == NULL) {
399 return NT_STATUS_NO_MEMORY;
407 /********************************************************
408 Utility function to ensure we always return at least
409 a valid char * pointer to an empty string for the
410 cli->server_os, cli->server_type and cli->server_domain
412 *******************************************************/
414 static NTSTATUS smb_bytes_talloc_string(TALLOC_CTX *mem_ctx,
421 *destlen = clistr_pull_talloc(mem_ctx,
428 if (*destlen == -1) {
429 return NT_STATUS_NO_MEMORY;
433 *dest = talloc_strdup(mem_ctx, "");
435 return NT_STATUS_NO_MEMORY;
441 /****************************************************************************
442 Work out suitable capabilities to offer the server.
443 ****************************************************************************/
445 static uint32_t cli_session_setup_capabilities(struct cli_state *cli,
446 uint32_t sesssetup_capabilities)
448 uint32_t client_capabilities = smb1cli_conn_capabilities(cli->conn);
451 * We only send capabilities based on the mask for:
452 * - client only flags
453 * - flags used in both directions
455 * We do not echo the server only flags, except some legacy flags.
457 * SMB_CAP_LEGACY_CLIENT_MASK contains CAP_LARGE_READX and
458 * CAP_LARGE_WRITEX in order to allow us to do large reads
459 * against old Samba releases (<= 3.6.x).
461 client_capabilities &= (SMB_CAP_BOTH_MASK | SMB_CAP_LEGACY_CLIENT_MASK);
464 * Session Setup specific flags CAP_DYNAMIC_REAUTH
465 * and CAP_EXTENDED_SECURITY are passed by the caller.
466 * We need that in order to do guest logins even if
467 * CAP_EXTENDED_SECURITY is negotiated.
469 client_capabilities &= ~(CAP_DYNAMIC_REAUTH|CAP_EXTENDED_SECURITY);
470 sesssetup_capabilities &= (CAP_DYNAMIC_REAUTH|CAP_EXTENDED_SECURITY);
471 client_capabilities |= sesssetup_capabilities;
473 return client_capabilities;
476 /****************************************************************************
477 Do a NT1 guest session setup.
478 ****************************************************************************/
480 struct cli_session_setup_guest_state {
481 struct cli_state *cli;
486 static void cli_session_setup_guest_done(struct tevent_req *subreq);
488 struct tevent_req *cli_session_setup_guest_create(TALLOC_CTX *mem_ctx,
489 struct tevent_context *ev,
490 struct cli_state *cli,
491 struct tevent_req **psmbreq)
493 struct tevent_req *req, *subreq;
494 struct cli_session_setup_guest_state *state;
498 req = tevent_req_create(mem_ctx, &state,
499 struct cli_session_setup_guest_state);
506 SCVAL(vwv+0, 0, 0xFF);
509 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
511 SSVAL(vwv+4, 0, cli_state_get_vc_num(cli));
512 SIVAL(vwv+5, 0, smb1cli_conn_server_session_key(cli->conn));
517 SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli, 0));
519 bytes = talloc_array(state, uint8_t, 0);
521 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "", 1, /* username */
523 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "", 1, /* workgroup */
525 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "Unix", 5, NULL);
526 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "Samba", 6, NULL);
533 state->bytes.iov_base = (void *)bytes;
534 state->bytes.iov_len = talloc_get_size(bytes);
536 subreq = cli_smb_req_create(state, ev, cli, SMBsesssetupX, 0, 0, 13,
537 vwv, 1, &state->bytes);
538 if (subreq == NULL) {
542 tevent_req_set_callback(subreq, cli_session_setup_guest_done, req);
547 struct tevent_req *cli_session_setup_guest_send(TALLOC_CTX *mem_ctx,
548 struct tevent_context *ev,
549 struct cli_state *cli)
551 struct tevent_req *req, *subreq;
554 req = cli_session_setup_guest_create(mem_ctx, ev, cli, &subreq);
559 status = smb1cli_req_chain_submit(&subreq, 1);
560 if (!NT_STATUS_IS_OK(status)) {
561 tevent_req_nterror(req, status);
562 return tevent_req_post(req, ev);
567 static void cli_session_setup_guest_done(struct tevent_req *subreq)
569 struct tevent_req *req = tevent_req_callback_data(
570 subreq, struct tevent_req);
571 struct cli_session_setup_guest_state *state = tevent_req_data(
572 req, struct cli_session_setup_guest_state);
573 struct cli_state *cli = state->cli;
584 status = cli_smb_recv(subreq, state, &in, 3, &wct, &vwv,
587 if (!NT_STATUS_IS_OK(status)) {
588 tevent_req_nterror(req, status);
592 inhdr = in + NBT_HDR_SIZE;
595 cli_state_set_uid(state->cli, SVAL(inhdr, HDR_UID));
596 smb1cli_session_set_action(cli->smb1.session, SVAL(vwv+2, 0));
598 status = smb_bytes_talloc_string(cli,
605 if (!NT_STATUS_IS_OK(status)) {
606 tevent_req_nterror(req, status);
611 status = smb_bytes_talloc_string(cli,
618 if (!NT_STATUS_IS_OK(status)) {
619 tevent_req_nterror(req, status);
624 status = smb_bytes_talloc_string(cli,
631 if (!NT_STATUS_IS_OK(status)) {
632 tevent_req_nterror(req, status);
637 tevent_req_done(req);
640 NTSTATUS cli_session_setup_guest_recv(struct tevent_req *req)
642 return tevent_req_simple_recv_ntstatus(req);
645 /* The following is calculated from :
647 * (smb_wcnt * 2) = 24 (smb_wcnt == 12 in cli_session_setup_blob_send() )
648 * (strlen("Unix") + 1 + strlen("Samba") + 1) * 2 = 22 (unicode strings at
652 #define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22)
654 struct cli_sesssetup_blob_state {
655 struct tevent_context *ev;
656 struct cli_state *cli;
658 uint16_t max_blob_size;
661 struct iovec *recv_iov;
664 const uint8_t *inbuf;
671 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state *state,
672 struct tevent_req **psubreq);
673 static void cli_sesssetup_blob_done(struct tevent_req *subreq);
675 static struct tevent_req *cli_sesssetup_blob_send(TALLOC_CTX *mem_ctx,
676 struct tevent_context *ev,
677 struct cli_state *cli,
680 struct tevent_req *req, *subreq;
681 struct cli_sesssetup_blob_state *state;
682 uint32_t usable_space;
684 req = tevent_req_create(mem_ctx, &state,
685 struct cli_sesssetup_blob_state);
693 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
694 usable_space = UINT16_MAX;
696 usable_space = cli_state_available_size(cli,
697 BASE_SESSSETUP_BLOB_PACKET_SIZE);
700 if (usable_space == 0) {
701 DEBUG(1, ("cli_session_setup_blob: cli->max_xmit too small "
702 "(not possible to send %u bytes)\n",
703 BASE_SESSSETUP_BLOB_PACKET_SIZE + 1));
704 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
705 return tevent_req_post(req, ev);
707 state->max_blob_size = MIN(usable_space, 0xFFFF);
709 if (!cli_sesssetup_blob_next(state, &subreq)) {
710 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
711 return tevent_req_post(req, ev);
713 tevent_req_set_callback(subreq, cli_sesssetup_blob_done, req);
717 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state *state,
718 struct tevent_req **psubreq)
720 struct tevent_req *subreq;
723 thistime = MIN(state->blob.length, state->max_blob_size);
725 state->this_blob.data = state->blob.data;
726 state->this_blob.length = thistime;
728 state->blob.data += thistime;
729 state->blob.length -= thistime;
731 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
732 subreq = smb2cli_session_setup_send(state, state->ev,
735 state->cli->smb2.session,
737 SMB2_CAP_DFS, /* in_capabilities */
739 0, /* in_previous_session_id */
741 if (subreq == NULL) {
745 uint16_t in_buf_size = 0;
746 uint16_t in_mpx_max = 0;
747 uint16_t in_vc_num = 0;
748 uint32_t in_sess_key = 0;
749 uint32_t in_capabilities = 0;
750 const char *in_native_os = NULL;
751 const char *in_native_lm = NULL;
753 in_buf_size = CLI_BUFFER_SIZE;
754 in_mpx_max = smbXcli_conn_max_requests(state->cli->conn);
755 in_vc_num = cli_state_get_vc_num(state->cli);
756 in_sess_key = smb1cli_conn_server_session_key(state->cli->conn);
757 in_capabilities = cli_session_setup_capabilities(state->cli,
758 CAP_EXTENDED_SECURITY);
759 in_native_os = "Unix";
760 in_native_lm = "Samba";
763 * For now we keep the same values as before,
764 * we may remove these in a separate commit later.
770 subreq = smb1cli_session_setup_ext_send(state, state->ev,
773 state->cli->smb1.pid,
774 state->cli->smb1.session,
783 if (subreq == NULL) {
791 static void cli_sesssetup_blob_done(struct tevent_req *subreq)
793 struct tevent_req *req = tevent_req_callback_data(
794 subreq, struct tevent_req);
795 struct cli_sesssetup_blob_state *state = tevent_req_data(
796 req, struct cli_sesssetup_blob_state);
799 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
800 status = smb2cli_session_setup_recv(subreq, state,
804 status = smb1cli_session_setup_ext_recv(subreq, state,
808 &state->out_native_os,
809 &state->out_native_lm);
812 if (!NT_STATUS_IS_OK(status)
813 && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
814 tevent_req_nterror(req, status);
818 state->status = status;
820 status = cli_state_update_after_sesssetup(state->cli,
821 state->out_native_os,
822 state->out_native_lm,
824 if (tevent_req_nterror(req, status)) {
828 if (state->blob.length != 0) {
832 if (!cli_sesssetup_blob_next(state, &subreq)) {
836 tevent_req_set_callback(subreq, cli_sesssetup_blob_done, req);
839 tevent_req_done(req);
842 static NTSTATUS cli_sesssetup_blob_recv(struct tevent_req *req,
845 const uint8_t **pinbuf,
846 struct iovec **precv_iov)
848 struct cli_sesssetup_blob_state *state = tevent_req_data(
849 req, struct cli_sesssetup_blob_state);
851 struct iovec *recv_iov;
853 if (tevent_req_is_nterror(req, &status)) {
854 TALLOC_FREE(state->cli->smb2.session);
855 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
856 tevent_req_received(req);
860 recv_iov = talloc_move(mem_ctx, &state->recv_iov);
862 *pblob = state->ret_blob;
864 if (pinbuf != NULL) {
865 *pinbuf = state->inbuf;
867 if (precv_iov != NULL) {
868 *precv_iov = recv_iov;
870 /* could be NT_STATUS_MORE_PROCESSING_REQUIRED */
871 status = state->status;
872 tevent_req_received(req);
876 /****************************************************************************
877 Do a spnego/NTLMSSP encrypted session setup.
878 ****************************************************************************/
880 struct cli_session_setup_gensec_state {
881 struct tevent_context *ev;
882 struct cli_state *cli;
883 struct auth_generic_state *auth_generic;
886 const uint8_t *inbuf;
887 struct iovec *recv_iov;
891 DATA_BLOB session_key;
894 static int cli_session_setup_gensec_state_destructor(
895 struct cli_session_setup_gensec_state *state)
897 TALLOC_FREE(state->auth_generic);
898 data_blob_clear_free(&state->session_key);
902 static void cli_session_setup_gensec_local_next(struct tevent_req *req);
903 static void cli_session_setup_gensec_local_done(struct tevent_req *subreq);
904 static void cli_session_setup_gensec_remote_next(struct tevent_req *req);
905 static void cli_session_setup_gensec_remote_done(struct tevent_req *subreq);
906 static void cli_session_setup_gensec_ready(struct tevent_req *req);
908 static struct tevent_req *cli_session_setup_gensec_send(
909 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
910 struct cli_credentials *creds,
911 const char *target_service,
912 const char *target_hostname)
914 struct tevent_req *req;
915 struct cli_session_setup_gensec_state *state;
917 const DATA_BLOB *b = NULL;
919 req = tevent_req_create(mem_ctx, &state,
920 struct cli_session_setup_gensec_state);
927 talloc_set_destructor(
928 state, cli_session_setup_gensec_state_destructor);
930 status = auth_generic_client_prepare(state, &state->auth_generic);
931 if (tevent_req_nterror(req, status)) {
932 return tevent_req_post(req, ev);
935 status = auth_generic_set_creds(state->auth_generic, creds);
936 if (tevent_req_nterror(req, status)) {
937 return tevent_req_post(req, ev);
940 gensec_want_feature(state->auth_generic->gensec_security,
941 GENSEC_FEATURE_SESSION_KEY);
943 if (target_service != NULL) {
944 status = gensec_set_target_service(
945 state->auth_generic->gensec_security,
947 if (tevent_req_nterror(req, status)) {
948 return tevent_req_post(req, ev);
952 if (target_hostname != NULL) {
953 status = gensec_set_target_hostname(
954 state->auth_generic->gensec_security,
956 if (tevent_req_nterror(req, status)) {
957 return tevent_req_post(req, ev);
961 b = smbXcli_conn_server_gss_blob(cli->conn);
966 state->is_anonymous = cli_credentials_is_anonymous(state->auth_generic->credentials);
968 status = auth_generic_client_start(state->auth_generic,
970 if (tevent_req_nterror(req, status)) {
971 return tevent_req_post(req, ev);
974 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
975 state->cli->smb2.session = smbXcli_session_create(cli,
977 if (tevent_req_nomem(state->cli->smb2.session, req)) {
978 return tevent_req_post(req, ev);
982 cli_session_setup_gensec_local_next(req);
983 if (!tevent_req_is_in_progress(req)) {
984 return tevent_req_post(req, ev);
990 static void cli_session_setup_gensec_local_next(struct tevent_req *req)
992 struct cli_session_setup_gensec_state *state =
994 struct cli_session_setup_gensec_state);
995 struct tevent_req *subreq = NULL;
997 if (state->local_ready) {
998 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1002 subreq = gensec_update_send(state, state->ev,
1003 state->auth_generic->gensec_security,
1005 if (tevent_req_nomem(subreq, req)) {
1008 tevent_req_set_callback(subreq, cli_session_setup_gensec_local_done, req);
1011 static void cli_session_setup_gensec_local_done(struct tevent_req *subreq)
1013 struct tevent_req *req =
1014 tevent_req_callback_data(subreq,
1016 struct cli_session_setup_gensec_state *state =
1017 tevent_req_data(req,
1018 struct cli_session_setup_gensec_state);
1021 status = gensec_update_recv(subreq, state, &state->blob_out);
1022 TALLOC_FREE(subreq);
1023 state->blob_in = data_blob_null;
1024 if (!NT_STATUS_IS_OK(status) &&
1025 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
1027 tevent_req_nterror(req, status);
1031 if (NT_STATUS_IS_OK(status)) {
1032 state->local_ready = true;
1035 if (state->local_ready && state->remote_ready) {
1036 cli_session_setup_gensec_ready(req);
1040 cli_session_setup_gensec_remote_next(req);
1043 static void cli_session_setup_gensec_remote_next(struct tevent_req *req)
1045 struct cli_session_setup_gensec_state *state =
1046 tevent_req_data(req,
1047 struct cli_session_setup_gensec_state);
1048 struct tevent_req *subreq = NULL;
1050 if (state->remote_ready) {
1051 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1055 subreq = cli_sesssetup_blob_send(state, state->ev,
1056 state->cli, state->blob_out);
1057 if (tevent_req_nomem(subreq, req)) {
1060 tevent_req_set_callback(subreq,
1061 cli_session_setup_gensec_remote_done,
1065 static void cli_session_setup_gensec_remote_done(struct tevent_req *subreq)
1067 struct tevent_req *req =
1068 tevent_req_callback_data(subreq,
1070 struct cli_session_setup_gensec_state *state =
1071 tevent_req_data(req,
1072 struct cli_session_setup_gensec_state);
1075 state->inbuf = NULL;
1076 TALLOC_FREE(state->recv_iov);
1078 status = cli_sesssetup_blob_recv(subreq, state, &state->blob_in,
1079 &state->inbuf, &state->recv_iov);
1080 TALLOC_FREE(subreq);
1081 data_blob_free(&state->blob_out);
1082 if (!NT_STATUS_IS_OK(status) &&
1083 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
1085 tevent_req_nterror(req, status);
1089 if (NT_STATUS_IS_OK(status)) {
1090 struct smbXcli_session *session = NULL;
1091 bool is_guest = false;
1093 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
1094 session = state->cli->smb2.session;
1096 session = state->cli->smb1.session;
1099 is_guest = smbXcli_session_is_guest(session);
1102 * We can't finish the gensec handshake, we don't
1103 * have a negotiated session key.
1105 * So just pretend we are completely done,
1106 * we need to continue as anonymous from this point,
1107 * as we can't get a session key.
1109 * Note that smbXcli_session_is_guest()
1110 * always returns false if we require signing.
1112 state->blob_in = data_blob_null;
1113 state->local_ready = true;
1114 state->is_anonymous = true;
1117 state->remote_ready = true;
1120 if (state->local_ready && state->remote_ready) {
1121 cli_session_setup_gensec_ready(req);
1125 cli_session_setup_gensec_local_next(req);
1128 static void cli_session_setup_gensec_ready(struct tevent_req *req)
1130 struct cli_session_setup_gensec_state *state =
1131 tevent_req_data(req,
1132 struct cli_session_setup_gensec_state);
1133 const char *server_domain = NULL;
1136 if (state->blob_in.length != 0) {
1137 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1141 if (state->blob_out.length != 0) {
1142 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1147 * gensec_ntlmssp_server_domain() returns NULL
1148 * if NTLMSSP is not used.
1150 * We can remove this later
1151 * and leave the server domain empty for SMB2 and above
1152 * in future releases.
1154 server_domain = gensec_ntlmssp_server_domain(
1155 state->auth_generic->gensec_security);
1157 if (state->cli->server_domain[0] == '\0' && server_domain != NULL) {
1158 TALLOC_FREE(state->cli->server_domain);
1159 state->cli->server_domain = talloc_strdup(state->cli,
1161 if (state->cli->server_domain == NULL) {
1162 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1167 if (state->is_anonymous) {
1169 * Windows server does not set the
1170 * SMB2_SESSION_FLAG_IS_NULL flag.
1172 * This fix makes sure we do not try
1173 * to verify a signature on the final
1174 * session setup response.
1176 tevent_req_done(req);
1180 status = gensec_session_key(state->auth_generic->gensec_security,
1181 state, &state->session_key);
1182 if (tevent_req_nterror(req, status)) {
1186 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
1187 struct smbXcli_session *session = state->cli->smb2.session;
1189 status = smb2cli_session_set_session_key(session,
1192 if (tevent_req_nterror(req, status)) {
1196 struct smbXcli_session *session = state->cli->smb1.session;
1199 status = smb1cli_session_set_session_key(session,
1200 state->session_key);
1201 if (tevent_req_nterror(req, status)) {
1205 active = smb1cli_conn_activate_signing(state->cli->conn,
1211 ok = smb1cli_conn_check_signing(state->cli->conn,
1214 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1220 tevent_req_done(req);
1223 static NTSTATUS cli_session_setup_gensec_recv(struct tevent_req *req)
1225 struct cli_session_setup_gensec_state *state =
1226 tevent_req_data(req,
1227 struct cli_session_setup_gensec_state);
1230 if (tevent_req_is_nterror(req, &status)) {
1231 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
1234 return NT_STATUS_OK;
1237 static char *cli_session_setup_get_account(TALLOC_CTX *mem_ctx,
1238 const char *principal)
1242 account = talloc_strdup(mem_ctx, principal);
1243 if (account == NULL) {
1246 p = strchr_m(account, '@');
1253 /****************************************************************************
1254 Do a spnego encrypted session setup.
1256 user_domain: The shortname of the domain the user/machine is a member of.
1257 dest_realm: The realm we're connecting to, if NULL we use our default realm.
1258 ****************************************************************************/
1260 struct cli_session_setup_spnego_state {
1264 static void cli_session_setup_spnego_done(struct tevent_req *subreq);
1266 static struct tevent_req *cli_session_setup_spnego_send(
1267 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
1268 struct cli_credentials *creds)
1270 struct tevent_req *req, *subreq;
1271 struct cli_session_setup_spnego_state *state;
1272 const char *target_service = NULL;
1273 const char *target_hostname = NULL;
1276 req = tevent_req_create(mem_ctx, &state,
1277 struct cli_session_setup_spnego_state);
1282 target_service = "cifs";
1283 target_hostname = smbXcli_conn_remote_name(cli->conn);
1285 status = cli_session_creds_prepare_krb5(cli, creds);
1286 if (tevent_req_nterror(req, status)) {
1287 return tevent_req_post(req, ev);;
1290 subreq = cli_session_setup_gensec_send(state, ev, cli, creds,
1291 target_service, target_hostname);
1292 if (tevent_req_nomem(subreq, req)) {
1293 return tevent_req_post(req, ev);
1295 tevent_req_set_callback(
1296 subreq, cli_session_setup_spnego_done, req);
1300 static void cli_session_setup_spnego_done(struct tevent_req *subreq)
1302 struct tevent_req *req = tevent_req_callback_data(
1303 subreq, struct tevent_req);
1306 status = cli_session_setup_gensec_recv(subreq);
1307 TALLOC_FREE(subreq);
1308 if (tevent_req_nterror(req, status)) {
1312 tevent_req_done(req);
1315 static ADS_STATUS cli_session_setup_spnego_recv(struct tevent_req *req)
1317 struct cli_session_setup_spnego_state *state = tevent_req_data(
1318 req, struct cli_session_setup_spnego_state);
1321 if (tevent_req_is_nterror(req, &status)) {
1322 state->result = ADS_ERROR_NT(status);
1325 return state->result;
1328 struct cli_session_setup_creds_state {
1329 struct cli_state *cli;
1330 DATA_BLOB apassword_blob;
1331 DATA_BLOB upassword_blob;
1332 DATA_BLOB lm_session_key;
1333 DATA_BLOB session_key;
1334 char *out_native_os;
1335 char *out_native_lm;
1336 char *out_primary_domain;
1339 static void cli_session_setup_creds_cleanup(struct tevent_req *req,
1340 enum tevent_req_state req_state)
1342 struct cli_session_setup_creds_state *state = tevent_req_data(
1343 req, struct cli_session_setup_creds_state);
1345 if (req_state != TEVENT_REQ_RECEIVED) {
1350 * We only call data_blob_clear() as
1351 * some of the blobs point to the same memory.
1353 * We let the talloc hierachy free the memory.
1355 data_blob_clear(&state->apassword_blob);
1356 data_blob_clear(&state->upassword_blob);
1357 data_blob_clear(&state->lm_session_key);
1358 data_blob_clear(&state->session_key);
1359 ZERO_STRUCTP(state);
1362 static void cli_session_setup_creds_done_spnego(struct tevent_req *subreq);
1363 static void cli_session_setup_creds_done_nt1(struct tevent_req *subreq);
1364 static void cli_session_setup_creds_done_lm21(struct tevent_req *subreq);
1366 /****************************************************************************
1367 Send a session setup. The username and workgroup is in UNIX character
1368 format and must be converted to DOS codepage format before sending. If the
1369 password is in plaintext, the same should be done.
1370 ****************************************************************************/
1372 struct tevent_req *cli_session_setup_creds_send(TALLOC_CTX *mem_ctx,
1373 struct tevent_context *ev,
1374 struct cli_state *cli,
1375 struct cli_credentials *creds)
1377 struct tevent_req *req, *subreq;
1378 struct cli_session_setup_creds_state *state;
1379 uint16_t sec_mode = smb1cli_conn_server_security_mode(cli->conn);
1380 bool use_spnego = false;
1382 enum credentials_use_kerberos krb5_state;
1383 uint32_t gensec_features;
1384 const char *username = "";
1385 const char *domain = "";
1386 DATA_BLOB target_info = data_blob_null;
1387 DATA_BLOB challenge = data_blob_null;
1388 uint16_t in_buf_size = 0;
1389 uint16_t in_mpx_max = 0;
1390 uint16_t in_vc_num = 0;
1391 uint32_t in_sess_key = 0;
1392 const char *in_native_os = NULL;
1393 const char *in_native_lm = NULL;
1396 req = tevent_req_create(mem_ctx, &state,
1397 struct cli_session_setup_creds_state);
1403 tevent_req_set_cleanup_fn(req, cli_session_setup_creds_cleanup);
1405 krb5_state = cli_credentials_get_kerberos_state(creds);
1406 gensec_features = cli_credentials_get_gensec_features(creds);
1408 switch (krb5_state) {
1409 case CRED_MUST_USE_KERBEROS:
1410 cli->use_kerberos = true;
1411 cli->fallback_after_kerberos = false;
1413 case CRED_AUTO_USE_KERBEROS:
1414 cli->use_kerberos = true;
1415 cli->fallback_after_kerberos = true;
1417 case CRED_DONT_USE_KERBEROS:
1418 cli->use_kerberos = false;
1419 cli->fallback_after_kerberos = false;
1423 if (gensec_features & GENSEC_FEATURE_NTLM_CCACHE) {
1424 cli->use_ccache = true;
1426 cli->use_ccache = false;
1430 * Now work out what sort of session setup we are going to
1431 * do. I have split this into separate functions to make the flow a bit
1432 * easier to understand (tridge).
1434 if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_NT1) {
1436 } else if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
1438 } else if (smb1cli_conn_capabilities(cli->conn) & CAP_EXTENDED_SECURITY) {
1440 * if the server supports extended security then use SPNEGO
1441 * even for anonymous connections.
1449 subreq = cli_session_setup_spnego_send(
1450 state, ev, cli, creds);
1451 if (tevent_req_nomem(subreq, req)) {
1452 return tevent_req_post(req, ev);
1454 tevent_req_set_callback(subreq, cli_session_setup_creds_done_spnego,
1459 if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_LANMAN1) {
1461 * SessionSetupAndX was introduced by LANMAN 1.0. So we skip
1462 * this step against older servers.
1464 tevent_req_done(req);
1465 return tevent_req_post(req, ev);
1468 if (cli_credentials_is_anonymous(creds)) {
1470 * Do an anonymous session setup
1472 goto non_spnego_creds_done;
1475 if ((sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0) {
1477 * Do an anonymous session setup,
1478 * the password is passed via the tree connect.
1480 goto non_spnego_creds_done;
1483 cli_credentials_get_ntlm_username_domain(creds, state,
1486 if (tevent_req_nomem(username, req)) {
1487 return tevent_req_post(req, ev);
1489 if (tevent_req_nomem(domain, req)) {
1490 return tevent_req_post(req, ev);
1493 if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) {
1494 bool use_unicode = smbXcli_conn_use_unicode(cli->conn);
1495 uint8_t *bytes = NULL;
1496 size_t bytes_len = 0;
1497 const char *pw = cli_credentials_get_password(creds);
1503 pw_len = strlen(pw) + 1;
1505 if (!lp_client_plaintext_auth()) {
1506 DEBUG(1, ("Server requested PLAINTEXT password but "
1507 "'client plaintext auth = no'\n"));
1508 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1509 return tevent_req_post(req, ev);
1512 bytes = talloc_array(state, uint8_t, 0);
1513 bytes = trans2_bytes_push_str(bytes, use_unicode,
1514 pw, pw_len, &bytes_len);
1515 if (tevent_req_nomem(bytes, req)) {
1516 return tevent_req_post(req, ev);
1521 * CAP_UNICODE, can only be negotiated by NT1.
1523 state->upassword_blob = data_blob_const(bytes,
1526 state->apassword_blob = data_blob_const(bytes,
1530 goto non_spnego_creds_done;
1533 challenge = data_blob_const(smb1cli_conn_server_challenge(cli->conn), 8);
1535 if (smbXcli_conn_protocol(cli->conn) == PROTOCOL_NT1) {
1536 if (lp_client_ntlmv2_auth() && lp_client_use_spnego()) {
1538 * Don't send an NTLMv2 response without NTLMSSP if we
1539 * want to use spnego support.
1541 DEBUG(1, ("Server does not support EXTENDED_SECURITY "
1542 " but 'client use spnego = yes'"
1543 " and 'client ntlmv2 auth = yes' is set\n"));
1544 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1545 return tevent_req_post(req, ev);
1548 if (lp_client_ntlmv2_auth()) {
1549 flags |= CLI_CRED_NTLMv2_AUTH;
1552 * note that the 'domain' here is a best
1553 * guess - we don't know the server's domain
1554 * at this point. Windows clients also don't
1557 target_info = NTLMv2_generate_names_blob(state,
1560 if (tevent_req_nomem(target_info.data, req)) {
1561 return tevent_req_post(req, ev);
1564 flags |= CLI_CRED_NTLM_AUTH;
1565 if (lp_client_lanman_auth()) {
1566 flags |= CLI_CRED_LANMAN_AUTH;
1570 if (!lp_client_lanman_auth()) {
1571 DEBUG(1, ("Server requested user level LM password but "
1572 "'client lanman auth = no' is set.\n"));
1573 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1574 return tevent_req_post(req, ev);
1577 flags |= CLI_CRED_LANMAN_AUTH;
1580 status = cli_credentials_get_ntlm_response(creds, state, &flags,
1583 &state->apassword_blob,
1584 &state->upassword_blob,
1585 &state->lm_session_key,
1586 &state->session_key);
1587 if (tevent_req_nterror(req, status)) {
1588 return tevent_req_post(req, ev);
1591 non_spnego_creds_done:
1593 in_buf_size = CLI_BUFFER_SIZE;
1594 in_mpx_max = smbXcli_conn_max_requests(cli->conn);
1595 in_vc_num = cli_state_get_vc_num(cli);
1596 in_sess_key = smb1cli_conn_server_session_key(cli->conn);
1597 in_native_os = "Unix";
1598 in_native_lm = "Samba";
1600 if (smbXcli_conn_protocol(cli->conn) == PROTOCOL_NT1) {
1601 uint32_t in_capabilities = 0;
1603 in_capabilities = cli_session_setup_capabilities(cli, 0);
1606 * For now we keep the same values as before,
1607 * we may remove these in a separate commit later.
1611 subreq = smb1cli_session_setup_nt1_send(state, ev,
1622 state->apassword_blob,
1623 state->upassword_blob,
1627 if (tevent_req_nomem(subreq, req)) {
1628 return tevent_req_post(req, ev);
1630 tevent_req_set_callback(subreq, cli_session_setup_creds_done_nt1,
1636 * For now we keep the same values as before,
1637 * we may remove these in a separate commit later.
1642 subreq = smb1cli_session_setup_lm21_send(state, ev,
1653 state->apassword_blob,
1656 if (tevent_req_nomem(subreq, req)) {
1657 return tevent_req_post(req, ev);
1659 tevent_req_set_callback(subreq, cli_session_setup_creds_done_lm21,
1664 static void cli_session_setup_creds_done_spnego(struct tevent_req *subreq)
1666 struct tevent_req *req = tevent_req_callback_data(
1667 subreq, struct tevent_req);
1670 status = cli_session_setup_spnego_recv(subreq);
1671 TALLOC_FREE(subreq);
1672 if (!ADS_ERR_OK(status)) {
1673 DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status)));
1674 tevent_req_nterror(req, ads_ntstatus(status));
1677 tevent_req_done(req);
1680 static void cli_session_setup_creds_done_nt1(struct tevent_req *subreq)
1682 struct tevent_req *req = tevent_req_callback_data(
1683 subreq, struct tevent_req);
1684 struct cli_session_setup_creds_state *state = tevent_req_data(
1685 req, struct cli_session_setup_creds_state);
1686 struct cli_state *cli = state->cli;
1688 struct iovec *recv_iov = NULL;
1689 const uint8_t *inbuf = NULL;
1692 status = smb1cli_session_setup_nt1_recv(subreq, state,
1695 &state->out_native_os,
1696 &state->out_native_lm,
1697 &state->out_primary_domain);
1698 TALLOC_FREE(subreq);
1699 if (!NT_STATUS_IS_OK(status)) {
1700 DEBUG(3, ("NT1 login failed: %s\n", nt_errstr(status)));
1701 tevent_req_nterror(req, status);
1705 status = cli_state_update_after_sesssetup(state->cli,
1706 state->out_native_os,
1707 state->out_native_lm,
1708 state->out_primary_domain);
1709 if (tevent_req_nterror(req, status)) {
1713 ok = smb1cli_conn_activate_signing(cli->conn,
1715 state->upassword_blob);
1717 ok = smb1cli_conn_check_signing(cli->conn, inbuf, 1);
1719 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1724 if (state->session_key.data) {
1725 struct smbXcli_session *session = cli->smb1.session;
1727 status = smb1cli_session_set_session_key(session,
1728 state->session_key);
1729 if (tevent_req_nterror(req, status)) {
1734 tevent_req_done(req);
1737 static void cli_session_setup_creds_done_lm21(struct tevent_req *subreq)
1739 struct tevent_req *req = tevent_req_callback_data(
1740 subreq, struct tevent_req);
1741 struct cli_session_setup_creds_state *state = tevent_req_data(
1742 req, struct cli_session_setup_creds_state);
1745 status = smb1cli_session_setup_lm21_recv(subreq, state,
1746 &state->out_native_os,
1747 &state->out_native_lm);
1748 TALLOC_FREE(subreq);
1749 if (!NT_STATUS_IS_OK(status)) {
1750 DEBUG(3, ("LM21 login failed: %s\n", nt_errstr(status)));
1751 tevent_req_nterror(req, status);
1755 status = cli_state_update_after_sesssetup(state->cli,
1756 state->out_native_os,
1757 state->out_native_lm,
1759 if (tevent_req_nterror(req, status)) {
1763 tevent_req_done(req);
1766 NTSTATUS cli_session_setup_creds_recv(struct tevent_req *req)
1768 return tevent_req_simple_recv_ntstatus(req);
1771 NTSTATUS cli_session_setup_creds(struct cli_state *cli,
1772 struct cli_credentials *creds)
1774 struct tevent_context *ev;
1775 struct tevent_req *req;
1776 NTSTATUS status = NT_STATUS_NO_MEMORY;
1778 if (smbXcli_conn_has_async_calls(cli->conn)) {
1779 return NT_STATUS_INVALID_PARAMETER;
1781 ev = samba_tevent_context_init(talloc_tos());
1785 req = cli_session_setup_creds_send(ev, ev, cli, creds);
1789 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1792 status = cli_session_setup_creds_recv(req);
1798 NTSTATUS cli_session_setup_anon(struct cli_state *cli)
1800 NTSTATUS status = NT_STATUS_NO_MEMORY;
1801 struct cli_credentials *creds = NULL;
1803 creds = cli_credentials_init_anon(cli);
1804 if (creds == NULL) {
1805 return NT_STATUS_NO_MEMORY;
1808 status = cli_session_setup_creds(cli, creds);
1810 if (!NT_STATUS_IS_OK(status)) {
1814 return NT_STATUS_OK;
1817 /****************************************************************************
1819 *****************************************************************************/
1821 struct cli_ulogoff_state {
1822 struct cli_state *cli;
1826 static void cli_ulogoff_done(struct tevent_req *subreq);
1828 static struct tevent_req *cli_ulogoff_send(TALLOC_CTX *mem_ctx,
1829 struct tevent_context *ev,
1830 struct cli_state *cli)
1832 struct tevent_req *req, *subreq;
1833 struct cli_ulogoff_state *state;
1835 req = tevent_req_create(mem_ctx, &state, struct cli_ulogoff_state);
1841 SCVAL(state->vwv+0, 0, 0xFF);
1842 SCVAL(state->vwv+1, 0, 0);
1843 SSVAL(state->vwv+2, 0, 0);
1845 subreq = cli_smb_send(state, ev, cli, SMBulogoffX, 0, 0, 2, state->vwv,
1847 if (tevent_req_nomem(subreq, req)) {
1848 return tevent_req_post(req, ev);
1850 tevent_req_set_callback(subreq, cli_ulogoff_done, req);
1854 static void cli_ulogoff_done(struct tevent_req *subreq)
1856 struct tevent_req *req = tevent_req_callback_data(
1857 subreq, struct tevent_req);
1858 struct cli_ulogoff_state *state = tevent_req_data(
1859 req, struct cli_ulogoff_state);
1862 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
1863 if (!NT_STATUS_IS_OK(status)) {
1864 tevent_req_nterror(req, status);
1867 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
1868 tevent_req_done(req);
1871 static NTSTATUS cli_ulogoff_recv(struct tevent_req *req)
1873 return tevent_req_simple_recv_ntstatus(req);
1876 NTSTATUS cli_ulogoff(struct cli_state *cli)
1878 struct tevent_context *ev;
1879 struct tevent_req *req;
1880 NTSTATUS status = NT_STATUS_NO_MEMORY;
1882 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
1883 status = smb2cli_logoff(cli->conn,
1886 if (!NT_STATUS_IS_OK(status)) {
1889 smb2cli_session_set_id_and_flags(cli->smb2.session,
1891 return NT_STATUS_OK;
1894 if (smbXcli_conn_has_async_calls(cli->conn)) {
1895 return NT_STATUS_INVALID_PARAMETER;
1897 ev = samba_tevent_context_init(talloc_tos());
1901 req = cli_ulogoff_send(ev, ev, cli);
1905 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1908 status = cli_ulogoff_recv(req);
1914 /****************************************************************************
1916 ****************************************************************************/
1918 struct cli_tcon_andx_state {
1919 struct cli_state *cli;
1924 static void cli_tcon_andx_done(struct tevent_req *subreq);
1926 struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx,
1927 struct tevent_context *ev,
1928 struct cli_state *cli,
1929 const char *share, const char *dev,
1930 const char *pass, int passlen,
1931 struct tevent_req **psmbreq)
1933 struct tevent_req *req, *subreq;
1934 struct cli_tcon_andx_state *state;
1939 uint16_t sec_mode = smb1cli_conn_server_security_mode(cli->conn);
1940 uint16_t tcon_flags = 0;
1944 req = tevent_req_create(mem_ctx, &state, struct cli_tcon_andx_state);
1951 TALLOC_FREE(cli->smb1.tcon);
1952 cli->smb1.tcon = smbXcli_tcon_create(cli);
1953 if (tevent_req_nomem(cli->smb1.tcon, req)) {
1954 return tevent_req_post(req, ev);
1956 smb1cli_tcon_set_id(cli->smb1.tcon, UINT16_MAX);
1958 cli->share = talloc_strdup(cli, share);
1963 /* in user level security don't send a password now */
1964 if (sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {
1967 } else if (pass == NULL) {
1968 DEBUG(1, ("Server not using user level security and no "
1969 "password supplied.\n"));
1973 if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) &&
1974 *pass && passlen != 24) {
1975 if (!lp_client_lanman_auth()) {
1976 DEBUG(1, ("Server requested LANMAN password "
1977 "(share-level security) but "
1978 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
1983 * Non-encrypted passwords - convert to DOS codepage before
1986 SMBencrypt(pass, smb1cli_conn_server_challenge(cli->conn), p24);
1988 pass = (const char *)p24;
1990 if((sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL
1991 |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE))
1995 if (!lp_client_plaintext_auth() && (*pass)) {
1996 DEBUG(1, ("Server requested PLAINTEXT "
1998 "'client plaintext auth = no' or 'client ntlmv2 auth = yes'\n"));
2003 * Non-encrypted passwords - convert to DOS codepage
2006 tmp_pass = talloc_array(talloc_tos(), uint8_t, 0);
2007 if (tevent_req_nomem(tmp_pass, req)) {
2008 return tevent_req_post(req, ev);
2010 tmp_pass = trans2_bytes_push_str(tmp_pass,
2011 false, /* always DOS */
2015 if (tevent_req_nomem(tmp_pass, req)) {
2016 return tevent_req_post(req, ev);
2018 pass = (const char *)tmp_pass;
2019 passlen = talloc_get_size(tmp_pass);
2023 tcon_flags |= TCONX_FLAG_EXTENDED_RESPONSE;
2024 tcon_flags |= TCONX_FLAG_EXTENDED_SIGNATURES;
2026 SCVAL(vwv+0, 0, 0xFF);
2029 SSVAL(vwv+2, 0, tcon_flags);
2030 SSVAL(vwv+3, 0, passlen);
2032 if (passlen && pass) {
2033 bytes = (uint8_t *)talloc_memdup(state, pass, passlen);
2035 bytes = talloc_array(state, uint8_t, 0);
2041 tmp = talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
2042 smbXcli_conn_remote_name(cli->conn), share);
2047 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), tmp, strlen(tmp)+1,
2052 * Add the devicetype
2054 tmp = talloc_strdup_upper(talloc_tos(), dev);
2059 bytes = smb_bytes_push_str(bytes, false, tmp, strlen(tmp)+1, NULL);
2062 if (bytes == NULL) {
2067 state->bytes.iov_base = (void *)bytes;
2068 state->bytes.iov_len = talloc_get_size(bytes);
2070 subreq = cli_smb_req_create(state, ev, cli, SMBtconX, 0, 0, 4, vwv,
2072 if (subreq == NULL) {
2076 tevent_req_set_callback(subreq, cli_tcon_andx_done, req);
2081 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
2082 return tevent_req_post(req, ev);
2085 struct tevent_req *cli_tcon_andx_send(TALLOC_CTX *mem_ctx,
2086 struct tevent_context *ev,
2087 struct cli_state *cli,
2088 const char *share, const char *dev,
2089 const char *pass, int passlen)
2091 struct tevent_req *req, *subreq;
2094 req = cli_tcon_andx_create(mem_ctx, ev, cli, share, dev, pass, passlen,
2099 if (subreq == NULL) {
2102 status = smb1cli_req_chain_submit(&subreq, 1);
2103 if (!NT_STATUS_IS_OK(status)) {
2104 tevent_req_nterror(req, status);
2105 return tevent_req_post(req, ev);
2110 static void cli_tcon_andx_done(struct tevent_req *subreq)
2112 struct tevent_req *req = tevent_req_callback_data(
2113 subreq, struct tevent_req);
2114 struct cli_tcon_andx_state *state = tevent_req_data(
2115 req, struct cli_tcon_andx_state);
2116 struct cli_state *cli = state->cli;
2124 uint16_t optional_support = 0;
2126 status = cli_smb_recv(subreq, state, &in, 0, &wct, &vwv,
2127 &num_bytes, &bytes);
2128 TALLOC_FREE(subreq);
2129 if (!NT_STATUS_IS_OK(status)) {
2130 tevent_req_nterror(req, status);
2134 inhdr = in + NBT_HDR_SIZE;
2137 if (clistr_pull_talloc(cli,
2138 (const char *)inhdr,
2139 SVAL(inhdr, HDR_FLG2),
2143 STR_TERMINATE|STR_ASCII) == -1) {
2144 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2148 cli->dev = talloc_strdup(cli, "");
2149 if (cli->dev == NULL) {
2150 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2155 if ((smbXcli_conn_protocol(cli->conn) >= PROTOCOL_NT1) && (num_bytes == 3)) {
2156 /* almost certainly win95 - enable bug fixes */
2161 * Make sure that we have the optional support 16-bit field. WCT > 2.
2162 * Avoids issues when connecting to Win9x boxes sharing files
2165 if ((wct > 2) && (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_LANMAN2)) {
2166 optional_support = SVAL(vwv+2, 0);
2169 if (optional_support & SMB_EXTENDED_SIGNATURES) {
2170 smb1cli_session_protect_session_key(cli->smb1.session);
2173 smb1cli_tcon_set_values(state->cli->smb1.tcon,
2174 SVAL(inhdr, HDR_TID),
2176 0, /* maximal_access */
2177 0, /* guest_maximal_access */
2179 NULL); /* fs_type */
2181 tevent_req_done(req);
2184 NTSTATUS cli_tcon_andx_recv(struct tevent_req *req)
2186 return tevent_req_simple_recv_ntstatus(req);
2189 NTSTATUS cli_tcon_andx(struct cli_state *cli, const char *share,
2190 const char *dev, const char *pass, int passlen)
2192 TALLOC_CTX *frame = talloc_stackframe();
2193 struct tevent_context *ev;
2194 struct tevent_req *req;
2195 NTSTATUS status = NT_STATUS_NO_MEMORY;
2197 if (smbXcli_conn_has_async_calls(cli->conn)) {
2199 * Can't use sync call while an async call is in flight
2201 status = NT_STATUS_INVALID_PARAMETER;
2205 ev = samba_tevent_context_init(frame);
2210 req = cli_tcon_andx_send(frame, ev, cli, share, dev, pass, passlen);
2215 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2219 status = cli_tcon_andx_recv(req);
2225 struct cli_tree_connect_state {
2226 struct cli_state *cli;
2229 static struct tevent_req *cli_raw_tcon_send(
2230 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
2231 const char *service, const char *pass, const char *dev);
2232 static NTSTATUS cli_raw_tcon_recv(struct tevent_req *req,
2233 uint16_t *max_xmit, uint16_t *tid);
2235 static void cli_tree_connect_smb2_done(struct tevent_req *subreq);
2236 static void cli_tree_connect_andx_done(struct tevent_req *subreq);
2237 static void cli_tree_connect_raw_done(struct tevent_req *subreq);
2239 static struct tevent_req *cli_tree_connect_send(
2240 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
2241 const char *share, const char *dev, const char *pass)
2243 struct tevent_req *req, *subreq;
2244 struct cli_tree_connect_state *state;
2250 passlen = strlen(pass) + 1;
2252 req = tevent_req_create(mem_ctx, &state,
2253 struct cli_tree_connect_state);
2259 cli->share = talloc_strdup(cli, share);
2260 if (tevent_req_nomem(cli->share, req)) {
2261 return tevent_req_post(req, ev);
2264 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
2267 TALLOC_FREE(cli->smb2.tcon);
2268 cli->smb2.tcon = smbXcli_tcon_create(cli);
2269 if (tevent_req_nomem(cli->smb2.tcon, req)) {
2270 return tevent_req_post(req, ev);
2273 unc = talloc_asprintf(state, "\\\\%s\\%s",
2274 smbXcli_conn_remote_name(cli->conn),
2276 if (tevent_req_nomem(unc, req)) {
2277 return tevent_req_post(req, ev);
2280 subreq = smb2cli_tcon_send(state, ev, cli->conn, cli->timeout,
2281 cli->smb2.session, cli->smb2.tcon,
2284 if (tevent_req_nomem(subreq, req)) {
2285 return tevent_req_post(req, ev);
2287 tevent_req_set_callback(subreq, cli_tree_connect_smb2_done,
2292 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_LANMAN1) {
2293 subreq = cli_tcon_andx_send(state, ev, cli, share, dev,
2295 if (tevent_req_nomem(subreq, req)) {
2296 return tevent_req_post(req, ev);
2298 tevent_req_set_callback(subreq, cli_tree_connect_andx_done,
2303 subreq = cli_raw_tcon_send(state, ev, cli, share, pass, dev);
2304 if (tevent_req_nomem(subreq, req)) {
2305 return tevent_req_post(req, ev);
2307 tevent_req_set_callback(subreq, cli_tree_connect_raw_done, req);
2312 static void cli_tree_connect_smb2_done(struct tevent_req *subreq)
2314 tevent_req_simple_finish_ntstatus(
2315 subreq, smb2cli_tcon_recv(subreq));
2318 static void cli_tree_connect_andx_done(struct tevent_req *subreq)
2320 tevent_req_simple_finish_ntstatus(
2321 subreq, cli_tcon_andx_recv(subreq));
2324 static void cli_tree_connect_raw_done(struct tevent_req *subreq)
2326 struct tevent_req *req = tevent_req_callback_data(
2327 subreq, struct tevent_req);
2328 struct cli_tree_connect_state *state = tevent_req_data(
2329 req, struct cli_tree_connect_state);
2331 uint16_t max_xmit = 0;
2334 status = cli_raw_tcon_recv(subreq, &max_xmit, &tid);
2335 if (tevent_req_nterror(req, status)) {
2339 smb1cli_tcon_set_values(state->cli->smb1.tcon,
2341 0, /* optional_support */
2342 0, /* maximal_access */
2343 0, /* guest_maximal_access */
2345 NULL); /* fs_type */
2347 tevent_req_done(req);
2350 static NTSTATUS cli_tree_connect_recv(struct tevent_req *req)
2352 return tevent_req_simple_recv_ntstatus(req);
2355 NTSTATUS cli_tree_connect(struct cli_state *cli, const char *share,
2356 const char *dev, const char *pass)
2358 struct tevent_context *ev;
2359 struct tevent_req *req;
2360 NTSTATUS status = NT_STATUS_NO_MEMORY;
2362 if (smbXcli_conn_has_async_calls(cli->conn)) {
2363 return NT_STATUS_INVALID_PARAMETER;
2365 ev = samba_tevent_context_init(talloc_tos());
2369 req = cli_tree_connect_send(ev, ev, cli, share, dev, pass);
2373 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2376 status = cli_tree_connect_recv(req);
2382 NTSTATUS cli_tree_connect_creds(struct cli_state *cli,
2383 const char *share, const char *dev,
2384 struct cli_credentials *creds)
2386 const char *pw = NULL;
2388 if (creds != NULL) {
2389 pw = cli_credentials_get_password(creds);
2392 return cli_tree_connect(cli, share, dev, pw);
2395 /****************************************************************************
2396 Send a tree disconnect.
2397 ****************************************************************************/
2399 struct cli_tdis_state {
2400 struct cli_state *cli;
2403 static void cli_tdis_done(struct tevent_req *subreq);
2405 static struct tevent_req *cli_tdis_send(TALLOC_CTX *mem_ctx,
2406 struct tevent_context *ev,
2407 struct cli_state *cli)
2409 struct tevent_req *req, *subreq;
2410 struct cli_tdis_state *state;
2412 req = tevent_req_create(mem_ctx, &state, struct cli_tdis_state);
2418 subreq = cli_smb_send(state, ev, cli, SMBtdis, 0, 0, 0, NULL, 0, NULL);
2419 if (tevent_req_nomem(subreq, req)) {
2420 return tevent_req_post(req, ev);
2422 tevent_req_set_callback(subreq, cli_tdis_done, req);
2426 static void cli_tdis_done(struct tevent_req *subreq)
2428 struct tevent_req *req = tevent_req_callback_data(
2429 subreq, struct tevent_req);
2430 struct cli_tdis_state *state = tevent_req_data(
2431 req, struct cli_tdis_state);
2434 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
2435 TALLOC_FREE(subreq);
2436 if (!NT_STATUS_IS_OK(status)) {
2437 tevent_req_nterror(req, status);
2440 TALLOC_FREE(state->cli->smb1.tcon);
2441 tevent_req_done(req);
2444 static NTSTATUS cli_tdis_recv(struct tevent_req *req)
2446 return tevent_req_simple_recv_ntstatus(req);
2449 NTSTATUS cli_tdis(struct cli_state *cli)
2451 struct tevent_context *ev;
2452 struct tevent_req *req;
2453 NTSTATUS status = NT_STATUS_NO_MEMORY;
2455 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
2456 status = smb2cli_tdis(cli->conn,
2460 if (NT_STATUS_IS_OK(status)) {
2461 TALLOC_FREE(cli->smb2.tcon);
2466 if (smbXcli_conn_has_async_calls(cli->conn)) {
2467 return NT_STATUS_INVALID_PARAMETER;
2469 ev = samba_tevent_context_init(talloc_tos());
2473 req = cli_tdis_send(ev, ev, cli);
2477 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2480 status = cli_tdis_recv(req);
2486 struct cli_connect_sock_state {
2487 const char **called_names;
2488 const char **calling_names;
2494 static void cli_connect_sock_done(struct tevent_req *subreq);
2497 * Async only if we don't have to look up the name, i.e. "pss" is set with a
2501 static struct tevent_req *cli_connect_sock_send(
2502 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2503 const char *host, int name_type, const struct sockaddr_storage *pss,
2504 const char *myname, uint16_t port)
2506 struct tevent_req *req, *subreq;
2507 struct cli_connect_sock_state *state;
2509 struct sockaddr_storage *addrs;
2510 unsigned i, num_addrs;
2513 req = tevent_req_create(mem_ctx, &state,
2514 struct cli_connect_sock_state);
2519 prog = getenv("LIBSMB_PROG");
2521 state->fd = sock_exec(prog);
2522 if (state->fd == -1) {
2523 status = map_nt_error_from_unix(errno);
2524 tevent_req_nterror(req, status);
2527 tevent_req_done(req);
2529 return tevent_req_post(req, ev);
2532 if ((pss == NULL) || is_zero_addr(pss)) {
2535 * Here we cheat. resolve_name_list is not async at all. So
2536 * this call will only be really async if the name lookup has
2537 * been done externally.
2540 status = resolve_name_list(state, host, name_type,
2541 &addrs, &num_addrs);
2542 if (!NT_STATUS_IS_OK(status)) {
2543 tevent_req_nterror(req, status);
2544 return tevent_req_post(req, ev);
2547 addrs = talloc_array(state, struct sockaddr_storage, 1);
2548 if (tevent_req_nomem(addrs, req)) {
2549 return tevent_req_post(req, ev);
2555 state->called_names = talloc_array(state, const char *, num_addrs);
2556 if (tevent_req_nomem(state->called_names, req)) {
2557 return tevent_req_post(req, ev);
2559 state->called_types = talloc_array(state, int, num_addrs);
2560 if (tevent_req_nomem(state->called_types, req)) {
2561 return tevent_req_post(req, ev);
2563 state->calling_names = talloc_array(state, const char *, num_addrs);
2564 if (tevent_req_nomem(state->calling_names, req)) {
2565 return tevent_req_post(req, ev);
2567 for (i=0; i<num_addrs; i++) {
2568 state->called_names[i] = host;
2569 state->called_types[i] = name_type;
2570 state->calling_names[i] = myname;
2573 subreq = smbsock_any_connect_send(
2574 state, ev, addrs, state->called_names, state->called_types,
2575 state->calling_names, NULL, num_addrs, port);
2576 if (tevent_req_nomem(subreq, req)) {
2577 return tevent_req_post(req, ev);
2579 tevent_req_set_callback(subreq, cli_connect_sock_done, req);
2583 static void cli_connect_sock_done(struct tevent_req *subreq)
2585 struct tevent_req *req = tevent_req_callback_data(
2586 subreq, struct tevent_req);
2587 struct cli_connect_sock_state *state = tevent_req_data(
2588 req, struct cli_connect_sock_state);
2591 status = smbsock_any_connect_recv(subreq, &state->fd, NULL,
2593 TALLOC_FREE(subreq);
2594 if (tevent_req_nterror(req, status)) {
2597 set_socket_options(state->fd, lp_socket_options());
2598 tevent_req_done(req);
2601 static NTSTATUS cli_connect_sock_recv(struct tevent_req *req,
2602 int *pfd, uint16_t *pport)
2604 struct cli_connect_sock_state *state = tevent_req_data(
2605 req, struct cli_connect_sock_state);
2608 if (tevent_req_is_nterror(req, &status)) {
2612 *pport = state->port;
2613 return NT_STATUS_OK;
2616 struct cli_connect_nb_state {
2617 const char *desthost;
2620 struct cli_state *cli;
2623 static void cli_connect_nb_done(struct tevent_req *subreq);
2625 static struct tevent_req *cli_connect_nb_send(
2626 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2627 const char *host, const struct sockaddr_storage *dest_ss,
2628 uint16_t port, int name_type, const char *myname,
2629 int signing_state, int flags)
2631 struct tevent_req *req, *subreq;
2632 struct cli_connect_nb_state *state;
2634 req = tevent_req_create(mem_ctx, &state, struct cli_connect_nb_state);
2638 state->signing_state = signing_state;
2639 state->flags = flags;
2642 char *p = strchr(host, '#');
2645 name_type = strtol(p+1, NULL, 16);
2646 host = talloc_strndup(state, host, p - host);
2647 if (tevent_req_nomem(host, req)) {
2648 return tevent_req_post(req, ev);
2652 state->desthost = host;
2653 } else if (dest_ss != NULL) {
2654 state->desthost = print_canonical_sockaddr(state, dest_ss);
2655 if (tevent_req_nomem(state->desthost, req)) {
2656 return tevent_req_post(req, ev);
2659 /* No host or dest_ss given. Error out. */
2660 tevent_req_error(req, EINVAL);
2661 return tevent_req_post(req, ev);
2664 subreq = cli_connect_sock_send(state, ev, host, name_type, dest_ss,
2666 if (tevent_req_nomem(subreq, req)) {
2667 return tevent_req_post(req, ev);
2669 tevent_req_set_callback(subreq, cli_connect_nb_done, req);
2673 static void cli_connect_nb_done(struct tevent_req *subreq)
2675 struct tevent_req *req = tevent_req_callback_data(
2676 subreq, struct tevent_req);
2677 struct cli_connect_nb_state *state = tevent_req_data(
2678 req, struct cli_connect_nb_state);
2683 status = cli_connect_sock_recv(subreq, &fd, &port);
2684 TALLOC_FREE(subreq);
2685 if (tevent_req_nterror(req, status)) {
2689 state->cli = cli_state_create(state, fd, state->desthost,
2690 state->signing_state, state->flags);
2691 if (tevent_req_nomem(state->cli, req)) {
2695 tevent_req_done(req);
2698 static NTSTATUS cli_connect_nb_recv(struct tevent_req *req,
2699 struct cli_state **pcli)
2701 struct cli_connect_nb_state *state = tevent_req_data(
2702 req, struct cli_connect_nb_state);
2705 if (tevent_req_is_nterror(req, &status)) {
2708 *pcli = talloc_move(NULL, &state->cli);
2709 return NT_STATUS_OK;
2712 NTSTATUS cli_connect_nb(const char *host, const struct sockaddr_storage *dest_ss,
2713 uint16_t port, int name_type, const char *myname,
2714 int signing_state, int flags, struct cli_state **pcli)
2716 struct tevent_context *ev;
2717 struct tevent_req *req;
2718 NTSTATUS status = NT_STATUS_NO_MEMORY;
2720 ev = samba_tevent_context_init(talloc_tos());
2724 req = cli_connect_nb_send(ev, ev, host, dest_ss, port, name_type,
2725 myname, signing_state, flags);
2729 if (!tevent_req_set_endtime(req, ev, timeval_current_ofs(20, 0))) {
2732 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2735 status = cli_connect_nb_recv(req, pcli);
2741 struct cli_start_connection_state {
2742 struct tevent_context *ev;
2743 struct cli_state *cli;
2748 static void cli_start_connection_connected(struct tevent_req *subreq);
2749 static void cli_start_connection_done(struct tevent_req *subreq);
2752 establishes a connection to after the negprot.
2753 @param output_cli A fully initialised cli structure, non-null only on success
2754 @param dest_host The netbios name of the remote host
2755 @param dest_ss (optional) The the destination IP, NULL for name based lookup
2756 @param port (optional) The destination port (0 for default)
2759 static struct tevent_req *cli_start_connection_send(
2760 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2761 const char *my_name, const char *dest_host,
2762 const struct sockaddr_storage *dest_ss, int port,
2763 int signing_state, int flags)
2765 struct tevent_req *req, *subreq;
2766 struct cli_start_connection_state *state;
2768 req = tevent_req_create(mem_ctx, &state,
2769 struct cli_start_connection_state);
2775 if (signing_state == SMB_SIGNING_IPC_DEFAULT) {
2776 state->min_protocol = lp_client_ipc_min_protocol();
2777 state->max_protocol = lp_client_ipc_max_protocol();
2779 state->min_protocol = lp_client_min_protocol();
2780 state->max_protocol = lp_client_max_protocol();
2783 if (flags & CLI_FULL_CONNECTION_FORCE_SMB1) {
2784 state->max_protocol = MIN(state->max_protocol, PROTOCOL_NT1);
2787 subreq = cli_connect_nb_send(state, ev, dest_host, dest_ss, port,
2788 0x20, my_name, signing_state, flags);
2789 if (tevent_req_nomem(subreq, req)) {
2790 return tevent_req_post(req, ev);
2792 tevent_req_set_callback(subreq, cli_start_connection_connected, req);
2796 static void cli_start_connection_connected(struct tevent_req *subreq)
2798 struct tevent_req *req = tevent_req_callback_data(
2799 subreq, struct tevent_req);
2800 struct cli_start_connection_state *state = tevent_req_data(
2801 req, struct cli_start_connection_state);
2804 status = cli_connect_nb_recv(subreq, &state->cli);
2805 TALLOC_FREE(subreq);
2806 if (tevent_req_nterror(req, status)) {
2810 subreq = smbXcli_negprot_send(state, state->ev, state->cli->conn,
2811 state->cli->timeout,
2812 state->min_protocol,
2813 state->max_protocol,
2814 WINDOWS_CLIENT_PURE_SMB2_NEGPROT_INITIAL_CREDIT_ASK);
2815 if (tevent_req_nomem(subreq, req)) {
2818 tevent_req_set_callback(subreq, cli_start_connection_done, req);
2821 static void cli_start_connection_done(struct tevent_req *subreq)
2823 struct tevent_req *req = tevent_req_callback_data(
2824 subreq, struct tevent_req);
2825 struct cli_start_connection_state *state = tevent_req_data(
2826 req, struct cli_start_connection_state);
2829 status = smbXcli_negprot_recv(subreq);
2830 TALLOC_FREE(subreq);
2831 if (tevent_req_nterror(req, status)) {
2835 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
2836 /* Ensure we ask for some initial credits. */
2837 smb2cli_conn_set_max_credits(state->cli->conn,
2838 DEFAULT_SMB2_MAX_CREDITS);
2841 tevent_req_done(req);
2844 static NTSTATUS cli_start_connection_recv(struct tevent_req *req,
2845 struct cli_state **output_cli)
2847 struct cli_start_connection_state *state = tevent_req_data(
2848 req, struct cli_start_connection_state);
2851 if (tevent_req_is_nterror(req, &status)) {
2854 *output_cli = state->cli;
2856 return NT_STATUS_OK;
2859 NTSTATUS cli_start_connection(struct cli_state **output_cli,
2860 const char *my_name,
2861 const char *dest_host,
2862 const struct sockaddr_storage *dest_ss, int port,
2863 int signing_state, int flags)
2865 struct tevent_context *ev;
2866 struct tevent_req *req;
2867 NTSTATUS status = NT_STATUS_NO_MEMORY;
2869 ev = samba_tevent_context_init(talloc_tos());
2873 req = cli_start_connection_send(ev, ev, my_name, dest_host, dest_ss,
2874 port, signing_state, flags);
2878 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2881 status = cli_start_connection_recv(req, output_cli);
2887 struct cli_smb1_setup_encryption_blob_state {
2892 uint16_t enc_ctx_id;
2895 static void cli_smb1_setup_encryption_blob_done(struct tevent_req *subreq);
2897 static struct tevent_req *cli_smb1_setup_encryption_blob_send(TALLOC_CTX *mem_ctx,
2898 struct tevent_context *ev,
2899 struct cli_state *cli,
2902 struct tevent_req *req = NULL;
2903 struct cli_smb1_setup_encryption_blob_state *state = NULL;
2904 struct tevent_req *subreq = NULL;
2906 req = tevent_req_create(mem_ctx, &state,
2907 struct cli_smb1_setup_encryption_blob_state);
2912 if (in.length > CLI_BUFFER_SIZE) {
2913 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
2914 return tevent_req_post(req, ev);
2917 SSVAL(state->setup+0, 0, TRANSACT2_SETFSINFO);
2918 SSVAL(state->param, 0, 0);
2919 SSVAL(state->param, 2, SMB_REQUEST_TRANSPORT_ENCRYPTION);
2921 subreq = smb1cli_trans_send(state, ev, cli->conn,
2929 NULL, /* pipe_name */
2935 in.data, in.length, CLI_BUFFER_SIZE);
2936 if (tevent_req_nomem(subreq, req)) {
2937 return tevent_req_post(req, ev);
2939 tevent_req_set_callback(subreq,
2940 cli_smb1_setup_encryption_blob_done,
2946 static void cli_smb1_setup_encryption_blob_done(struct tevent_req *subreq)
2948 struct tevent_req *req =
2949 tevent_req_callback_data(subreq,
2951 struct cli_smb1_setup_encryption_blob_state *state =
2952 tevent_req_data(req,
2953 struct cli_smb1_setup_encryption_blob_state);
2954 uint8_t *rparam=NULL, *rdata=NULL;
2955 uint32_t num_rparam, num_rdata;
2958 status = smb1cli_trans_recv(subreq, state,
2959 NULL, /* recv_flags */
2960 NULL, 0, NULL, /* rsetup */
2961 &rparam, 0, &num_rparam,
2962 &rdata, 0, &num_rdata);
2963 TALLOC_FREE(subreq);
2964 state->status = status;
2965 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
2966 status = NT_STATUS_OK;
2968 if (tevent_req_nterror(req, status)) {
2972 if (num_rparam == 2) {
2973 state->enc_ctx_id = SVAL(rparam, 0);
2975 TALLOC_FREE(rparam);
2977 state->out = data_blob_const(rdata, num_rdata);
2979 tevent_req_done(req);
2982 static NTSTATUS cli_smb1_setup_encryption_blob_recv(struct tevent_req *req,
2983 TALLOC_CTX *mem_ctx,
2985 uint16_t *enc_ctx_id)
2987 struct cli_smb1_setup_encryption_blob_state *state =
2988 tevent_req_data(req,
2989 struct cli_smb1_setup_encryption_blob_state);
2992 if (tevent_req_is_nterror(req, &status)) {
2993 tevent_req_received(req);
2997 status = state->status;
3000 talloc_steal(mem_ctx, out->data);
3002 *enc_ctx_id = state->enc_ctx_id;
3004 tevent_req_received(req);
3008 struct cli_smb1_setup_encryption_state {
3009 struct tevent_context *ev;
3010 struct cli_state *cli;
3011 struct smb_trans_enc_state *es;
3018 static void cli_smb1_setup_encryption_local_next(struct tevent_req *req);
3019 static void cli_smb1_setup_encryption_local_done(struct tevent_req *subreq);
3020 static void cli_smb1_setup_encryption_remote_next(struct tevent_req *req);
3021 static void cli_smb1_setup_encryption_remote_done(struct tevent_req *subreq);
3022 static void cli_smb1_setup_encryption_ready(struct tevent_req *req);
3024 static struct tevent_req *cli_smb1_setup_encryption_send(TALLOC_CTX *mem_ctx,
3025 struct tevent_context *ev,
3026 struct cli_state *cli,
3027 struct cli_credentials *creds)
3029 struct tevent_req *req = NULL;
3030 struct cli_smb1_setup_encryption_state *state = NULL;
3031 struct auth_generic_state *ags = NULL;
3032 const DATA_BLOB *b = NULL;
3033 bool auth_requested = false;
3034 const char *target_service = NULL;
3035 const char *target_hostname = NULL;
3038 req = tevent_req_create(mem_ctx, &state,
3039 struct cli_smb1_setup_encryption_state);
3046 auth_requested = cli_credentials_authentication_requested(creds);
3047 if (!auth_requested) {
3048 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
3049 return tevent_req_post(req, ev);
3052 target_service = "cifs";
3053 target_hostname = smbXcli_conn_remote_name(cli->conn);
3055 status = cli_session_creds_prepare_krb5(cli, creds);
3056 if (tevent_req_nterror(req, status)) {
3057 return tevent_req_post(req, ev);
3060 state->es = talloc_zero(state, struct smb_trans_enc_state);
3061 if (tevent_req_nomem(state->es, req)) {
3062 return tevent_req_post(req, ev);
3065 status = auth_generic_client_prepare(state->es, &ags);
3066 if (tevent_req_nterror(req, status)) {
3067 return tevent_req_post(req, ev);
3070 gensec_want_feature(ags->gensec_security,
3071 GENSEC_FEATURE_SIGN);
3072 gensec_want_feature(ags->gensec_security,
3073 GENSEC_FEATURE_SEAL);
3075 status = auth_generic_set_creds(ags, creds);
3076 if (tevent_req_nterror(req, status)) {
3077 return tevent_req_post(req, ev);
3080 if (target_service != NULL) {
3081 status = gensec_set_target_service(ags->gensec_security,
3083 if (tevent_req_nterror(req, status)) {
3084 return tevent_req_post(req, ev);
3088 if (target_hostname != NULL) {
3089 status = gensec_set_target_hostname(ags->gensec_security,
3091 if (tevent_req_nterror(req, status)) {
3092 return tevent_req_post(req, ev);
3096 gensec_set_max_update_size(ags->gensec_security,
3099 b = smbXcli_conn_server_gss_blob(state->cli->conn);
3101 state->blob_in = *b;
3104 status = auth_generic_client_start(ags, GENSEC_OID_SPNEGO);
3105 if (tevent_req_nterror(req, status)) {
3106 return tevent_req_post(req, ev);
3110 * We only need the gensec_security part from here.
3112 state->es->gensec_security = talloc_move(state->es,
3113 &ags->gensec_security);
3116 cli_smb1_setup_encryption_local_next(req);
3117 if (!tevent_req_is_in_progress(req)) {
3118 return tevent_req_post(req, ev);
3124 static void cli_smb1_setup_encryption_local_next(struct tevent_req *req)
3126 struct cli_smb1_setup_encryption_state *state =
3127 tevent_req_data(req,
3128 struct cli_smb1_setup_encryption_state);
3129 struct tevent_req *subreq = NULL;
3131 if (state->local_ready) {
3132 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3136 subreq = gensec_update_send(state, state->ev,
3137 state->es->gensec_security,
3139 if (tevent_req_nomem(subreq, req)) {
3142 tevent_req_set_callback(subreq, cli_smb1_setup_encryption_local_done, req);
3145 static void cli_smb1_setup_encryption_local_done(struct tevent_req *subreq)
3147 struct tevent_req *req =
3148 tevent_req_callback_data(subreq,
3150 struct cli_smb1_setup_encryption_state *state =
3151 tevent_req_data(req,
3152 struct cli_smb1_setup_encryption_state);
3155 status = gensec_update_recv(subreq, state, &state->blob_out);
3156 TALLOC_FREE(subreq);
3157 state->blob_in = data_blob_null;
3158 if (!NT_STATUS_IS_OK(status) &&
3159 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
3161 tevent_req_nterror(req, status);
3165 if (NT_STATUS_IS_OK(status)) {
3166 state->local_ready = true;
3170 * We always get NT_STATUS_OK from the server even if it is not ready.
3171 * So guess the server is ready when we are ready and already sent
3172 * our last blob to the server.
3174 if (state->local_ready && state->blob_out.length == 0) {
3175 state->remote_ready = true;
3178 if (state->local_ready && state->remote_ready) {
3179 cli_smb1_setup_encryption_ready(req);
3183 cli_smb1_setup_encryption_remote_next(req);
3186 static void cli_smb1_setup_encryption_remote_next(struct tevent_req *req)
3188 struct cli_smb1_setup_encryption_state *state =
3189 tevent_req_data(req,
3190 struct cli_smb1_setup_encryption_state);
3191 struct tevent_req *subreq = NULL;
3193 if (state->remote_ready) {
3194 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3198 subreq = cli_smb1_setup_encryption_blob_send(state, state->ev,
3199 state->cli, state->blob_out);
3200 if (tevent_req_nomem(subreq, req)) {
3203 tevent_req_set_callback(subreq,
3204 cli_smb1_setup_encryption_remote_done,
3208 static void cli_smb1_setup_encryption_remote_done(struct tevent_req *subreq)
3210 struct tevent_req *req =
3211 tevent_req_callback_data(subreq,
3213 struct cli_smb1_setup_encryption_state *state =
3214 tevent_req_data(req,
3215 struct cli_smb1_setup_encryption_state);
3218 status = cli_smb1_setup_encryption_blob_recv(subreq, state,
3220 &state->es->enc_ctx_num);
3221 TALLOC_FREE(subreq);
3222 data_blob_free(&state->blob_out);
3223 if (!NT_STATUS_IS_OK(status) &&
3224 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
3226 tevent_req_nterror(req, status);
3231 * We always get NT_STATUS_OK even if the server is not ready.
3232 * So guess the server is ready when we are ready and sent
3233 * our last blob to the server.
3235 if (state->local_ready) {
3236 state->remote_ready = true;
3239 if (state->local_ready && state->remote_ready) {
3240 cli_smb1_setup_encryption_ready(req);
3244 cli_smb1_setup_encryption_local_next(req);
3247 static void cli_smb1_setup_encryption_ready(struct tevent_req *req)
3249 struct cli_smb1_setup_encryption_state *state =
3250 tevent_req_data(req,
3251 struct cli_smb1_setup_encryption_state);
3252 struct smb_trans_enc_state *es = NULL;
3254 if (state->blob_in.length != 0) {
3255 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3259 if (state->blob_out.length != 0) {
3260 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3264 es = talloc_move(state->cli->conn, &state->es);
3266 smb1cli_conn_set_encryption(state->cli->conn, es);
3269 tevent_req_done(req);
3272 static NTSTATUS cli_smb1_setup_encryption_recv(struct tevent_req *req)
3274 return tevent_req_simple_recv_ntstatus(req);
3277 NTSTATUS cli_smb1_setup_encryption(struct cli_state *cli,
3278 struct cli_credentials *creds)
3280 struct tevent_context *ev = NULL;
3281 struct tevent_req *req = NULL;
3282 NTSTATUS status = NT_STATUS_NO_MEMORY;
3284 ev = samba_tevent_context_init(talloc_tos());
3288 req = cli_smb1_setup_encryption_send(ev, ev, cli, creds);
3292 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
3295 status = cli_smb1_setup_encryption_recv(req);
3302 establishes a connection right up to doing tconX, password specified.
3303 @param output_cli A fully initialised cli structure, non-null only on success
3304 @param dest_host The netbios name of the remote host
3305 @param dest_ip (optional) The the destination IP, NULL for name based lookup
3306 @param port (optional) The destination port (0 for default)
3307 @param service (optional) The share to make the connection to. Should be 'unqualified' in any way.
3308 @param service_type The 'type' of serivice.
3309 @param creds The used user credentials
3312 struct cli_full_connection_creds_state {
3313 struct tevent_context *ev;
3314 const char *service;
3315 const char *service_type;
3316 struct cli_credentials *creds;
3318 struct cli_state *cli;
3321 static int cli_full_connection_creds_state_destructor(
3322 struct cli_full_connection_creds_state *s)
3324 if (s->cli != NULL) {
3325 cli_shutdown(s->cli);
3331 static void cli_full_connection_creds_conn_done(struct tevent_req *subreq);
3332 static void cli_full_connection_creds_sess_start(struct tevent_req *req);
3333 static void cli_full_connection_creds_sess_done(struct tevent_req *subreq);
3334 static void cli_full_connection_creds_tcon_start(struct tevent_req *req);
3335 static void cli_full_connection_creds_tcon_done(struct tevent_req *subreq);
3337 struct tevent_req *cli_full_connection_creds_send(
3338 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
3339 const char *my_name, const char *dest_host,
3340 const struct sockaddr_storage *dest_ss, int port,
3341 const char *service, const char *service_type,
3342 struct cli_credentials *creds,
3343 int flags, int signing_state)
3345 struct tevent_req *req, *subreq;
3346 struct cli_full_connection_creds_state *state;
3347 enum credentials_use_kerberos krb5_state;
3348 uint32_t gensec_features = 0;
3350 req = tevent_req_create(mem_ctx, &state,
3351 struct cli_full_connection_creds_state);
3355 talloc_set_destructor(state, cli_full_connection_creds_state_destructor);
3357 flags &= ~CLI_FULL_CONNECTION_USE_KERBEROS;
3358 flags &= ~CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS;
3359 flags &= ~CLI_FULL_CONNECTION_USE_CCACHE;
3360 flags &= ~CLI_FULL_CONNECTION_USE_NT_HASH;
3362 krb5_state = cli_credentials_get_kerberos_state(creds);
3363 switch (krb5_state) {
3364 case CRED_MUST_USE_KERBEROS:
3365 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
3366 flags &= ~CLI_FULL_CONNECTION_DONT_SPNEGO;
3368 case CRED_AUTO_USE_KERBEROS:
3369 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
3370 flags |= CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS;
3372 case CRED_DONT_USE_KERBEROS:
3376 gensec_features = cli_credentials_get_gensec_features(creds);
3377 if (gensec_features & GENSEC_FEATURE_NTLM_CCACHE) {
3378 flags |= CLI_FULL_CONNECTION_USE_CCACHE;
3382 state->service = service;
3383 state->service_type = service_type;
3384 state->creds = creds;
3385 state->flags = flags;
3387 subreq = cli_start_connection_send(
3388 state, ev, my_name, dest_host, dest_ss, port,
3389 signing_state, flags);
3390 if (tevent_req_nomem(subreq, req)) {
3391 return tevent_req_post(req, ev);
3393 tevent_req_set_callback(subreq,
3394 cli_full_connection_creds_conn_done,
3399 static void cli_full_connection_creds_conn_done(struct tevent_req *subreq)
3401 struct tevent_req *req = tevent_req_callback_data(
3402 subreq, struct tevent_req);
3403 struct cli_full_connection_creds_state *state = tevent_req_data(
3404 req, struct cli_full_connection_creds_state);
3407 status = cli_start_connection_recv(subreq, &state->cli);
3408 TALLOC_FREE(subreq);
3409 if (tevent_req_nterror(req, status)) {
3413 cli_full_connection_creds_sess_start(req);
3416 static void cli_full_connection_creds_sess_start(struct tevent_req *req)
3418 struct cli_full_connection_creds_state *state = tevent_req_data(
3419 req, struct cli_full_connection_creds_state);
3420 struct tevent_req *subreq = NULL;
3422 subreq = cli_session_setup_creds_send(
3423 state, state->ev, state->cli, state->creds);
3424 if (tevent_req_nomem(subreq, req)) {
3427 tevent_req_set_callback(subreq,
3428 cli_full_connection_creds_sess_done,
3432 static void cli_full_connection_creds_sess_done(struct tevent_req *subreq)
3434 struct tevent_req *req = tevent_req_callback_data(
3435 subreq, struct tevent_req);
3436 struct cli_full_connection_creds_state *state = tevent_req_data(
3437 req, struct cli_full_connection_creds_state);
3440 status = cli_session_setup_creds_recv(subreq);
3441 TALLOC_FREE(subreq);
3443 if (!NT_STATUS_IS_OK(status) &&
3444 (state->flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)) {
3446 state->flags &= ~CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
3448 state->creds = cli_credentials_init_anon(state);
3449 if (tevent_req_nomem(state->creds, req)) {
3453 cli_full_connection_creds_sess_start(req);
3457 if (tevent_req_nterror(req, status)) {
3461 cli_full_connection_creds_tcon_start(req);
3464 static void cli_full_connection_creds_tcon_start(struct tevent_req *req)
3466 struct cli_full_connection_creds_state *state = tevent_req_data(
3467 req, struct cli_full_connection_creds_state);
3468 struct tevent_req *subreq = NULL;
3469 const char *password = NULL;
3471 if (state->service == NULL) {
3472 tevent_req_done(req);
3476 password = cli_credentials_get_password(state->creds);
3478 subreq = cli_tree_connect_send(state, state->ev,
3481 state->service_type,
3483 if (tevent_req_nomem(subreq, req)) {
3486 tevent_req_set_callback(subreq,
3487 cli_full_connection_creds_tcon_done,
3491 static void cli_full_connection_creds_tcon_done(struct tevent_req *subreq)
3493 struct tevent_req *req = tevent_req_callback_data(
3494 subreq, struct tevent_req);
3497 status = cli_tree_connect_recv(subreq);
3498 TALLOC_FREE(subreq);
3499 if (tevent_req_nterror(req, status)) {
3503 tevent_req_done(req);
3506 NTSTATUS cli_full_connection_creds_recv(struct tevent_req *req,
3507 struct cli_state **output_cli)
3509 struct cli_full_connection_creds_state *state = tevent_req_data(
3510 req, struct cli_full_connection_creds_state);
3513 if (tevent_req_is_nterror(req, &status)) {
3516 *output_cli = state->cli;
3517 talloc_set_destructor(state, NULL);
3518 return NT_STATUS_OK;
3521 NTSTATUS cli_full_connection_creds(struct cli_state **output_cli,
3522 const char *my_name,
3523 const char *dest_host,
3524 const struct sockaddr_storage *dest_ss, int port,
3525 const char *service, const char *service_type,
3526 struct cli_credentials *creds,
3530 struct tevent_context *ev;
3531 struct tevent_req *req;
3532 NTSTATUS status = NT_STATUS_NO_MEMORY;
3534 ev = samba_tevent_context_init(talloc_tos());
3538 req = cli_full_connection_creds_send(
3539 ev, ev, my_name, dest_host, dest_ss, port, service,
3540 service_type, creds, flags, signing_state);
3544 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
3547 status = cli_full_connection_creds_recv(req, output_cli);
3553 NTSTATUS cli_full_connection(struct cli_state **output_cli,
3554 const char *my_name,
3555 const char *dest_host,
3556 const struct sockaddr_storage *dest_ss, int port,
3557 const char *service, const char *service_type,
3558 const char *user, const char *domain,
3559 const char *password, int flags,
3562 TALLOC_CTX *frame = talloc_stackframe();
3564 bool use_kerberos = false;
3565 bool fallback_after_kerberos = false;
3566 bool use_ccache = false;
3567 bool pw_nt_hash = false;
3568 struct cli_credentials *creds = NULL;
3570 if (flags & CLI_FULL_CONNECTION_USE_KERBEROS) {
3571 use_kerberos = true;
3574 if (flags & CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS) {
3575 fallback_after_kerberos = true;
3578 if (flags & CLI_FULL_CONNECTION_USE_CCACHE) {
3582 if (flags & CLI_FULL_CONNECTION_USE_NT_HASH) {
3586 creds = cli_session_creds_init(frame,
3589 NULL, /* realm (use default) */
3592 fallback_after_kerberos,
3595 if (creds == NULL) {
3597 return NT_STATUS_NO_MEMORY;
3600 status = cli_full_connection_creds(output_cli, my_name,
3601 dest_host, dest_ss, port,
3602 service, service_type,
3603 creds, flags, signing_state);
3604 if (!NT_STATUS_IS_OK(status)) {
3610 return NT_STATUS_OK;
3613 /****************************************************************************
3614 Send an old style tcon.
3615 ****************************************************************************/
3616 struct cli_raw_tcon_state {
3620 static void cli_raw_tcon_done(struct tevent_req *subreq);
3622 static struct tevent_req *cli_raw_tcon_send(
3623 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
3624 const char *service, const char *pass, const char *dev)
3626 struct tevent_req *req, *subreq;
3627 struct cli_raw_tcon_state *state;
3630 req = tevent_req_create(mem_ctx, &state, struct cli_raw_tcon_state);
3635 if (!lp_client_plaintext_auth() && (*pass)) {
3636 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
3637 " or 'client ntlmv2 auth = yes'\n"));
3638 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
3639 return tevent_req_post(req, ev);
3642 TALLOC_FREE(cli->smb1.tcon);
3643 cli->smb1.tcon = smbXcli_tcon_create(cli);
3644 if (tevent_req_nomem(cli->smb1.tcon, req)) {
3645 return tevent_req_post(req, ev);
3647 smb1cli_tcon_set_id(cli->smb1.tcon, UINT16_MAX);
3649 bytes = talloc_array(state, uint8_t, 0);
3650 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3651 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3652 service, strlen(service)+1, NULL);
3653 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3654 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3655 pass, strlen(pass)+1, NULL);
3656 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3657 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3658 dev, strlen(dev)+1, NULL);
3660 if (tevent_req_nomem(bytes, req)) {
3661 return tevent_req_post(req, ev);
3664 subreq = cli_smb_send(state, ev, cli, SMBtcon, 0, 0, 0, NULL,
3665 talloc_get_size(bytes), bytes);
3666 if (tevent_req_nomem(subreq, req)) {
3667 return tevent_req_post(req, ev);
3669 tevent_req_set_callback(subreq, cli_raw_tcon_done, req);
3673 static void cli_raw_tcon_done(struct tevent_req *subreq)
3675 struct tevent_req *req = tevent_req_callback_data(
3676 subreq, struct tevent_req);
3677 struct cli_raw_tcon_state *state = tevent_req_data(
3678 req, struct cli_raw_tcon_state);
3681 status = cli_smb_recv(subreq, state, NULL, 2, NULL, &state->ret_vwv,
3683 TALLOC_FREE(subreq);
3684 if (tevent_req_nterror(req, status)) {
3687 tevent_req_done(req);
3690 static NTSTATUS cli_raw_tcon_recv(struct tevent_req *req,
3691 uint16_t *max_xmit, uint16_t *tid)
3693 struct cli_raw_tcon_state *state = tevent_req_data(
3694 req, struct cli_raw_tcon_state);
3697 if (tevent_req_is_nterror(req, &status)) {
3700 *max_xmit = SVAL(state->ret_vwv + 0, 0);
3701 *tid = SVAL(state->ret_vwv + 1, 0);
3702 return NT_STATUS_OK;
3705 NTSTATUS cli_raw_tcon(struct cli_state *cli,
3706 const char *service, const char *pass, const char *dev,
3707 uint16_t *max_xmit, uint16_t *tid)
3709 struct tevent_context *ev;
3710 struct tevent_req *req;
3711 NTSTATUS status = NT_STATUS_NO_MEMORY;
3713 ev = samba_tevent_context_init(talloc_tos());
3717 req = cli_raw_tcon_send(ev, ev, cli, service, pass, dev);
3721 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
3724 status = cli_raw_tcon_recv(req, max_xmit, tid);
3730 /* Return a cli_state pointing at the IPC$ share for the given server */
3732 struct cli_state *get_ipc_connect(char *server,
3733 struct sockaddr_storage *server_ss,
3734 const struct user_auth_info *user_info)
3736 struct cli_state *cli;
3738 uint32_t flags = CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
3740 if (get_cmdline_auth_info_use_kerberos(user_info)) {
3741 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
3744 nt_status = cli_full_connection(&cli, NULL, server, server_ss, 0, "IPC$", "IPC",
3745 get_cmdline_auth_info_username(user_info),
3747 get_cmdline_auth_info_password(user_info),
3749 SMB_SIGNING_DEFAULT);
3751 if (NT_STATUS_IS_OK(nt_status)) {
3753 } else if (is_ipaddress(server)) {
3754 /* windows 9* needs a correct NMB name for connections */
3755 fstring remote_name;
3757 if (name_status_find("*", 0, 0, server_ss, remote_name)) {
3758 cli = get_ipc_connect(remote_name, server_ss, user_info);
3767 * Given the IP address of a master browser on the network, return its
3768 * workgroup and connect to it.
3770 * This function is provided to allow additional processing beyond what
3771 * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
3772 * browsers and obtain each master browsers' list of domains (in case the
3773 * first master browser is recently on the network and has not yet
3774 * synchronized with other master browsers and therefore does not yet have the
3775 * entire network browse list)
3778 struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx,
3779 struct sockaddr_storage *mb_ip,
3780 const struct user_auth_info *user_info,
3781 char **pp_workgroup_out)
3783 char addr[INET6_ADDRSTRLEN];
3785 struct cli_state *cli;
3786 struct sockaddr_storage server_ss;
3788 *pp_workgroup_out = NULL;
3790 print_sockaddr(addr, sizeof(addr), mb_ip);
3791 DEBUG(99, ("Looking up name of master browser %s\n",
3795 * Do a name status query to find out the name of the master browser.
3796 * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
3797 * master browser will not respond to a wildcard query (or, at least,
3798 * an NT4 server acting as the domain master browser will not).
3800 * We might be able to use ONLY the query on MSBROWSE, but that's not
3801 * yet been tested with all Windows versions, so until it is, leave
3802 * the original wildcard query as the first choice and fall back to
3803 * MSBROWSE if the wildcard query fails.
3805 if (!name_status_find("*", 0, 0x1d, mb_ip, name) &&
3806 !name_status_find(MSBROWSE, 1, 0x1d, mb_ip, name)) {
3808 DEBUG(99, ("Could not retrieve name status for %s\n",
3813 if (!find_master_ip(name, &server_ss)) {
3814 DEBUG(99, ("Could not find master ip for %s\n", name));
3818 *pp_workgroup_out = talloc_strdup(ctx, name);
3820 DEBUG(4, ("found master browser %s, %s\n", name, addr));
3822 print_sockaddr(addr, sizeof(addr), &server_ss);
3823 cli = get_ipc_connect(addr, &server_ss, user_info);
3829 * Return the IP address and workgroup of a master browser on the network, and
3833 struct cli_state *get_ipc_connect_master_ip_bcast(TALLOC_CTX *ctx,
3834 const struct user_auth_info *user_info,
3835 char **pp_workgroup_out)
3837 struct sockaddr_storage *ip_list;
3838 struct cli_state *cli;
3842 *pp_workgroup_out = NULL;
3844 DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
3846 /* Go looking for workgroups by broadcasting on the local network */
3848 status = name_resolve_bcast(MSBROWSE, 1, talloc_tos(),
3850 if (!NT_STATUS_IS_OK(status)) {
3851 DEBUG(99, ("No master browsers responded: %s\n",
3852 nt_errstr(status)));
3856 for (i = 0; i < count; i++) {
3857 char addr[INET6_ADDRSTRLEN];
3858 print_sockaddr(addr, sizeof(addr), &ip_list[i]);
3859 DEBUG(99, ("Found master browser %s\n", addr));
3861 cli = get_ipc_connect_master_ip(ctx, &ip_list[i],
3862 user_info, pp_workgroup_out);