2 Unix SMB/CIFS implementation.
3 client connect/disconnect routines
4 Copyright (C) Andrew Tridgell 1994-1998
5 Copyright (C) Andrew Bartlett 2001-2003
6 Copyright (C) Volker Lendecke 2011
7 Copyright (C) Jeremy Allison 2011
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "libsmb/libsmb.h"
25 #include "libsmb/namequery.h"
26 #include "auth_info.h"
27 #include "../libcli/auth/libcli_auth.h"
28 #include "../libcli/auth/spnego.h"
30 #include "auth/credentials/credentials.h"
31 #include "auth/gensec/gensec.h"
32 #include "auth/ntlmssp/ntlmssp.h"
33 #include "auth_generic.h"
34 #include "libads/kerberos_proto.h"
36 #include "../lib/util/tevent_ntstatus.h"
37 #include "async_smb.h"
38 #include "libsmb/nmblib.h"
39 #include "librpc/ndr/libndr.h"
40 #include "../libcli/smb/smbXcli_base.h"
41 #include "../libcli/smb/smb_seal.h"
42 #include "lib/param/param.h"
43 #include "../libcli/smb/smb2_negotiate_context.h"
44 #include "libads/krb5_errs.h"
46 #define STAR_SMBSERVER "*SMBSERVER"
48 static char *cli_session_setup_get_account(TALLOC_CTX *mem_ctx,
49 const char *principal);
51 struct cli_credentials *cli_session_creds_init(TALLOC_CTX *mem_ctx,
57 bool fallback_after_kerberos,
59 bool password_is_nt_hash)
61 struct loadparm_context *lp_ctx = NULL;
62 struct cli_credentials *creds = NULL;
63 const char *principal = NULL;
68 creds = cli_credentials_init(mem_ctx);
73 lp_ctx = loadparm_init_s3(creds, loadparm_s3_helpers());
77 cli_credentials_set_conf(creds, lp_ctx);
79 if (username == NULL) {
83 if (strlen(username) == 0) {
84 if (password != NULL && strlen(password) == 0) {
86 * some callers pass "" as no password
88 * gensec only handles NULL as no password.
92 if (password == NULL) {
93 cli_credentials_set_anonymous(creds);
98 tmp = talloc_strdup(creds, username);
104 /* allow for workgroups as part of the username */
105 if ((p = strchr_m(tmp, '\\')) ||
106 (p = strchr_m(tmp, '/')) ||
107 (p = strchr_m(tmp, *lp_winbind_separator()))) {
113 principal = username;
114 username = cli_session_setup_get_account(creds, principal);
115 if (username == NULL) {
118 ok = strequal(username, principal);
121 * Ok still the same, so it's not a principal
126 if (use_kerberos && fallback_after_kerberos) {
127 cli_credentials_set_kerberos_state(creds,
128 CRED_AUTO_USE_KERBEROS);
129 } else if (use_kerberos) {
130 cli_credentials_set_kerberos_state(creds,
131 CRED_MUST_USE_KERBEROS);
133 cli_credentials_set_kerberos_state(creds,
134 CRED_DONT_USE_KERBEROS);
140 features = cli_credentials_get_gensec_features(creds);
141 features |= GENSEC_FEATURE_NTLM_CCACHE;
142 cli_credentials_set_gensec_features(creds, features);
144 if (password != NULL && strlen(password) == 0) {
146 * some callers pass "" as no password
148 * GENSEC_FEATURE_NTLM_CCACHE only handles
149 * NULL as no password.
155 ok = cli_credentials_set_username(creds,
162 if (domain != NULL) {
163 ok = cli_credentials_set_domain(creds,
171 if (principal != NULL) {
172 ok = cli_credentials_set_principal(creds,
181 ok = cli_credentials_set_realm(creds,
189 if (password != NULL && strlen(password) > 0) {
190 if (password_is_nt_hash) {
191 struct samr_Password nt_hash;
194 converted = strhex_to_str((char *)nt_hash.hash,
195 sizeof(nt_hash.hash),
198 if (converted != sizeof(nt_hash.hash)) {
202 ok = cli_credentials_set_nt_hash(creds,
209 ok = cli_credentials_set_password(creds,
224 NTSTATUS cli_session_creds_prepare_krb5(struct cli_state *cli,
225 struct cli_credentials *creds)
227 TALLOC_CTX *frame = talloc_stackframe();
228 const char *user_principal = NULL;
229 const char *user_account = NULL;
230 const char *user_domain = NULL;
231 const char *pass = NULL;
232 const char *target_hostname = NULL;
233 const DATA_BLOB *server_blob = NULL;
234 bool got_kerberos_mechanism = false;
235 enum credentials_use_kerberos krb5_state;
236 bool try_kerberos = false;
237 bool need_kinit = false;
238 bool auth_requested = true;
241 target_hostname = smbXcli_conn_remote_name(cli->conn);
242 server_blob = smbXcli_conn_server_gss_blob(cli->conn);
244 /* the server might not even do spnego */
245 if (server_blob != NULL && server_blob->length != 0) {
246 char *OIDs[ASN1_MAX_OIDS] = { NULL, };
251 * The server sent us the first part of the SPNEGO exchange in the
252 * negprot reply. It is WRONG to depend on the principal sent in the
253 * negprot reply, but right now we do it. If we don't receive one,
254 * we try to best guess, then fall back to NTLM.
256 ok = spnego_parse_negTokenInit(frame,
263 return NT_STATUS_INVALID_PARAMETER;
265 if (OIDs[0] == NULL) {
267 return NT_STATUS_INVALID_PARAMETER;
270 /* make sure the server understands kerberos */
271 for (i = 0; OIDs[i] != NULL; i++) {
273 DEBUG(3,("got OID=%s\n", OIDs[i]));
275 DEBUGADD(3,("got OID=%s\n", OIDs[i]));
278 if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0 ||
279 strcmp(OIDs[i], OID_KERBEROS5) == 0) {
280 got_kerberos_mechanism = true;
286 auth_requested = cli_credentials_authentication_requested(creds);
287 if (auth_requested) {
289 user_principal = cli_credentials_get_principal(creds, frame);
292 return NT_STATUS_NO_MEMORY;
295 user_account = cli_credentials_get_username(creds);
296 user_domain = cli_credentials_get_domain(creds);
297 pass = cli_credentials_get_password(creds);
299 krb5_state = cli_credentials_get_kerberos_state(creds);
301 if (krb5_state != CRED_DONT_USE_KERBEROS) {
305 if (user_principal == NULL) {
306 try_kerberos = false;
309 if (target_hostname == NULL) {
310 try_kerberos = false;
311 } else if (is_ipaddress(target_hostname)) {
312 try_kerberos = false;
313 } else if (strequal(target_hostname, "localhost")) {
314 try_kerberos = false;
315 } else if (strequal(target_hostname, STAR_SMBSERVER)) {
316 try_kerberos = false;
317 } else if (!auth_requested) {
318 try_kerberos = false;
321 if (krb5_state == CRED_MUST_USE_KERBEROS && !try_kerberos) {
322 DEBUG(0, ("Kerberos auth with '%s' (%s\\%s) to access "
323 "'%s' not possible\n",
324 user_principal, user_domain, user_account,
327 return NT_STATUS_ACCESS_DENIED;
330 if (pass == NULL || strlen(pass) == 0) {
332 } else if (krb5_state == CRED_MUST_USE_KERBEROS) {
333 need_kinit = try_kerberos;
334 } else if (!got_kerberos_mechanism) {
336 * Most likely the server doesn't support
337 * Kerberos, don't waste time doing a kinit
341 need_kinit = try_kerberos;
351 * TODO: This should be done within the gensec layer
354 setenv(KRB5_ENV_CCNAME, "MEMORY:cliconnect", 1);
355 ret = kerberos_kinit_password(user_principal, pass,
356 0 /* no time correction for now */,
359 int dbglvl = DBGLVL_NOTICE;
361 if (krb5_state == CRED_MUST_USE_KERBEROS) {
365 DEBUG(dbglvl, ("Kinit for %s to access %s failed: %s\n",
366 user_principal, target_hostname,
367 error_message(ret)));
368 if (krb5_state == CRED_MUST_USE_KERBEROS) {
370 return krb5_to_nt_status(ret);
374 * Ignore the error and hope that NTLM will work
382 NTSTATUS cli_state_update_after_negprot(struct cli_state *cli)
384 static const struct {
385 enum protocol_types proto;
388 {PROTOCOL_SMB3_11, "SMB3_11"},
389 {PROTOCOL_SMB3_10, "SMB3_10"},
390 {PROTOCOL_SMB3_02, "SMB3_02"},
391 {PROTOCOL_SMB3_00, "SMB3_00"},
392 {PROTOCOL_SMB2_24, "SMB2_24"},
393 {PROTOCOL_SMB2_22, "SMB2_22"},
394 {PROTOCOL_SMB2_10, "SMB2_10"},
395 {PROTOCOL_SMB2_02, "SMB2_02"},
396 {PROTOCOL_NT1, "NT1"},
397 {PROTOCOL_LANMAN2, "LANMAN2"},
398 {PROTOCOL_LANMAN1, "LANMAN1"},
399 {PROTOCOL_CORE, "CORE"},
400 {PROTOCOL_COREPLUS, "COREPLUS"},
401 {PROTOCOL_NONE, "NONE"},
402 {PROTOCOL_DEFAULT, "DEFAULT"},
404 enum protocol_types protocol;
405 const char *proto_name = NULL;
408 protocol = smbXcli_conn_protocol(cli->conn);
410 if (protocol >= PROTOCOL_SMB2_02) {
411 /* Ensure we ask for some initial credits. */
412 smb2cli_conn_set_max_credits(cli->conn, DEFAULT_SMB2_MAX_CREDITS);
415 for (i=0; i < ARRAY_SIZE(protos); i++) {
416 if (protos[i].proto == protocol) {
417 proto_name = protos[i].name;
422 cli->server_os = talloc_asprintf(cli, "%s Server", proto_name);
423 if (cli->server_os == NULL) {
424 return NT_STATUS_NO_MEMORY;
426 cli->server_type = talloc_asprintf(cli, "%s",
427 smbXcli_conn_remote_name(cli->conn));
428 if (cli->server_type == NULL) {
429 return NT_STATUS_NO_MEMORY;
435 static NTSTATUS cli_state_update_after_sesssetup(struct cli_state *cli,
436 const char *native_os,
437 const char *native_lm,
438 const char *primary_domain)
440 #define _VALID_STR(p) ((p) != NULL && (p)[0] != '\0')
442 if (_VALID_STR(native_os)) {
443 cli->server_os = talloc_strdup(cli, native_os);
444 if (cli->server_os == NULL) {
445 return NT_STATUS_NO_MEMORY;
449 if (_VALID_STR(native_lm)) {
450 cli->server_type = talloc_strdup(cli, native_lm);
451 if (cli->server_type == NULL) {
452 return NT_STATUS_NO_MEMORY;
456 if (_VALID_STR(primary_domain)) {
457 cli->server_domain = talloc_strdup(cli, primary_domain);
458 if (cli->server_domain == NULL) {
459 return NT_STATUS_NO_MEMORY;
467 /********************************************************
468 Utility function to ensure we always return at least
469 a valid char * pointer to an empty string for the
470 cli->server_os, cli->server_type and cli->server_domain
472 *******************************************************/
474 static NTSTATUS smb_bytes_talloc_string(TALLOC_CTX *mem_ctx,
481 *destlen = clistr_pull_talloc(mem_ctx,
488 if (*destlen == -1) {
489 return NT_STATUS_NO_MEMORY;
493 *dest = talloc_strdup(mem_ctx, "");
495 return NT_STATUS_NO_MEMORY;
501 /****************************************************************************
502 Work out suitable capabilities to offer the server.
503 ****************************************************************************/
505 static uint32_t cli_session_setup_capabilities(struct cli_state *cli,
506 uint32_t sesssetup_capabilities)
508 uint32_t client_capabilities = smb1cli_conn_capabilities(cli->conn);
511 * We only send capabilities based on the mask for:
512 * - client only flags
513 * - flags used in both directions
515 * We do not echo the server only flags, except some legacy flags.
517 * SMB_CAP_LEGACY_CLIENT_MASK contains CAP_LARGE_READX and
518 * CAP_LARGE_WRITEX in order to allow us to do large reads
519 * against old Samba releases (<= 3.6.x).
521 client_capabilities &= (SMB_CAP_BOTH_MASK | SMB_CAP_LEGACY_CLIENT_MASK);
524 * Session Setup specific flags CAP_DYNAMIC_REAUTH
525 * and CAP_EXTENDED_SECURITY are passed by the caller.
526 * We need that in order to do guest logins even if
527 * CAP_EXTENDED_SECURITY is negotiated.
529 client_capabilities &= ~(CAP_DYNAMIC_REAUTH|CAP_EXTENDED_SECURITY);
530 sesssetup_capabilities &= (CAP_DYNAMIC_REAUTH|CAP_EXTENDED_SECURITY);
531 client_capabilities |= sesssetup_capabilities;
533 return client_capabilities;
536 /****************************************************************************
537 Do a NT1 guest session setup.
538 ****************************************************************************/
540 struct cli_session_setup_guest_state {
541 struct cli_state *cli;
546 static void cli_session_setup_guest_done(struct tevent_req *subreq);
548 struct tevent_req *cli_session_setup_guest_create(TALLOC_CTX *mem_ctx,
549 struct tevent_context *ev,
550 struct cli_state *cli,
551 struct tevent_req **psmbreq)
553 struct tevent_req *req, *subreq;
554 struct cli_session_setup_guest_state *state;
558 req = tevent_req_create(mem_ctx, &state,
559 struct cli_session_setup_guest_state);
566 SCVAL(vwv+0, 0, 0xFF);
569 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
571 SSVAL(vwv+4, 0, cli_state_get_vc_num(cli));
572 SIVAL(vwv+5, 0, smb1cli_conn_server_session_key(cli->conn));
577 SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli, 0));
579 bytes = talloc_array(state, uint8_t, 0);
581 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "", 1, /* username */
583 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "", 1, /* workgroup */
585 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "Unix", 5, NULL);
586 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "Samba", 6, NULL);
593 state->bytes.iov_base = (void *)bytes;
594 state->bytes.iov_len = talloc_get_size(bytes);
596 subreq = cli_smb_req_create(state, ev, cli, SMBsesssetupX, 0, 0, 13,
597 vwv, 1, &state->bytes);
598 if (subreq == NULL) {
602 tevent_req_set_callback(subreq, cli_session_setup_guest_done, req);
607 struct tevent_req *cli_session_setup_guest_send(TALLOC_CTX *mem_ctx,
608 struct tevent_context *ev,
609 struct cli_state *cli)
611 struct tevent_req *req, *subreq;
614 req = cli_session_setup_guest_create(mem_ctx, ev, cli, &subreq);
619 status = smb1cli_req_chain_submit(&subreq, 1);
620 if (!NT_STATUS_IS_OK(status)) {
621 tevent_req_nterror(req, status);
622 return tevent_req_post(req, ev);
627 static void cli_session_setup_guest_done(struct tevent_req *subreq)
629 struct tevent_req *req = tevent_req_callback_data(
630 subreq, struct tevent_req);
631 struct cli_session_setup_guest_state *state = tevent_req_data(
632 req, struct cli_session_setup_guest_state);
633 struct cli_state *cli = state->cli;
644 status = cli_smb_recv(subreq, state, &in, 3, &wct, &vwv,
647 if (!NT_STATUS_IS_OK(status)) {
648 tevent_req_nterror(req, status);
652 inhdr = in + NBT_HDR_SIZE;
655 cli_state_set_uid(state->cli, SVAL(inhdr, HDR_UID));
656 smb1cli_session_set_action(cli->smb1.session, SVAL(vwv+2, 0));
658 status = smb_bytes_talloc_string(cli,
665 if (!NT_STATUS_IS_OK(status)) {
666 tevent_req_nterror(req, status);
671 status = smb_bytes_talloc_string(cli,
678 if (!NT_STATUS_IS_OK(status)) {
679 tevent_req_nterror(req, status);
684 status = smb_bytes_talloc_string(cli,
691 if (!NT_STATUS_IS_OK(status)) {
692 tevent_req_nterror(req, status);
697 tevent_req_done(req);
700 NTSTATUS cli_session_setup_guest_recv(struct tevent_req *req)
702 return tevent_req_simple_recv_ntstatus(req);
705 /* The following is calculated from :
707 * (smb_wcnt * 2) = 24 (smb_wcnt == 12 in cli_session_setup_blob_send() )
708 * (strlen("Unix") + 1 + strlen("Samba") + 1) * 2 = 22 (unicode strings at
712 #define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22)
714 struct cli_sesssetup_blob_state {
715 struct tevent_context *ev;
716 struct cli_state *cli;
718 uint16_t max_blob_size;
721 struct iovec *recv_iov;
724 const uint8_t *inbuf;
731 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state *state,
732 struct tevent_req **psubreq);
733 static void cli_sesssetup_blob_done(struct tevent_req *subreq);
735 static struct tevent_req *cli_sesssetup_blob_send(TALLOC_CTX *mem_ctx,
736 struct tevent_context *ev,
737 struct cli_state *cli,
740 struct tevent_req *req, *subreq;
741 struct cli_sesssetup_blob_state *state;
742 uint32_t usable_space;
744 req = tevent_req_create(mem_ctx, &state,
745 struct cli_sesssetup_blob_state);
753 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
754 usable_space = UINT16_MAX;
756 usable_space = cli_state_available_size(cli,
757 BASE_SESSSETUP_BLOB_PACKET_SIZE);
760 if (usable_space == 0) {
761 DEBUG(1, ("cli_session_setup_blob: cli->max_xmit too small "
762 "(not possible to send %u bytes)\n",
763 BASE_SESSSETUP_BLOB_PACKET_SIZE + 1));
764 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
765 return tevent_req_post(req, ev);
767 state->max_blob_size = MIN(usable_space, 0xFFFF);
769 if (!cli_sesssetup_blob_next(state, &subreq)) {
770 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
771 return tevent_req_post(req, ev);
773 tevent_req_set_callback(subreq, cli_sesssetup_blob_done, req);
777 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state *state,
778 struct tevent_req **psubreq)
780 struct tevent_req *subreq;
783 thistime = MIN(state->blob.length, state->max_blob_size);
785 state->this_blob.data = state->blob.data;
786 state->this_blob.length = thistime;
788 state->blob.data += thistime;
789 state->blob.length -= thistime;
791 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
792 subreq = smb2cli_session_setup_send(state, state->ev,
795 state->cli->smb2.session,
797 SMB2_CAP_DFS, /* in_capabilities */
799 0, /* in_previous_session_id */
801 if (subreq == NULL) {
805 uint16_t in_buf_size = 0;
806 uint16_t in_mpx_max = 0;
807 uint16_t in_vc_num = 0;
808 uint32_t in_sess_key = 0;
809 uint32_t in_capabilities = 0;
810 const char *in_native_os = NULL;
811 const char *in_native_lm = NULL;
813 in_buf_size = CLI_BUFFER_SIZE;
814 in_mpx_max = smbXcli_conn_max_requests(state->cli->conn);
815 in_vc_num = cli_state_get_vc_num(state->cli);
816 in_sess_key = smb1cli_conn_server_session_key(state->cli->conn);
817 in_capabilities = cli_session_setup_capabilities(state->cli,
818 CAP_EXTENDED_SECURITY);
819 in_native_os = "Unix";
820 in_native_lm = "Samba";
823 * For now we keep the same values as before,
824 * we may remove these in a separate commit later.
830 subreq = smb1cli_session_setup_ext_send(state, state->ev,
833 state->cli->smb1.pid,
834 state->cli->smb1.session,
843 if (subreq == NULL) {
851 static void cli_sesssetup_blob_done(struct tevent_req *subreq)
853 struct tevent_req *req = tevent_req_callback_data(
854 subreq, struct tevent_req);
855 struct cli_sesssetup_blob_state *state = tevent_req_data(
856 req, struct cli_sesssetup_blob_state);
859 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
860 status = smb2cli_session_setup_recv(subreq, state,
864 status = smb1cli_session_setup_ext_recv(subreq, state,
868 &state->out_native_os,
869 &state->out_native_lm);
872 if (!NT_STATUS_IS_OK(status)
873 && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
874 tevent_req_nterror(req, status);
878 state->status = status;
880 status = cli_state_update_after_sesssetup(state->cli,
881 state->out_native_os,
882 state->out_native_lm,
884 if (tevent_req_nterror(req, status)) {
888 if (state->blob.length != 0) {
892 if (!cli_sesssetup_blob_next(state, &subreq)) {
896 tevent_req_set_callback(subreq, cli_sesssetup_blob_done, req);
899 tevent_req_done(req);
902 static NTSTATUS cli_sesssetup_blob_recv(struct tevent_req *req,
905 const uint8_t **pinbuf,
906 struct iovec **precv_iov)
908 struct cli_sesssetup_blob_state *state = tevent_req_data(
909 req, struct cli_sesssetup_blob_state);
911 struct iovec *recv_iov;
913 if (tevent_req_is_nterror(req, &status)) {
914 TALLOC_FREE(state->cli->smb2.session);
915 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
916 tevent_req_received(req);
920 recv_iov = talloc_move(mem_ctx, &state->recv_iov);
922 *pblob = state->ret_blob;
924 if (pinbuf != NULL) {
925 *pinbuf = state->inbuf;
927 if (precv_iov != NULL) {
928 *precv_iov = recv_iov;
930 /* could be NT_STATUS_MORE_PROCESSING_REQUIRED */
931 status = state->status;
932 tevent_req_received(req);
936 /****************************************************************************
937 Do a spnego/NTLMSSP encrypted session setup.
938 ****************************************************************************/
940 struct cli_session_setup_gensec_state {
941 struct tevent_context *ev;
942 struct cli_state *cli;
943 struct auth_generic_state *auth_generic;
946 const uint8_t *inbuf;
947 struct iovec *recv_iov;
951 DATA_BLOB session_key;
954 static int cli_session_setup_gensec_state_destructor(
955 struct cli_session_setup_gensec_state *state)
957 TALLOC_FREE(state->auth_generic);
958 data_blob_clear_free(&state->session_key);
962 static void cli_session_setup_gensec_local_next(struct tevent_req *req);
963 static void cli_session_setup_gensec_local_done(struct tevent_req *subreq);
964 static void cli_session_setup_gensec_remote_next(struct tevent_req *req);
965 static void cli_session_setup_gensec_remote_done(struct tevent_req *subreq);
966 static void cli_session_setup_gensec_ready(struct tevent_req *req);
968 static struct tevent_req *cli_session_setup_gensec_send(
969 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
970 struct cli_credentials *creds,
971 const char *target_service,
972 const char *target_hostname)
974 struct tevent_req *req;
975 struct cli_session_setup_gensec_state *state;
977 const DATA_BLOB *b = NULL;
979 req = tevent_req_create(mem_ctx, &state,
980 struct cli_session_setup_gensec_state);
987 talloc_set_destructor(
988 state, cli_session_setup_gensec_state_destructor);
990 status = auth_generic_client_prepare(state, &state->auth_generic);
991 if (tevent_req_nterror(req, status)) {
992 return tevent_req_post(req, ev);
995 status = auth_generic_set_creds(state->auth_generic, creds);
996 if (tevent_req_nterror(req, status)) {
997 return tevent_req_post(req, ev);
1000 gensec_want_feature(state->auth_generic->gensec_security,
1001 GENSEC_FEATURE_SESSION_KEY);
1003 if (target_service != NULL) {
1004 status = gensec_set_target_service(
1005 state->auth_generic->gensec_security,
1007 if (tevent_req_nterror(req, status)) {
1008 return tevent_req_post(req, ev);
1012 if (target_hostname != NULL) {
1013 status = gensec_set_target_hostname(
1014 state->auth_generic->gensec_security,
1016 if (tevent_req_nterror(req, status)) {
1017 return tevent_req_post(req, ev);
1021 b = smbXcli_conn_server_gss_blob(cli->conn);
1023 state->blob_in = *b;
1026 state->is_anonymous = cli_credentials_is_anonymous(state->auth_generic->credentials);
1028 status = auth_generic_client_start(state->auth_generic,
1030 if (tevent_req_nterror(req, status)) {
1031 return tevent_req_post(req, ev);
1034 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
1035 state->cli->smb2.session = smbXcli_session_create(cli,
1037 if (tevent_req_nomem(state->cli->smb2.session, req)) {
1038 return tevent_req_post(req, ev);
1042 cli_session_setup_gensec_local_next(req);
1043 if (!tevent_req_is_in_progress(req)) {
1044 return tevent_req_post(req, ev);
1050 static void cli_session_setup_gensec_local_next(struct tevent_req *req)
1052 struct cli_session_setup_gensec_state *state =
1053 tevent_req_data(req,
1054 struct cli_session_setup_gensec_state);
1055 struct tevent_req *subreq = NULL;
1057 if (state->local_ready) {
1058 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1062 subreq = gensec_update_send(state, state->ev,
1063 state->auth_generic->gensec_security,
1065 if (tevent_req_nomem(subreq, req)) {
1068 tevent_req_set_callback(subreq, cli_session_setup_gensec_local_done, req);
1071 static void cli_session_setup_gensec_local_done(struct tevent_req *subreq)
1073 struct tevent_req *req =
1074 tevent_req_callback_data(subreq,
1076 struct cli_session_setup_gensec_state *state =
1077 tevent_req_data(req,
1078 struct cli_session_setup_gensec_state);
1081 status = gensec_update_recv(subreq, state, &state->blob_out);
1082 TALLOC_FREE(subreq);
1083 state->blob_in = data_blob_null;
1084 if (!NT_STATUS_IS_OK(status) &&
1085 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
1087 tevent_req_nterror(req, status);
1091 if (NT_STATUS_IS_OK(status)) {
1092 state->local_ready = true;
1095 if (state->local_ready && state->remote_ready) {
1096 cli_session_setup_gensec_ready(req);
1100 cli_session_setup_gensec_remote_next(req);
1103 static void cli_session_setup_gensec_remote_next(struct tevent_req *req)
1105 struct cli_session_setup_gensec_state *state =
1106 tevent_req_data(req,
1107 struct cli_session_setup_gensec_state);
1108 struct tevent_req *subreq = NULL;
1110 if (state->remote_ready) {
1111 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1115 subreq = cli_sesssetup_blob_send(state, state->ev,
1116 state->cli, state->blob_out);
1117 if (tevent_req_nomem(subreq, req)) {
1120 tevent_req_set_callback(subreq,
1121 cli_session_setup_gensec_remote_done,
1125 static void cli_session_setup_gensec_remote_done(struct tevent_req *subreq)
1127 struct tevent_req *req =
1128 tevent_req_callback_data(subreq,
1130 struct cli_session_setup_gensec_state *state =
1131 tevent_req_data(req,
1132 struct cli_session_setup_gensec_state);
1135 state->inbuf = NULL;
1136 TALLOC_FREE(state->recv_iov);
1138 status = cli_sesssetup_blob_recv(subreq, state, &state->blob_in,
1139 &state->inbuf, &state->recv_iov);
1140 TALLOC_FREE(subreq);
1141 data_blob_free(&state->blob_out);
1142 if (!NT_STATUS_IS_OK(status) &&
1143 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
1145 tevent_req_nterror(req, status);
1149 if (NT_STATUS_IS_OK(status)) {
1150 struct smbXcli_session *session = NULL;
1151 bool is_guest = false;
1153 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
1154 session = state->cli->smb2.session;
1156 session = state->cli->smb1.session;
1159 is_guest = smbXcli_session_is_guest(session);
1162 * We can't finish the gensec handshake, we don't
1163 * have a negotiated session key.
1165 * So just pretend we are completely done,
1166 * we need to continue as anonymous from this point,
1167 * as we can't get a session key.
1169 * Note that smbXcli_session_is_guest()
1170 * always returns false if we require signing.
1172 state->blob_in = data_blob_null;
1173 state->local_ready = true;
1174 state->is_anonymous = true;
1177 state->remote_ready = true;
1180 if (state->local_ready && state->remote_ready) {
1181 cli_session_setup_gensec_ready(req);
1185 cli_session_setup_gensec_local_next(req);
1188 static void cli_session_dump_keys(TALLOC_CTX *mem_ctx,
1189 struct smbXcli_session *session,
1190 DATA_BLOB session_key)
1193 DATA_BLOB sig = data_blob_null;
1194 DATA_BLOB app = data_blob_null;
1195 DATA_BLOB enc = data_blob_null;
1196 DATA_BLOB dec = data_blob_null;
1197 uint64_t sid = smb2cli_session_current_id(session);
1199 status = smb2cli_session_signing_key(session, mem_ctx, &sig);
1200 if (!NT_STATUS_IS_OK(status)) {
1203 status = smbXcli_session_application_key(session, mem_ctx, &app);
1204 if (!NT_STATUS_IS_OK(status)) {
1207 status = smb2cli_session_encryption_key(session, mem_ctx, &enc);
1208 if (!NT_STATUS_IS_OK(status)) {
1211 status = smb2cli_session_decryption_key(session, mem_ctx, &dec);
1212 if (!NT_STATUS_IS_OK(status)) {
1216 DEBUG(0, ("debug encryption: dumping generated session keys\n"));
1217 DEBUGADD(0, ("Session Id "));
1218 dump_data(0, (uint8_t*)&sid, sizeof(sid));
1219 DEBUGADD(0, ("Session Key "));
1220 dump_data(0, session_key.data, session_key.length);
1221 DEBUGADD(0, ("Signing Key "));
1222 dump_data(0, sig.data, sig.length);
1223 DEBUGADD(0, ("App Key "));
1224 dump_data(0, app.data, app.length);
1226 /* In client code, ServerIn is the encryption key */
1228 DEBUGADD(0, ("ServerIn Key "));
1229 dump_data(0, enc.data, enc.length);
1230 DEBUGADD(0, ("ServerOut Key "));
1231 dump_data(0, dec.data, dec.length);
1234 data_blob_clear_free(&sig);
1235 data_blob_clear_free(&app);
1236 data_blob_clear_free(&enc);
1237 data_blob_clear_free(&dec);
1240 static void cli_session_setup_gensec_ready(struct tevent_req *req)
1242 struct cli_session_setup_gensec_state *state =
1243 tevent_req_data(req,
1244 struct cli_session_setup_gensec_state);
1247 if (state->blob_in.length != 0) {
1248 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1252 if (state->blob_out.length != 0) {
1253 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1257 if (state->is_anonymous) {
1259 * Windows server does not set the
1260 * SMB2_SESSION_FLAG_IS_NULL flag.
1262 * This fix makes sure we do not try
1263 * to verify a signature on the final
1264 * session setup response.
1266 tevent_req_done(req);
1270 status = gensec_session_key(state->auth_generic->gensec_security,
1271 state, &state->session_key);
1272 if (tevent_req_nterror(req, status)) {
1276 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
1277 struct smbXcli_session *session = state->cli->smb2.session;
1279 status = smb2cli_session_set_session_key(session,
1282 if (tevent_req_nterror(req, status)) {
1285 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB3_00
1286 && lp_debug_encryption())
1288 cli_session_dump_keys(state, session, state->session_key);
1291 struct smbXcli_session *session = state->cli->smb1.session;
1294 status = smb1cli_session_set_session_key(session,
1295 state->session_key);
1296 if (tevent_req_nterror(req, status)) {
1300 active = smb1cli_conn_activate_signing(state->cli->conn,
1306 ok = smb1cli_conn_check_signing(state->cli->conn,
1309 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1315 tevent_req_done(req);
1318 static NTSTATUS cli_session_setup_gensec_recv(struct tevent_req *req)
1320 struct cli_session_setup_gensec_state *state =
1321 tevent_req_data(req,
1322 struct cli_session_setup_gensec_state);
1325 if (tevent_req_is_nterror(req, &status)) {
1326 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
1329 return NT_STATUS_OK;
1332 static char *cli_session_setup_get_account(TALLOC_CTX *mem_ctx,
1333 const char *principal)
1337 account = talloc_strdup(mem_ctx, principal);
1338 if (account == NULL) {
1341 p = strchr_m(account, '@');
1348 /****************************************************************************
1349 Do a spnego encrypted session setup.
1351 user_domain: The shortname of the domain the user/machine is a member of.
1352 dest_realm: The realm we're connecting to, if NULL we use our default realm.
1353 ****************************************************************************/
1355 struct cli_session_setup_spnego_state {
1359 static void cli_session_setup_spnego_done(struct tevent_req *subreq);
1361 static struct tevent_req *cli_session_setup_spnego_send(
1362 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
1363 struct cli_credentials *creds)
1365 struct tevent_req *req, *subreq;
1366 struct cli_session_setup_spnego_state *state;
1367 const char *target_service = NULL;
1368 const char *target_hostname = NULL;
1371 req = tevent_req_create(mem_ctx, &state,
1372 struct cli_session_setup_spnego_state);
1377 target_service = "cifs";
1378 target_hostname = smbXcli_conn_remote_name(cli->conn);
1380 status = cli_session_creds_prepare_krb5(cli, creds);
1381 if (tevent_req_nterror(req, status)) {
1382 return tevent_req_post(req, ev);
1385 subreq = cli_session_setup_gensec_send(state, ev, cli, creds,
1386 target_service, target_hostname);
1387 if (tevent_req_nomem(subreq, req)) {
1388 return tevent_req_post(req, ev);
1390 tevent_req_set_callback(
1391 subreq, cli_session_setup_spnego_done, req);
1395 static void cli_session_setup_spnego_done(struct tevent_req *subreq)
1397 struct tevent_req *req = tevent_req_callback_data(
1398 subreq, struct tevent_req);
1401 status = cli_session_setup_gensec_recv(subreq);
1402 TALLOC_FREE(subreq);
1403 if (tevent_req_nterror(req, status)) {
1407 tevent_req_done(req);
1410 static ADS_STATUS cli_session_setup_spnego_recv(struct tevent_req *req)
1412 struct cli_session_setup_spnego_state *state = tevent_req_data(
1413 req, struct cli_session_setup_spnego_state);
1416 if (tevent_req_is_nterror(req, &status)) {
1417 state->result = ADS_ERROR_NT(status);
1420 return state->result;
1423 struct cli_session_setup_creds_state {
1424 struct cli_state *cli;
1425 DATA_BLOB apassword_blob;
1426 DATA_BLOB upassword_blob;
1427 DATA_BLOB lm_session_key;
1428 DATA_BLOB session_key;
1429 char *out_native_os;
1430 char *out_native_lm;
1431 char *out_primary_domain;
1434 static void cli_session_setup_creds_cleanup(struct tevent_req *req,
1435 enum tevent_req_state req_state)
1437 struct cli_session_setup_creds_state *state = tevent_req_data(
1438 req, struct cli_session_setup_creds_state);
1440 if (req_state != TEVENT_REQ_RECEIVED) {
1445 * We only call data_blob_clear() as
1446 * some of the blobs point to the same memory.
1448 * We let the talloc hierachy free the memory.
1450 data_blob_clear(&state->apassword_blob);
1451 data_blob_clear(&state->upassword_blob);
1452 data_blob_clear(&state->lm_session_key);
1453 data_blob_clear(&state->session_key);
1454 ZERO_STRUCTP(state);
1457 static void cli_session_setup_creds_done_spnego(struct tevent_req *subreq);
1458 static void cli_session_setup_creds_done_nt1(struct tevent_req *subreq);
1459 static void cli_session_setup_creds_done_lm21(struct tevent_req *subreq);
1461 /****************************************************************************
1462 Send a session setup. The username and workgroup is in UNIX character
1463 format and must be converted to DOS codepage format before sending. If the
1464 password is in plaintext, the same should be done.
1465 ****************************************************************************/
1467 struct tevent_req *cli_session_setup_creds_send(TALLOC_CTX *mem_ctx,
1468 struct tevent_context *ev,
1469 struct cli_state *cli,
1470 struct cli_credentials *creds)
1472 struct tevent_req *req, *subreq;
1473 struct cli_session_setup_creds_state *state;
1474 uint16_t sec_mode = smb1cli_conn_server_security_mode(cli->conn);
1475 bool use_spnego = false;
1477 enum credentials_use_kerberos krb5_state;
1478 uint32_t gensec_features;
1479 const char *username = "";
1480 const char *domain = "";
1481 DATA_BLOB target_info = data_blob_null;
1482 DATA_BLOB challenge = data_blob_null;
1483 uint16_t in_buf_size = 0;
1484 uint16_t in_mpx_max = 0;
1485 uint16_t in_vc_num = 0;
1486 uint32_t in_sess_key = 0;
1487 const char *in_native_os = NULL;
1488 const char *in_native_lm = NULL;
1491 req = tevent_req_create(mem_ctx, &state,
1492 struct cli_session_setup_creds_state);
1498 tevent_req_set_cleanup_fn(req, cli_session_setup_creds_cleanup);
1500 krb5_state = cli_credentials_get_kerberos_state(creds);
1501 gensec_features = cli_credentials_get_gensec_features(creds);
1503 switch (krb5_state) {
1504 case CRED_MUST_USE_KERBEROS:
1505 cli->use_kerberos = true;
1506 cli->fallback_after_kerberos = false;
1508 case CRED_AUTO_USE_KERBEROS:
1509 cli->use_kerberos = true;
1510 cli->fallback_after_kerberos = true;
1512 case CRED_DONT_USE_KERBEROS:
1513 cli->use_kerberos = false;
1514 cli->fallback_after_kerberos = false;
1518 if (gensec_features & GENSEC_FEATURE_NTLM_CCACHE) {
1519 cli->use_ccache = true;
1521 cli->use_ccache = false;
1525 * Now work out what sort of session setup we are going to
1526 * do. I have split this into separate functions to make the flow a bit
1527 * easier to understand (tridge).
1529 if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_NT1) {
1531 } else if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
1533 } else if (smb1cli_conn_capabilities(cli->conn) & CAP_EXTENDED_SECURITY) {
1535 * if the server supports extended security then use SPNEGO
1536 * even for anonymous connections.
1544 subreq = cli_session_setup_spnego_send(
1545 state, ev, cli, creds);
1546 if (tevent_req_nomem(subreq, req)) {
1547 return tevent_req_post(req, ev);
1549 tevent_req_set_callback(subreq, cli_session_setup_creds_done_spnego,
1554 if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_LANMAN1) {
1556 * SessionSetupAndX was introduced by LANMAN 1.0. So we skip
1557 * this step against older servers.
1559 tevent_req_done(req);
1560 return tevent_req_post(req, ev);
1563 if (cli_credentials_is_anonymous(creds)) {
1565 * Do an anonymous session setup
1567 goto non_spnego_creds_done;
1570 if ((sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0) {
1572 * Do an anonymous session setup,
1573 * the password is passed via the tree connect.
1575 goto non_spnego_creds_done;
1578 cli_credentials_get_ntlm_username_domain(creds, state,
1581 if (tevent_req_nomem(username, req)) {
1582 return tevent_req_post(req, ev);
1584 if (tevent_req_nomem(domain, req)) {
1585 return tevent_req_post(req, ev);
1588 if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) {
1589 bool use_unicode = smbXcli_conn_use_unicode(cli->conn);
1590 uint8_t *bytes = NULL;
1591 size_t bytes_len = 0;
1592 const char *pw = cli_credentials_get_password(creds);
1598 pw_len = strlen(pw) + 1;
1600 if (!lp_client_plaintext_auth()) {
1601 DEBUG(1, ("Server requested PLAINTEXT password but "
1602 "'client plaintext auth = no'\n"));
1603 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1604 return tevent_req_post(req, ev);
1607 bytes = talloc_array(state, uint8_t, 0);
1608 bytes = trans2_bytes_push_str(bytes, use_unicode,
1609 pw, pw_len, &bytes_len);
1610 if (tevent_req_nomem(bytes, req)) {
1611 return tevent_req_post(req, ev);
1616 * CAP_UNICODE, can only be negotiated by NT1.
1618 state->upassword_blob = data_blob_const(bytes,
1621 state->apassword_blob = data_blob_const(bytes,
1625 goto non_spnego_creds_done;
1628 challenge = data_blob_const(smb1cli_conn_server_challenge(cli->conn), 8);
1630 if (smbXcli_conn_protocol(cli->conn) == PROTOCOL_NT1) {
1631 if (lp_client_ntlmv2_auth() && lp_client_use_spnego()) {
1633 * Don't send an NTLMv2 response without NTLMSSP if we
1634 * want to use spnego support.
1636 DEBUG(1, ("Server does not support EXTENDED_SECURITY "
1637 " but 'client use spnego = yes'"
1638 " and 'client ntlmv2 auth = yes' is set\n"));
1639 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1640 return tevent_req_post(req, ev);
1643 if (lp_client_ntlmv2_auth()) {
1644 flags |= CLI_CRED_NTLMv2_AUTH;
1647 * note that the 'domain' here is a best
1648 * guess - we don't know the server's domain
1649 * at this point. Windows clients also don't
1652 target_info = NTLMv2_generate_names_blob(state,
1655 if (tevent_req_nomem(target_info.data, req)) {
1656 return tevent_req_post(req, ev);
1659 flags |= CLI_CRED_NTLM_AUTH;
1660 if (lp_client_lanman_auth()) {
1661 flags |= CLI_CRED_LANMAN_AUTH;
1665 if (!lp_client_lanman_auth()) {
1666 DEBUG(1, ("Server requested user level LM password but "
1667 "'client lanman auth = no' is set.\n"));
1668 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1669 return tevent_req_post(req, ev);
1672 flags |= CLI_CRED_LANMAN_AUTH;
1675 status = cli_credentials_get_ntlm_response(creds, state, &flags,
1678 &state->apassword_blob,
1679 &state->upassword_blob,
1680 &state->lm_session_key,
1681 &state->session_key);
1682 if (tevent_req_nterror(req, status)) {
1683 return tevent_req_post(req, ev);
1686 non_spnego_creds_done:
1688 in_buf_size = CLI_BUFFER_SIZE;
1689 in_mpx_max = smbXcli_conn_max_requests(cli->conn);
1690 in_vc_num = cli_state_get_vc_num(cli);
1691 in_sess_key = smb1cli_conn_server_session_key(cli->conn);
1692 in_native_os = "Unix";
1693 in_native_lm = "Samba";
1695 if (smbXcli_conn_protocol(cli->conn) == PROTOCOL_NT1) {
1696 uint32_t in_capabilities = 0;
1698 in_capabilities = cli_session_setup_capabilities(cli, 0);
1701 * For now we keep the same values as before,
1702 * we may remove these in a separate commit later.
1706 subreq = smb1cli_session_setup_nt1_send(state, ev,
1717 state->apassword_blob,
1718 state->upassword_blob,
1722 if (tevent_req_nomem(subreq, req)) {
1723 return tevent_req_post(req, ev);
1725 tevent_req_set_callback(subreq, cli_session_setup_creds_done_nt1,
1731 * For now we keep the same values as before,
1732 * we may remove these in a separate commit later.
1737 subreq = smb1cli_session_setup_lm21_send(state, ev,
1748 state->apassword_blob,
1751 if (tevent_req_nomem(subreq, req)) {
1752 return tevent_req_post(req, ev);
1754 tevent_req_set_callback(subreq, cli_session_setup_creds_done_lm21,
1759 static void cli_session_setup_creds_done_spnego(struct tevent_req *subreq)
1761 struct tevent_req *req = tevent_req_callback_data(
1762 subreq, struct tevent_req);
1765 status = cli_session_setup_spnego_recv(subreq);
1766 TALLOC_FREE(subreq);
1767 if (!ADS_ERR_OK(status)) {
1768 DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status)));
1769 tevent_req_nterror(req, ads_ntstatus(status));
1772 tevent_req_done(req);
1775 static void cli_session_setup_creds_done_nt1(struct tevent_req *subreq)
1777 struct tevent_req *req = tevent_req_callback_data(
1778 subreq, struct tevent_req);
1779 struct cli_session_setup_creds_state *state = tevent_req_data(
1780 req, struct cli_session_setup_creds_state);
1781 struct cli_state *cli = state->cli;
1783 struct iovec *recv_iov = NULL;
1784 const uint8_t *inbuf = NULL;
1787 status = smb1cli_session_setup_nt1_recv(subreq, state,
1790 &state->out_native_os,
1791 &state->out_native_lm,
1792 &state->out_primary_domain);
1793 TALLOC_FREE(subreq);
1794 if (!NT_STATUS_IS_OK(status)) {
1795 DEBUG(3, ("NT1 login failed: %s\n", nt_errstr(status)));
1796 tevent_req_nterror(req, status);
1800 status = cli_state_update_after_sesssetup(state->cli,
1801 state->out_native_os,
1802 state->out_native_lm,
1803 state->out_primary_domain);
1804 if (tevent_req_nterror(req, status)) {
1808 ok = smb1cli_conn_activate_signing(cli->conn,
1810 state->upassword_blob);
1812 ok = smb1cli_conn_check_signing(cli->conn, inbuf, 1);
1814 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1819 if (state->session_key.data) {
1820 struct smbXcli_session *session = cli->smb1.session;
1822 status = smb1cli_session_set_session_key(session,
1823 state->session_key);
1824 if (tevent_req_nterror(req, status)) {
1829 tevent_req_done(req);
1832 static void cli_session_setup_creds_done_lm21(struct tevent_req *subreq)
1834 struct tevent_req *req = tevent_req_callback_data(
1835 subreq, struct tevent_req);
1836 struct cli_session_setup_creds_state *state = tevent_req_data(
1837 req, struct cli_session_setup_creds_state);
1840 status = smb1cli_session_setup_lm21_recv(subreq, state,
1841 &state->out_native_os,
1842 &state->out_native_lm);
1843 TALLOC_FREE(subreq);
1844 if (!NT_STATUS_IS_OK(status)) {
1845 DEBUG(3, ("LM21 login failed: %s\n", nt_errstr(status)));
1846 tevent_req_nterror(req, status);
1850 status = cli_state_update_after_sesssetup(state->cli,
1851 state->out_native_os,
1852 state->out_native_lm,
1854 if (tevent_req_nterror(req, status)) {
1858 tevent_req_done(req);
1861 NTSTATUS cli_session_setup_creds_recv(struct tevent_req *req)
1863 return tevent_req_simple_recv_ntstatus(req);
1866 NTSTATUS cli_session_setup_creds(struct cli_state *cli,
1867 struct cli_credentials *creds)
1869 struct tevent_context *ev;
1870 struct tevent_req *req;
1871 NTSTATUS status = NT_STATUS_NO_MEMORY;
1873 if (smbXcli_conn_has_async_calls(cli->conn)) {
1874 return NT_STATUS_INVALID_PARAMETER;
1876 ev = samba_tevent_context_init(talloc_tos());
1880 req = cli_session_setup_creds_send(ev, ev, cli, creds);
1884 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1887 status = cli_session_setup_creds_recv(req);
1893 NTSTATUS cli_session_setup_anon(struct cli_state *cli)
1895 NTSTATUS status = NT_STATUS_NO_MEMORY;
1896 struct cli_credentials *creds = NULL;
1898 creds = cli_credentials_init_anon(cli);
1899 if (creds == NULL) {
1900 return NT_STATUS_NO_MEMORY;
1903 status = cli_session_setup_creds(cli, creds);
1905 if (!NT_STATUS_IS_OK(status)) {
1909 return NT_STATUS_OK;
1912 /****************************************************************************
1914 *****************************************************************************/
1916 struct cli_ulogoff_state {
1917 struct cli_state *cli;
1921 static void cli_ulogoff_done(struct tevent_req *subreq);
1923 static struct tevent_req *cli_ulogoff_send(TALLOC_CTX *mem_ctx,
1924 struct tevent_context *ev,
1925 struct cli_state *cli)
1927 struct tevent_req *req, *subreq;
1928 struct cli_ulogoff_state *state;
1930 req = tevent_req_create(mem_ctx, &state, struct cli_ulogoff_state);
1936 SCVAL(state->vwv+0, 0, 0xFF);
1937 SCVAL(state->vwv+1, 0, 0);
1938 SSVAL(state->vwv+2, 0, 0);
1940 subreq = cli_smb_send(state, ev, cli, SMBulogoffX, 0, 0, 2, state->vwv,
1942 if (tevent_req_nomem(subreq, req)) {
1943 return tevent_req_post(req, ev);
1945 tevent_req_set_callback(subreq, cli_ulogoff_done, req);
1949 static void cli_ulogoff_done(struct tevent_req *subreq)
1951 struct tevent_req *req = tevent_req_callback_data(
1952 subreq, struct tevent_req);
1953 struct cli_ulogoff_state *state = tevent_req_data(
1954 req, struct cli_ulogoff_state);
1957 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
1958 if (!NT_STATUS_IS_OK(status)) {
1959 tevent_req_nterror(req, status);
1962 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
1963 tevent_req_done(req);
1966 static NTSTATUS cli_ulogoff_recv(struct tevent_req *req)
1968 return tevent_req_simple_recv_ntstatus(req);
1971 NTSTATUS cli_ulogoff(struct cli_state *cli)
1973 struct tevent_context *ev;
1974 struct tevent_req *req;
1975 NTSTATUS status = NT_STATUS_NO_MEMORY;
1977 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
1978 status = smb2cli_logoff(cli->conn,
1981 if (!NT_STATUS_IS_OK(status)) {
1984 smb2cli_session_set_id_and_flags(cli->smb2.session,
1986 return NT_STATUS_OK;
1989 if (smbXcli_conn_has_async_calls(cli->conn)) {
1990 return NT_STATUS_INVALID_PARAMETER;
1992 ev = samba_tevent_context_init(talloc_tos());
1996 req = cli_ulogoff_send(ev, ev, cli);
2000 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2003 status = cli_ulogoff_recv(req);
2009 /****************************************************************************
2011 ****************************************************************************/
2013 struct cli_tcon_andx_state {
2014 struct cli_state *cli;
2019 static void cli_tcon_andx_done(struct tevent_req *subreq);
2021 struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx,
2022 struct tevent_context *ev,
2023 struct cli_state *cli,
2024 const char *share, const char *dev,
2025 const char *pass, int passlen,
2026 struct tevent_req **psmbreq)
2028 struct tevent_req *req, *subreq;
2029 struct cli_tcon_andx_state *state;
2034 uint16_t sec_mode = smb1cli_conn_server_security_mode(cli->conn);
2035 uint16_t tcon_flags = 0;
2039 req = tevent_req_create(mem_ctx, &state, struct cli_tcon_andx_state);
2046 TALLOC_FREE(cli->smb1.tcon);
2047 cli->smb1.tcon = smbXcli_tcon_create(cli);
2048 if (tevent_req_nomem(cli->smb1.tcon, req)) {
2049 return tevent_req_post(req, ev);
2051 smb1cli_tcon_set_id(cli->smb1.tcon, UINT16_MAX);
2053 cli->share = talloc_strdup(cli, share);
2058 /* in user level security don't send a password now */
2059 if (sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {
2062 } else if (pass == NULL) {
2063 DEBUG(1, ("Server not using user level security and no "
2064 "password supplied.\n"));
2068 if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) &&
2069 *pass && passlen != 24) {
2070 if (!lp_client_lanman_auth()) {
2071 DEBUG(1, ("Server requested LANMAN password "
2072 "(share-level security) but "
2073 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2078 * Non-encrypted passwords - convert to DOS codepage before
2081 SMBencrypt(pass, smb1cli_conn_server_challenge(cli->conn), p24);
2083 pass = (const char *)p24;
2085 if((sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL
2086 |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE))
2090 if (!lp_client_plaintext_auth() && (*pass)) {
2091 DEBUG(1, ("Server requested PLAINTEXT "
2093 "'client plaintext auth = no' or 'client ntlmv2 auth = yes'\n"));
2098 * Non-encrypted passwords - convert to DOS codepage
2101 tmp_pass = talloc_array(talloc_tos(), uint8_t, 0);
2102 if (tevent_req_nomem(tmp_pass, req)) {
2103 return tevent_req_post(req, ev);
2105 tmp_pass = trans2_bytes_push_str(tmp_pass,
2106 false, /* always DOS */
2110 if (tevent_req_nomem(tmp_pass, req)) {
2111 return tevent_req_post(req, ev);
2113 pass = (const char *)tmp_pass;
2114 passlen = talloc_get_size(tmp_pass);
2118 tcon_flags |= TCONX_FLAG_EXTENDED_RESPONSE;
2119 tcon_flags |= TCONX_FLAG_EXTENDED_SIGNATURES;
2121 SCVAL(vwv+0, 0, 0xFF);
2124 SSVAL(vwv+2, 0, tcon_flags);
2125 SSVAL(vwv+3, 0, passlen);
2127 if (passlen && pass) {
2128 bytes = (uint8_t *)talloc_memdup(state, pass, passlen);
2130 bytes = talloc_array(state, uint8_t, 0);
2136 tmp = talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
2137 smbXcli_conn_remote_name(cli->conn), share);
2142 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), tmp, strlen(tmp)+1,
2147 * Add the devicetype
2149 tmp = talloc_strdup_upper(talloc_tos(), dev);
2154 bytes = smb_bytes_push_str(bytes, false, tmp, strlen(tmp)+1, NULL);
2157 if (bytes == NULL) {
2162 state->bytes.iov_base = (void *)bytes;
2163 state->bytes.iov_len = talloc_get_size(bytes);
2165 subreq = cli_smb_req_create(state, ev, cli, SMBtconX, 0, 0, 4, vwv,
2167 if (subreq == NULL) {
2171 tevent_req_set_callback(subreq, cli_tcon_andx_done, req);
2176 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
2177 return tevent_req_post(req, ev);
2180 struct tevent_req *cli_tcon_andx_send(TALLOC_CTX *mem_ctx,
2181 struct tevent_context *ev,
2182 struct cli_state *cli,
2183 const char *share, const char *dev,
2184 const char *pass, int passlen)
2186 struct tevent_req *req, *subreq;
2189 req = cli_tcon_andx_create(mem_ctx, ev, cli, share, dev, pass, passlen,
2194 if (subreq == NULL) {
2197 status = smb1cli_req_chain_submit(&subreq, 1);
2198 if (!NT_STATUS_IS_OK(status)) {
2199 tevent_req_nterror(req, status);
2200 return tevent_req_post(req, ev);
2205 static void cli_tcon_andx_done(struct tevent_req *subreq)
2207 struct tevent_req *req = tevent_req_callback_data(
2208 subreq, struct tevent_req);
2209 struct cli_tcon_andx_state *state = tevent_req_data(
2210 req, struct cli_tcon_andx_state);
2211 struct cli_state *cli = state->cli;
2219 uint16_t optional_support = 0;
2221 status = cli_smb_recv(subreq, state, &in, 0, &wct, &vwv,
2222 &num_bytes, &bytes);
2223 TALLOC_FREE(subreq);
2224 if (!NT_STATUS_IS_OK(status)) {
2225 tevent_req_nterror(req, status);
2229 inhdr = in + NBT_HDR_SIZE;
2232 if (clistr_pull_talloc(cli,
2233 (const char *)inhdr,
2234 SVAL(inhdr, HDR_FLG2),
2238 STR_TERMINATE|STR_ASCII) == -1) {
2239 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2243 cli->dev = talloc_strdup(cli, "");
2244 if (cli->dev == NULL) {
2245 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2250 if ((smbXcli_conn_protocol(cli->conn) >= PROTOCOL_NT1) && (num_bytes == 3)) {
2251 /* almost certainly win95 - enable bug fixes */
2256 * Make sure that we have the optional support 16-bit field. WCT > 2.
2257 * Avoids issues when connecting to Win9x boxes sharing files
2260 if ((wct > 2) && (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_LANMAN2)) {
2261 optional_support = SVAL(vwv+2, 0);
2264 if (optional_support & SMB_EXTENDED_SIGNATURES) {
2265 smb1cli_session_protect_session_key(cli->smb1.session);
2268 smb1cli_tcon_set_values(state->cli->smb1.tcon,
2269 SVAL(inhdr, HDR_TID),
2271 0, /* maximal_access */
2272 0, /* guest_maximal_access */
2274 NULL); /* fs_type */
2276 tevent_req_done(req);
2279 NTSTATUS cli_tcon_andx_recv(struct tevent_req *req)
2281 return tevent_req_simple_recv_ntstatus(req);
2284 NTSTATUS cli_tcon_andx(struct cli_state *cli, const char *share,
2285 const char *dev, const char *pass, int passlen)
2287 TALLOC_CTX *frame = talloc_stackframe();
2288 struct tevent_context *ev;
2289 struct tevent_req *req;
2290 NTSTATUS status = NT_STATUS_NO_MEMORY;
2292 if (smbXcli_conn_has_async_calls(cli->conn)) {
2294 * Can't use sync call while an async call is in flight
2296 status = NT_STATUS_INVALID_PARAMETER;
2300 ev = samba_tevent_context_init(frame);
2305 req = cli_tcon_andx_send(frame, ev, cli, share, dev, pass, passlen);
2310 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2314 status = cli_tcon_andx_recv(req);
2320 struct cli_tree_connect_state {
2321 struct cli_state *cli;
2324 static struct tevent_req *cli_raw_tcon_send(
2325 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
2326 const char *service, const char *pass, const char *dev);
2327 static NTSTATUS cli_raw_tcon_recv(struct tevent_req *req,
2328 uint16_t *max_xmit, uint16_t *tid);
2330 static void cli_tree_connect_smb2_done(struct tevent_req *subreq);
2331 static void cli_tree_connect_andx_done(struct tevent_req *subreq);
2332 static void cli_tree_connect_raw_done(struct tevent_req *subreq);
2334 static struct tevent_req *cli_tree_connect_send(
2335 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
2336 const char *share, const char *dev, const char *pass)
2338 struct tevent_req *req, *subreq;
2339 struct cli_tree_connect_state *state;
2345 passlen = strlen(pass) + 1;
2347 req = tevent_req_create(mem_ctx, &state,
2348 struct cli_tree_connect_state);
2354 cli->share = talloc_strdup(cli, share);
2355 if (tevent_req_nomem(cli->share, req)) {
2356 return tevent_req_post(req, ev);
2359 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
2362 TALLOC_FREE(cli->smb2.tcon);
2363 cli->smb2.tcon = smbXcli_tcon_create(cli);
2364 if (tevent_req_nomem(cli->smb2.tcon, req)) {
2365 return tevent_req_post(req, ev);
2368 unc = talloc_asprintf(state, "\\\\%s\\%s",
2369 smbXcli_conn_remote_name(cli->conn),
2371 if (tevent_req_nomem(unc, req)) {
2372 return tevent_req_post(req, ev);
2375 subreq = smb2cli_tcon_send(state, ev, cli->conn, cli->timeout,
2376 cli->smb2.session, cli->smb2.tcon,
2379 if (tevent_req_nomem(subreq, req)) {
2380 return tevent_req_post(req, ev);
2382 tevent_req_set_callback(subreq, cli_tree_connect_smb2_done,
2387 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_LANMAN1) {
2388 subreq = cli_tcon_andx_send(state, ev, cli, share, dev,
2390 if (tevent_req_nomem(subreq, req)) {
2391 return tevent_req_post(req, ev);
2393 tevent_req_set_callback(subreq, cli_tree_connect_andx_done,
2398 subreq = cli_raw_tcon_send(state, ev, cli, share, pass, dev);
2399 if (tevent_req_nomem(subreq, req)) {
2400 return tevent_req_post(req, ev);
2402 tevent_req_set_callback(subreq, cli_tree_connect_raw_done, req);
2407 static void cli_tree_connect_smb2_done(struct tevent_req *subreq)
2409 tevent_req_simple_finish_ntstatus(
2410 subreq, smb2cli_tcon_recv(subreq));
2413 static void cli_tree_connect_andx_done(struct tevent_req *subreq)
2415 tevent_req_simple_finish_ntstatus(
2416 subreq, cli_tcon_andx_recv(subreq));
2419 static void cli_tree_connect_raw_done(struct tevent_req *subreq)
2421 struct tevent_req *req = tevent_req_callback_data(
2422 subreq, struct tevent_req);
2423 struct cli_tree_connect_state *state = tevent_req_data(
2424 req, struct cli_tree_connect_state);
2426 uint16_t max_xmit = 0;
2429 status = cli_raw_tcon_recv(subreq, &max_xmit, &tid);
2430 if (tevent_req_nterror(req, status)) {
2434 smb1cli_tcon_set_values(state->cli->smb1.tcon,
2436 0, /* optional_support */
2437 0, /* maximal_access */
2438 0, /* guest_maximal_access */
2440 NULL); /* fs_type */
2442 tevent_req_done(req);
2445 static NTSTATUS cli_tree_connect_recv(struct tevent_req *req)
2447 return tevent_req_simple_recv_ntstatus(req);
2450 NTSTATUS cli_tree_connect(struct cli_state *cli, const char *share,
2451 const char *dev, const char *pass)
2453 struct tevent_context *ev;
2454 struct tevent_req *req;
2455 NTSTATUS status = NT_STATUS_NO_MEMORY;
2457 if (smbXcli_conn_has_async_calls(cli->conn)) {
2458 return NT_STATUS_INVALID_PARAMETER;
2460 ev = samba_tevent_context_init(talloc_tos());
2464 req = cli_tree_connect_send(ev, ev, cli, share, dev, pass);
2468 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2471 status = cli_tree_connect_recv(req);
2477 NTSTATUS cli_tree_connect_creds(struct cli_state *cli,
2478 const char *share, const char *dev,
2479 struct cli_credentials *creds)
2481 const char *pw = NULL;
2483 if (creds != NULL) {
2484 pw = cli_credentials_get_password(creds);
2487 return cli_tree_connect(cli, share, dev, pw);
2490 /****************************************************************************
2491 Send a tree disconnect.
2492 ****************************************************************************/
2494 struct cli_tdis_state {
2495 struct cli_state *cli;
2498 static void cli_tdis_done(struct tevent_req *subreq);
2500 static struct tevent_req *cli_tdis_send(TALLOC_CTX *mem_ctx,
2501 struct tevent_context *ev,
2502 struct cli_state *cli)
2504 struct tevent_req *req, *subreq;
2505 struct cli_tdis_state *state;
2507 req = tevent_req_create(mem_ctx, &state, struct cli_tdis_state);
2513 subreq = cli_smb_send(state, ev, cli, SMBtdis, 0, 0, 0, NULL, 0, NULL);
2514 if (tevent_req_nomem(subreq, req)) {
2515 return tevent_req_post(req, ev);
2517 tevent_req_set_callback(subreq, cli_tdis_done, req);
2521 static void cli_tdis_done(struct tevent_req *subreq)
2523 struct tevent_req *req = tevent_req_callback_data(
2524 subreq, struct tevent_req);
2525 struct cli_tdis_state *state = tevent_req_data(
2526 req, struct cli_tdis_state);
2529 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
2530 TALLOC_FREE(subreq);
2531 if (!NT_STATUS_IS_OK(status)) {
2532 tevent_req_nterror(req, status);
2535 TALLOC_FREE(state->cli->smb1.tcon);
2536 tevent_req_done(req);
2539 static NTSTATUS cli_tdis_recv(struct tevent_req *req)
2541 return tevent_req_simple_recv_ntstatus(req);
2544 NTSTATUS cli_tdis(struct cli_state *cli)
2546 struct tevent_context *ev;
2547 struct tevent_req *req;
2548 NTSTATUS status = NT_STATUS_NO_MEMORY;
2550 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
2551 status = smb2cli_tdis(cli->conn,
2555 if (NT_STATUS_IS_OK(status)) {
2556 TALLOC_FREE(cli->smb2.tcon);
2561 if (smbXcli_conn_has_async_calls(cli->conn)) {
2562 return NT_STATUS_INVALID_PARAMETER;
2564 ev = samba_tevent_context_init(talloc_tos());
2568 req = cli_tdis_send(ev, ev, cli);
2572 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2575 status = cli_tdis_recv(req);
2581 struct cli_connect_sock_state {
2582 const char **called_names;
2583 const char **calling_names;
2589 static void cli_connect_sock_done(struct tevent_req *subreq);
2592 * Async only if we don't have to look up the name, i.e. "pss" is set with a
2596 static struct tevent_req *cli_connect_sock_send(
2597 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2598 const char *host, int name_type, const struct sockaddr_storage *pss,
2599 const char *myname, uint16_t port)
2601 struct tevent_req *req, *subreq;
2602 struct cli_connect_sock_state *state;
2603 struct sockaddr_storage *addrs;
2604 unsigned i, num_addrs;
2607 req = tevent_req_create(mem_ctx, &state,
2608 struct cli_connect_sock_state);
2613 if ((pss == NULL) || is_zero_addr(pss)) {
2616 * Here we cheat. resolve_name_list is not async at all. So
2617 * this call will only be really async if the name lookup has
2618 * been done externally.
2621 status = resolve_name_list(state, host, name_type,
2622 &addrs, &num_addrs);
2623 if (!NT_STATUS_IS_OK(status)) {
2624 tevent_req_nterror(req, status);
2625 return tevent_req_post(req, ev);
2628 addrs = talloc_array(state, struct sockaddr_storage, 1);
2629 if (tevent_req_nomem(addrs, req)) {
2630 return tevent_req_post(req, ev);
2636 state->called_names = talloc_array(state, const char *, num_addrs);
2637 if (tevent_req_nomem(state->called_names, req)) {
2638 return tevent_req_post(req, ev);
2640 state->called_types = talloc_array(state, int, num_addrs);
2641 if (tevent_req_nomem(state->called_types, req)) {
2642 return tevent_req_post(req, ev);
2644 state->calling_names = talloc_array(state, const char *, num_addrs);
2645 if (tevent_req_nomem(state->calling_names, req)) {
2646 return tevent_req_post(req, ev);
2648 for (i=0; i<num_addrs; i++) {
2649 state->called_names[i] = host;
2650 state->called_types[i] = name_type;
2651 state->calling_names[i] = myname;
2654 subreq = smbsock_any_connect_send(
2655 state, ev, addrs, state->called_names, state->called_types,
2656 state->calling_names, NULL, num_addrs, port);
2657 if (tevent_req_nomem(subreq, req)) {
2658 return tevent_req_post(req, ev);
2660 tevent_req_set_callback(subreq, cli_connect_sock_done, req);
2664 static void cli_connect_sock_done(struct tevent_req *subreq)
2666 struct tevent_req *req = tevent_req_callback_data(
2667 subreq, struct tevent_req);
2668 struct cli_connect_sock_state *state = tevent_req_data(
2669 req, struct cli_connect_sock_state);
2672 status = smbsock_any_connect_recv(subreq, &state->fd, NULL,
2674 TALLOC_FREE(subreq);
2675 if (tevent_req_nterror(req, status)) {
2678 set_socket_options(state->fd, lp_socket_options());
2679 tevent_req_done(req);
2682 static NTSTATUS cli_connect_sock_recv(struct tevent_req *req,
2683 int *pfd, uint16_t *pport)
2685 struct cli_connect_sock_state *state = tevent_req_data(
2686 req, struct cli_connect_sock_state);
2689 if (tevent_req_is_nterror(req, &status)) {
2693 *pport = state->port;
2694 return NT_STATUS_OK;
2697 struct cli_connect_nb_state {
2698 const char *desthost;
2701 struct cli_state *cli;
2704 static void cli_connect_nb_done(struct tevent_req *subreq);
2706 static struct tevent_req *cli_connect_nb_send(
2707 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2708 const char *host, const struct sockaddr_storage *dest_ss,
2709 uint16_t port, int name_type, const char *myname,
2710 int signing_state, int flags)
2712 struct tevent_req *req, *subreq;
2713 struct cli_connect_nb_state *state;
2715 req = tevent_req_create(mem_ctx, &state, struct cli_connect_nb_state);
2719 state->signing_state = signing_state;
2720 state->flags = flags;
2723 char *p = strchr(host, '#');
2726 name_type = strtol(p+1, NULL, 16);
2727 host = talloc_strndup(state, host, p - host);
2728 if (tevent_req_nomem(host, req)) {
2729 return tevent_req_post(req, ev);
2733 state->desthost = host;
2734 } else if (dest_ss != NULL) {
2735 state->desthost = print_canonical_sockaddr(state, dest_ss);
2736 if (tevent_req_nomem(state->desthost, req)) {
2737 return tevent_req_post(req, ev);
2740 /* No host or dest_ss given. Error out. */
2741 tevent_req_error(req, EINVAL);
2742 return tevent_req_post(req, ev);
2745 subreq = cli_connect_sock_send(state, ev, host, name_type, dest_ss,
2747 if (tevent_req_nomem(subreq, req)) {
2748 return tevent_req_post(req, ev);
2750 tevent_req_set_callback(subreq, cli_connect_nb_done, req);
2754 static void cli_connect_nb_done(struct tevent_req *subreq)
2756 struct tevent_req *req = tevent_req_callback_data(
2757 subreq, struct tevent_req);
2758 struct cli_connect_nb_state *state = tevent_req_data(
2759 req, struct cli_connect_nb_state);
2764 status = cli_connect_sock_recv(subreq, &fd, &port);
2765 TALLOC_FREE(subreq);
2766 if (tevent_req_nterror(req, status)) {
2770 state->cli = cli_state_create(state, fd, state->desthost,
2771 state->signing_state, state->flags);
2772 if (tevent_req_nomem(state->cli, req)) {
2776 tevent_req_done(req);
2779 static NTSTATUS cli_connect_nb_recv(struct tevent_req *req,
2780 struct cli_state **pcli)
2782 struct cli_connect_nb_state *state = tevent_req_data(
2783 req, struct cli_connect_nb_state);
2786 if (tevent_req_is_nterror(req, &status)) {
2789 *pcli = talloc_move(NULL, &state->cli);
2790 return NT_STATUS_OK;
2793 NTSTATUS cli_connect_nb(const char *host, const struct sockaddr_storage *dest_ss,
2794 uint16_t port, int name_type, const char *myname,
2795 int signing_state, int flags, struct cli_state **pcli)
2797 struct tevent_context *ev;
2798 struct tevent_req *req;
2799 NTSTATUS status = NT_STATUS_NO_MEMORY;
2801 ev = samba_tevent_context_init(talloc_tos());
2805 req = cli_connect_nb_send(ev, ev, host, dest_ss, port, name_type,
2806 myname, signing_state, flags);
2810 if (!tevent_req_set_endtime(req, ev, timeval_current_ofs(20, 0))) {
2813 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2816 status = cli_connect_nb_recv(req, pcli);
2822 struct cli_start_connection_state {
2823 struct tevent_context *ev;
2824 struct cli_state *cli;
2829 static void cli_start_connection_connected(struct tevent_req *subreq);
2830 static void cli_start_connection_done(struct tevent_req *subreq);
2833 establishes a connection to after the negprot.
2834 @param output_cli A fully initialised cli structure, non-null only on success
2835 @param dest_host The netbios name of the remote host
2836 @param dest_ss (optional) The the destination IP, NULL for name based lookup
2837 @param port (optional) The destination port (0 for default)
2840 static struct tevent_req *cli_start_connection_send(
2841 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2842 const char *my_name, const char *dest_host,
2843 const struct sockaddr_storage *dest_ss, int port,
2844 int signing_state, int flags)
2846 struct tevent_req *req, *subreq;
2847 struct cli_start_connection_state *state;
2849 req = tevent_req_create(mem_ctx, &state,
2850 struct cli_start_connection_state);
2856 if (signing_state == SMB_SIGNING_IPC_DEFAULT) {
2857 state->min_protocol = lp_client_ipc_min_protocol();
2858 state->max_protocol = lp_client_ipc_max_protocol();
2860 state->min_protocol = lp_client_min_protocol();
2861 state->max_protocol = lp_client_max_protocol();
2864 if (flags & CLI_FULL_CONNECTION_FORCE_SMB1) {
2865 state->max_protocol = MIN(state->max_protocol, PROTOCOL_NT1);
2868 if (flags & CLI_FULL_CONNECTION_DISABLE_SMB1) {
2869 state->min_protocol = MAX(state->max_protocol, PROTOCOL_SMB2_02);
2870 state->max_protocol = MAX(state->max_protocol, PROTOCOL_LATEST);
2873 subreq = cli_connect_nb_send(state, ev, dest_host, dest_ss, port,
2874 0x20, my_name, signing_state, flags);
2875 if (tevent_req_nomem(subreq, req)) {
2876 return tevent_req_post(req, ev);
2878 tevent_req_set_callback(subreq, cli_start_connection_connected, req);
2882 static void cli_start_connection_connected(struct tevent_req *subreq)
2884 struct tevent_req *req = tevent_req_callback_data(
2885 subreq, struct tevent_req);
2886 struct cli_start_connection_state *state = tevent_req_data(
2887 req, struct cli_start_connection_state);
2890 status = cli_connect_nb_recv(subreq, &state->cli);
2891 TALLOC_FREE(subreq);
2892 if (tevent_req_nterror(req, status)) {
2896 subreq = smbXcli_negprot_send(state, state->ev, state->cli->conn,
2897 state->cli->timeout,
2898 state->min_protocol,
2899 state->max_protocol,
2900 WINDOWS_CLIENT_PURE_SMB2_NEGPROT_INITIAL_CREDIT_ASK);
2901 if (tevent_req_nomem(subreq, req)) {
2904 tevent_req_set_callback(subreq, cli_start_connection_done, req);
2907 static void cli_start_connection_done(struct tevent_req *subreq)
2909 struct tevent_req *req = tevent_req_callback_data(
2910 subreq, struct tevent_req);
2911 struct cli_start_connection_state *state = tevent_req_data(
2912 req, struct cli_start_connection_state);
2915 status = smbXcli_negprot_recv(subreq);
2916 TALLOC_FREE(subreq);
2917 if (tevent_req_nterror(req, status)) {
2921 status = cli_state_update_after_negprot(state->cli);
2922 if (tevent_req_nterror(req, status)) {
2926 tevent_req_done(req);
2929 static NTSTATUS cli_start_connection_recv(struct tevent_req *req,
2930 struct cli_state **output_cli)
2932 struct cli_start_connection_state *state = tevent_req_data(
2933 req, struct cli_start_connection_state);
2936 if (tevent_req_is_nterror(req, &status)) {
2939 *output_cli = state->cli;
2941 return NT_STATUS_OK;
2944 NTSTATUS cli_start_connection(struct cli_state **output_cli,
2945 const char *my_name,
2946 const char *dest_host,
2947 const struct sockaddr_storage *dest_ss, int port,
2948 int signing_state, int flags)
2950 struct tevent_context *ev;
2951 struct tevent_req *req;
2952 NTSTATUS status = NT_STATUS_NO_MEMORY;
2954 ev = samba_tevent_context_init(talloc_tos());
2958 req = cli_start_connection_send(ev, ev, my_name, dest_host, dest_ss,
2959 port, signing_state, flags);
2963 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2966 status = cli_start_connection_recv(req, output_cli);
2972 struct cli_smb1_setup_encryption_blob_state {
2977 uint16_t enc_ctx_id;
2980 static void cli_smb1_setup_encryption_blob_done(struct tevent_req *subreq);
2982 static struct tevent_req *cli_smb1_setup_encryption_blob_send(TALLOC_CTX *mem_ctx,
2983 struct tevent_context *ev,
2984 struct cli_state *cli,
2987 struct tevent_req *req = NULL;
2988 struct cli_smb1_setup_encryption_blob_state *state = NULL;
2989 struct tevent_req *subreq = NULL;
2991 req = tevent_req_create(mem_ctx, &state,
2992 struct cli_smb1_setup_encryption_blob_state);
2997 if (in.length > CLI_BUFFER_SIZE) {
2998 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
2999 return tevent_req_post(req, ev);
3002 SSVAL(state->setup+0, 0, TRANSACT2_SETFSINFO);
3003 SSVAL(state->param, 0, 0);
3004 SSVAL(state->param, 2, SMB_REQUEST_TRANSPORT_ENCRYPTION);
3006 subreq = smb1cli_trans_send(state, ev, cli->conn,
3014 NULL, /* pipe_name */
3020 in.data, in.length, CLI_BUFFER_SIZE);
3021 if (tevent_req_nomem(subreq, req)) {
3022 return tevent_req_post(req, ev);
3024 tevent_req_set_callback(subreq,
3025 cli_smb1_setup_encryption_blob_done,
3031 static void cli_smb1_setup_encryption_blob_done(struct tevent_req *subreq)
3033 struct tevent_req *req =
3034 tevent_req_callback_data(subreq,
3036 struct cli_smb1_setup_encryption_blob_state *state =
3037 tevent_req_data(req,
3038 struct cli_smb1_setup_encryption_blob_state);
3039 uint8_t *rparam=NULL, *rdata=NULL;
3040 uint32_t num_rparam, num_rdata;
3043 status = smb1cli_trans_recv(subreq, state,
3044 NULL, /* recv_flags */
3045 NULL, 0, NULL, /* rsetup */
3046 &rparam, 0, &num_rparam,
3047 &rdata, 0, &num_rdata);
3048 TALLOC_FREE(subreq);
3049 state->status = status;
3050 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
3051 status = NT_STATUS_OK;
3053 if (tevent_req_nterror(req, status)) {
3057 if (num_rparam == 2) {
3058 state->enc_ctx_id = SVAL(rparam, 0);
3060 TALLOC_FREE(rparam);
3062 state->out = data_blob_const(rdata, num_rdata);
3064 tevent_req_done(req);
3067 static NTSTATUS cli_smb1_setup_encryption_blob_recv(struct tevent_req *req,
3068 TALLOC_CTX *mem_ctx,
3070 uint16_t *enc_ctx_id)
3072 struct cli_smb1_setup_encryption_blob_state *state =
3073 tevent_req_data(req,
3074 struct cli_smb1_setup_encryption_blob_state);
3077 if (tevent_req_is_nterror(req, &status)) {
3078 tevent_req_received(req);
3082 status = state->status;
3085 talloc_steal(mem_ctx, out->data);
3087 *enc_ctx_id = state->enc_ctx_id;
3089 tevent_req_received(req);
3093 struct cli_smb1_setup_encryption_state {
3094 struct tevent_context *ev;
3095 struct cli_state *cli;
3096 struct smb_trans_enc_state *es;
3103 static void cli_smb1_setup_encryption_local_next(struct tevent_req *req);
3104 static void cli_smb1_setup_encryption_local_done(struct tevent_req *subreq);
3105 static void cli_smb1_setup_encryption_remote_next(struct tevent_req *req);
3106 static void cli_smb1_setup_encryption_remote_done(struct tevent_req *subreq);
3107 static void cli_smb1_setup_encryption_ready(struct tevent_req *req);
3109 static struct tevent_req *cli_smb1_setup_encryption_send(TALLOC_CTX *mem_ctx,
3110 struct tevent_context *ev,
3111 struct cli_state *cli,
3112 struct cli_credentials *creds)
3114 struct tevent_req *req = NULL;
3115 struct cli_smb1_setup_encryption_state *state = NULL;
3116 struct auth_generic_state *ags = NULL;
3117 const DATA_BLOB *b = NULL;
3118 bool auth_requested = false;
3119 const char *target_service = NULL;
3120 const char *target_hostname = NULL;
3123 req = tevent_req_create(mem_ctx, &state,
3124 struct cli_smb1_setup_encryption_state);
3131 auth_requested = cli_credentials_authentication_requested(creds);
3132 if (!auth_requested) {
3133 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
3134 return tevent_req_post(req, ev);
3137 target_service = "cifs";
3138 target_hostname = smbXcli_conn_remote_name(cli->conn);
3140 status = cli_session_creds_prepare_krb5(cli, creds);
3141 if (tevent_req_nterror(req, status)) {
3142 return tevent_req_post(req, ev);
3145 state->es = talloc_zero(state, struct smb_trans_enc_state);
3146 if (tevent_req_nomem(state->es, req)) {
3147 return tevent_req_post(req, ev);
3150 status = auth_generic_client_prepare(state->es, &ags);
3151 if (tevent_req_nterror(req, status)) {
3152 return tevent_req_post(req, ev);
3155 gensec_want_feature(ags->gensec_security,
3156 GENSEC_FEATURE_SIGN);
3157 gensec_want_feature(ags->gensec_security,
3158 GENSEC_FEATURE_SEAL);
3160 status = auth_generic_set_creds(ags, creds);
3161 if (tevent_req_nterror(req, status)) {
3162 return tevent_req_post(req, ev);
3165 if (target_service != NULL) {
3166 status = gensec_set_target_service(ags->gensec_security,
3168 if (tevent_req_nterror(req, status)) {
3169 return tevent_req_post(req, ev);
3173 if (target_hostname != NULL) {
3174 status = gensec_set_target_hostname(ags->gensec_security,
3176 if (tevent_req_nterror(req, status)) {
3177 return tevent_req_post(req, ev);
3181 gensec_set_max_update_size(ags->gensec_security,
3184 b = smbXcli_conn_server_gss_blob(state->cli->conn);
3186 state->blob_in = *b;
3189 status = auth_generic_client_start(ags, GENSEC_OID_SPNEGO);
3190 if (tevent_req_nterror(req, status)) {
3191 return tevent_req_post(req, ev);
3195 * We only need the gensec_security part from here.
3197 state->es->gensec_security = talloc_move(state->es,
3198 &ags->gensec_security);
3201 cli_smb1_setup_encryption_local_next(req);
3202 if (!tevent_req_is_in_progress(req)) {
3203 return tevent_req_post(req, ev);
3209 static void cli_smb1_setup_encryption_local_next(struct tevent_req *req)
3211 struct cli_smb1_setup_encryption_state *state =
3212 tevent_req_data(req,
3213 struct cli_smb1_setup_encryption_state);
3214 struct tevent_req *subreq = NULL;
3216 if (state->local_ready) {
3217 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3221 subreq = gensec_update_send(state, state->ev,
3222 state->es->gensec_security,
3224 if (tevent_req_nomem(subreq, req)) {
3227 tevent_req_set_callback(subreq, cli_smb1_setup_encryption_local_done, req);
3230 static void cli_smb1_setup_encryption_local_done(struct tevent_req *subreq)
3232 struct tevent_req *req =
3233 tevent_req_callback_data(subreq,
3235 struct cli_smb1_setup_encryption_state *state =
3236 tevent_req_data(req,
3237 struct cli_smb1_setup_encryption_state);
3240 status = gensec_update_recv(subreq, state, &state->blob_out);
3241 TALLOC_FREE(subreq);
3242 state->blob_in = data_blob_null;
3243 if (!NT_STATUS_IS_OK(status) &&
3244 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
3246 tevent_req_nterror(req, status);
3250 if (NT_STATUS_IS_OK(status)) {
3251 state->local_ready = true;
3255 * We always get NT_STATUS_OK from the server even if it is not ready.
3256 * So guess the server is ready when we are ready and already sent
3257 * our last blob to the server.
3259 if (state->local_ready && state->blob_out.length == 0) {
3260 state->remote_ready = true;
3263 if (state->local_ready && state->remote_ready) {
3264 cli_smb1_setup_encryption_ready(req);
3268 cli_smb1_setup_encryption_remote_next(req);
3271 static void cli_smb1_setup_encryption_remote_next(struct tevent_req *req)
3273 struct cli_smb1_setup_encryption_state *state =
3274 tevent_req_data(req,
3275 struct cli_smb1_setup_encryption_state);
3276 struct tevent_req *subreq = NULL;
3278 if (state->remote_ready) {
3279 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3283 subreq = cli_smb1_setup_encryption_blob_send(state, state->ev,
3284 state->cli, state->blob_out);
3285 if (tevent_req_nomem(subreq, req)) {
3288 tevent_req_set_callback(subreq,
3289 cli_smb1_setup_encryption_remote_done,
3293 static void cli_smb1_setup_encryption_remote_done(struct tevent_req *subreq)
3295 struct tevent_req *req =
3296 tevent_req_callback_data(subreq,
3298 struct cli_smb1_setup_encryption_state *state =
3299 tevent_req_data(req,
3300 struct cli_smb1_setup_encryption_state);
3303 status = cli_smb1_setup_encryption_blob_recv(subreq, state,
3305 &state->es->enc_ctx_num);
3306 TALLOC_FREE(subreq);
3307 data_blob_free(&state->blob_out);
3308 if (!NT_STATUS_IS_OK(status) &&
3309 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
3311 tevent_req_nterror(req, status);
3316 * We always get NT_STATUS_OK even if the server is not ready.
3317 * So guess the server is ready when we are ready and sent
3318 * our last blob to the server.
3320 if (state->local_ready) {
3321 state->remote_ready = true;
3324 if (state->local_ready && state->remote_ready) {
3325 cli_smb1_setup_encryption_ready(req);
3329 cli_smb1_setup_encryption_local_next(req);
3332 static void cli_smb1_setup_encryption_ready(struct tevent_req *req)
3334 struct cli_smb1_setup_encryption_state *state =
3335 tevent_req_data(req,
3336 struct cli_smb1_setup_encryption_state);
3337 struct smb_trans_enc_state *es = NULL;
3339 if (state->blob_in.length != 0) {
3340 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3344 if (state->blob_out.length != 0) {
3345 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3349 es = talloc_move(state->cli->conn, &state->es);
3351 smb1cli_conn_set_encryption(state->cli->conn, es);
3354 tevent_req_done(req);
3357 static NTSTATUS cli_smb1_setup_encryption_recv(struct tevent_req *req)
3359 return tevent_req_simple_recv_ntstatus(req);
3362 NTSTATUS cli_smb1_setup_encryption(struct cli_state *cli,
3363 struct cli_credentials *creds)
3365 struct tevent_context *ev = NULL;
3366 struct tevent_req *req = NULL;
3367 NTSTATUS status = NT_STATUS_NO_MEMORY;
3369 ev = samba_tevent_context_init(talloc_tos());
3373 req = cli_smb1_setup_encryption_send(ev, ev, cli, creds);
3377 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
3380 status = cli_smb1_setup_encryption_recv(req);
3387 establishes a connection right up to doing tconX, password specified.
3388 @param output_cli A fully initialised cli structure, non-null only on success
3389 @param dest_host The netbios name of the remote host
3390 @param dest_ip (optional) The the destination IP, NULL for name based lookup
3391 @param port (optional) The destination port (0 for default)
3392 @param service (optional) The share to make the connection to. Should be 'unqualified' in any way.
3393 @param service_type The 'type' of serivice.
3394 @param creds The used user credentials
3397 struct cli_full_connection_creds_state {
3398 struct tevent_context *ev;
3399 const char *service;
3400 const char *service_type;
3401 struct cli_credentials *creds;
3403 struct cli_state *cli;
3406 static int cli_full_connection_creds_state_destructor(
3407 struct cli_full_connection_creds_state *s)
3409 if (s->cli != NULL) {
3410 cli_shutdown(s->cli);
3416 static void cli_full_connection_creds_conn_done(struct tevent_req *subreq);
3417 static void cli_full_connection_creds_sess_start(struct tevent_req *req);
3418 static void cli_full_connection_creds_sess_done(struct tevent_req *subreq);
3419 static void cli_full_connection_creds_tcon_start(struct tevent_req *req);
3420 static void cli_full_connection_creds_tcon_done(struct tevent_req *subreq);
3422 struct tevent_req *cli_full_connection_creds_send(
3423 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
3424 const char *my_name, const char *dest_host,
3425 const struct sockaddr_storage *dest_ss, int port,
3426 const char *service, const char *service_type,
3427 struct cli_credentials *creds,
3428 int flags, int signing_state)
3430 struct tevent_req *req, *subreq;
3431 struct cli_full_connection_creds_state *state;
3432 enum credentials_use_kerberos krb5_state;
3433 uint32_t gensec_features = 0;
3435 req = tevent_req_create(mem_ctx, &state,
3436 struct cli_full_connection_creds_state);
3440 talloc_set_destructor(state, cli_full_connection_creds_state_destructor);
3442 flags &= ~CLI_FULL_CONNECTION_USE_KERBEROS;
3443 flags &= ~CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS;
3444 flags &= ~CLI_FULL_CONNECTION_USE_CCACHE;
3445 flags &= ~CLI_FULL_CONNECTION_USE_NT_HASH;
3447 krb5_state = cli_credentials_get_kerberos_state(creds);
3448 switch (krb5_state) {
3449 case CRED_MUST_USE_KERBEROS:
3450 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
3451 flags &= ~CLI_FULL_CONNECTION_DONT_SPNEGO;
3453 case CRED_AUTO_USE_KERBEROS:
3454 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
3455 flags |= CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS;
3457 case CRED_DONT_USE_KERBEROS:
3461 gensec_features = cli_credentials_get_gensec_features(creds);
3462 if (gensec_features & GENSEC_FEATURE_NTLM_CCACHE) {
3463 flags |= CLI_FULL_CONNECTION_USE_CCACHE;
3467 state->service = service;
3468 state->service_type = service_type;
3469 state->creds = creds;
3470 state->flags = flags;
3472 subreq = cli_start_connection_send(
3473 state, ev, my_name, dest_host, dest_ss, port,
3474 signing_state, flags);
3475 if (tevent_req_nomem(subreq, req)) {
3476 return tevent_req_post(req, ev);
3478 tevent_req_set_callback(subreq,
3479 cli_full_connection_creds_conn_done,
3484 static void cli_full_connection_creds_conn_done(struct tevent_req *subreq)
3486 struct tevent_req *req = tevent_req_callback_data(
3487 subreq, struct tevent_req);
3488 struct cli_full_connection_creds_state *state = tevent_req_data(
3489 req, struct cli_full_connection_creds_state);
3492 status = cli_start_connection_recv(subreq, &state->cli);
3493 TALLOC_FREE(subreq);
3494 if (tevent_req_nterror(req, status)) {
3498 cli_full_connection_creds_sess_start(req);
3501 static void cli_full_connection_creds_sess_start(struct tevent_req *req)
3503 struct cli_full_connection_creds_state *state = tevent_req_data(
3504 req, struct cli_full_connection_creds_state);
3505 struct tevent_req *subreq = NULL;
3507 subreq = cli_session_setup_creds_send(
3508 state, state->ev, state->cli, state->creds);
3509 if (tevent_req_nomem(subreq, req)) {
3512 tevent_req_set_callback(subreq,
3513 cli_full_connection_creds_sess_done,
3517 static void cli_full_connection_creds_sess_done(struct tevent_req *subreq)
3519 struct tevent_req *req = tevent_req_callback_data(
3520 subreq, struct tevent_req);
3521 struct cli_full_connection_creds_state *state = tevent_req_data(
3522 req, struct cli_full_connection_creds_state);
3525 status = cli_session_setup_creds_recv(subreq);
3526 TALLOC_FREE(subreq);
3528 if (!NT_STATUS_IS_OK(status) &&
3529 (state->flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)) {
3531 state->flags &= ~CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
3533 state->creds = cli_credentials_init_anon(state);
3534 if (tevent_req_nomem(state->creds, req)) {
3538 cli_full_connection_creds_sess_start(req);
3542 if (tevent_req_nterror(req, status)) {
3546 cli_full_connection_creds_tcon_start(req);
3549 static void cli_full_connection_creds_tcon_start(struct tevent_req *req)
3551 struct cli_full_connection_creds_state *state = tevent_req_data(
3552 req, struct cli_full_connection_creds_state);
3553 struct tevent_req *subreq = NULL;
3554 const char *password = NULL;
3556 if (state->service == NULL) {
3557 tevent_req_done(req);
3561 password = cli_credentials_get_password(state->creds);
3563 subreq = cli_tree_connect_send(state, state->ev,
3566 state->service_type,
3568 if (tevent_req_nomem(subreq, req)) {
3571 tevent_req_set_callback(subreq,
3572 cli_full_connection_creds_tcon_done,
3576 static void cli_full_connection_creds_tcon_done(struct tevent_req *subreq)
3578 struct tevent_req *req = tevent_req_callback_data(
3579 subreq, struct tevent_req);
3582 status = cli_tree_connect_recv(subreq);
3583 TALLOC_FREE(subreq);
3584 if (tevent_req_nterror(req, status)) {
3588 tevent_req_done(req);
3591 NTSTATUS cli_full_connection_creds_recv(struct tevent_req *req,
3592 struct cli_state **output_cli)
3594 struct cli_full_connection_creds_state *state = tevent_req_data(
3595 req, struct cli_full_connection_creds_state);
3598 if (tevent_req_is_nterror(req, &status)) {
3601 *output_cli = state->cli;
3602 talloc_set_destructor(state, NULL);
3603 return NT_STATUS_OK;
3606 NTSTATUS cli_full_connection_creds(struct cli_state **output_cli,
3607 const char *my_name,
3608 const char *dest_host,
3609 const struct sockaddr_storage *dest_ss, int port,
3610 const char *service, const char *service_type,
3611 struct cli_credentials *creds,
3615 struct tevent_context *ev;
3616 struct tevent_req *req;
3617 NTSTATUS status = NT_STATUS_NO_MEMORY;
3619 ev = samba_tevent_context_init(talloc_tos());
3623 req = cli_full_connection_creds_send(
3624 ev, ev, my_name, dest_host, dest_ss, port, service,
3625 service_type, creds, flags, signing_state);
3629 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
3632 status = cli_full_connection_creds_recv(req, output_cli);
3638 NTSTATUS cli_full_connection(struct cli_state **output_cli,
3639 const char *my_name,
3640 const char *dest_host,
3641 const struct sockaddr_storage *dest_ss, int port,
3642 const char *service, const char *service_type,
3643 const char *user, const char *domain,
3644 const char *password, int flags,
3647 TALLOC_CTX *frame = talloc_stackframe();
3649 bool use_kerberos = false;
3650 bool fallback_after_kerberos = false;
3651 bool use_ccache = false;
3652 bool pw_nt_hash = false;
3653 struct cli_credentials *creds = NULL;
3655 if (flags & CLI_FULL_CONNECTION_USE_KERBEROS) {
3656 use_kerberos = true;
3659 if (flags & CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS) {
3660 fallback_after_kerberos = true;
3663 if (flags & CLI_FULL_CONNECTION_USE_CCACHE) {
3667 if (flags & CLI_FULL_CONNECTION_USE_NT_HASH) {
3671 creds = cli_session_creds_init(frame,
3674 NULL, /* realm (use default) */
3677 fallback_after_kerberos,
3680 if (creds == NULL) {
3682 return NT_STATUS_NO_MEMORY;
3685 status = cli_full_connection_creds(output_cli, my_name,
3686 dest_host, dest_ss, port,
3687 service, service_type,
3688 creds, flags, signing_state);
3689 if (!NT_STATUS_IS_OK(status)) {
3695 return NT_STATUS_OK;
3698 /****************************************************************************
3699 Send an old style tcon.
3700 ****************************************************************************/
3701 struct cli_raw_tcon_state {
3705 static void cli_raw_tcon_done(struct tevent_req *subreq);
3707 static struct tevent_req *cli_raw_tcon_send(
3708 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
3709 const char *service, const char *pass, const char *dev)
3711 struct tevent_req *req, *subreq;
3712 struct cli_raw_tcon_state *state;
3715 req = tevent_req_create(mem_ctx, &state, struct cli_raw_tcon_state);
3720 if (!lp_client_plaintext_auth() && (*pass)) {
3721 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
3722 " or 'client ntlmv2 auth = yes'\n"));
3723 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
3724 return tevent_req_post(req, ev);
3727 TALLOC_FREE(cli->smb1.tcon);
3728 cli->smb1.tcon = smbXcli_tcon_create(cli);
3729 if (tevent_req_nomem(cli->smb1.tcon, req)) {
3730 return tevent_req_post(req, ev);
3732 smb1cli_tcon_set_id(cli->smb1.tcon, UINT16_MAX);
3734 bytes = talloc_array(state, uint8_t, 0);
3735 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3736 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3737 service, strlen(service)+1, NULL);
3738 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3739 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3740 pass, strlen(pass)+1, NULL);
3741 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3742 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3743 dev, strlen(dev)+1, NULL);
3745 if (tevent_req_nomem(bytes, req)) {
3746 return tevent_req_post(req, ev);
3749 subreq = cli_smb_send(state, ev, cli, SMBtcon, 0, 0, 0, NULL,
3750 talloc_get_size(bytes), bytes);
3751 if (tevent_req_nomem(subreq, req)) {
3752 return tevent_req_post(req, ev);
3754 tevent_req_set_callback(subreq, cli_raw_tcon_done, req);
3758 static void cli_raw_tcon_done(struct tevent_req *subreq)
3760 struct tevent_req *req = tevent_req_callback_data(
3761 subreq, struct tevent_req);
3762 struct cli_raw_tcon_state *state = tevent_req_data(
3763 req, struct cli_raw_tcon_state);
3766 status = cli_smb_recv(subreq, state, NULL, 2, NULL, &state->ret_vwv,
3768 TALLOC_FREE(subreq);
3769 if (tevent_req_nterror(req, status)) {
3772 tevent_req_done(req);
3775 static NTSTATUS cli_raw_tcon_recv(struct tevent_req *req,
3776 uint16_t *max_xmit, uint16_t *tid)
3778 struct cli_raw_tcon_state *state = tevent_req_data(
3779 req, struct cli_raw_tcon_state);
3782 if (tevent_req_is_nterror(req, &status)) {
3785 *max_xmit = SVAL(state->ret_vwv + 0, 0);
3786 *tid = SVAL(state->ret_vwv + 1, 0);
3787 return NT_STATUS_OK;
3790 NTSTATUS cli_raw_tcon(struct cli_state *cli,
3791 const char *service, const char *pass, const char *dev,
3792 uint16_t *max_xmit, uint16_t *tid)
3794 struct tevent_context *ev;
3795 struct tevent_req *req;
3796 NTSTATUS status = NT_STATUS_NO_MEMORY;
3798 ev = samba_tevent_context_init(talloc_tos());
3802 req = cli_raw_tcon_send(ev, ev, cli, service, pass, dev);
3806 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
3809 status = cli_raw_tcon_recv(req, max_xmit, tid);
3815 /* Return a cli_state pointing at the IPC$ share for the given server */
3817 struct cli_state *get_ipc_connect(char *server,
3818 struct sockaddr_storage *server_ss,
3819 const struct user_auth_info *user_info)
3821 struct cli_state *cli;
3823 uint32_t flags = CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
3825 if (get_cmdline_auth_info_use_kerberos(user_info)) {
3826 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
3829 flags |= CLI_FULL_CONNECTION_FORCE_SMB1;
3831 nt_status = cli_full_connection(&cli, NULL, server, server_ss, 0, "IPC$", "IPC",
3832 get_cmdline_auth_info_username(user_info),
3834 get_cmdline_auth_info_password(user_info),
3836 SMB_SIGNING_DEFAULT);
3838 if (NT_STATUS_IS_OK(nt_status)) {
3840 } else if (is_ipaddress(server)) {
3841 /* windows 9* needs a correct NMB name for connections */
3842 fstring remote_name;
3844 if (name_status_find("*", 0, 0, server_ss, remote_name)) {
3845 cli = get_ipc_connect(remote_name, server_ss, user_info);
3854 * Given the IP address of a master browser on the network, return its
3855 * workgroup and connect to it.
3857 * This function is provided to allow additional processing beyond what
3858 * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
3859 * browsers and obtain each master browsers' list of domains (in case the
3860 * first master browser is recently on the network and has not yet
3861 * synchronized with other master browsers and therefore does not yet have the
3862 * entire network browse list)
3865 struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx,
3866 struct sockaddr_storage *mb_ip,
3867 const struct user_auth_info *user_info,
3868 char **pp_workgroup_out)
3870 char addr[INET6_ADDRSTRLEN];
3872 struct cli_state *cli;
3873 struct sockaddr_storage server_ss;
3875 *pp_workgroup_out = NULL;
3877 print_sockaddr(addr, sizeof(addr), mb_ip);
3878 DEBUG(99, ("Looking up name of master browser %s\n",
3882 * Do a name status query to find out the name of the master browser.
3883 * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
3884 * master browser will not respond to a wildcard query (or, at least,
3885 * an NT4 server acting as the domain master browser will not).
3887 * We might be able to use ONLY the query on MSBROWSE, but that's not
3888 * yet been tested with all Windows versions, so until it is, leave
3889 * the original wildcard query as the first choice and fall back to
3890 * MSBROWSE if the wildcard query fails.
3892 if (!name_status_find("*", 0, 0x1d, mb_ip, name) &&
3893 !name_status_find(MSBROWSE, 1, 0x1d, mb_ip, name)) {
3895 DEBUG(99, ("Could not retrieve name status for %s\n",
3900 if (!find_master_ip(name, &server_ss)) {
3901 DEBUG(99, ("Could not find master ip for %s\n", name));
3905 *pp_workgroup_out = talloc_strdup(ctx, name);
3907 DEBUG(4, ("found master browser %s, %s\n", name, addr));
3909 print_sockaddr(addr, sizeof(addr), &server_ss);
3910 cli = get_ipc_connect(addr, &server_ss, user_info);
3916 * Return the IP address and workgroup of a master browser on the network, and
3920 struct cli_state *get_ipc_connect_master_ip_bcast(TALLOC_CTX *ctx,
3921 const struct user_auth_info *user_info,
3922 char **pp_workgroup_out)
3924 struct sockaddr_storage *ip_list;
3925 struct cli_state *cli;
3929 *pp_workgroup_out = NULL;
3931 DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
3933 /* Go looking for workgroups by broadcasting on the local network */
3935 status = name_resolve_bcast(MSBROWSE, 1, talloc_tos(),
3937 if (!NT_STATUS_IS_OK(status)) {
3938 DEBUG(99, ("No master browsers responded: %s\n",
3939 nt_errstr(status)));
3943 for (i = 0; i < count; i++) {
3944 char addr[INET6_ADDRSTRLEN];
3945 print_sockaddr(addr, sizeof(addr), &ip_list[i]);
3946 DEBUG(99, ("Found master browser %s\n", addr));
3948 cli = get_ipc_connect_master_ip(ctx, &ip_list[i],
3949 user_info, pp_workgroup_out);