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);
1245 const char *server_domain = NULL;
1248 if (state->blob_in.length != 0) {
1249 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1253 if (state->blob_out.length != 0) {
1254 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1259 * gensec_ntlmssp_server_domain() returns NULL
1260 * if NTLMSSP is not used.
1262 * We can remove this later
1263 * and leave the server domain empty for SMB2 and above
1264 * in future releases.
1266 server_domain = gensec_ntlmssp_server_domain(
1267 state->auth_generic->gensec_security);
1269 if (state->cli->server_domain[0] == '\0' && server_domain != NULL) {
1270 TALLOC_FREE(state->cli->server_domain);
1271 state->cli->server_domain = talloc_strdup(state->cli,
1273 if (state->cli->server_domain == NULL) {
1274 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1279 if (state->is_anonymous) {
1281 * Windows server does not set the
1282 * SMB2_SESSION_FLAG_IS_NULL flag.
1284 * This fix makes sure we do not try
1285 * to verify a signature on the final
1286 * session setup response.
1288 tevent_req_done(req);
1292 status = gensec_session_key(state->auth_generic->gensec_security,
1293 state, &state->session_key);
1294 if (tevent_req_nterror(req, status)) {
1298 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
1299 struct smbXcli_session *session = state->cli->smb2.session;
1301 status = smb2cli_session_set_session_key(session,
1304 if (tevent_req_nterror(req, status)) {
1307 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB3_00
1308 && lp_debug_encryption())
1310 cli_session_dump_keys(state, session, state->session_key);
1313 struct smbXcli_session *session = state->cli->smb1.session;
1316 status = smb1cli_session_set_session_key(session,
1317 state->session_key);
1318 if (tevent_req_nterror(req, status)) {
1322 active = smb1cli_conn_activate_signing(state->cli->conn,
1328 ok = smb1cli_conn_check_signing(state->cli->conn,
1331 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1337 tevent_req_done(req);
1340 static NTSTATUS cli_session_setup_gensec_recv(struct tevent_req *req)
1342 struct cli_session_setup_gensec_state *state =
1343 tevent_req_data(req,
1344 struct cli_session_setup_gensec_state);
1347 if (tevent_req_is_nterror(req, &status)) {
1348 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
1351 return NT_STATUS_OK;
1354 static char *cli_session_setup_get_account(TALLOC_CTX *mem_ctx,
1355 const char *principal)
1359 account = talloc_strdup(mem_ctx, principal);
1360 if (account == NULL) {
1363 p = strchr_m(account, '@');
1370 /****************************************************************************
1371 Do a spnego encrypted session setup.
1373 user_domain: The shortname of the domain the user/machine is a member of.
1374 dest_realm: The realm we're connecting to, if NULL we use our default realm.
1375 ****************************************************************************/
1377 struct cli_session_setup_spnego_state {
1381 static void cli_session_setup_spnego_done(struct tevent_req *subreq);
1383 static struct tevent_req *cli_session_setup_spnego_send(
1384 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
1385 struct cli_credentials *creds)
1387 struct tevent_req *req, *subreq;
1388 struct cli_session_setup_spnego_state *state;
1389 const char *target_service = NULL;
1390 const char *target_hostname = NULL;
1393 req = tevent_req_create(mem_ctx, &state,
1394 struct cli_session_setup_spnego_state);
1399 target_service = "cifs";
1400 target_hostname = smbXcli_conn_remote_name(cli->conn);
1402 status = cli_session_creds_prepare_krb5(cli, creds);
1403 if (tevent_req_nterror(req, status)) {
1404 return tevent_req_post(req, ev);
1407 subreq = cli_session_setup_gensec_send(state, ev, cli, creds,
1408 target_service, target_hostname);
1409 if (tevent_req_nomem(subreq, req)) {
1410 return tevent_req_post(req, ev);
1412 tevent_req_set_callback(
1413 subreq, cli_session_setup_spnego_done, req);
1417 static void cli_session_setup_spnego_done(struct tevent_req *subreq)
1419 struct tevent_req *req = tevent_req_callback_data(
1420 subreq, struct tevent_req);
1423 status = cli_session_setup_gensec_recv(subreq);
1424 TALLOC_FREE(subreq);
1425 if (tevent_req_nterror(req, status)) {
1429 tevent_req_done(req);
1432 static ADS_STATUS cli_session_setup_spnego_recv(struct tevent_req *req)
1434 struct cli_session_setup_spnego_state *state = tevent_req_data(
1435 req, struct cli_session_setup_spnego_state);
1438 if (tevent_req_is_nterror(req, &status)) {
1439 state->result = ADS_ERROR_NT(status);
1442 return state->result;
1445 struct cli_session_setup_creds_state {
1446 struct cli_state *cli;
1447 DATA_BLOB apassword_blob;
1448 DATA_BLOB upassword_blob;
1449 DATA_BLOB lm_session_key;
1450 DATA_BLOB session_key;
1451 char *out_native_os;
1452 char *out_native_lm;
1453 char *out_primary_domain;
1456 static void cli_session_setup_creds_cleanup(struct tevent_req *req,
1457 enum tevent_req_state req_state)
1459 struct cli_session_setup_creds_state *state = tevent_req_data(
1460 req, struct cli_session_setup_creds_state);
1462 if (req_state != TEVENT_REQ_RECEIVED) {
1467 * We only call data_blob_clear() as
1468 * some of the blobs point to the same memory.
1470 * We let the talloc hierachy free the memory.
1472 data_blob_clear(&state->apassword_blob);
1473 data_blob_clear(&state->upassword_blob);
1474 data_blob_clear(&state->lm_session_key);
1475 data_blob_clear(&state->session_key);
1476 ZERO_STRUCTP(state);
1479 static void cli_session_setup_creds_done_spnego(struct tevent_req *subreq);
1480 static void cli_session_setup_creds_done_nt1(struct tevent_req *subreq);
1481 static void cli_session_setup_creds_done_lm21(struct tevent_req *subreq);
1483 /****************************************************************************
1484 Send a session setup. The username and workgroup is in UNIX character
1485 format and must be converted to DOS codepage format before sending. If the
1486 password is in plaintext, the same should be done.
1487 ****************************************************************************/
1489 struct tevent_req *cli_session_setup_creds_send(TALLOC_CTX *mem_ctx,
1490 struct tevent_context *ev,
1491 struct cli_state *cli,
1492 struct cli_credentials *creds)
1494 struct tevent_req *req, *subreq;
1495 struct cli_session_setup_creds_state *state;
1496 uint16_t sec_mode = smb1cli_conn_server_security_mode(cli->conn);
1497 bool use_spnego = false;
1499 enum credentials_use_kerberos krb5_state;
1500 uint32_t gensec_features;
1501 const char *username = "";
1502 const char *domain = "";
1503 DATA_BLOB target_info = data_blob_null;
1504 DATA_BLOB challenge = data_blob_null;
1505 uint16_t in_buf_size = 0;
1506 uint16_t in_mpx_max = 0;
1507 uint16_t in_vc_num = 0;
1508 uint32_t in_sess_key = 0;
1509 const char *in_native_os = NULL;
1510 const char *in_native_lm = NULL;
1513 req = tevent_req_create(mem_ctx, &state,
1514 struct cli_session_setup_creds_state);
1520 tevent_req_set_cleanup_fn(req, cli_session_setup_creds_cleanup);
1522 krb5_state = cli_credentials_get_kerberos_state(creds);
1523 gensec_features = cli_credentials_get_gensec_features(creds);
1525 switch (krb5_state) {
1526 case CRED_MUST_USE_KERBEROS:
1527 cli->use_kerberos = true;
1528 cli->fallback_after_kerberos = false;
1530 case CRED_AUTO_USE_KERBEROS:
1531 cli->use_kerberos = true;
1532 cli->fallback_after_kerberos = true;
1534 case CRED_DONT_USE_KERBEROS:
1535 cli->use_kerberos = false;
1536 cli->fallback_after_kerberos = false;
1540 if (gensec_features & GENSEC_FEATURE_NTLM_CCACHE) {
1541 cli->use_ccache = true;
1543 cli->use_ccache = false;
1547 * Now work out what sort of session setup we are going to
1548 * do. I have split this into separate functions to make the flow a bit
1549 * easier to understand (tridge).
1551 if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_NT1) {
1553 } else if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
1555 } else if (smb1cli_conn_capabilities(cli->conn) & CAP_EXTENDED_SECURITY) {
1557 * if the server supports extended security then use SPNEGO
1558 * even for anonymous connections.
1566 subreq = cli_session_setup_spnego_send(
1567 state, ev, cli, creds);
1568 if (tevent_req_nomem(subreq, req)) {
1569 return tevent_req_post(req, ev);
1571 tevent_req_set_callback(subreq, cli_session_setup_creds_done_spnego,
1576 if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_LANMAN1) {
1578 * SessionSetupAndX was introduced by LANMAN 1.0. So we skip
1579 * this step against older servers.
1581 tevent_req_done(req);
1582 return tevent_req_post(req, ev);
1585 if (cli_credentials_is_anonymous(creds)) {
1587 * Do an anonymous session setup
1589 goto non_spnego_creds_done;
1592 if ((sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0) {
1594 * Do an anonymous session setup,
1595 * the password is passed via the tree connect.
1597 goto non_spnego_creds_done;
1600 cli_credentials_get_ntlm_username_domain(creds, state,
1603 if (tevent_req_nomem(username, req)) {
1604 return tevent_req_post(req, ev);
1606 if (tevent_req_nomem(domain, req)) {
1607 return tevent_req_post(req, ev);
1610 if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) {
1611 bool use_unicode = smbXcli_conn_use_unicode(cli->conn);
1612 uint8_t *bytes = NULL;
1613 size_t bytes_len = 0;
1614 const char *pw = cli_credentials_get_password(creds);
1620 pw_len = strlen(pw) + 1;
1622 if (!lp_client_plaintext_auth()) {
1623 DEBUG(1, ("Server requested PLAINTEXT password but "
1624 "'client plaintext auth = no'\n"));
1625 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1626 return tevent_req_post(req, ev);
1629 bytes = talloc_array(state, uint8_t, 0);
1630 bytes = trans2_bytes_push_str(bytes, use_unicode,
1631 pw, pw_len, &bytes_len);
1632 if (tevent_req_nomem(bytes, req)) {
1633 return tevent_req_post(req, ev);
1638 * CAP_UNICODE, can only be negotiated by NT1.
1640 state->upassword_blob = data_blob_const(bytes,
1643 state->apassword_blob = data_blob_const(bytes,
1647 goto non_spnego_creds_done;
1650 challenge = data_blob_const(smb1cli_conn_server_challenge(cli->conn), 8);
1652 if (smbXcli_conn_protocol(cli->conn) == PROTOCOL_NT1) {
1653 if (lp_client_ntlmv2_auth() && lp_client_use_spnego()) {
1655 * Don't send an NTLMv2 response without NTLMSSP if we
1656 * want to use spnego support.
1658 DEBUG(1, ("Server does not support EXTENDED_SECURITY "
1659 " but 'client use spnego = yes'"
1660 " and 'client ntlmv2 auth = yes' is set\n"));
1661 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1662 return tevent_req_post(req, ev);
1665 if (lp_client_ntlmv2_auth()) {
1666 flags |= CLI_CRED_NTLMv2_AUTH;
1669 * note that the 'domain' here is a best
1670 * guess - we don't know the server's domain
1671 * at this point. Windows clients also don't
1674 target_info = NTLMv2_generate_names_blob(state,
1677 if (tevent_req_nomem(target_info.data, req)) {
1678 return tevent_req_post(req, ev);
1681 flags |= CLI_CRED_NTLM_AUTH;
1682 if (lp_client_lanman_auth()) {
1683 flags |= CLI_CRED_LANMAN_AUTH;
1687 if (!lp_client_lanman_auth()) {
1688 DEBUG(1, ("Server requested user level LM password but "
1689 "'client lanman auth = no' is set.\n"));
1690 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1691 return tevent_req_post(req, ev);
1694 flags |= CLI_CRED_LANMAN_AUTH;
1697 status = cli_credentials_get_ntlm_response(creds, state, &flags,
1700 &state->apassword_blob,
1701 &state->upassword_blob,
1702 &state->lm_session_key,
1703 &state->session_key);
1704 if (tevent_req_nterror(req, status)) {
1705 return tevent_req_post(req, ev);
1708 non_spnego_creds_done:
1710 in_buf_size = CLI_BUFFER_SIZE;
1711 in_mpx_max = smbXcli_conn_max_requests(cli->conn);
1712 in_vc_num = cli_state_get_vc_num(cli);
1713 in_sess_key = smb1cli_conn_server_session_key(cli->conn);
1714 in_native_os = "Unix";
1715 in_native_lm = "Samba";
1717 if (smbXcli_conn_protocol(cli->conn) == PROTOCOL_NT1) {
1718 uint32_t in_capabilities = 0;
1720 in_capabilities = cli_session_setup_capabilities(cli, 0);
1723 * For now we keep the same values as before,
1724 * we may remove these in a separate commit later.
1728 subreq = smb1cli_session_setup_nt1_send(state, ev,
1739 state->apassword_blob,
1740 state->upassword_blob,
1744 if (tevent_req_nomem(subreq, req)) {
1745 return tevent_req_post(req, ev);
1747 tevent_req_set_callback(subreq, cli_session_setup_creds_done_nt1,
1753 * For now we keep the same values as before,
1754 * we may remove these in a separate commit later.
1759 subreq = smb1cli_session_setup_lm21_send(state, ev,
1770 state->apassword_blob,
1773 if (tevent_req_nomem(subreq, req)) {
1774 return tevent_req_post(req, ev);
1776 tevent_req_set_callback(subreq, cli_session_setup_creds_done_lm21,
1781 static void cli_session_setup_creds_done_spnego(struct tevent_req *subreq)
1783 struct tevent_req *req = tevent_req_callback_data(
1784 subreq, struct tevent_req);
1787 status = cli_session_setup_spnego_recv(subreq);
1788 TALLOC_FREE(subreq);
1789 if (!ADS_ERR_OK(status)) {
1790 DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status)));
1791 tevent_req_nterror(req, ads_ntstatus(status));
1794 tevent_req_done(req);
1797 static void cli_session_setup_creds_done_nt1(struct tevent_req *subreq)
1799 struct tevent_req *req = tevent_req_callback_data(
1800 subreq, struct tevent_req);
1801 struct cli_session_setup_creds_state *state = tevent_req_data(
1802 req, struct cli_session_setup_creds_state);
1803 struct cli_state *cli = state->cli;
1805 struct iovec *recv_iov = NULL;
1806 const uint8_t *inbuf = NULL;
1809 status = smb1cli_session_setup_nt1_recv(subreq, state,
1812 &state->out_native_os,
1813 &state->out_native_lm,
1814 &state->out_primary_domain);
1815 TALLOC_FREE(subreq);
1816 if (!NT_STATUS_IS_OK(status)) {
1817 DEBUG(3, ("NT1 login failed: %s\n", nt_errstr(status)));
1818 tevent_req_nterror(req, status);
1822 status = cli_state_update_after_sesssetup(state->cli,
1823 state->out_native_os,
1824 state->out_native_lm,
1825 state->out_primary_domain);
1826 if (tevent_req_nterror(req, status)) {
1830 ok = smb1cli_conn_activate_signing(cli->conn,
1832 state->upassword_blob);
1834 ok = smb1cli_conn_check_signing(cli->conn, inbuf, 1);
1836 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1841 if (state->session_key.data) {
1842 struct smbXcli_session *session = cli->smb1.session;
1844 status = smb1cli_session_set_session_key(session,
1845 state->session_key);
1846 if (tevent_req_nterror(req, status)) {
1851 tevent_req_done(req);
1854 static void cli_session_setup_creds_done_lm21(struct tevent_req *subreq)
1856 struct tevent_req *req = tevent_req_callback_data(
1857 subreq, struct tevent_req);
1858 struct cli_session_setup_creds_state *state = tevent_req_data(
1859 req, struct cli_session_setup_creds_state);
1862 status = smb1cli_session_setup_lm21_recv(subreq, state,
1863 &state->out_native_os,
1864 &state->out_native_lm);
1865 TALLOC_FREE(subreq);
1866 if (!NT_STATUS_IS_OK(status)) {
1867 DEBUG(3, ("LM21 login failed: %s\n", nt_errstr(status)));
1868 tevent_req_nterror(req, status);
1872 status = cli_state_update_after_sesssetup(state->cli,
1873 state->out_native_os,
1874 state->out_native_lm,
1876 if (tevent_req_nterror(req, status)) {
1880 tevent_req_done(req);
1883 NTSTATUS cli_session_setup_creds_recv(struct tevent_req *req)
1885 return tevent_req_simple_recv_ntstatus(req);
1888 NTSTATUS cli_session_setup_creds(struct cli_state *cli,
1889 struct cli_credentials *creds)
1891 struct tevent_context *ev;
1892 struct tevent_req *req;
1893 NTSTATUS status = NT_STATUS_NO_MEMORY;
1895 if (smbXcli_conn_has_async_calls(cli->conn)) {
1896 return NT_STATUS_INVALID_PARAMETER;
1898 ev = samba_tevent_context_init(talloc_tos());
1902 req = cli_session_setup_creds_send(ev, ev, cli, creds);
1906 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1909 status = cli_session_setup_creds_recv(req);
1915 NTSTATUS cli_session_setup_anon(struct cli_state *cli)
1917 NTSTATUS status = NT_STATUS_NO_MEMORY;
1918 struct cli_credentials *creds = NULL;
1920 creds = cli_credentials_init_anon(cli);
1921 if (creds == NULL) {
1922 return NT_STATUS_NO_MEMORY;
1925 status = cli_session_setup_creds(cli, creds);
1927 if (!NT_STATUS_IS_OK(status)) {
1931 return NT_STATUS_OK;
1934 /****************************************************************************
1936 *****************************************************************************/
1938 struct cli_ulogoff_state {
1939 struct cli_state *cli;
1943 static void cli_ulogoff_done(struct tevent_req *subreq);
1945 static struct tevent_req *cli_ulogoff_send(TALLOC_CTX *mem_ctx,
1946 struct tevent_context *ev,
1947 struct cli_state *cli)
1949 struct tevent_req *req, *subreq;
1950 struct cli_ulogoff_state *state;
1952 req = tevent_req_create(mem_ctx, &state, struct cli_ulogoff_state);
1958 SCVAL(state->vwv+0, 0, 0xFF);
1959 SCVAL(state->vwv+1, 0, 0);
1960 SSVAL(state->vwv+2, 0, 0);
1962 subreq = cli_smb_send(state, ev, cli, SMBulogoffX, 0, 0, 2, state->vwv,
1964 if (tevent_req_nomem(subreq, req)) {
1965 return tevent_req_post(req, ev);
1967 tevent_req_set_callback(subreq, cli_ulogoff_done, req);
1971 static void cli_ulogoff_done(struct tevent_req *subreq)
1973 struct tevent_req *req = tevent_req_callback_data(
1974 subreq, struct tevent_req);
1975 struct cli_ulogoff_state *state = tevent_req_data(
1976 req, struct cli_ulogoff_state);
1979 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
1980 if (!NT_STATUS_IS_OK(status)) {
1981 tevent_req_nterror(req, status);
1984 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
1985 tevent_req_done(req);
1988 static NTSTATUS cli_ulogoff_recv(struct tevent_req *req)
1990 return tevent_req_simple_recv_ntstatus(req);
1993 NTSTATUS cli_ulogoff(struct cli_state *cli)
1995 struct tevent_context *ev;
1996 struct tevent_req *req;
1997 NTSTATUS status = NT_STATUS_NO_MEMORY;
1999 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
2000 status = smb2cli_logoff(cli->conn,
2003 if (!NT_STATUS_IS_OK(status)) {
2006 smb2cli_session_set_id_and_flags(cli->smb2.session,
2008 return NT_STATUS_OK;
2011 if (smbXcli_conn_has_async_calls(cli->conn)) {
2012 return NT_STATUS_INVALID_PARAMETER;
2014 ev = samba_tevent_context_init(talloc_tos());
2018 req = cli_ulogoff_send(ev, ev, cli);
2022 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2025 status = cli_ulogoff_recv(req);
2031 /****************************************************************************
2033 ****************************************************************************/
2035 struct cli_tcon_andx_state {
2036 struct cli_state *cli;
2041 static void cli_tcon_andx_done(struct tevent_req *subreq);
2043 struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx,
2044 struct tevent_context *ev,
2045 struct cli_state *cli,
2046 const char *share, const char *dev,
2047 const char *pass, int passlen,
2048 struct tevent_req **psmbreq)
2050 struct tevent_req *req, *subreq;
2051 struct cli_tcon_andx_state *state;
2056 uint16_t sec_mode = smb1cli_conn_server_security_mode(cli->conn);
2057 uint16_t tcon_flags = 0;
2061 req = tevent_req_create(mem_ctx, &state, struct cli_tcon_andx_state);
2068 TALLOC_FREE(cli->smb1.tcon);
2069 cli->smb1.tcon = smbXcli_tcon_create(cli);
2070 if (tevent_req_nomem(cli->smb1.tcon, req)) {
2071 return tevent_req_post(req, ev);
2073 smb1cli_tcon_set_id(cli->smb1.tcon, UINT16_MAX);
2075 cli->share = talloc_strdup(cli, share);
2080 /* in user level security don't send a password now */
2081 if (sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {
2084 } else if (pass == NULL) {
2085 DEBUG(1, ("Server not using user level security and no "
2086 "password supplied.\n"));
2090 if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) &&
2091 *pass && passlen != 24) {
2092 if (!lp_client_lanman_auth()) {
2093 DEBUG(1, ("Server requested LANMAN password "
2094 "(share-level security) but "
2095 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2100 * Non-encrypted passwords - convert to DOS codepage before
2103 SMBencrypt(pass, smb1cli_conn_server_challenge(cli->conn), p24);
2105 pass = (const char *)p24;
2107 if((sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL
2108 |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE))
2112 if (!lp_client_plaintext_auth() && (*pass)) {
2113 DEBUG(1, ("Server requested PLAINTEXT "
2115 "'client plaintext auth = no' or 'client ntlmv2 auth = yes'\n"));
2120 * Non-encrypted passwords - convert to DOS codepage
2123 tmp_pass = talloc_array(talloc_tos(), uint8_t, 0);
2124 if (tevent_req_nomem(tmp_pass, req)) {
2125 return tevent_req_post(req, ev);
2127 tmp_pass = trans2_bytes_push_str(tmp_pass,
2128 false, /* always DOS */
2132 if (tevent_req_nomem(tmp_pass, req)) {
2133 return tevent_req_post(req, ev);
2135 pass = (const char *)tmp_pass;
2136 passlen = talloc_get_size(tmp_pass);
2140 tcon_flags |= TCONX_FLAG_EXTENDED_RESPONSE;
2141 tcon_flags |= TCONX_FLAG_EXTENDED_SIGNATURES;
2143 SCVAL(vwv+0, 0, 0xFF);
2146 SSVAL(vwv+2, 0, tcon_flags);
2147 SSVAL(vwv+3, 0, passlen);
2149 if (passlen && pass) {
2150 bytes = (uint8_t *)talloc_memdup(state, pass, passlen);
2152 bytes = talloc_array(state, uint8_t, 0);
2158 tmp = talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
2159 smbXcli_conn_remote_name(cli->conn), share);
2164 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), tmp, strlen(tmp)+1,
2169 * Add the devicetype
2171 tmp = talloc_strdup_upper(talloc_tos(), dev);
2176 bytes = smb_bytes_push_str(bytes, false, tmp, strlen(tmp)+1, NULL);
2179 if (bytes == NULL) {
2184 state->bytes.iov_base = (void *)bytes;
2185 state->bytes.iov_len = talloc_get_size(bytes);
2187 subreq = cli_smb_req_create(state, ev, cli, SMBtconX, 0, 0, 4, vwv,
2189 if (subreq == NULL) {
2193 tevent_req_set_callback(subreq, cli_tcon_andx_done, req);
2198 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
2199 return tevent_req_post(req, ev);
2202 struct tevent_req *cli_tcon_andx_send(TALLOC_CTX *mem_ctx,
2203 struct tevent_context *ev,
2204 struct cli_state *cli,
2205 const char *share, const char *dev,
2206 const char *pass, int passlen)
2208 struct tevent_req *req, *subreq;
2211 req = cli_tcon_andx_create(mem_ctx, ev, cli, share, dev, pass, passlen,
2216 if (subreq == NULL) {
2219 status = smb1cli_req_chain_submit(&subreq, 1);
2220 if (!NT_STATUS_IS_OK(status)) {
2221 tevent_req_nterror(req, status);
2222 return tevent_req_post(req, ev);
2227 static void cli_tcon_andx_done(struct tevent_req *subreq)
2229 struct tevent_req *req = tevent_req_callback_data(
2230 subreq, struct tevent_req);
2231 struct cli_tcon_andx_state *state = tevent_req_data(
2232 req, struct cli_tcon_andx_state);
2233 struct cli_state *cli = state->cli;
2241 uint16_t optional_support = 0;
2243 status = cli_smb_recv(subreq, state, &in, 0, &wct, &vwv,
2244 &num_bytes, &bytes);
2245 TALLOC_FREE(subreq);
2246 if (!NT_STATUS_IS_OK(status)) {
2247 tevent_req_nterror(req, status);
2251 inhdr = in + NBT_HDR_SIZE;
2254 if (clistr_pull_talloc(cli,
2255 (const char *)inhdr,
2256 SVAL(inhdr, HDR_FLG2),
2260 STR_TERMINATE|STR_ASCII) == -1) {
2261 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2265 cli->dev = talloc_strdup(cli, "");
2266 if (cli->dev == NULL) {
2267 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2272 if ((smbXcli_conn_protocol(cli->conn) >= PROTOCOL_NT1) && (num_bytes == 3)) {
2273 /* almost certainly win95 - enable bug fixes */
2278 * Make sure that we have the optional support 16-bit field. WCT > 2.
2279 * Avoids issues when connecting to Win9x boxes sharing files
2282 if ((wct > 2) && (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_LANMAN2)) {
2283 optional_support = SVAL(vwv+2, 0);
2286 if (optional_support & SMB_EXTENDED_SIGNATURES) {
2287 smb1cli_session_protect_session_key(cli->smb1.session);
2290 smb1cli_tcon_set_values(state->cli->smb1.tcon,
2291 SVAL(inhdr, HDR_TID),
2293 0, /* maximal_access */
2294 0, /* guest_maximal_access */
2296 NULL); /* fs_type */
2298 tevent_req_done(req);
2301 NTSTATUS cli_tcon_andx_recv(struct tevent_req *req)
2303 return tevent_req_simple_recv_ntstatus(req);
2306 NTSTATUS cli_tcon_andx(struct cli_state *cli, const char *share,
2307 const char *dev, const char *pass, int passlen)
2309 TALLOC_CTX *frame = talloc_stackframe();
2310 struct tevent_context *ev;
2311 struct tevent_req *req;
2312 NTSTATUS status = NT_STATUS_NO_MEMORY;
2314 if (smbXcli_conn_has_async_calls(cli->conn)) {
2316 * Can't use sync call while an async call is in flight
2318 status = NT_STATUS_INVALID_PARAMETER;
2322 ev = samba_tevent_context_init(frame);
2327 req = cli_tcon_andx_send(frame, ev, cli, share, dev, pass, passlen);
2332 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2336 status = cli_tcon_andx_recv(req);
2342 struct cli_tree_connect_state {
2343 struct cli_state *cli;
2346 static struct tevent_req *cli_raw_tcon_send(
2347 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
2348 const char *service, const char *pass, const char *dev);
2349 static NTSTATUS cli_raw_tcon_recv(struct tevent_req *req,
2350 uint16_t *max_xmit, uint16_t *tid);
2352 static void cli_tree_connect_smb2_done(struct tevent_req *subreq);
2353 static void cli_tree_connect_andx_done(struct tevent_req *subreq);
2354 static void cli_tree_connect_raw_done(struct tevent_req *subreq);
2356 static struct tevent_req *cli_tree_connect_send(
2357 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
2358 const char *share, const char *dev, const char *pass)
2360 struct tevent_req *req, *subreq;
2361 struct cli_tree_connect_state *state;
2367 passlen = strlen(pass) + 1;
2369 req = tevent_req_create(mem_ctx, &state,
2370 struct cli_tree_connect_state);
2376 cli->share = talloc_strdup(cli, share);
2377 if (tevent_req_nomem(cli->share, req)) {
2378 return tevent_req_post(req, ev);
2381 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
2384 TALLOC_FREE(cli->smb2.tcon);
2385 cli->smb2.tcon = smbXcli_tcon_create(cli);
2386 if (tevent_req_nomem(cli->smb2.tcon, req)) {
2387 return tevent_req_post(req, ev);
2390 unc = talloc_asprintf(state, "\\\\%s\\%s",
2391 smbXcli_conn_remote_name(cli->conn),
2393 if (tevent_req_nomem(unc, req)) {
2394 return tevent_req_post(req, ev);
2397 subreq = smb2cli_tcon_send(state, ev, cli->conn, cli->timeout,
2398 cli->smb2.session, cli->smb2.tcon,
2401 if (tevent_req_nomem(subreq, req)) {
2402 return tevent_req_post(req, ev);
2404 tevent_req_set_callback(subreq, cli_tree_connect_smb2_done,
2409 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_LANMAN1) {
2410 subreq = cli_tcon_andx_send(state, ev, cli, share, dev,
2412 if (tevent_req_nomem(subreq, req)) {
2413 return tevent_req_post(req, ev);
2415 tevent_req_set_callback(subreq, cli_tree_connect_andx_done,
2420 subreq = cli_raw_tcon_send(state, ev, cli, share, pass, dev);
2421 if (tevent_req_nomem(subreq, req)) {
2422 return tevent_req_post(req, ev);
2424 tevent_req_set_callback(subreq, cli_tree_connect_raw_done, req);
2429 static void cli_tree_connect_smb2_done(struct tevent_req *subreq)
2431 tevent_req_simple_finish_ntstatus(
2432 subreq, smb2cli_tcon_recv(subreq));
2435 static void cli_tree_connect_andx_done(struct tevent_req *subreq)
2437 tevent_req_simple_finish_ntstatus(
2438 subreq, cli_tcon_andx_recv(subreq));
2441 static void cli_tree_connect_raw_done(struct tevent_req *subreq)
2443 struct tevent_req *req = tevent_req_callback_data(
2444 subreq, struct tevent_req);
2445 struct cli_tree_connect_state *state = tevent_req_data(
2446 req, struct cli_tree_connect_state);
2448 uint16_t max_xmit = 0;
2451 status = cli_raw_tcon_recv(subreq, &max_xmit, &tid);
2452 if (tevent_req_nterror(req, status)) {
2456 smb1cli_tcon_set_values(state->cli->smb1.tcon,
2458 0, /* optional_support */
2459 0, /* maximal_access */
2460 0, /* guest_maximal_access */
2462 NULL); /* fs_type */
2464 tevent_req_done(req);
2467 static NTSTATUS cli_tree_connect_recv(struct tevent_req *req)
2469 return tevent_req_simple_recv_ntstatus(req);
2472 NTSTATUS cli_tree_connect(struct cli_state *cli, const char *share,
2473 const char *dev, const char *pass)
2475 struct tevent_context *ev;
2476 struct tevent_req *req;
2477 NTSTATUS status = NT_STATUS_NO_MEMORY;
2479 if (smbXcli_conn_has_async_calls(cli->conn)) {
2480 return NT_STATUS_INVALID_PARAMETER;
2482 ev = samba_tevent_context_init(talloc_tos());
2486 req = cli_tree_connect_send(ev, ev, cli, share, dev, pass);
2490 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2493 status = cli_tree_connect_recv(req);
2499 NTSTATUS cli_tree_connect_creds(struct cli_state *cli,
2500 const char *share, const char *dev,
2501 struct cli_credentials *creds)
2503 const char *pw = NULL;
2505 if (creds != NULL) {
2506 pw = cli_credentials_get_password(creds);
2509 return cli_tree_connect(cli, share, dev, pw);
2512 /****************************************************************************
2513 Send a tree disconnect.
2514 ****************************************************************************/
2516 struct cli_tdis_state {
2517 struct cli_state *cli;
2520 static void cli_tdis_done(struct tevent_req *subreq);
2522 static struct tevent_req *cli_tdis_send(TALLOC_CTX *mem_ctx,
2523 struct tevent_context *ev,
2524 struct cli_state *cli)
2526 struct tevent_req *req, *subreq;
2527 struct cli_tdis_state *state;
2529 req = tevent_req_create(mem_ctx, &state, struct cli_tdis_state);
2535 subreq = cli_smb_send(state, ev, cli, SMBtdis, 0, 0, 0, NULL, 0, NULL);
2536 if (tevent_req_nomem(subreq, req)) {
2537 return tevent_req_post(req, ev);
2539 tevent_req_set_callback(subreq, cli_tdis_done, req);
2543 static void cli_tdis_done(struct tevent_req *subreq)
2545 struct tevent_req *req = tevent_req_callback_data(
2546 subreq, struct tevent_req);
2547 struct cli_tdis_state *state = tevent_req_data(
2548 req, struct cli_tdis_state);
2551 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
2552 TALLOC_FREE(subreq);
2553 if (!NT_STATUS_IS_OK(status)) {
2554 tevent_req_nterror(req, status);
2557 TALLOC_FREE(state->cli->smb1.tcon);
2558 tevent_req_done(req);
2561 static NTSTATUS cli_tdis_recv(struct tevent_req *req)
2563 return tevent_req_simple_recv_ntstatus(req);
2566 NTSTATUS cli_tdis(struct cli_state *cli)
2568 struct tevent_context *ev;
2569 struct tevent_req *req;
2570 NTSTATUS status = NT_STATUS_NO_MEMORY;
2572 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
2573 status = smb2cli_tdis(cli->conn,
2577 if (NT_STATUS_IS_OK(status)) {
2578 TALLOC_FREE(cli->smb2.tcon);
2583 if (smbXcli_conn_has_async_calls(cli->conn)) {
2584 return NT_STATUS_INVALID_PARAMETER;
2586 ev = samba_tevent_context_init(talloc_tos());
2590 req = cli_tdis_send(ev, ev, cli);
2594 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2597 status = cli_tdis_recv(req);
2603 struct cli_connect_sock_state {
2604 const char **called_names;
2605 const char **calling_names;
2611 static void cli_connect_sock_done(struct tevent_req *subreq);
2614 * Async only if we don't have to look up the name, i.e. "pss" is set with a
2618 static struct tevent_req *cli_connect_sock_send(
2619 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2620 const char *host, int name_type, const struct sockaddr_storage *pss,
2621 const char *myname, uint16_t port)
2623 struct tevent_req *req, *subreq;
2624 struct cli_connect_sock_state *state;
2625 struct sockaddr_storage *addrs;
2626 unsigned i, num_addrs;
2629 req = tevent_req_create(mem_ctx, &state,
2630 struct cli_connect_sock_state);
2635 if ((pss == NULL) || is_zero_addr(pss)) {
2638 * Here we cheat. resolve_name_list is not async at all. So
2639 * this call will only be really async if the name lookup has
2640 * been done externally.
2643 status = resolve_name_list(state, host, name_type,
2644 &addrs, &num_addrs);
2645 if (!NT_STATUS_IS_OK(status)) {
2646 tevent_req_nterror(req, status);
2647 return tevent_req_post(req, ev);
2650 addrs = talloc_array(state, struct sockaddr_storage, 1);
2651 if (tevent_req_nomem(addrs, req)) {
2652 return tevent_req_post(req, ev);
2658 state->called_names = talloc_array(state, const char *, num_addrs);
2659 if (tevent_req_nomem(state->called_names, req)) {
2660 return tevent_req_post(req, ev);
2662 state->called_types = talloc_array(state, int, num_addrs);
2663 if (tevent_req_nomem(state->called_types, req)) {
2664 return tevent_req_post(req, ev);
2666 state->calling_names = talloc_array(state, const char *, num_addrs);
2667 if (tevent_req_nomem(state->calling_names, req)) {
2668 return tevent_req_post(req, ev);
2670 for (i=0; i<num_addrs; i++) {
2671 state->called_names[i] = host;
2672 state->called_types[i] = name_type;
2673 state->calling_names[i] = myname;
2676 subreq = smbsock_any_connect_send(
2677 state, ev, addrs, state->called_names, state->called_types,
2678 state->calling_names, NULL, num_addrs, port);
2679 if (tevent_req_nomem(subreq, req)) {
2680 return tevent_req_post(req, ev);
2682 tevent_req_set_callback(subreq, cli_connect_sock_done, req);
2686 static void cli_connect_sock_done(struct tevent_req *subreq)
2688 struct tevent_req *req = tevent_req_callback_data(
2689 subreq, struct tevent_req);
2690 struct cli_connect_sock_state *state = tevent_req_data(
2691 req, struct cli_connect_sock_state);
2694 status = smbsock_any_connect_recv(subreq, &state->fd, NULL,
2696 TALLOC_FREE(subreq);
2697 if (tevent_req_nterror(req, status)) {
2700 set_socket_options(state->fd, lp_socket_options());
2701 tevent_req_done(req);
2704 static NTSTATUS cli_connect_sock_recv(struct tevent_req *req,
2705 int *pfd, uint16_t *pport)
2707 struct cli_connect_sock_state *state = tevent_req_data(
2708 req, struct cli_connect_sock_state);
2711 if (tevent_req_is_nterror(req, &status)) {
2715 *pport = state->port;
2716 return NT_STATUS_OK;
2719 struct cli_connect_nb_state {
2720 const char *desthost;
2723 struct cli_state *cli;
2726 static void cli_connect_nb_done(struct tevent_req *subreq);
2728 static struct tevent_req *cli_connect_nb_send(
2729 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2730 const char *host, const struct sockaddr_storage *dest_ss,
2731 uint16_t port, int name_type, const char *myname,
2732 int signing_state, int flags)
2734 struct tevent_req *req, *subreq;
2735 struct cli_connect_nb_state *state;
2737 req = tevent_req_create(mem_ctx, &state, struct cli_connect_nb_state);
2741 state->signing_state = signing_state;
2742 state->flags = flags;
2745 char *p = strchr(host, '#');
2748 name_type = strtol(p+1, NULL, 16);
2749 host = talloc_strndup(state, host, p - host);
2750 if (tevent_req_nomem(host, req)) {
2751 return tevent_req_post(req, ev);
2755 state->desthost = host;
2756 } else if (dest_ss != NULL) {
2757 state->desthost = print_canonical_sockaddr(state, dest_ss);
2758 if (tevent_req_nomem(state->desthost, req)) {
2759 return tevent_req_post(req, ev);
2762 /* No host or dest_ss given. Error out. */
2763 tevent_req_error(req, EINVAL);
2764 return tevent_req_post(req, ev);
2767 subreq = cli_connect_sock_send(state, ev, host, name_type, dest_ss,
2769 if (tevent_req_nomem(subreq, req)) {
2770 return tevent_req_post(req, ev);
2772 tevent_req_set_callback(subreq, cli_connect_nb_done, req);
2776 static void cli_connect_nb_done(struct tevent_req *subreq)
2778 struct tevent_req *req = tevent_req_callback_data(
2779 subreq, struct tevent_req);
2780 struct cli_connect_nb_state *state = tevent_req_data(
2781 req, struct cli_connect_nb_state);
2786 status = cli_connect_sock_recv(subreq, &fd, &port);
2787 TALLOC_FREE(subreq);
2788 if (tevent_req_nterror(req, status)) {
2792 state->cli = cli_state_create(state, fd, state->desthost,
2793 state->signing_state, state->flags);
2794 if (tevent_req_nomem(state->cli, req)) {
2798 tevent_req_done(req);
2801 static NTSTATUS cli_connect_nb_recv(struct tevent_req *req,
2802 struct cli_state **pcli)
2804 struct cli_connect_nb_state *state = tevent_req_data(
2805 req, struct cli_connect_nb_state);
2808 if (tevent_req_is_nterror(req, &status)) {
2811 *pcli = talloc_move(NULL, &state->cli);
2812 return NT_STATUS_OK;
2815 NTSTATUS cli_connect_nb(const char *host, const struct sockaddr_storage *dest_ss,
2816 uint16_t port, int name_type, const char *myname,
2817 int signing_state, int flags, struct cli_state **pcli)
2819 struct tevent_context *ev;
2820 struct tevent_req *req;
2821 NTSTATUS status = NT_STATUS_NO_MEMORY;
2823 ev = samba_tevent_context_init(talloc_tos());
2827 req = cli_connect_nb_send(ev, ev, host, dest_ss, port, name_type,
2828 myname, signing_state, flags);
2832 if (!tevent_req_set_endtime(req, ev, timeval_current_ofs(20, 0))) {
2835 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2838 status = cli_connect_nb_recv(req, pcli);
2844 struct cli_start_connection_state {
2845 struct tevent_context *ev;
2846 struct cli_state *cli;
2851 static void cli_start_connection_connected(struct tevent_req *subreq);
2852 static void cli_start_connection_done(struct tevent_req *subreq);
2855 establishes a connection to after the negprot.
2856 @param output_cli A fully initialised cli structure, non-null only on success
2857 @param dest_host The netbios name of the remote host
2858 @param dest_ss (optional) The the destination IP, NULL for name based lookup
2859 @param port (optional) The destination port (0 for default)
2862 static struct tevent_req *cli_start_connection_send(
2863 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2864 const char *my_name, const char *dest_host,
2865 const struct sockaddr_storage *dest_ss, int port,
2866 int signing_state, int flags)
2868 struct tevent_req *req, *subreq;
2869 struct cli_start_connection_state *state;
2871 req = tevent_req_create(mem_ctx, &state,
2872 struct cli_start_connection_state);
2878 if (signing_state == SMB_SIGNING_IPC_DEFAULT) {
2879 state->min_protocol = lp_client_ipc_min_protocol();
2880 state->max_protocol = lp_client_ipc_max_protocol();
2882 state->min_protocol = lp_client_min_protocol();
2883 state->max_protocol = lp_client_max_protocol();
2886 if (flags & CLI_FULL_CONNECTION_FORCE_SMB1) {
2887 state->max_protocol = MIN(state->max_protocol, PROTOCOL_NT1);
2890 if (flags & CLI_FULL_CONNECTION_DISABLE_SMB1) {
2891 state->min_protocol = MAX(state->max_protocol, PROTOCOL_SMB2_02);
2892 state->max_protocol = MAX(state->max_protocol, PROTOCOL_LATEST);
2895 subreq = cli_connect_nb_send(state, ev, dest_host, dest_ss, port,
2896 0x20, my_name, signing_state, flags);
2897 if (tevent_req_nomem(subreq, req)) {
2898 return tevent_req_post(req, ev);
2900 tevent_req_set_callback(subreq, cli_start_connection_connected, req);
2904 static void cli_start_connection_connected(struct tevent_req *subreq)
2906 struct tevent_req *req = tevent_req_callback_data(
2907 subreq, struct tevent_req);
2908 struct cli_start_connection_state *state = tevent_req_data(
2909 req, struct cli_start_connection_state);
2912 status = cli_connect_nb_recv(subreq, &state->cli);
2913 TALLOC_FREE(subreq);
2914 if (tevent_req_nterror(req, status)) {
2918 subreq = smbXcli_negprot_send(state, state->ev, state->cli->conn,
2919 state->cli->timeout,
2920 state->min_protocol,
2921 state->max_protocol,
2922 WINDOWS_CLIENT_PURE_SMB2_NEGPROT_INITIAL_CREDIT_ASK);
2923 if (tevent_req_nomem(subreq, req)) {
2926 tevent_req_set_callback(subreq, cli_start_connection_done, req);
2929 static void cli_start_connection_done(struct tevent_req *subreq)
2931 struct tevent_req *req = tevent_req_callback_data(
2932 subreq, struct tevent_req);
2933 struct cli_start_connection_state *state = tevent_req_data(
2934 req, struct cli_start_connection_state);
2937 status = smbXcli_negprot_recv(subreq);
2938 TALLOC_FREE(subreq);
2939 if (tevent_req_nterror(req, status)) {
2943 status = cli_state_update_after_negprot(state->cli);
2944 if (tevent_req_nterror(req, status)) {
2948 tevent_req_done(req);
2951 static NTSTATUS cli_start_connection_recv(struct tevent_req *req,
2952 struct cli_state **output_cli)
2954 struct cli_start_connection_state *state = tevent_req_data(
2955 req, struct cli_start_connection_state);
2958 if (tevent_req_is_nterror(req, &status)) {
2961 *output_cli = state->cli;
2963 return NT_STATUS_OK;
2966 NTSTATUS cli_start_connection(struct cli_state **output_cli,
2967 const char *my_name,
2968 const char *dest_host,
2969 const struct sockaddr_storage *dest_ss, int port,
2970 int signing_state, int flags)
2972 struct tevent_context *ev;
2973 struct tevent_req *req;
2974 NTSTATUS status = NT_STATUS_NO_MEMORY;
2976 ev = samba_tevent_context_init(talloc_tos());
2980 req = cli_start_connection_send(ev, ev, my_name, dest_host, dest_ss,
2981 port, signing_state, flags);
2985 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2988 status = cli_start_connection_recv(req, output_cli);
2994 struct cli_smb1_setup_encryption_blob_state {
2999 uint16_t enc_ctx_id;
3002 static void cli_smb1_setup_encryption_blob_done(struct tevent_req *subreq);
3004 static struct tevent_req *cli_smb1_setup_encryption_blob_send(TALLOC_CTX *mem_ctx,
3005 struct tevent_context *ev,
3006 struct cli_state *cli,
3009 struct tevent_req *req = NULL;
3010 struct cli_smb1_setup_encryption_blob_state *state = NULL;
3011 struct tevent_req *subreq = NULL;
3013 req = tevent_req_create(mem_ctx, &state,
3014 struct cli_smb1_setup_encryption_blob_state);
3019 if (in.length > CLI_BUFFER_SIZE) {
3020 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
3021 return tevent_req_post(req, ev);
3024 SSVAL(state->setup+0, 0, TRANSACT2_SETFSINFO);
3025 SSVAL(state->param, 0, 0);
3026 SSVAL(state->param, 2, SMB_REQUEST_TRANSPORT_ENCRYPTION);
3028 subreq = smb1cli_trans_send(state, ev, cli->conn,
3036 NULL, /* pipe_name */
3042 in.data, in.length, CLI_BUFFER_SIZE);
3043 if (tevent_req_nomem(subreq, req)) {
3044 return tevent_req_post(req, ev);
3046 tevent_req_set_callback(subreq,
3047 cli_smb1_setup_encryption_blob_done,
3053 static void cli_smb1_setup_encryption_blob_done(struct tevent_req *subreq)
3055 struct tevent_req *req =
3056 tevent_req_callback_data(subreq,
3058 struct cli_smb1_setup_encryption_blob_state *state =
3059 tevent_req_data(req,
3060 struct cli_smb1_setup_encryption_blob_state);
3061 uint8_t *rparam=NULL, *rdata=NULL;
3062 uint32_t num_rparam, num_rdata;
3065 status = smb1cli_trans_recv(subreq, state,
3066 NULL, /* recv_flags */
3067 NULL, 0, NULL, /* rsetup */
3068 &rparam, 0, &num_rparam,
3069 &rdata, 0, &num_rdata);
3070 TALLOC_FREE(subreq);
3071 state->status = status;
3072 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
3073 status = NT_STATUS_OK;
3075 if (tevent_req_nterror(req, status)) {
3079 if (num_rparam == 2) {
3080 state->enc_ctx_id = SVAL(rparam, 0);
3082 TALLOC_FREE(rparam);
3084 state->out = data_blob_const(rdata, num_rdata);
3086 tevent_req_done(req);
3089 static NTSTATUS cli_smb1_setup_encryption_blob_recv(struct tevent_req *req,
3090 TALLOC_CTX *mem_ctx,
3092 uint16_t *enc_ctx_id)
3094 struct cli_smb1_setup_encryption_blob_state *state =
3095 tevent_req_data(req,
3096 struct cli_smb1_setup_encryption_blob_state);
3099 if (tevent_req_is_nterror(req, &status)) {
3100 tevent_req_received(req);
3104 status = state->status;
3107 talloc_steal(mem_ctx, out->data);
3109 *enc_ctx_id = state->enc_ctx_id;
3111 tevent_req_received(req);
3115 struct cli_smb1_setup_encryption_state {
3116 struct tevent_context *ev;
3117 struct cli_state *cli;
3118 struct smb_trans_enc_state *es;
3125 static void cli_smb1_setup_encryption_local_next(struct tevent_req *req);
3126 static void cli_smb1_setup_encryption_local_done(struct tevent_req *subreq);
3127 static void cli_smb1_setup_encryption_remote_next(struct tevent_req *req);
3128 static void cli_smb1_setup_encryption_remote_done(struct tevent_req *subreq);
3129 static void cli_smb1_setup_encryption_ready(struct tevent_req *req);
3131 static struct tevent_req *cli_smb1_setup_encryption_send(TALLOC_CTX *mem_ctx,
3132 struct tevent_context *ev,
3133 struct cli_state *cli,
3134 struct cli_credentials *creds)
3136 struct tevent_req *req = NULL;
3137 struct cli_smb1_setup_encryption_state *state = NULL;
3138 struct auth_generic_state *ags = NULL;
3139 const DATA_BLOB *b = NULL;
3140 bool auth_requested = false;
3141 const char *target_service = NULL;
3142 const char *target_hostname = NULL;
3145 req = tevent_req_create(mem_ctx, &state,
3146 struct cli_smb1_setup_encryption_state);
3153 auth_requested = cli_credentials_authentication_requested(creds);
3154 if (!auth_requested) {
3155 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
3156 return tevent_req_post(req, ev);
3159 target_service = "cifs";
3160 target_hostname = smbXcli_conn_remote_name(cli->conn);
3162 status = cli_session_creds_prepare_krb5(cli, creds);
3163 if (tevent_req_nterror(req, status)) {
3164 return tevent_req_post(req, ev);
3167 state->es = talloc_zero(state, struct smb_trans_enc_state);
3168 if (tevent_req_nomem(state->es, req)) {
3169 return tevent_req_post(req, ev);
3172 status = auth_generic_client_prepare(state->es, &ags);
3173 if (tevent_req_nterror(req, status)) {
3174 return tevent_req_post(req, ev);
3177 gensec_want_feature(ags->gensec_security,
3178 GENSEC_FEATURE_SIGN);
3179 gensec_want_feature(ags->gensec_security,
3180 GENSEC_FEATURE_SEAL);
3182 status = auth_generic_set_creds(ags, creds);
3183 if (tevent_req_nterror(req, status)) {
3184 return tevent_req_post(req, ev);
3187 if (target_service != NULL) {
3188 status = gensec_set_target_service(ags->gensec_security,
3190 if (tevent_req_nterror(req, status)) {
3191 return tevent_req_post(req, ev);
3195 if (target_hostname != NULL) {
3196 status = gensec_set_target_hostname(ags->gensec_security,
3198 if (tevent_req_nterror(req, status)) {
3199 return tevent_req_post(req, ev);
3203 gensec_set_max_update_size(ags->gensec_security,
3206 b = smbXcli_conn_server_gss_blob(state->cli->conn);
3208 state->blob_in = *b;
3211 status = auth_generic_client_start(ags, GENSEC_OID_SPNEGO);
3212 if (tevent_req_nterror(req, status)) {
3213 return tevent_req_post(req, ev);
3217 * We only need the gensec_security part from here.
3219 state->es->gensec_security = talloc_move(state->es,
3220 &ags->gensec_security);
3223 cli_smb1_setup_encryption_local_next(req);
3224 if (!tevent_req_is_in_progress(req)) {
3225 return tevent_req_post(req, ev);
3231 static void cli_smb1_setup_encryption_local_next(struct tevent_req *req)
3233 struct cli_smb1_setup_encryption_state *state =
3234 tevent_req_data(req,
3235 struct cli_smb1_setup_encryption_state);
3236 struct tevent_req *subreq = NULL;
3238 if (state->local_ready) {
3239 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3243 subreq = gensec_update_send(state, state->ev,
3244 state->es->gensec_security,
3246 if (tevent_req_nomem(subreq, req)) {
3249 tevent_req_set_callback(subreq, cli_smb1_setup_encryption_local_done, req);
3252 static void cli_smb1_setup_encryption_local_done(struct tevent_req *subreq)
3254 struct tevent_req *req =
3255 tevent_req_callback_data(subreq,
3257 struct cli_smb1_setup_encryption_state *state =
3258 tevent_req_data(req,
3259 struct cli_smb1_setup_encryption_state);
3262 status = gensec_update_recv(subreq, state, &state->blob_out);
3263 TALLOC_FREE(subreq);
3264 state->blob_in = data_blob_null;
3265 if (!NT_STATUS_IS_OK(status) &&
3266 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
3268 tevent_req_nterror(req, status);
3272 if (NT_STATUS_IS_OK(status)) {
3273 state->local_ready = true;
3277 * We always get NT_STATUS_OK from the server even if it is not ready.
3278 * So guess the server is ready when we are ready and already sent
3279 * our last blob to the server.
3281 if (state->local_ready && state->blob_out.length == 0) {
3282 state->remote_ready = true;
3285 if (state->local_ready && state->remote_ready) {
3286 cli_smb1_setup_encryption_ready(req);
3290 cli_smb1_setup_encryption_remote_next(req);
3293 static void cli_smb1_setup_encryption_remote_next(struct tevent_req *req)
3295 struct cli_smb1_setup_encryption_state *state =
3296 tevent_req_data(req,
3297 struct cli_smb1_setup_encryption_state);
3298 struct tevent_req *subreq = NULL;
3300 if (state->remote_ready) {
3301 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3305 subreq = cli_smb1_setup_encryption_blob_send(state, state->ev,
3306 state->cli, state->blob_out);
3307 if (tevent_req_nomem(subreq, req)) {
3310 tevent_req_set_callback(subreq,
3311 cli_smb1_setup_encryption_remote_done,
3315 static void cli_smb1_setup_encryption_remote_done(struct tevent_req *subreq)
3317 struct tevent_req *req =
3318 tevent_req_callback_data(subreq,
3320 struct cli_smb1_setup_encryption_state *state =
3321 tevent_req_data(req,
3322 struct cli_smb1_setup_encryption_state);
3325 status = cli_smb1_setup_encryption_blob_recv(subreq, state,
3327 &state->es->enc_ctx_num);
3328 TALLOC_FREE(subreq);
3329 data_blob_free(&state->blob_out);
3330 if (!NT_STATUS_IS_OK(status) &&
3331 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
3333 tevent_req_nterror(req, status);
3338 * We always get NT_STATUS_OK even if the server is not ready.
3339 * So guess the server is ready when we are ready and sent
3340 * our last blob to the server.
3342 if (state->local_ready) {
3343 state->remote_ready = true;
3346 if (state->local_ready && state->remote_ready) {
3347 cli_smb1_setup_encryption_ready(req);
3351 cli_smb1_setup_encryption_local_next(req);
3354 static void cli_smb1_setup_encryption_ready(struct tevent_req *req)
3356 struct cli_smb1_setup_encryption_state *state =
3357 tevent_req_data(req,
3358 struct cli_smb1_setup_encryption_state);
3359 struct smb_trans_enc_state *es = NULL;
3361 if (state->blob_in.length != 0) {
3362 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3366 if (state->blob_out.length != 0) {
3367 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3371 es = talloc_move(state->cli->conn, &state->es);
3373 smb1cli_conn_set_encryption(state->cli->conn, es);
3376 tevent_req_done(req);
3379 static NTSTATUS cli_smb1_setup_encryption_recv(struct tevent_req *req)
3381 return tevent_req_simple_recv_ntstatus(req);
3384 NTSTATUS cli_smb1_setup_encryption(struct cli_state *cli,
3385 struct cli_credentials *creds)
3387 struct tevent_context *ev = NULL;
3388 struct tevent_req *req = NULL;
3389 NTSTATUS status = NT_STATUS_NO_MEMORY;
3391 ev = samba_tevent_context_init(talloc_tos());
3395 req = cli_smb1_setup_encryption_send(ev, ev, cli, creds);
3399 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
3402 status = cli_smb1_setup_encryption_recv(req);
3409 establishes a connection right up to doing tconX, password specified.
3410 @param output_cli A fully initialised cli structure, non-null only on success
3411 @param dest_host The netbios name of the remote host
3412 @param dest_ip (optional) The the destination IP, NULL for name based lookup
3413 @param port (optional) The destination port (0 for default)
3414 @param service (optional) The share to make the connection to. Should be 'unqualified' in any way.
3415 @param service_type The 'type' of serivice.
3416 @param creds The used user credentials
3419 struct cli_full_connection_creds_state {
3420 struct tevent_context *ev;
3421 const char *service;
3422 const char *service_type;
3423 struct cli_credentials *creds;
3425 struct cli_state *cli;
3428 static int cli_full_connection_creds_state_destructor(
3429 struct cli_full_connection_creds_state *s)
3431 if (s->cli != NULL) {
3432 cli_shutdown(s->cli);
3438 static void cli_full_connection_creds_conn_done(struct tevent_req *subreq);
3439 static void cli_full_connection_creds_sess_start(struct tevent_req *req);
3440 static void cli_full_connection_creds_sess_done(struct tevent_req *subreq);
3441 static void cli_full_connection_creds_tcon_start(struct tevent_req *req);
3442 static void cli_full_connection_creds_tcon_done(struct tevent_req *subreq);
3444 struct tevent_req *cli_full_connection_creds_send(
3445 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
3446 const char *my_name, const char *dest_host,
3447 const struct sockaddr_storage *dest_ss, int port,
3448 const char *service, const char *service_type,
3449 struct cli_credentials *creds,
3450 int flags, int signing_state)
3452 struct tevent_req *req, *subreq;
3453 struct cli_full_connection_creds_state *state;
3454 enum credentials_use_kerberos krb5_state;
3455 uint32_t gensec_features = 0;
3457 req = tevent_req_create(mem_ctx, &state,
3458 struct cli_full_connection_creds_state);
3462 talloc_set_destructor(state, cli_full_connection_creds_state_destructor);
3464 flags &= ~CLI_FULL_CONNECTION_USE_KERBEROS;
3465 flags &= ~CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS;
3466 flags &= ~CLI_FULL_CONNECTION_USE_CCACHE;
3467 flags &= ~CLI_FULL_CONNECTION_USE_NT_HASH;
3469 krb5_state = cli_credentials_get_kerberos_state(creds);
3470 switch (krb5_state) {
3471 case CRED_MUST_USE_KERBEROS:
3472 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
3473 flags &= ~CLI_FULL_CONNECTION_DONT_SPNEGO;
3475 case CRED_AUTO_USE_KERBEROS:
3476 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
3477 flags |= CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS;
3479 case CRED_DONT_USE_KERBEROS:
3483 gensec_features = cli_credentials_get_gensec_features(creds);
3484 if (gensec_features & GENSEC_FEATURE_NTLM_CCACHE) {
3485 flags |= CLI_FULL_CONNECTION_USE_CCACHE;
3489 state->service = service;
3490 state->service_type = service_type;
3491 state->creds = creds;
3492 state->flags = flags;
3494 subreq = cli_start_connection_send(
3495 state, ev, my_name, dest_host, dest_ss, port,
3496 signing_state, flags);
3497 if (tevent_req_nomem(subreq, req)) {
3498 return tevent_req_post(req, ev);
3500 tevent_req_set_callback(subreq,
3501 cli_full_connection_creds_conn_done,
3506 static void cli_full_connection_creds_conn_done(struct tevent_req *subreq)
3508 struct tevent_req *req = tevent_req_callback_data(
3509 subreq, struct tevent_req);
3510 struct cli_full_connection_creds_state *state = tevent_req_data(
3511 req, struct cli_full_connection_creds_state);
3514 status = cli_start_connection_recv(subreq, &state->cli);
3515 TALLOC_FREE(subreq);
3516 if (tevent_req_nterror(req, status)) {
3520 cli_full_connection_creds_sess_start(req);
3523 static void cli_full_connection_creds_sess_start(struct tevent_req *req)
3525 struct cli_full_connection_creds_state *state = tevent_req_data(
3526 req, struct cli_full_connection_creds_state);
3527 struct tevent_req *subreq = NULL;
3529 subreq = cli_session_setup_creds_send(
3530 state, state->ev, state->cli, state->creds);
3531 if (tevent_req_nomem(subreq, req)) {
3534 tevent_req_set_callback(subreq,
3535 cli_full_connection_creds_sess_done,
3539 static void cli_full_connection_creds_sess_done(struct tevent_req *subreq)
3541 struct tevent_req *req = tevent_req_callback_data(
3542 subreq, struct tevent_req);
3543 struct cli_full_connection_creds_state *state = tevent_req_data(
3544 req, struct cli_full_connection_creds_state);
3547 status = cli_session_setup_creds_recv(subreq);
3548 TALLOC_FREE(subreq);
3550 if (!NT_STATUS_IS_OK(status) &&
3551 (state->flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)) {
3553 state->flags &= ~CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
3555 state->creds = cli_credentials_init_anon(state);
3556 if (tevent_req_nomem(state->creds, req)) {
3560 cli_full_connection_creds_sess_start(req);
3564 if (tevent_req_nterror(req, status)) {
3568 cli_full_connection_creds_tcon_start(req);
3571 static void cli_full_connection_creds_tcon_start(struct tevent_req *req)
3573 struct cli_full_connection_creds_state *state = tevent_req_data(
3574 req, struct cli_full_connection_creds_state);
3575 struct tevent_req *subreq = NULL;
3576 const char *password = NULL;
3578 if (state->service == NULL) {
3579 tevent_req_done(req);
3583 password = cli_credentials_get_password(state->creds);
3585 subreq = cli_tree_connect_send(state, state->ev,
3588 state->service_type,
3590 if (tevent_req_nomem(subreq, req)) {
3593 tevent_req_set_callback(subreq,
3594 cli_full_connection_creds_tcon_done,
3598 static void cli_full_connection_creds_tcon_done(struct tevent_req *subreq)
3600 struct tevent_req *req = tevent_req_callback_data(
3601 subreq, struct tevent_req);
3604 status = cli_tree_connect_recv(subreq);
3605 TALLOC_FREE(subreq);
3606 if (tevent_req_nterror(req, status)) {
3610 tevent_req_done(req);
3613 NTSTATUS cli_full_connection_creds_recv(struct tevent_req *req,
3614 struct cli_state **output_cli)
3616 struct cli_full_connection_creds_state *state = tevent_req_data(
3617 req, struct cli_full_connection_creds_state);
3620 if (tevent_req_is_nterror(req, &status)) {
3623 *output_cli = state->cli;
3624 talloc_set_destructor(state, NULL);
3625 return NT_STATUS_OK;
3628 NTSTATUS cli_full_connection_creds(struct cli_state **output_cli,
3629 const char *my_name,
3630 const char *dest_host,
3631 const struct sockaddr_storage *dest_ss, int port,
3632 const char *service, const char *service_type,
3633 struct cli_credentials *creds,
3637 struct tevent_context *ev;
3638 struct tevent_req *req;
3639 NTSTATUS status = NT_STATUS_NO_MEMORY;
3641 ev = samba_tevent_context_init(talloc_tos());
3645 req = cli_full_connection_creds_send(
3646 ev, ev, my_name, dest_host, dest_ss, port, service,
3647 service_type, creds, flags, signing_state);
3651 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
3654 status = cli_full_connection_creds_recv(req, output_cli);
3660 NTSTATUS cli_full_connection(struct cli_state **output_cli,
3661 const char *my_name,
3662 const char *dest_host,
3663 const struct sockaddr_storage *dest_ss, int port,
3664 const char *service, const char *service_type,
3665 const char *user, const char *domain,
3666 const char *password, int flags,
3669 TALLOC_CTX *frame = talloc_stackframe();
3671 bool use_kerberos = false;
3672 bool fallback_after_kerberos = false;
3673 bool use_ccache = false;
3674 bool pw_nt_hash = false;
3675 struct cli_credentials *creds = NULL;
3677 if (flags & CLI_FULL_CONNECTION_USE_KERBEROS) {
3678 use_kerberos = true;
3681 if (flags & CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS) {
3682 fallback_after_kerberos = true;
3685 if (flags & CLI_FULL_CONNECTION_USE_CCACHE) {
3689 if (flags & CLI_FULL_CONNECTION_USE_NT_HASH) {
3693 creds = cli_session_creds_init(frame,
3696 NULL, /* realm (use default) */
3699 fallback_after_kerberos,
3702 if (creds == NULL) {
3704 return NT_STATUS_NO_MEMORY;
3707 status = cli_full_connection_creds(output_cli, my_name,
3708 dest_host, dest_ss, port,
3709 service, service_type,
3710 creds, flags, signing_state);
3711 if (!NT_STATUS_IS_OK(status)) {
3717 return NT_STATUS_OK;
3720 /****************************************************************************
3721 Send an old style tcon.
3722 ****************************************************************************/
3723 struct cli_raw_tcon_state {
3727 static void cli_raw_tcon_done(struct tevent_req *subreq);
3729 static struct tevent_req *cli_raw_tcon_send(
3730 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
3731 const char *service, const char *pass, const char *dev)
3733 struct tevent_req *req, *subreq;
3734 struct cli_raw_tcon_state *state;
3737 req = tevent_req_create(mem_ctx, &state, struct cli_raw_tcon_state);
3742 if (!lp_client_plaintext_auth() && (*pass)) {
3743 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
3744 " or 'client ntlmv2 auth = yes'\n"));
3745 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
3746 return tevent_req_post(req, ev);
3749 TALLOC_FREE(cli->smb1.tcon);
3750 cli->smb1.tcon = smbXcli_tcon_create(cli);
3751 if (tevent_req_nomem(cli->smb1.tcon, req)) {
3752 return tevent_req_post(req, ev);
3754 smb1cli_tcon_set_id(cli->smb1.tcon, UINT16_MAX);
3756 bytes = talloc_array(state, uint8_t, 0);
3757 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3758 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3759 service, strlen(service)+1, NULL);
3760 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3761 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3762 pass, strlen(pass)+1, NULL);
3763 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3764 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3765 dev, strlen(dev)+1, NULL);
3767 if (tevent_req_nomem(bytes, req)) {
3768 return tevent_req_post(req, ev);
3771 subreq = cli_smb_send(state, ev, cli, SMBtcon, 0, 0, 0, NULL,
3772 talloc_get_size(bytes), bytes);
3773 if (tevent_req_nomem(subreq, req)) {
3774 return tevent_req_post(req, ev);
3776 tevent_req_set_callback(subreq, cli_raw_tcon_done, req);
3780 static void cli_raw_tcon_done(struct tevent_req *subreq)
3782 struct tevent_req *req = tevent_req_callback_data(
3783 subreq, struct tevent_req);
3784 struct cli_raw_tcon_state *state = tevent_req_data(
3785 req, struct cli_raw_tcon_state);
3788 status = cli_smb_recv(subreq, state, NULL, 2, NULL, &state->ret_vwv,
3790 TALLOC_FREE(subreq);
3791 if (tevent_req_nterror(req, status)) {
3794 tevent_req_done(req);
3797 static NTSTATUS cli_raw_tcon_recv(struct tevent_req *req,
3798 uint16_t *max_xmit, uint16_t *tid)
3800 struct cli_raw_tcon_state *state = tevent_req_data(
3801 req, struct cli_raw_tcon_state);
3804 if (tevent_req_is_nterror(req, &status)) {
3807 *max_xmit = SVAL(state->ret_vwv + 0, 0);
3808 *tid = SVAL(state->ret_vwv + 1, 0);
3809 return NT_STATUS_OK;
3812 NTSTATUS cli_raw_tcon(struct cli_state *cli,
3813 const char *service, const char *pass, const char *dev,
3814 uint16_t *max_xmit, uint16_t *tid)
3816 struct tevent_context *ev;
3817 struct tevent_req *req;
3818 NTSTATUS status = NT_STATUS_NO_MEMORY;
3820 ev = samba_tevent_context_init(talloc_tos());
3824 req = cli_raw_tcon_send(ev, ev, cli, service, pass, dev);
3828 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
3831 status = cli_raw_tcon_recv(req, max_xmit, tid);
3837 /* Return a cli_state pointing at the IPC$ share for the given server */
3839 struct cli_state *get_ipc_connect(char *server,
3840 struct sockaddr_storage *server_ss,
3841 const struct user_auth_info *user_info)
3843 struct cli_state *cli;
3845 uint32_t flags = CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
3847 if (get_cmdline_auth_info_use_kerberos(user_info)) {
3848 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
3851 flags |= CLI_FULL_CONNECTION_FORCE_SMB1;
3853 nt_status = cli_full_connection(&cli, NULL, server, server_ss, 0, "IPC$", "IPC",
3854 get_cmdline_auth_info_username(user_info),
3856 get_cmdline_auth_info_password(user_info),
3858 SMB_SIGNING_DEFAULT);
3860 if (NT_STATUS_IS_OK(nt_status)) {
3862 } else if (is_ipaddress(server)) {
3863 /* windows 9* needs a correct NMB name for connections */
3864 fstring remote_name;
3866 if (name_status_find("*", 0, 0, server_ss, remote_name)) {
3867 cli = get_ipc_connect(remote_name, server_ss, user_info);
3876 * Given the IP address of a master browser on the network, return its
3877 * workgroup and connect to it.
3879 * This function is provided to allow additional processing beyond what
3880 * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
3881 * browsers and obtain each master browsers' list of domains (in case the
3882 * first master browser is recently on the network and has not yet
3883 * synchronized with other master browsers and therefore does not yet have the
3884 * entire network browse list)
3887 struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx,
3888 struct sockaddr_storage *mb_ip,
3889 const struct user_auth_info *user_info,
3890 char **pp_workgroup_out)
3892 char addr[INET6_ADDRSTRLEN];
3894 struct cli_state *cli;
3895 struct sockaddr_storage server_ss;
3897 *pp_workgroup_out = NULL;
3899 print_sockaddr(addr, sizeof(addr), mb_ip);
3900 DEBUG(99, ("Looking up name of master browser %s\n",
3904 * Do a name status query to find out the name of the master browser.
3905 * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
3906 * master browser will not respond to a wildcard query (or, at least,
3907 * an NT4 server acting as the domain master browser will not).
3909 * We might be able to use ONLY the query on MSBROWSE, but that's not
3910 * yet been tested with all Windows versions, so until it is, leave
3911 * the original wildcard query as the first choice and fall back to
3912 * MSBROWSE if the wildcard query fails.
3914 if (!name_status_find("*", 0, 0x1d, mb_ip, name) &&
3915 !name_status_find(MSBROWSE, 1, 0x1d, mb_ip, name)) {
3917 DEBUG(99, ("Could not retrieve name status for %s\n",
3922 if (!find_master_ip(name, &server_ss)) {
3923 DEBUG(99, ("Could not find master ip for %s\n", name));
3927 *pp_workgroup_out = talloc_strdup(ctx, name);
3929 DEBUG(4, ("found master browser %s, %s\n", name, addr));
3931 print_sockaddr(addr, sizeof(addr), &server_ss);
3932 cli = get_ipc_connect(addr, &server_ss, user_info);
3938 * Return the IP address and workgroup of a master browser on the network, and
3942 struct cli_state *get_ipc_connect_master_ip_bcast(TALLOC_CTX *ctx,
3943 const struct user_auth_info *user_info,
3944 char **pp_workgroup_out)
3946 struct sockaddr_storage *ip_list;
3947 struct cli_state *cli;
3951 *pp_workgroup_out = NULL;
3953 DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
3955 /* Go looking for workgroups by broadcasting on the local network */
3957 status = name_resolve_bcast(MSBROWSE, 1, talloc_tos(),
3959 if (!NT_STATUS_IS_OK(status)) {
3960 DEBUG(99, ("No master browsers responded: %s\n",
3961 nt_errstr(status)));
3965 for (i = 0; i < count; i++) {
3966 char addr[INET6_ADDRSTRLEN];
3967 print_sockaddr(addr, sizeof(addr), &ip_list[i]);
3968 DEBUG(99, ("Found master browser %s\n", addr));
3970 cli = get_ipc_connect_master_ip(ctx, &ip_list[i],
3971 user_info, pp_workgroup_out);