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 subreq = cli_connect_nb_send(state, ev, dest_host, dest_ss, port,
2784 0x20, my_name, signing_state, flags);
2785 if (tevent_req_nomem(subreq, req)) {
2786 return tevent_req_post(req, ev);
2788 tevent_req_set_callback(subreq, cli_start_connection_connected, req);
2792 static void cli_start_connection_connected(struct tevent_req *subreq)
2794 struct tevent_req *req = tevent_req_callback_data(
2795 subreq, struct tevent_req);
2796 struct cli_start_connection_state *state = tevent_req_data(
2797 req, struct cli_start_connection_state);
2800 status = cli_connect_nb_recv(subreq, &state->cli);
2801 TALLOC_FREE(subreq);
2802 if (tevent_req_nterror(req, status)) {
2806 subreq = smbXcli_negprot_send(state, state->ev, state->cli->conn,
2807 state->cli->timeout,
2808 state->min_protocol,
2809 state->max_protocol,
2810 WINDOWS_CLIENT_PURE_SMB2_NEGPROT_INITIAL_CREDIT_ASK);
2811 if (tevent_req_nomem(subreq, req)) {
2814 tevent_req_set_callback(subreq, cli_start_connection_done, req);
2817 static void cli_start_connection_done(struct tevent_req *subreq)
2819 struct tevent_req *req = tevent_req_callback_data(
2820 subreq, struct tevent_req);
2821 struct cli_start_connection_state *state = tevent_req_data(
2822 req, struct cli_start_connection_state);
2825 status = smbXcli_negprot_recv(subreq);
2826 TALLOC_FREE(subreq);
2827 if (tevent_req_nterror(req, status)) {
2831 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
2832 /* Ensure we ask for some initial credits. */
2833 smb2cli_conn_set_max_credits(state->cli->conn,
2834 DEFAULT_SMB2_MAX_CREDITS);
2837 tevent_req_done(req);
2840 static NTSTATUS cli_start_connection_recv(struct tevent_req *req,
2841 struct cli_state **output_cli)
2843 struct cli_start_connection_state *state = tevent_req_data(
2844 req, struct cli_start_connection_state);
2847 if (tevent_req_is_nterror(req, &status)) {
2850 *output_cli = state->cli;
2852 return NT_STATUS_OK;
2855 NTSTATUS cli_start_connection(struct cli_state **output_cli,
2856 const char *my_name,
2857 const char *dest_host,
2858 const struct sockaddr_storage *dest_ss, int port,
2859 int signing_state, int flags)
2861 struct tevent_context *ev;
2862 struct tevent_req *req;
2863 NTSTATUS status = NT_STATUS_NO_MEMORY;
2865 ev = samba_tevent_context_init(talloc_tos());
2869 req = cli_start_connection_send(ev, ev, my_name, dest_host, dest_ss,
2870 port, signing_state, flags);
2874 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2877 status = cli_start_connection_recv(req, output_cli);
2883 struct cli_smb1_setup_encryption_blob_state {
2888 uint16_t enc_ctx_id;
2891 static void cli_smb1_setup_encryption_blob_done(struct tevent_req *subreq);
2893 static struct tevent_req *cli_smb1_setup_encryption_blob_send(TALLOC_CTX *mem_ctx,
2894 struct tevent_context *ev,
2895 struct cli_state *cli,
2898 struct tevent_req *req = NULL;
2899 struct cli_smb1_setup_encryption_blob_state *state = NULL;
2900 struct tevent_req *subreq = NULL;
2902 req = tevent_req_create(mem_ctx, &state,
2903 struct cli_smb1_setup_encryption_blob_state);
2908 if (in.length > CLI_BUFFER_SIZE) {
2909 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
2910 return tevent_req_post(req, ev);
2913 SSVAL(state->setup+0, 0, TRANSACT2_SETFSINFO);
2914 SSVAL(state->param, 0, 0);
2915 SSVAL(state->param, 2, SMB_REQUEST_TRANSPORT_ENCRYPTION);
2917 subreq = smb1cli_trans_send(state, ev, cli->conn,
2925 NULL, /* pipe_name */
2931 in.data, in.length, CLI_BUFFER_SIZE);
2932 if (tevent_req_nomem(subreq, req)) {
2933 return tevent_req_post(req, ev);
2935 tevent_req_set_callback(subreq,
2936 cli_smb1_setup_encryption_blob_done,
2942 static void cli_smb1_setup_encryption_blob_done(struct tevent_req *subreq)
2944 struct tevent_req *req =
2945 tevent_req_callback_data(subreq,
2947 struct cli_smb1_setup_encryption_blob_state *state =
2948 tevent_req_data(req,
2949 struct cli_smb1_setup_encryption_blob_state);
2950 uint8_t *rparam=NULL, *rdata=NULL;
2951 uint32_t num_rparam, num_rdata;
2954 status = smb1cli_trans_recv(subreq, state,
2955 NULL, /* recv_flags */
2956 NULL, 0, NULL, /* rsetup */
2957 &rparam, 0, &num_rparam,
2958 &rdata, 0, &num_rdata);
2959 TALLOC_FREE(subreq);
2960 state->status = status;
2961 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
2962 status = NT_STATUS_OK;
2964 if (tevent_req_nterror(req, status)) {
2968 if (num_rparam == 2) {
2969 state->enc_ctx_id = SVAL(rparam, 0);
2971 TALLOC_FREE(rparam);
2973 state->out = data_blob_const(rdata, num_rdata);
2975 tevent_req_done(req);
2978 static NTSTATUS cli_smb1_setup_encryption_blob_recv(struct tevent_req *req,
2979 TALLOC_CTX *mem_ctx,
2981 uint16_t *enc_ctx_id)
2983 struct cli_smb1_setup_encryption_blob_state *state =
2984 tevent_req_data(req,
2985 struct cli_smb1_setup_encryption_blob_state);
2988 if (tevent_req_is_nterror(req, &status)) {
2989 tevent_req_received(req);
2993 status = state->status;
2996 talloc_steal(mem_ctx, out->data);
2998 *enc_ctx_id = state->enc_ctx_id;
3000 tevent_req_received(req);
3004 struct cli_smb1_setup_encryption_state {
3005 struct tevent_context *ev;
3006 struct cli_state *cli;
3007 struct smb_trans_enc_state *es;
3014 static void cli_smb1_setup_encryption_local_next(struct tevent_req *req);
3015 static void cli_smb1_setup_encryption_local_done(struct tevent_req *subreq);
3016 static void cli_smb1_setup_encryption_remote_next(struct tevent_req *req);
3017 static void cli_smb1_setup_encryption_remote_done(struct tevent_req *subreq);
3018 static void cli_smb1_setup_encryption_ready(struct tevent_req *req);
3020 static struct tevent_req *cli_smb1_setup_encryption_send(TALLOC_CTX *mem_ctx,
3021 struct tevent_context *ev,
3022 struct cli_state *cli,
3023 struct cli_credentials *creds)
3025 struct tevent_req *req = NULL;
3026 struct cli_smb1_setup_encryption_state *state = NULL;
3027 struct auth_generic_state *ags = NULL;
3028 const DATA_BLOB *b = NULL;
3029 bool auth_requested = false;
3030 const char *target_service = NULL;
3031 const char *target_hostname = NULL;
3034 req = tevent_req_create(mem_ctx, &state,
3035 struct cli_smb1_setup_encryption_state);
3042 auth_requested = cli_credentials_authentication_requested(creds);
3043 if (!auth_requested) {
3044 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
3045 return tevent_req_post(req, ev);
3048 target_service = "cifs";
3049 target_hostname = smbXcli_conn_remote_name(cli->conn);
3051 status = cli_session_creds_prepare_krb5(cli, creds);
3052 if (tevent_req_nterror(req, status)) {
3053 return tevent_req_post(req, ev);
3056 state->es = talloc_zero(state, struct smb_trans_enc_state);
3057 if (tevent_req_nomem(state->es, req)) {
3058 return tevent_req_post(req, ev);
3061 status = auth_generic_client_prepare(state->es, &ags);
3062 if (tevent_req_nterror(req, status)) {
3063 return tevent_req_post(req, ev);
3066 gensec_want_feature(ags->gensec_security,
3067 GENSEC_FEATURE_SIGN);
3068 gensec_want_feature(ags->gensec_security,
3069 GENSEC_FEATURE_SEAL);
3071 status = auth_generic_set_creds(ags, creds);
3072 if (tevent_req_nterror(req, status)) {
3073 return tevent_req_post(req, ev);
3076 if (target_service != NULL) {
3077 status = gensec_set_target_service(ags->gensec_security,
3079 if (tevent_req_nterror(req, status)) {
3080 return tevent_req_post(req, ev);
3084 if (target_hostname != NULL) {
3085 status = gensec_set_target_hostname(ags->gensec_security,
3087 if (tevent_req_nterror(req, status)) {
3088 return tevent_req_post(req, ev);
3092 gensec_set_max_update_size(ags->gensec_security,
3095 b = smbXcli_conn_server_gss_blob(state->cli->conn);
3097 state->blob_in = *b;
3100 status = auth_generic_client_start(ags, GENSEC_OID_SPNEGO);
3101 if (tevent_req_nterror(req, status)) {
3102 return tevent_req_post(req, ev);
3106 * We only need the gensec_security part from here.
3108 state->es->gensec_security = talloc_move(state->es,
3109 &ags->gensec_security);
3112 cli_smb1_setup_encryption_local_next(req);
3113 if (!tevent_req_is_in_progress(req)) {
3114 return tevent_req_post(req, ev);
3120 static void cli_smb1_setup_encryption_local_next(struct tevent_req *req)
3122 struct cli_smb1_setup_encryption_state *state =
3123 tevent_req_data(req,
3124 struct cli_smb1_setup_encryption_state);
3125 struct tevent_req *subreq = NULL;
3127 if (state->local_ready) {
3128 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3132 subreq = gensec_update_send(state, state->ev,
3133 state->es->gensec_security,
3135 if (tevent_req_nomem(subreq, req)) {
3138 tevent_req_set_callback(subreq, cli_smb1_setup_encryption_local_done, req);
3141 static void cli_smb1_setup_encryption_local_done(struct tevent_req *subreq)
3143 struct tevent_req *req =
3144 tevent_req_callback_data(subreq,
3146 struct cli_smb1_setup_encryption_state *state =
3147 tevent_req_data(req,
3148 struct cli_smb1_setup_encryption_state);
3151 status = gensec_update_recv(subreq, state, &state->blob_out);
3152 TALLOC_FREE(subreq);
3153 state->blob_in = data_blob_null;
3154 if (!NT_STATUS_IS_OK(status) &&
3155 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
3157 tevent_req_nterror(req, status);
3161 if (NT_STATUS_IS_OK(status)) {
3162 state->local_ready = true;
3166 * We always get NT_STATUS_OK from the server even if it is not ready.
3167 * So guess the server is ready when we are ready and already sent
3168 * our last blob to the server.
3170 if (state->local_ready && state->blob_out.length == 0) {
3171 state->remote_ready = true;
3174 if (state->local_ready && state->remote_ready) {
3175 cli_smb1_setup_encryption_ready(req);
3179 cli_smb1_setup_encryption_remote_next(req);
3182 static void cli_smb1_setup_encryption_remote_next(struct tevent_req *req)
3184 struct cli_smb1_setup_encryption_state *state =
3185 tevent_req_data(req,
3186 struct cli_smb1_setup_encryption_state);
3187 struct tevent_req *subreq = NULL;
3189 if (state->remote_ready) {
3190 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3194 subreq = cli_smb1_setup_encryption_blob_send(state, state->ev,
3195 state->cli, state->blob_out);
3196 if (tevent_req_nomem(subreq, req)) {
3199 tevent_req_set_callback(subreq,
3200 cli_smb1_setup_encryption_remote_done,
3204 static void cli_smb1_setup_encryption_remote_done(struct tevent_req *subreq)
3206 struct tevent_req *req =
3207 tevent_req_callback_data(subreq,
3209 struct cli_smb1_setup_encryption_state *state =
3210 tevent_req_data(req,
3211 struct cli_smb1_setup_encryption_state);
3214 status = cli_smb1_setup_encryption_blob_recv(subreq, state,
3216 &state->es->enc_ctx_num);
3217 TALLOC_FREE(subreq);
3218 data_blob_free(&state->blob_out);
3219 if (!NT_STATUS_IS_OK(status) &&
3220 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
3222 tevent_req_nterror(req, status);
3227 * We always get NT_STATUS_OK even if the server is not ready.
3228 * So guess the server is ready when we are ready and sent
3229 * our last blob to the server.
3231 if (state->local_ready) {
3232 state->remote_ready = true;
3235 if (state->local_ready && state->remote_ready) {
3236 cli_smb1_setup_encryption_ready(req);
3240 cli_smb1_setup_encryption_local_next(req);
3243 static void cli_smb1_setup_encryption_ready(struct tevent_req *req)
3245 struct cli_smb1_setup_encryption_state *state =
3246 tevent_req_data(req,
3247 struct cli_smb1_setup_encryption_state);
3248 struct smb_trans_enc_state *es = NULL;
3250 if (state->blob_in.length != 0) {
3251 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3255 if (state->blob_out.length != 0) {
3256 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3260 es = talloc_move(state->cli->conn, &state->es);
3262 smb1cli_conn_set_encryption(state->cli->conn, es);
3265 tevent_req_done(req);
3268 static NTSTATUS cli_smb1_setup_encryption_recv(struct tevent_req *req)
3270 return tevent_req_simple_recv_ntstatus(req);
3273 NTSTATUS cli_smb1_setup_encryption(struct cli_state *cli,
3274 struct cli_credentials *creds)
3276 struct tevent_context *ev = NULL;
3277 struct tevent_req *req = NULL;
3278 NTSTATUS status = NT_STATUS_NO_MEMORY;
3280 ev = samba_tevent_context_init(talloc_tos());
3284 req = cli_smb1_setup_encryption_send(ev, ev, cli, creds);
3288 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
3291 status = cli_smb1_setup_encryption_recv(req);
3298 establishes a connection right up to doing tconX, password specified.
3299 @param output_cli A fully initialised cli structure, non-null only on success
3300 @param dest_host The netbios name of the remote host
3301 @param dest_ip (optional) The the destination IP, NULL for name based lookup
3302 @param port (optional) The destination port (0 for default)
3303 @param service (optional) The share to make the connection to. Should be 'unqualified' in any way.
3304 @param service_type The 'type' of serivice.
3305 @param creds The used user credentials
3308 struct cli_full_connection_creds_state {
3309 struct tevent_context *ev;
3310 const char *service;
3311 const char *service_type;
3312 struct cli_credentials *creds;
3314 struct cli_state *cli;
3317 static int cli_full_connection_creds_state_destructor(
3318 struct cli_full_connection_creds_state *s)
3320 if (s->cli != NULL) {
3321 cli_shutdown(s->cli);
3327 static void cli_full_connection_creds_conn_done(struct tevent_req *subreq);
3328 static void cli_full_connection_creds_sess_start(struct tevent_req *req);
3329 static void cli_full_connection_creds_sess_done(struct tevent_req *subreq);
3330 static void cli_full_connection_creds_tcon_start(struct tevent_req *req);
3331 static void cli_full_connection_creds_tcon_done(struct tevent_req *subreq);
3333 struct tevent_req *cli_full_connection_creds_send(
3334 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
3335 const char *my_name, const char *dest_host,
3336 const struct sockaddr_storage *dest_ss, int port,
3337 const char *service, const char *service_type,
3338 struct cli_credentials *creds,
3339 int flags, int signing_state)
3341 struct tevent_req *req, *subreq;
3342 struct cli_full_connection_creds_state *state;
3343 enum credentials_use_kerberos krb5_state;
3344 uint32_t gensec_features = 0;
3346 req = tevent_req_create(mem_ctx, &state,
3347 struct cli_full_connection_creds_state);
3351 talloc_set_destructor(state, cli_full_connection_creds_state_destructor);
3353 flags &= ~CLI_FULL_CONNECTION_USE_KERBEROS;
3354 flags &= ~CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS;
3355 flags &= ~CLI_FULL_CONNECTION_USE_CCACHE;
3356 flags &= ~CLI_FULL_CONNECTION_USE_NT_HASH;
3358 krb5_state = cli_credentials_get_kerberos_state(creds);
3359 switch (krb5_state) {
3360 case CRED_MUST_USE_KERBEROS:
3361 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
3362 flags &= ~CLI_FULL_CONNECTION_DONT_SPNEGO;
3364 case CRED_AUTO_USE_KERBEROS:
3365 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
3366 flags |= CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS;
3368 case CRED_DONT_USE_KERBEROS:
3372 gensec_features = cli_credentials_get_gensec_features(creds);
3373 if (gensec_features & GENSEC_FEATURE_NTLM_CCACHE) {
3374 flags |= CLI_FULL_CONNECTION_USE_CCACHE;
3378 state->service = service;
3379 state->service_type = service_type;
3380 state->creds = creds;
3381 state->flags = flags;
3383 subreq = cli_start_connection_send(
3384 state, ev, my_name, dest_host, dest_ss, port,
3385 signing_state, flags);
3386 if (tevent_req_nomem(subreq, req)) {
3387 return tevent_req_post(req, ev);
3389 tevent_req_set_callback(subreq,
3390 cli_full_connection_creds_conn_done,
3395 static void cli_full_connection_creds_conn_done(struct tevent_req *subreq)
3397 struct tevent_req *req = tevent_req_callback_data(
3398 subreq, struct tevent_req);
3399 struct cli_full_connection_creds_state *state = tevent_req_data(
3400 req, struct cli_full_connection_creds_state);
3403 status = cli_start_connection_recv(subreq, &state->cli);
3404 TALLOC_FREE(subreq);
3405 if (tevent_req_nterror(req, status)) {
3409 cli_full_connection_creds_sess_start(req);
3412 static void cli_full_connection_creds_sess_start(struct tevent_req *req)
3414 struct cli_full_connection_creds_state *state = tevent_req_data(
3415 req, struct cli_full_connection_creds_state);
3416 struct tevent_req *subreq = NULL;
3418 subreq = cli_session_setup_creds_send(
3419 state, state->ev, state->cli, state->creds);
3420 if (tevent_req_nomem(subreq, req)) {
3423 tevent_req_set_callback(subreq,
3424 cli_full_connection_creds_sess_done,
3428 static void cli_full_connection_creds_sess_done(struct tevent_req *subreq)
3430 struct tevent_req *req = tevent_req_callback_data(
3431 subreq, struct tevent_req);
3432 struct cli_full_connection_creds_state *state = tevent_req_data(
3433 req, struct cli_full_connection_creds_state);
3436 status = cli_session_setup_creds_recv(subreq);
3437 TALLOC_FREE(subreq);
3439 if (!NT_STATUS_IS_OK(status) &&
3440 (state->flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)) {
3442 state->flags &= ~CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
3444 state->creds = cli_credentials_init_anon(state);
3445 if (tevent_req_nomem(state->creds, req)) {
3449 cli_full_connection_creds_sess_start(req);
3453 if (tevent_req_nterror(req, status)) {
3457 cli_full_connection_creds_tcon_start(req);
3460 static void cli_full_connection_creds_tcon_start(struct tevent_req *req)
3462 struct cli_full_connection_creds_state *state = tevent_req_data(
3463 req, struct cli_full_connection_creds_state);
3464 struct tevent_req *subreq = NULL;
3465 const char *password = NULL;
3467 if (state->service == NULL) {
3468 tevent_req_done(req);
3472 password = cli_credentials_get_password(state->creds);
3474 subreq = cli_tree_connect_send(state, state->ev,
3477 state->service_type,
3479 if (tevent_req_nomem(subreq, req)) {
3482 tevent_req_set_callback(subreq,
3483 cli_full_connection_creds_tcon_done,
3487 static void cli_full_connection_creds_tcon_done(struct tevent_req *subreq)
3489 struct tevent_req *req = tevent_req_callback_data(
3490 subreq, struct tevent_req);
3493 status = cli_tree_connect_recv(subreq);
3494 TALLOC_FREE(subreq);
3495 if (tevent_req_nterror(req, status)) {
3499 tevent_req_done(req);
3502 NTSTATUS cli_full_connection_creds_recv(struct tevent_req *req,
3503 struct cli_state **output_cli)
3505 struct cli_full_connection_creds_state *state = tevent_req_data(
3506 req, struct cli_full_connection_creds_state);
3509 if (tevent_req_is_nterror(req, &status)) {
3512 *output_cli = state->cli;
3513 talloc_set_destructor(state, NULL);
3514 return NT_STATUS_OK;
3517 NTSTATUS cli_full_connection_creds(struct cli_state **output_cli,
3518 const char *my_name,
3519 const char *dest_host,
3520 const struct sockaddr_storage *dest_ss, int port,
3521 const char *service, const char *service_type,
3522 struct cli_credentials *creds,
3526 struct tevent_context *ev;
3527 struct tevent_req *req;
3528 NTSTATUS status = NT_STATUS_NO_MEMORY;
3530 ev = samba_tevent_context_init(talloc_tos());
3534 req = cli_full_connection_creds_send(
3535 ev, ev, my_name, dest_host, dest_ss, port, service,
3536 service_type, creds, flags, signing_state);
3540 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
3543 status = cli_full_connection_creds_recv(req, output_cli);
3549 NTSTATUS cli_full_connection(struct cli_state **output_cli,
3550 const char *my_name,
3551 const char *dest_host,
3552 const struct sockaddr_storage *dest_ss, int port,
3553 const char *service, const char *service_type,
3554 const char *user, const char *domain,
3555 const char *password, int flags,
3558 TALLOC_CTX *frame = talloc_stackframe();
3560 bool use_kerberos = false;
3561 bool fallback_after_kerberos = false;
3562 bool use_ccache = false;
3563 bool pw_nt_hash = false;
3564 struct cli_credentials *creds = NULL;
3566 if (flags & CLI_FULL_CONNECTION_USE_KERBEROS) {
3567 use_kerberos = true;
3570 if (flags & CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS) {
3571 fallback_after_kerberos = true;
3574 if (flags & CLI_FULL_CONNECTION_USE_CCACHE) {
3578 if (flags & CLI_FULL_CONNECTION_USE_NT_HASH) {
3582 creds = cli_session_creds_init(frame,
3585 NULL, /* realm (use default) */
3588 fallback_after_kerberos,
3591 if (creds == NULL) {
3593 return NT_STATUS_NO_MEMORY;
3596 status = cli_full_connection_creds(output_cli, my_name,
3597 dest_host, dest_ss, port,
3598 service, service_type,
3599 creds, flags, signing_state);
3600 if (!NT_STATUS_IS_OK(status)) {
3606 return NT_STATUS_OK;
3609 /****************************************************************************
3610 Send an old style tcon.
3611 ****************************************************************************/
3612 struct cli_raw_tcon_state {
3616 static void cli_raw_tcon_done(struct tevent_req *subreq);
3618 static struct tevent_req *cli_raw_tcon_send(
3619 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
3620 const char *service, const char *pass, const char *dev)
3622 struct tevent_req *req, *subreq;
3623 struct cli_raw_tcon_state *state;
3626 req = tevent_req_create(mem_ctx, &state, struct cli_raw_tcon_state);
3631 if (!lp_client_plaintext_auth() && (*pass)) {
3632 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
3633 " or 'client ntlmv2 auth = yes'\n"));
3634 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
3635 return tevent_req_post(req, ev);
3638 TALLOC_FREE(cli->smb1.tcon);
3639 cli->smb1.tcon = smbXcli_tcon_create(cli);
3640 if (tevent_req_nomem(cli->smb1.tcon, req)) {
3641 return tevent_req_post(req, ev);
3643 smb1cli_tcon_set_id(cli->smb1.tcon, UINT16_MAX);
3645 bytes = talloc_array(state, uint8_t, 0);
3646 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3647 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3648 service, strlen(service)+1, NULL);
3649 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3650 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3651 pass, strlen(pass)+1, NULL);
3652 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3653 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3654 dev, strlen(dev)+1, NULL);
3656 if (tevent_req_nomem(bytes, req)) {
3657 return tevent_req_post(req, ev);
3660 subreq = cli_smb_send(state, ev, cli, SMBtcon, 0, 0, 0, NULL,
3661 talloc_get_size(bytes), bytes);
3662 if (tevent_req_nomem(subreq, req)) {
3663 return tevent_req_post(req, ev);
3665 tevent_req_set_callback(subreq, cli_raw_tcon_done, req);
3669 static void cli_raw_tcon_done(struct tevent_req *subreq)
3671 struct tevent_req *req = tevent_req_callback_data(
3672 subreq, struct tevent_req);
3673 struct cli_raw_tcon_state *state = tevent_req_data(
3674 req, struct cli_raw_tcon_state);
3677 status = cli_smb_recv(subreq, state, NULL, 2, NULL, &state->ret_vwv,
3679 TALLOC_FREE(subreq);
3680 if (tevent_req_nterror(req, status)) {
3683 tevent_req_done(req);
3686 static NTSTATUS cli_raw_tcon_recv(struct tevent_req *req,
3687 uint16_t *max_xmit, uint16_t *tid)
3689 struct cli_raw_tcon_state *state = tevent_req_data(
3690 req, struct cli_raw_tcon_state);
3693 if (tevent_req_is_nterror(req, &status)) {
3696 *max_xmit = SVAL(state->ret_vwv + 0, 0);
3697 *tid = SVAL(state->ret_vwv + 1, 0);
3698 return NT_STATUS_OK;
3701 NTSTATUS cli_raw_tcon(struct cli_state *cli,
3702 const char *service, const char *pass, const char *dev,
3703 uint16_t *max_xmit, uint16_t *tid)
3705 struct tevent_context *ev;
3706 struct tevent_req *req;
3707 NTSTATUS status = NT_STATUS_NO_MEMORY;
3709 ev = samba_tevent_context_init(talloc_tos());
3713 req = cli_raw_tcon_send(ev, ev, cli, service, pass, dev);
3717 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
3720 status = cli_raw_tcon_recv(req, max_xmit, tid);
3726 /* Return a cli_state pointing at the IPC$ share for the given server */
3728 struct cli_state *get_ipc_connect(char *server,
3729 struct sockaddr_storage *server_ss,
3730 const struct user_auth_info *user_info)
3732 struct cli_state *cli;
3734 uint32_t flags = CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
3736 if (get_cmdline_auth_info_use_kerberos(user_info)) {
3737 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
3740 nt_status = cli_full_connection(&cli, NULL, server, server_ss, 0, "IPC$", "IPC",
3741 get_cmdline_auth_info_username(user_info),
3743 get_cmdline_auth_info_password(user_info),
3745 SMB_SIGNING_DEFAULT);
3747 if (NT_STATUS_IS_OK(nt_status)) {
3749 } else if (is_ipaddress(server)) {
3750 /* windows 9* needs a correct NMB name for connections */
3751 fstring remote_name;
3753 if (name_status_find("*", 0, 0, server_ss, remote_name)) {
3754 cli = get_ipc_connect(remote_name, server_ss, user_info);
3763 * Given the IP address of a master browser on the network, return its
3764 * workgroup and connect to it.
3766 * This function is provided to allow additional processing beyond what
3767 * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
3768 * browsers and obtain each master browsers' list of domains (in case the
3769 * first master browser is recently on the network and has not yet
3770 * synchronized with other master browsers and therefore does not yet have the
3771 * entire network browse list)
3774 struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx,
3775 struct sockaddr_storage *mb_ip,
3776 const struct user_auth_info *user_info,
3777 char **pp_workgroup_out)
3779 char addr[INET6_ADDRSTRLEN];
3781 struct cli_state *cli;
3782 struct sockaddr_storage server_ss;
3784 *pp_workgroup_out = NULL;
3786 print_sockaddr(addr, sizeof(addr), mb_ip);
3787 DEBUG(99, ("Looking up name of master browser %s\n",
3791 * Do a name status query to find out the name of the master browser.
3792 * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
3793 * master browser will not respond to a wildcard query (or, at least,
3794 * an NT4 server acting as the domain master browser will not).
3796 * We might be able to use ONLY the query on MSBROWSE, but that's not
3797 * yet been tested with all Windows versions, so until it is, leave
3798 * the original wildcard query as the first choice and fall back to
3799 * MSBROWSE if the wildcard query fails.
3801 if (!name_status_find("*", 0, 0x1d, mb_ip, name) &&
3802 !name_status_find(MSBROWSE, 1, 0x1d, mb_ip, name)) {
3804 DEBUG(99, ("Could not retrieve name status for %s\n",
3809 if (!find_master_ip(name, &server_ss)) {
3810 DEBUG(99, ("Could not find master ip for %s\n", name));
3814 *pp_workgroup_out = talloc_strdup(ctx, name);
3816 DEBUG(4, ("found master browser %s, %s\n", name, addr));
3818 print_sockaddr(addr, sizeof(addr), &server_ss);
3819 cli = get_ipc_connect(addr, &server_ss, user_info);
3825 * Return the IP address and workgroup of a master browser on the network, and
3829 struct cli_state *get_ipc_connect_master_ip_bcast(TALLOC_CTX *ctx,
3830 const struct user_auth_info *user_info,
3831 char **pp_workgroup_out)
3833 struct sockaddr_storage *ip_list;
3834 struct cli_state *cli;
3838 *pp_workgroup_out = NULL;
3840 DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
3842 /* Go looking for workgroups by broadcasting on the local network */
3844 status = name_resolve_bcast(MSBROWSE, 1, talloc_tos(),
3846 if (!NT_STATUS_IS_OK(status)) {
3847 DEBUG(99, ("No master browsers responded: %s\n",
3848 nt_errstr(status)));
3852 for (i = 0; i < count; i++) {
3853 char addr[INET6_ADDRSTRLEN];
3854 print_sockaddr(addr, sizeof(addr), &ip_list[i]);
3855 DEBUG(99, ("Found master browser %s\n", addr));
3857 cli = get_ipc_connect_master_ip(ctx, &ip_list[i],
3858 user_info, pp_workgroup_out);