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 static NTSTATUS cli_state_update_after_sesssetup(struct cli_state *cli,
383 const char *native_os,
384 const char *native_lm,
385 const char *primary_domain)
387 #define _VALID_STR(p) ((p) != NULL && (p)[0] != '\0')
389 if (!_VALID_STR(cli->server_os) && _VALID_STR(native_os)) {
390 cli->server_os = talloc_strdup(cli, native_os);
391 if (cli->server_os == NULL) {
392 return NT_STATUS_NO_MEMORY;
396 if (!_VALID_STR(cli->server_type) && _VALID_STR(native_lm)) {
397 cli->server_type = talloc_strdup(cli, native_lm);
398 if (cli->server_type == NULL) {
399 return NT_STATUS_NO_MEMORY;
403 if (!_VALID_STR(cli->server_domain) && _VALID_STR(primary_domain)) {
404 cli->server_domain = talloc_strdup(cli, primary_domain);
405 if (cli->server_domain == NULL) {
406 return NT_STATUS_NO_MEMORY;
414 /********************************************************
415 Utility function to ensure we always return at least
416 a valid char * pointer to an empty string for the
417 cli->server_os, cli->server_type and cli->server_domain
419 *******************************************************/
421 static NTSTATUS smb_bytes_talloc_string(TALLOC_CTX *mem_ctx,
428 *destlen = clistr_pull_talloc(mem_ctx,
435 if (*destlen == -1) {
436 return NT_STATUS_NO_MEMORY;
440 *dest = talloc_strdup(mem_ctx, "");
442 return NT_STATUS_NO_MEMORY;
448 /****************************************************************************
449 Work out suitable capabilities to offer the server.
450 ****************************************************************************/
452 static uint32_t cli_session_setup_capabilities(struct cli_state *cli,
453 uint32_t sesssetup_capabilities)
455 uint32_t client_capabilities = smb1cli_conn_capabilities(cli->conn);
458 * We only send capabilities based on the mask for:
459 * - client only flags
460 * - flags used in both directions
462 * We do not echo the server only flags, except some legacy flags.
464 * SMB_CAP_LEGACY_CLIENT_MASK contains CAP_LARGE_READX and
465 * CAP_LARGE_WRITEX in order to allow us to do large reads
466 * against old Samba releases (<= 3.6.x).
468 client_capabilities &= (SMB_CAP_BOTH_MASK | SMB_CAP_LEGACY_CLIENT_MASK);
471 * Session Setup specific flags CAP_DYNAMIC_REAUTH
472 * and CAP_EXTENDED_SECURITY are passed by the caller.
473 * We need that in order to do guest logins even if
474 * CAP_EXTENDED_SECURITY is negotiated.
476 client_capabilities &= ~(CAP_DYNAMIC_REAUTH|CAP_EXTENDED_SECURITY);
477 sesssetup_capabilities &= (CAP_DYNAMIC_REAUTH|CAP_EXTENDED_SECURITY);
478 client_capabilities |= sesssetup_capabilities;
480 return client_capabilities;
483 /****************************************************************************
484 Do a NT1 guest session setup.
485 ****************************************************************************/
487 struct cli_session_setup_guest_state {
488 struct cli_state *cli;
493 static void cli_session_setup_guest_done(struct tevent_req *subreq);
495 struct tevent_req *cli_session_setup_guest_create(TALLOC_CTX *mem_ctx,
496 struct tevent_context *ev,
497 struct cli_state *cli,
498 struct tevent_req **psmbreq)
500 struct tevent_req *req, *subreq;
501 struct cli_session_setup_guest_state *state;
505 req = tevent_req_create(mem_ctx, &state,
506 struct cli_session_setup_guest_state);
513 SCVAL(vwv+0, 0, 0xFF);
516 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
518 SSVAL(vwv+4, 0, cli_state_get_vc_num(cli));
519 SIVAL(vwv+5, 0, smb1cli_conn_server_session_key(cli->conn));
524 SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli, 0));
526 bytes = talloc_array(state, uint8_t, 0);
528 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "", 1, /* username */
530 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "", 1, /* workgroup */
532 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "Unix", 5, NULL);
533 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "Samba", 6, NULL);
540 state->bytes.iov_base = (void *)bytes;
541 state->bytes.iov_len = talloc_get_size(bytes);
543 subreq = cli_smb_req_create(state, ev, cli, SMBsesssetupX, 0, 0, 13,
544 vwv, 1, &state->bytes);
545 if (subreq == NULL) {
549 tevent_req_set_callback(subreq, cli_session_setup_guest_done, req);
554 struct tevent_req *cli_session_setup_guest_send(TALLOC_CTX *mem_ctx,
555 struct tevent_context *ev,
556 struct cli_state *cli)
558 struct tevent_req *req, *subreq;
561 req = cli_session_setup_guest_create(mem_ctx, ev, cli, &subreq);
566 status = smb1cli_req_chain_submit(&subreq, 1);
567 if (!NT_STATUS_IS_OK(status)) {
568 tevent_req_nterror(req, status);
569 return tevent_req_post(req, ev);
574 static void cli_session_setup_guest_done(struct tevent_req *subreq)
576 struct tevent_req *req = tevent_req_callback_data(
577 subreq, struct tevent_req);
578 struct cli_session_setup_guest_state *state = tevent_req_data(
579 req, struct cli_session_setup_guest_state);
580 struct cli_state *cli = state->cli;
591 status = cli_smb_recv(subreq, state, &in, 3, &wct, &vwv,
594 if (!NT_STATUS_IS_OK(status)) {
595 tevent_req_nterror(req, status);
599 inhdr = in + NBT_HDR_SIZE;
602 cli_state_set_uid(state->cli, SVAL(inhdr, HDR_UID));
603 smb1cli_session_set_action(cli->smb1.session, SVAL(vwv+2, 0));
605 status = smb_bytes_talloc_string(cli,
612 if (!NT_STATUS_IS_OK(status)) {
613 tevent_req_nterror(req, status);
618 status = smb_bytes_talloc_string(cli,
625 if (!NT_STATUS_IS_OK(status)) {
626 tevent_req_nterror(req, status);
631 status = smb_bytes_talloc_string(cli,
638 if (!NT_STATUS_IS_OK(status)) {
639 tevent_req_nterror(req, status);
644 tevent_req_done(req);
647 NTSTATUS cli_session_setup_guest_recv(struct tevent_req *req)
649 return tevent_req_simple_recv_ntstatus(req);
652 /* The following is calculated from :
654 * (smb_wcnt * 2) = 24 (smb_wcnt == 12 in cli_session_setup_blob_send() )
655 * (strlen("Unix") + 1 + strlen("Samba") + 1) * 2 = 22 (unicode strings at
659 #define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22)
661 struct cli_sesssetup_blob_state {
662 struct tevent_context *ev;
663 struct cli_state *cli;
665 uint16_t max_blob_size;
668 struct iovec *recv_iov;
671 const uint8_t *inbuf;
678 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state *state,
679 struct tevent_req **psubreq);
680 static void cli_sesssetup_blob_done(struct tevent_req *subreq);
682 static struct tevent_req *cli_sesssetup_blob_send(TALLOC_CTX *mem_ctx,
683 struct tevent_context *ev,
684 struct cli_state *cli,
687 struct tevent_req *req, *subreq;
688 struct cli_sesssetup_blob_state *state;
689 uint32_t usable_space;
691 req = tevent_req_create(mem_ctx, &state,
692 struct cli_sesssetup_blob_state);
700 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
701 usable_space = UINT16_MAX;
703 usable_space = cli_state_available_size(cli,
704 BASE_SESSSETUP_BLOB_PACKET_SIZE);
707 if (usable_space == 0) {
708 DEBUG(1, ("cli_session_setup_blob: cli->max_xmit too small "
709 "(not possible to send %u bytes)\n",
710 BASE_SESSSETUP_BLOB_PACKET_SIZE + 1));
711 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
712 return tevent_req_post(req, ev);
714 state->max_blob_size = MIN(usable_space, 0xFFFF);
716 if (!cli_sesssetup_blob_next(state, &subreq)) {
717 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
718 return tevent_req_post(req, ev);
720 tevent_req_set_callback(subreq, cli_sesssetup_blob_done, req);
724 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state *state,
725 struct tevent_req **psubreq)
727 struct tevent_req *subreq;
730 thistime = MIN(state->blob.length, state->max_blob_size);
732 state->this_blob.data = state->blob.data;
733 state->this_blob.length = thistime;
735 state->blob.data += thistime;
736 state->blob.length -= thistime;
738 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
739 subreq = smb2cli_session_setup_send(state, state->ev,
742 state->cli->smb2.session,
744 SMB2_CAP_DFS, /* in_capabilities */
746 0, /* in_previous_session_id */
748 if (subreq == NULL) {
752 uint16_t in_buf_size = 0;
753 uint16_t in_mpx_max = 0;
754 uint16_t in_vc_num = 0;
755 uint32_t in_sess_key = 0;
756 uint32_t in_capabilities = 0;
757 const char *in_native_os = NULL;
758 const char *in_native_lm = NULL;
760 in_buf_size = CLI_BUFFER_SIZE;
761 in_mpx_max = smbXcli_conn_max_requests(state->cli->conn);
762 in_vc_num = cli_state_get_vc_num(state->cli);
763 in_sess_key = smb1cli_conn_server_session_key(state->cli->conn);
764 in_capabilities = cli_session_setup_capabilities(state->cli,
765 CAP_EXTENDED_SECURITY);
766 in_native_os = "Unix";
767 in_native_lm = "Samba";
770 * For now we keep the same values as before,
771 * we may remove these in a separate commit later.
777 subreq = smb1cli_session_setup_ext_send(state, state->ev,
780 state->cli->smb1.pid,
781 state->cli->smb1.session,
790 if (subreq == NULL) {
798 static void cli_sesssetup_blob_done(struct tevent_req *subreq)
800 struct tevent_req *req = tevent_req_callback_data(
801 subreq, struct tevent_req);
802 struct cli_sesssetup_blob_state *state = tevent_req_data(
803 req, struct cli_sesssetup_blob_state);
806 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
807 status = smb2cli_session_setup_recv(subreq, state,
811 status = smb1cli_session_setup_ext_recv(subreq, state,
815 &state->out_native_os,
816 &state->out_native_lm);
819 if (!NT_STATUS_IS_OK(status)
820 && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
821 tevent_req_nterror(req, status);
825 state->status = status;
827 status = cli_state_update_after_sesssetup(state->cli,
828 state->out_native_os,
829 state->out_native_lm,
831 if (tevent_req_nterror(req, status)) {
835 if (state->blob.length != 0) {
839 if (!cli_sesssetup_blob_next(state, &subreq)) {
843 tevent_req_set_callback(subreq, cli_sesssetup_blob_done, req);
846 tevent_req_done(req);
849 static NTSTATUS cli_sesssetup_blob_recv(struct tevent_req *req,
852 const uint8_t **pinbuf,
853 struct iovec **precv_iov)
855 struct cli_sesssetup_blob_state *state = tevent_req_data(
856 req, struct cli_sesssetup_blob_state);
858 struct iovec *recv_iov;
860 if (tevent_req_is_nterror(req, &status)) {
861 TALLOC_FREE(state->cli->smb2.session);
862 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
863 tevent_req_received(req);
867 recv_iov = talloc_move(mem_ctx, &state->recv_iov);
869 *pblob = state->ret_blob;
871 if (pinbuf != NULL) {
872 *pinbuf = state->inbuf;
874 if (precv_iov != NULL) {
875 *precv_iov = recv_iov;
877 /* could be NT_STATUS_MORE_PROCESSING_REQUIRED */
878 status = state->status;
879 tevent_req_received(req);
883 /****************************************************************************
884 Do a spnego/NTLMSSP encrypted session setup.
885 ****************************************************************************/
887 struct cli_session_setup_gensec_state {
888 struct tevent_context *ev;
889 struct cli_state *cli;
890 struct auth_generic_state *auth_generic;
893 const uint8_t *inbuf;
894 struct iovec *recv_iov;
898 DATA_BLOB session_key;
901 static int cli_session_setup_gensec_state_destructor(
902 struct cli_session_setup_gensec_state *state)
904 TALLOC_FREE(state->auth_generic);
905 data_blob_clear_free(&state->session_key);
909 static void cli_session_setup_gensec_local_next(struct tevent_req *req);
910 static void cli_session_setup_gensec_local_done(struct tevent_req *subreq);
911 static void cli_session_setup_gensec_remote_next(struct tevent_req *req);
912 static void cli_session_setup_gensec_remote_done(struct tevent_req *subreq);
913 static void cli_session_setup_gensec_ready(struct tevent_req *req);
915 static struct tevent_req *cli_session_setup_gensec_send(
916 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
917 struct cli_credentials *creds,
918 const char *target_service,
919 const char *target_hostname)
921 struct tevent_req *req;
922 struct cli_session_setup_gensec_state *state;
924 const DATA_BLOB *b = NULL;
926 req = tevent_req_create(mem_ctx, &state,
927 struct cli_session_setup_gensec_state);
934 talloc_set_destructor(
935 state, cli_session_setup_gensec_state_destructor);
937 status = auth_generic_client_prepare(state, &state->auth_generic);
938 if (tevent_req_nterror(req, status)) {
939 return tevent_req_post(req, ev);
942 status = auth_generic_set_creds(state->auth_generic, creds);
943 if (tevent_req_nterror(req, status)) {
944 return tevent_req_post(req, ev);
947 gensec_want_feature(state->auth_generic->gensec_security,
948 GENSEC_FEATURE_SESSION_KEY);
950 if (target_service != NULL) {
951 status = gensec_set_target_service(
952 state->auth_generic->gensec_security,
954 if (tevent_req_nterror(req, status)) {
955 return tevent_req_post(req, ev);
959 if (target_hostname != NULL) {
960 status = gensec_set_target_hostname(
961 state->auth_generic->gensec_security,
963 if (tevent_req_nterror(req, status)) {
964 return tevent_req_post(req, ev);
968 b = smbXcli_conn_server_gss_blob(cli->conn);
973 state->is_anonymous = cli_credentials_is_anonymous(state->auth_generic->credentials);
975 status = auth_generic_client_start(state->auth_generic,
977 if (tevent_req_nterror(req, status)) {
978 return tevent_req_post(req, ev);
981 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
982 state->cli->smb2.session = smbXcli_session_create(cli,
984 if (tevent_req_nomem(state->cli->smb2.session, req)) {
985 return tevent_req_post(req, ev);
989 cli_session_setup_gensec_local_next(req);
990 if (!tevent_req_is_in_progress(req)) {
991 return tevent_req_post(req, ev);
997 static void cli_session_setup_gensec_local_next(struct tevent_req *req)
999 struct cli_session_setup_gensec_state *state =
1000 tevent_req_data(req,
1001 struct cli_session_setup_gensec_state);
1002 struct tevent_req *subreq = NULL;
1004 if (state->local_ready) {
1005 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1009 subreq = gensec_update_send(state, state->ev,
1010 state->auth_generic->gensec_security,
1012 if (tevent_req_nomem(subreq, req)) {
1015 tevent_req_set_callback(subreq, cli_session_setup_gensec_local_done, req);
1018 static void cli_session_setup_gensec_local_done(struct tevent_req *subreq)
1020 struct tevent_req *req =
1021 tevent_req_callback_data(subreq,
1023 struct cli_session_setup_gensec_state *state =
1024 tevent_req_data(req,
1025 struct cli_session_setup_gensec_state);
1028 status = gensec_update_recv(subreq, state, &state->blob_out);
1029 TALLOC_FREE(subreq);
1030 state->blob_in = data_blob_null;
1031 if (!NT_STATUS_IS_OK(status) &&
1032 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
1034 tevent_req_nterror(req, status);
1038 if (NT_STATUS_IS_OK(status)) {
1039 state->local_ready = true;
1042 if (state->local_ready && state->remote_ready) {
1043 cli_session_setup_gensec_ready(req);
1047 cli_session_setup_gensec_remote_next(req);
1050 static void cli_session_setup_gensec_remote_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->remote_ready) {
1058 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1062 subreq = cli_sesssetup_blob_send(state, state->ev,
1063 state->cli, state->blob_out);
1064 if (tevent_req_nomem(subreq, req)) {
1067 tevent_req_set_callback(subreq,
1068 cli_session_setup_gensec_remote_done,
1072 static void cli_session_setup_gensec_remote_done(struct tevent_req *subreq)
1074 struct tevent_req *req =
1075 tevent_req_callback_data(subreq,
1077 struct cli_session_setup_gensec_state *state =
1078 tevent_req_data(req,
1079 struct cli_session_setup_gensec_state);
1082 state->inbuf = NULL;
1083 TALLOC_FREE(state->recv_iov);
1085 status = cli_sesssetup_blob_recv(subreq, state, &state->blob_in,
1086 &state->inbuf, &state->recv_iov);
1087 TALLOC_FREE(subreq);
1088 data_blob_free(&state->blob_out);
1089 if (!NT_STATUS_IS_OK(status) &&
1090 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
1092 tevent_req_nterror(req, status);
1096 if (NT_STATUS_IS_OK(status)) {
1097 struct smbXcli_session *session = NULL;
1098 bool is_guest = false;
1100 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
1101 session = state->cli->smb2.session;
1103 session = state->cli->smb1.session;
1106 is_guest = smbXcli_session_is_guest(session);
1109 * We can't finish the gensec handshake, we don't
1110 * have a negotiated session key.
1112 * So just pretend we are completely done,
1113 * we need to continue as anonymous from this point,
1114 * as we can't get a session key.
1116 * Note that smbXcli_session_is_guest()
1117 * always returns false if we require signing.
1119 state->blob_in = data_blob_null;
1120 state->local_ready = true;
1121 state->is_anonymous = true;
1124 state->remote_ready = true;
1127 if (state->local_ready && state->remote_ready) {
1128 cli_session_setup_gensec_ready(req);
1132 cli_session_setup_gensec_local_next(req);
1135 static void cli_session_dump_keys(TALLOC_CTX *mem_ctx,
1136 struct smbXcli_session *session,
1137 DATA_BLOB session_key)
1140 DATA_BLOB sig = data_blob_null;
1141 DATA_BLOB app = data_blob_null;
1142 DATA_BLOB enc = data_blob_null;
1143 DATA_BLOB dec = data_blob_null;
1144 uint64_t sid = smb2cli_session_current_id(session);
1146 status = smb2cli_session_signing_key(session, mem_ctx, &sig);
1147 if (!NT_STATUS_IS_OK(status)) {
1150 status = smbXcli_session_application_key(session, mem_ctx, &app);
1151 if (!NT_STATUS_IS_OK(status)) {
1154 status = smb2cli_session_encryption_key(session, mem_ctx, &enc);
1155 if (!NT_STATUS_IS_OK(status)) {
1158 status = smb2cli_session_decryption_key(session, mem_ctx, &dec);
1159 if (!NT_STATUS_IS_OK(status)) {
1163 DEBUG(0, ("debug encryption: dumping generated session keys\n"));
1164 DEBUGADD(0, ("Session Id "));
1165 dump_data(0, (uint8_t*)&sid, sizeof(sid));
1166 DEBUGADD(0, ("Session Key "));
1167 dump_data(0, session_key.data, session_key.length);
1168 DEBUGADD(0, ("Signing Key "));
1169 dump_data(0, sig.data, sig.length);
1170 DEBUGADD(0, ("App Key "));
1171 dump_data(0, app.data, app.length);
1173 /* In client code, ServerIn is the encryption key */
1175 DEBUGADD(0, ("ServerIn Key "));
1176 dump_data(0, enc.data, enc.length);
1177 DEBUGADD(0, ("ServerOut Key "));
1178 dump_data(0, dec.data, dec.length);
1181 data_blob_clear_free(&sig);
1182 data_blob_clear_free(&app);
1183 data_blob_clear_free(&enc);
1184 data_blob_clear_free(&dec);
1187 static void cli_session_setup_gensec_ready(struct tevent_req *req)
1189 struct cli_session_setup_gensec_state *state =
1190 tevent_req_data(req,
1191 struct cli_session_setup_gensec_state);
1192 const char *server_domain = NULL;
1195 if (state->blob_in.length != 0) {
1196 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1200 if (state->blob_out.length != 0) {
1201 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1206 * gensec_ntlmssp_server_domain() returns NULL
1207 * if NTLMSSP is not used.
1209 * We can remove this later
1210 * and leave the server domain empty for SMB2 and above
1211 * in future releases.
1213 server_domain = gensec_ntlmssp_server_domain(
1214 state->auth_generic->gensec_security);
1216 if (state->cli->server_domain[0] == '\0' && server_domain != NULL) {
1217 TALLOC_FREE(state->cli->server_domain);
1218 state->cli->server_domain = talloc_strdup(state->cli,
1220 if (state->cli->server_domain == NULL) {
1221 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1226 if (state->is_anonymous) {
1228 * Windows server does not set the
1229 * SMB2_SESSION_FLAG_IS_NULL flag.
1231 * This fix makes sure we do not try
1232 * to verify a signature on the final
1233 * session setup response.
1235 tevent_req_done(req);
1239 status = gensec_session_key(state->auth_generic->gensec_security,
1240 state, &state->session_key);
1241 if (tevent_req_nterror(req, status)) {
1245 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
1246 struct smbXcli_session *session = state->cli->smb2.session;
1248 status = smb2cli_session_set_session_key(session,
1251 if (tevent_req_nterror(req, status)) {
1254 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB3_00
1255 && lp_debug_encryption())
1257 cli_session_dump_keys(state, session, state->session_key);
1260 struct smbXcli_session *session = state->cli->smb1.session;
1263 status = smb1cli_session_set_session_key(session,
1264 state->session_key);
1265 if (tevent_req_nterror(req, status)) {
1269 active = smb1cli_conn_activate_signing(state->cli->conn,
1275 ok = smb1cli_conn_check_signing(state->cli->conn,
1278 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1284 tevent_req_done(req);
1287 static NTSTATUS cli_session_setup_gensec_recv(struct tevent_req *req)
1289 struct cli_session_setup_gensec_state *state =
1290 tevent_req_data(req,
1291 struct cli_session_setup_gensec_state);
1294 if (tevent_req_is_nterror(req, &status)) {
1295 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
1298 return NT_STATUS_OK;
1301 static char *cli_session_setup_get_account(TALLOC_CTX *mem_ctx,
1302 const char *principal)
1306 account = talloc_strdup(mem_ctx, principal);
1307 if (account == NULL) {
1310 p = strchr_m(account, '@');
1317 /****************************************************************************
1318 Do a spnego encrypted session setup.
1320 user_domain: The shortname of the domain the user/machine is a member of.
1321 dest_realm: The realm we're connecting to, if NULL we use our default realm.
1322 ****************************************************************************/
1324 struct cli_session_setup_spnego_state {
1328 static void cli_session_setup_spnego_done(struct tevent_req *subreq);
1330 static struct tevent_req *cli_session_setup_spnego_send(
1331 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
1332 struct cli_credentials *creds)
1334 struct tevent_req *req, *subreq;
1335 struct cli_session_setup_spnego_state *state;
1336 const char *target_service = NULL;
1337 const char *target_hostname = NULL;
1340 req = tevent_req_create(mem_ctx, &state,
1341 struct cli_session_setup_spnego_state);
1346 target_service = "cifs";
1347 target_hostname = smbXcli_conn_remote_name(cli->conn);
1349 status = cli_session_creds_prepare_krb5(cli, creds);
1350 if (tevent_req_nterror(req, status)) {
1351 return tevent_req_post(req, ev);
1354 subreq = cli_session_setup_gensec_send(state, ev, cli, creds,
1355 target_service, target_hostname);
1356 if (tevent_req_nomem(subreq, req)) {
1357 return tevent_req_post(req, ev);
1359 tevent_req_set_callback(
1360 subreq, cli_session_setup_spnego_done, req);
1364 static void cli_session_setup_spnego_done(struct tevent_req *subreq)
1366 struct tevent_req *req = tevent_req_callback_data(
1367 subreq, struct tevent_req);
1370 status = cli_session_setup_gensec_recv(subreq);
1371 TALLOC_FREE(subreq);
1372 if (tevent_req_nterror(req, status)) {
1376 tevent_req_done(req);
1379 static ADS_STATUS cli_session_setup_spnego_recv(struct tevent_req *req)
1381 struct cli_session_setup_spnego_state *state = tevent_req_data(
1382 req, struct cli_session_setup_spnego_state);
1385 if (tevent_req_is_nterror(req, &status)) {
1386 state->result = ADS_ERROR_NT(status);
1389 return state->result;
1392 struct cli_session_setup_creds_state {
1393 struct cli_state *cli;
1394 DATA_BLOB apassword_blob;
1395 DATA_BLOB upassword_blob;
1396 DATA_BLOB lm_session_key;
1397 DATA_BLOB session_key;
1398 char *out_native_os;
1399 char *out_native_lm;
1400 char *out_primary_domain;
1403 static void cli_session_setup_creds_cleanup(struct tevent_req *req,
1404 enum tevent_req_state req_state)
1406 struct cli_session_setup_creds_state *state = tevent_req_data(
1407 req, struct cli_session_setup_creds_state);
1409 if (req_state != TEVENT_REQ_RECEIVED) {
1414 * We only call data_blob_clear() as
1415 * some of the blobs point to the same memory.
1417 * We let the talloc hierachy free the memory.
1419 data_blob_clear(&state->apassword_blob);
1420 data_blob_clear(&state->upassword_blob);
1421 data_blob_clear(&state->lm_session_key);
1422 data_blob_clear(&state->session_key);
1423 ZERO_STRUCTP(state);
1426 static void cli_session_setup_creds_done_spnego(struct tevent_req *subreq);
1427 static void cli_session_setup_creds_done_nt1(struct tevent_req *subreq);
1428 static void cli_session_setup_creds_done_lm21(struct tevent_req *subreq);
1430 /****************************************************************************
1431 Send a session setup. The username and workgroup is in UNIX character
1432 format and must be converted to DOS codepage format before sending. If the
1433 password is in plaintext, the same should be done.
1434 ****************************************************************************/
1436 struct tevent_req *cli_session_setup_creds_send(TALLOC_CTX *mem_ctx,
1437 struct tevent_context *ev,
1438 struct cli_state *cli,
1439 struct cli_credentials *creds)
1441 struct tevent_req *req, *subreq;
1442 struct cli_session_setup_creds_state *state;
1443 uint16_t sec_mode = smb1cli_conn_server_security_mode(cli->conn);
1444 bool use_spnego = false;
1446 enum credentials_use_kerberos krb5_state;
1447 uint32_t gensec_features;
1448 const char *username = "";
1449 const char *domain = "";
1450 DATA_BLOB target_info = data_blob_null;
1451 DATA_BLOB challenge = data_blob_null;
1452 uint16_t in_buf_size = 0;
1453 uint16_t in_mpx_max = 0;
1454 uint16_t in_vc_num = 0;
1455 uint32_t in_sess_key = 0;
1456 const char *in_native_os = NULL;
1457 const char *in_native_lm = NULL;
1460 req = tevent_req_create(mem_ctx, &state,
1461 struct cli_session_setup_creds_state);
1467 tevent_req_set_cleanup_fn(req, cli_session_setup_creds_cleanup);
1469 krb5_state = cli_credentials_get_kerberos_state(creds);
1470 gensec_features = cli_credentials_get_gensec_features(creds);
1472 switch (krb5_state) {
1473 case CRED_MUST_USE_KERBEROS:
1474 cli->use_kerberos = true;
1475 cli->fallback_after_kerberos = false;
1477 case CRED_AUTO_USE_KERBEROS:
1478 cli->use_kerberos = true;
1479 cli->fallback_after_kerberos = true;
1481 case CRED_DONT_USE_KERBEROS:
1482 cli->use_kerberos = false;
1483 cli->fallback_after_kerberos = false;
1487 if (gensec_features & GENSEC_FEATURE_NTLM_CCACHE) {
1488 cli->use_ccache = true;
1490 cli->use_ccache = false;
1494 * Now work out what sort of session setup we are going to
1495 * do. I have split this into separate functions to make the flow a bit
1496 * easier to understand (tridge).
1498 if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_NT1) {
1500 } else if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
1502 } else if (smb1cli_conn_capabilities(cli->conn) & CAP_EXTENDED_SECURITY) {
1504 * if the server supports extended security then use SPNEGO
1505 * even for anonymous connections.
1513 subreq = cli_session_setup_spnego_send(
1514 state, ev, cli, creds);
1515 if (tevent_req_nomem(subreq, req)) {
1516 return tevent_req_post(req, ev);
1518 tevent_req_set_callback(subreq, cli_session_setup_creds_done_spnego,
1523 if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_LANMAN1) {
1525 * SessionSetupAndX was introduced by LANMAN 1.0. So we skip
1526 * this step against older servers.
1528 tevent_req_done(req);
1529 return tevent_req_post(req, ev);
1532 if (cli_credentials_is_anonymous(creds)) {
1534 * Do an anonymous session setup
1536 goto non_spnego_creds_done;
1539 if ((sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0) {
1541 * Do an anonymous session setup,
1542 * the password is passed via the tree connect.
1544 goto non_spnego_creds_done;
1547 cli_credentials_get_ntlm_username_domain(creds, state,
1550 if (tevent_req_nomem(username, req)) {
1551 return tevent_req_post(req, ev);
1553 if (tevent_req_nomem(domain, req)) {
1554 return tevent_req_post(req, ev);
1557 if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) {
1558 bool use_unicode = smbXcli_conn_use_unicode(cli->conn);
1559 uint8_t *bytes = NULL;
1560 size_t bytes_len = 0;
1561 const char *pw = cli_credentials_get_password(creds);
1567 pw_len = strlen(pw) + 1;
1569 if (!lp_client_plaintext_auth()) {
1570 DEBUG(1, ("Server requested PLAINTEXT password but "
1571 "'client plaintext auth = no'\n"));
1572 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1573 return tevent_req_post(req, ev);
1576 bytes = talloc_array(state, uint8_t, 0);
1577 bytes = trans2_bytes_push_str(bytes, use_unicode,
1578 pw, pw_len, &bytes_len);
1579 if (tevent_req_nomem(bytes, req)) {
1580 return tevent_req_post(req, ev);
1585 * CAP_UNICODE, can only be negotiated by NT1.
1587 state->upassword_blob = data_blob_const(bytes,
1590 state->apassword_blob = data_blob_const(bytes,
1594 goto non_spnego_creds_done;
1597 challenge = data_blob_const(smb1cli_conn_server_challenge(cli->conn), 8);
1599 if (smbXcli_conn_protocol(cli->conn) == PROTOCOL_NT1) {
1600 if (lp_client_ntlmv2_auth() && lp_client_use_spnego()) {
1602 * Don't send an NTLMv2 response without NTLMSSP if we
1603 * want to use spnego support.
1605 DEBUG(1, ("Server does not support EXTENDED_SECURITY "
1606 " but 'client use spnego = yes'"
1607 " and 'client ntlmv2 auth = yes' is set\n"));
1608 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1609 return tevent_req_post(req, ev);
1612 if (lp_client_ntlmv2_auth()) {
1613 flags |= CLI_CRED_NTLMv2_AUTH;
1616 * note that the 'domain' here is a best
1617 * guess - we don't know the server's domain
1618 * at this point. Windows clients also don't
1621 target_info = NTLMv2_generate_names_blob(state,
1624 if (tevent_req_nomem(target_info.data, req)) {
1625 return tevent_req_post(req, ev);
1628 flags |= CLI_CRED_NTLM_AUTH;
1629 if (lp_client_lanman_auth()) {
1630 flags |= CLI_CRED_LANMAN_AUTH;
1634 if (!lp_client_lanman_auth()) {
1635 DEBUG(1, ("Server requested user level LM password but "
1636 "'client lanman auth = no' is set.\n"));
1637 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1638 return tevent_req_post(req, ev);
1641 flags |= CLI_CRED_LANMAN_AUTH;
1644 status = cli_credentials_get_ntlm_response(creds, state, &flags,
1647 &state->apassword_blob,
1648 &state->upassword_blob,
1649 &state->lm_session_key,
1650 &state->session_key);
1651 if (tevent_req_nterror(req, status)) {
1652 return tevent_req_post(req, ev);
1655 non_spnego_creds_done:
1657 in_buf_size = CLI_BUFFER_SIZE;
1658 in_mpx_max = smbXcli_conn_max_requests(cli->conn);
1659 in_vc_num = cli_state_get_vc_num(cli);
1660 in_sess_key = smb1cli_conn_server_session_key(cli->conn);
1661 in_native_os = "Unix";
1662 in_native_lm = "Samba";
1664 if (smbXcli_conn_protocol(cli->conn) == PROTOCOL_NT1) {
1665 uint32_t in_capabilities = 0;
1667 in_capabilities = cli_session_setup_capabilities(cli, 0);
1670 * For now we keep the same values as before,
1671 * we may remove these in a separate commit later.
1675 subreq = smb1cli_session_setup_nt1_send(state, ev,
1686 state->apassword_blob,
1687 state->upassword_blob,
1691 if (tevent_req_nomem(subreq, req)) {
1692 return tevent_req_post(req, ev);
1694 tevent_req_set_callback(subreq, cli_session_setup_creds_done_nt1,
1700 * For now we keep the same values as before,
1701 * we may remove these in a separate commit later.
1706 subreq = smb1cli_session_setup_lm21_send(state, ev,
1717 state->apassword_blob,
1720 if (tevent_req_nomem(subreq, req)) {
1721 return tevent_req_post(req, ev);
1723 tevent_req_set_callback(subreq, cli_session_setup_creds_done_lm21,
1728 static void cli_session_setup_creds_done_spnego(struct tevent_req *subreq)
1730 struct tevent_req *req = tevent_req_callback_data(
1731 subreq, struct tevent_req);
1734 status = cli_session_setup_spnego_recv(subreq);
1735 TALLOC_FREE(subreq);
1736 if (!ADS_ERR_OK(status)) {
1737 DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status)));
1738 tevent_req_nterror(req, ads_ntstatus(status));
1741 tevent_req_done(req);
1744 static void cli_session_setup_creds_done_nt1(struct tevent_req *subreq)
1746 struct tevent_req *req = tevent_req_callback_data(
1747 subreq, struct tevent_req);
1748 struct cli_session_setup_creds_state *state = tevent_req_data(
1749 req, struct cli_session_setup_creds_state);
1750 struct cli_state *cli = state->cli;
1752 struct iovec *recv_iov = NULL;
1753 const uint8_t *inbuf = NULL;
1756 status = smb1cli_session_setup_nt1_recv(subreq, state,
1759 &state->out_native_os,
1760 &state->out_native_lm,
1761 &state->out_primary_domain);
1762 TALLOC_FREE(subreq);
1763 if (!NT_STATUS_IS_OK(status)) {
1764 DEBUG(3, ("NT1 login failed: %s\n", nt_errstr(status)));
1765 tevent_req_nterror(req, status);
1769 status = cli_state_update_after_sesssetup(state->cli,
1770 state->out_native_os,
1771 state->out_native_lm,
1772 state->out_primary_domain);
1773 if (tevent_req_nterror(req, status)) {
1777 ok = smb1cli_conn_activate_signing(cli->conn,
1779 state->upassword_blob);
1781 ok = smb1cli_conn_check_signing(cli->conn, inbuf, 1);
1783 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1788 if (state->session_key.data) {
1789 struct smbXcli_session *session = cli->smb1.session;
1791 status = smb1cli_session_set_session_key(session,
1792 state->session_key);
1793 if (tevent_req_nterror(req, status)) {
1798 tevent_req_done(req);
1801 static void cli_session_setup_creds_done_lm21(struct tevent_req *subreq)
1803 struct tevent_req *req = tevent_req_callback_data(
1804 subreq, struct tevent_req);
1805 struct cli_session_setup_creds_state *state = tevent_req_data(
1806 req, struct cli_session_setup_creds_state);
1809 status = smb1cli_session_setup_lm21_recv(subreq, state,
1810 &state->out_native_os,
1811 &state->out_native_lm);
1812 TALLOC_FREE(subreq);
1813 if (!NT_STATUS_IS_OK(status)) {
1814 DEBUG(3, ("LM21 login failed: %s\n", nt_errstr(status)));
1815 tevent_req_nterror(req, status);
1819 status = cli_state_update_after_sesssetup(state->cli,
1820 state->out_native_os,
1821 state->out_native_lm,
1823 if (tevent_req_nterror(req, status)) {
1827 tevent_req_done(req);
1830 NTSTATUS cli_session_setup_creds_recv(struct tevent_req *req)
1832 return tevent_req_simple_recv_ntstatus(req);
1835 NTSTATUS cli_session_setup_creds(struct cli_state *cli,
1836 struct cli_credentials *creds)
1838 struct tevent_context *ev;
1839 struct tevent_req *req;
1840 NTSTATUS status = NT_STATUS_NO_MEMORY;
1842 if (smbXcli_conn_has_async_calls(cli->conn)) {
1843 return NT_STATUS_INVALID_PARAMETER;
1845 ev = samba_tevent_context_init(talloc_tos());
1849 req = cli_session_setup_creds_send(ev, ev, cli, creds);
1853 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1856 status = cli_session_setup_creds_recv(req);
1862 NTSTATUS cli_session_setup_anon(struct cli_state *cli)
1864 NTSTATUS status = NT_STATUS_NO_MEMORY;
1865 struct cli_credentials *creds = NULL;
1867 creds = cli_credentials_init_anon(cli);
1868 if (creds == NULL) {
1869 return NT_STATUS_NO_MEMORY;
1872 status = cli_session_setup_creds(cli, creds);
1874 if (!NT_STATUS_IS_OK(status)) {
1878 return NT_STATUS_OK;
1881 /****************************************************************************
1883 *****************************************************************************/
1885 struct cli_ulogoff_state {
1886 struct cli_state *cli;
1890 static void cli_ulogoff_done(struct tevent_req *subreq);
1892 static struct tevent_req *cli_ulogoff_send(TALLOC_CTX *mem_ctx,
1893 struct tevent_context *ev,
1894 struct cli_state *cli)
1896 struct tevent_req *req, *subreq;
1897 struct cli_ulogoff_state *state;
1899 req = tevent_req_create(mem_ctx, &state, struct cli_ulogoff_state);
1905 SCVAL(state->vwv+0, 0, 0xFF);
1906 SCVAL(state->vwv+1, 0, 0);
1907 SSVAL(state->vwv+2, 0, 0);
1909 subreq = cli_smb_send(state, ev, cli, SMBulogoffX, 0, 0, 2, state->vwv,
1911 if (tevent_req_nomem(subreq, req)) {
1912 return tevent_req_post(req, ev);
1914 tevent_req_set_callback(subreq, cli_ulogoff_done, req);
1918 static void cli_ulogoff_done(struct tevent_req *subreq)
1920 struct tevent_req *req = tevent_req_callback_data(
1921 subreq, struct tevent_req);
1922 struct cli_ulogoff_state *state = tevent_req_data(
1923 req, struct cli_ulogoff_state);
1926 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
1927 if (!NT_STATUS_IS_OK(status)) {
1928 tevent_req_nterror(req, status);
1931 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
1932 tevent_req_done(req);
1935 static NTSTATUS cli_ulogoff_recv(struct tevent_req *req)
1937 return tevent_req_simple_recv_ntstatus(req);
1940 NTSTATUS cli_ulogoff(struct cli_state *cli)
1942 struct tevent_context *ev;
1943 struct tevent_req *req;
1944 NTSTATUS status = NT_STATUS_NO_MEMORY;
1946 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
1947 status = smb2cli_logoff(cli->conn,
1950 if (!NT_STATUS_IS_OK(status)) {
1953 smb2cli_session_set_id_and_flags(cli->smb2.session,
1955 return NT_STATUS_OK;
1958 if (smbXcli_conn_has_async_calls(cli->conn)) {
1959 return NT_STATUS_INVALID_PARAMETER;
1961 ev = samba_tevent_context_init(talloc_tos());
1965 req = cli_ulogoff_send(ev, ev, cli);
1969 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1972 status = cli_ulogoff_recv(req);
1978 /****************************************************************************
1980 ****************************************************************************/
1982 struct cli_tcon_andx_state {
1983 struct cli_state *cli;
1988 static void cli_tcon_andx_done(struct tevent_req *subreq);
1990 struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx,
1991 struct tevent_context *ev,
1992 struct cli_state *cli,
1993 const char *share, const char *dev,
1994 const char *pass, int passlen,
1995 struct tevent_req **psmbreq)
1997 struct tevent_req *req, *subreq;
1998 struct cli_tcon_andx_state *state;
2003 uint16_t sec_mode = smb1cli_conn_server_security_mode(cli->conn);
2004 uint16_t tcon_flags = 0;
2008 req = tevent_req_create(mem_ctx, &state, struct cli_tcon_andx_state);
2015 TALLOC_FREE(cli->smb1.tcon);
2016 cli->smb1.tcon = smbXcli_tcon_create(cli);
2017 if (tevent_req_nomem(cli->smb1.tcon, req)) {
2018 return tevent_req_post(req, ev);
2020 smb1cli_tcon_set_id(cli->smb1.tcon, UINT16_MAX);
2022 cli->share = talloc_strdup(cli, share);
2027 /* in user level security don't send a password now */
2028 if (sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {
2031 } else if (pass == NULL) {
2032 DEBUG(1, ("Server not using user level security and no "
2033 "password supplied.\n"));
2037 if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) &&
2038 *pass && passlen != 24) {
2039 if (!lp_client_lanman_auth()) {
2040 DEBUG(1, ("Server requested LANMAN password "
2041 "(share-level security) but "
2042 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2047 * Non-encrypted passwords - convert to DOS codepage before
2050 SMBencrypt(pass, smb1cli_conn_server_challenge(cli->conn), p24);
2052 pass = (const char *)p24;
2054 if((sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL
2055 |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE))
2059 if (!lp_client_plaintext_auth() && (*pass)) {
2060 DEBUG(1, ("Server requested PLAINTEXT "
2062 "'client plaintext auth = no' or 'client ntlmv2 auth = yes'\n"));
2067 * Non-encrypted passwords - convert to DOS codepage
2070 tmp_pass = talloc_array(talloc_tos(), uint8_t, 0);
2071 if (tevent_req_nomem(tmp_pass, req)) {
2072 return tevent_req_post(req, ev);
2074 tmp_pass = trans2_bytes_push_str(tmp_pass,
2075 false, /* always DOS */
2079 if (tevent_req_nomem(tmp_pass, req)) {
2080 return tevent_req_post(req, ev);
2082 pass = (const char *)tmp_pass;
2083 passlen = talloc_get_size(tmp_pass);
2087 tcon_flags |= TCONX_FLAG_EXTENDED_RESPONSE;
2088 tcon_flags |= TCONX_FLAG_EXTENDED_SIGNATURES;
2090 SCVAL(vwv+0, 0, 0xFF);
2093 SSVAL(vwv+2, 0, tcon_flags);
2094 SSVAL(vwv+3, 0, passlen);
2096 if (passlen && pass) {
2097 bytes = (uint8_t *)talloc_memdup(state, pass, passlen);
2099 bytes = talloc_array(state, uint8_t, 0);
2105 tmp = talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
2106 smbXcli_conn_remote_name(cli->conn), share);
2111 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), tmp, strlen(tmp)+1,
2116 * Add the devicetype
2118 tmp = talloc_strdup_upper(talloc_tos(), dev);
2123 bytes = smb_bytes_push_str(bytes, false, tmp, strlen(tmp)+1, NULL);
2126 if (bytes == NULL) {
2131 state->bytes.iov_base = (void *)bytes;
2132 state->bytes.iov_len = talloc_get_size(bytes);
2134 subreq = cli_smb_req_create(state, ev, cli, SMBtconX, 0, 0, 4, vwv,
2136 if (subreq == NULL) {
2140 tevent_req_set_callback(subreq, cli_tcon_andx_done, req);
2145 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
2146 return tevent_req_post(req, ev);
2149 struct tevent_req *cli_tcon_andx_send(TALLOC_CTX *mem_ctx,
2150 struct tevent_context *ev,
2151 struct cli_state *cli,
2152 const char *share, const char *dev,
2153 const char *pass, int passlen)
2155 struct tevent_req *req, *subreq;
2158 req = cli_tcon_andx_create(mem_ctx, ev, cli, share, dev, pass, passlen,
2163 if (subreq == NULL) {
2166 status = smb1cli_req_chain_submit(&subreq, 1);
2167 if (!NT_STATUS_IS_OK(status)) {
2168 tevent_req_nterror(req, status);
2169 return tevent_req_post(req, ev);
2174 static void cli_tcon_andx_done(struct tevent_req *subreq)
2176 struct tevent_req *req = tevent_req_callback_data(
2177 subreq, struct tevent_req);
2178 struct cli_tcon_andx_state *state = tevent_req_data(
2179 req, struct cli_tcon_andx_state);
2180 struct cli_state *cli = state->cli;
2188 uint16_t optional_support = 0;
2190 status = cli_smb_recv(subreq, state, &in, 0, &wct, &vwv,
2191 &num_bytes, &bytes);
2192 TALLOC_FREE(subreq);
2193 if (!NT_STATUS_IS_OK(status)) {
2194 tevent_req_nterror(req, status);
2198 inhdr = in + NBT_HDR_SIZE;
2201 if (clistr_pull_talloc(cli,
2202 (const char *)inhdr,
2203 SVAL(inhdr, HDR_FLG2),
2207 STR_TERMINATE|STR_ASCII) == -1) {
2208 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2212 cli->dev = talloc_strdup(cli, "");
2213 if (cli->dev == NULL) {
2214 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2219 if ((smbXcli_conn_protocol(cli->conn) >= PROTOCOL_NT1) && (num_bytes == 3)) {
2220 /* almost certainly win95 - enable bug fixes */
2225 * Make sure that we have the optional support 16-bit field. WCT > 2.
2226 * Avoids issues when connecting to Win9x boxes sharing files
2229 if ((wct > 2) && (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_LANMAN2)) {
2230 optional_support = SVAL(vwv+2, 0);
2233 if (optional_support & SMB_EXTENDED_SIGNATURES) {
2234 smb1cli_session_protect_session_key(cli->smb1.session);
2237 smb1cli_tcon_set_values(state->cli->smb1.tcon,
2238 SVAL(inhdr, HDR_TID),
2240 0, /* maximal_access */
2241 0, /* guest_maximal_access */
2243 NULL); /* fs_type */
2245 tevent_req_done(req);
2248 NTSTATUS cli_tcon_andx_recv(struct tevent_req *req)
2250 return tevent_req_simple_recv_ntstatus(req);
2253 NTSTATUS cli_tcon_andx(struct cli_state *cli, const char *share,
2254 const char *dev, const char *pass, int passlen)
2256 TALLOC_CTX *frame = talloc_stackframe();
2257 struct tevent_context *ev;
2258 struct tevent_req *req;
2259 NTSTATUS status = NT_STATUS_NO_MEMORY;
2261 if (smbXcli_conn_has_async_calls(cli->conn)) {
2263 * Can't use sync call while an async call is in flight
2265 status = NT_STATUS_INVALID_PARAMETER;
2269 ev = samba_tevent_context_init(frame);
2274 req = cli_tcon_andx_send(frame, ev, cli, share, dev, pass, passlen);
2279 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2283 status = cli_tcon_andx_recv(req);
2289 struct cli_tree_connect_state {
2290 struct cli_state *cli;
2293 static struct tevent_req *cli_raw_tcon_send(
2294 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
2295 const char *service, const char *pass, const char *dev);
2296 static NTSTATUS cli_raw_tcon_recv(struct tevent_req *req,
2297 uint16_t *max_xmit, uint16_t *tid);
2299 static void cli_tree_connect_smb2_done(struct tevent_req *subreq);
2300 static void cli_tree_connect_andx_done(struct tevent_req *subreq);
2301 static void cli_tree_connect_raw_done(struct tevent_req *subreq);
2303 static struct tevent_req *cli_tree_connect_send(
2304 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
2305 const char *share, const char *dev, const char *pass)
2307 struct tevent_req *req, *subreq;
2308 struct cli_tree_connect_state *state;
2314 passlen = strlen(pass) + 1;
2316 req = tevent_req_create(mem_ctx, &state,
2317 struct cli_tree_connect_state);
2323 cli->share = talloc_strdup(cli, share);
2324 if (tevent_req_nomem(cli->share, req)) {
2325 return tevent_req_post(req, ev);
2328 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
2331 TALLOC_FREE(cli->smb2.tcon);
2332 cli->smb2.tcon = smbXcli_tcon_create(cli);
2333 if (tevent_req_nomem(cli->smb2.tcon, req)) {
2334 return tevent_req_post(req, ev);
2337 unc = talloc_asprintf(state, "\\\\%s\\%s",
2338 smbXcli_conn_remote_name(cli->conn),
2340 if (tevent_req_nomem(unc, req)) {
2341 return tevent_req_post(req, ev);
2344 subreq = smb2cli_tcon_send(state, ev, cli->conn, cli->timeout,
2345 cli->smb2.session, cli->smb2.tcon,
2348 if (tevent_req_nomem(subreq, req)) {
2349 return tevent_req_post(req, ev);
2351 tevent_req_set_callback(subreq, cli_tree_connect_smb2_done,
2356 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_LANMAN1) {
2357 subreq = cli_tcon_andx_send(state, ev, cli, share, dev,
2359 if (tevent_req_nomem(subreq, req)) {
2360 return tevent_req_post(req, ev);
2362 tevent_req_set_callback(subreq, cli_tree_connect_andx_done,
2367 subreq = cli_raw_tcon_send(state, ev, cli, share, pass, dev);
2368 if (tevent_req_nomem(subreq, req)) {
2369 return tevent_req_post(req, ev);
2371 tevent_req_set_callback(subreq, cli_tree_connect_raw_done, req);
2376 static void cli_tree_connect_smb2_done(struct tevent_req *subreq)
2378 tevent_req_simple_finish_ntstatus(
2379 subreq, smb2cli_tcon_recv(subreq));
2382 static void cli_tree_connect_andx_done(struct tevent_req *subreq)
2384 tevent_req_simple_finish_ntstatus(
2385 subreq, cli_tcon_andx_recv(subreq));
2388 static void cli_tree_connect_raw_done(struct tevent_req *subreq)
2390 struct tevent_req *req = tevent_req_callback_data(
2391 subreq, struct tevent_req);
2392 struct cli_tree_connect_state *state = tevent_req_data(
2393 req, struct cli_tree_connect_state);
2395 uint16_t max_xmit = 0;
2398 status = cli_raw_tcon_recv(subreq, &max_xmit, &tid);
2399 if (tevent_req_nterror(req, status)) {
2403 smb1cli_tcon_set_values(state->cli->smb1.tcon,
2405 0, /* optional_support */
2406 0, /* maximal_access */
2407 0, /* guest_maximal_access */
2409 NULL); /* fs_type */
2411 tevent_req_done(req);
2414 static NTSTATUS cli_tree_connect_recv(struct tevent_req *req)
2416 return tevent_req_simple_recv_ntstatus(req);
2419 NTSTATUS cli_tree_connect(struct cli_state *cli, const char *share,
2420 const char *dev, const char *pass)
2422 struct tevent_context *ev;
2423 struct tevent_req *req;
2424 NTSTATUS status = NT_STATUS_NO_MEMORY;
2426 if (smbXcli_conn_has_async_calls(cli->conn)) {
2427 return NT_STATUS_INVALID_PARAMETER;
2429 ev = samba_tevent_context_init(talloc_tos());
2433 req = cli_tree_connect_send(ev, ev, cli, share, dev, pass);
2437 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2440 status = cli_tree_connect_recv(req);
2446 NTSTATUS cli_tree_connect_creds(struct cli_state *cli,
2447 const char *share, const char *dev,
2448 struct cli_credentials *creds)
2450 const char *pw = NULL;
2452 if (creds != NULL) {
2453 pw = cli_credentials_get_password(creds);
2456 return cli_tree_connect(cli, share, dev, pw);
2459 /****************************************************************************
2460 Send a tree disconnect.
2461 ****************************************************************************/
2463 struct cli_tdis_state {
2464 struct cli_state *cli;
2467 static void cli_tdis_done(struct tevent_req *subreq);
2469 static struct tevent_req *cli_tdis_send(TALLOC_CTX *mem_ctx,
2470 struct tevent_context *ev,
2471 struct cli_state *cli)
2473 struct tevent_req *req, *subreq;
2474 struct cli_tdis_state *state;
2476 req = tevent_req_create(mem_ctx, &state, struct cli_tdis_state);
2482 subreq = cli_smb_send(state, ev, cli, SMBtdis, 0, 0, 0, NULL, 0, NULL);
2483 if (tevent_req_nomem(subreq, req)) {
2484 return tevent_req_post(req, ev);
2486 tevent_req_set_callback(subreq, cli_tdis_done, req);
2490 static void cli_tdis_done(struct tevent_req *subreq)
2492 struct tevent_req *req = tevent_req_callback_data(
2493 subreq, struct tevent_req);
2494 struct cli_tdis_state *state = tevent_req_data(
2495 req, struct cli_tdis_state);
2498 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
2499 TALLOC_FREE(subreq);
2500 if (!NT_STATUS_IS_OK(status)) {
2501 tevent_req_nterror(req, status);
2504 TALLOC_FREE(state->cli->smb1.tcon);
2505 tevent_req_done(req);
2508 static NTSTATUS cli_tdis_recv(struct tevent_req *req)
2510 return tevent_req_simple_recv_ntstatus(req);
2513 NTSTATUS cli_tdis(struct cli_state *cli)
2515 struct tevent_context *ev;
2516 struct tevent_req *req;
2517 NTSTATUS status = NT_STATUS_NO_MEMORY;
2519 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
2520 status = smb2cli_tdis(cli->conn,
2524 if (NT_STATUS_IS_OK(status)) {
2525 TALLOC_FREE(cli->smb2.tcon);
2530 if (smbXcli_conn_has_async_calls(cli->conn)) {
2531 return NT_STATUS_INVALID_PARAMETER;
2533 ev = samba_tevent_context_init(talloc_tos());
2537 req = cli_tdis_send(ev, ev, cli);
2541 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2544 status = cli_tdis_recv(req);
2550 struct cli_connect_sock_state {
2551 struct sockaddr_storage *addrs;
2553 const char **called_names;
2554 const char **calling_names;
2556 size_t chosen_index;
2561 static void cli_connect_sock_done(struct tevent_req *subreq);
2564 * Async only if we don't have to look up the name, i.e. "pss" is set with a
2568 static struct tevent_req *cli_connect_sock_send(
2569 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2570 const char *host, int name_type, const struct sockaddr_storage *pss,
2571 const char *myname, uint16_t port)
2573 struct tevent_req *req, *subreq;
2574 struct cli_connect_sock_state *state;
2575 struct sockaddr_storage *addrs;
2579 req = tevent_req_create(mem_ctx, &state,
2580 struct cli_connect_sock_state);
2585 if ((pss == NULL) || is_zero_addr(pss)) {
2588 * Here we cheat. resolve_name_list is not async at all. So
2589 * this call will only be really async if the name lookup has
2590 * been done externally.
2593 status = resolve_name_list(state, host, name_type,
2594 &state->addrs, &state->num_addrs);
2595 if (!NT_STATUS_IS_OK(status)) {
2596 tevent_req_nterror(req, status);
2597 return tevent_req_post(req, ev);
2600 state->addrs = talloc_array(state, struct sockaddr_storage, 1);
2601 if (tevent_req_nomem(state->addrs, req)) {
2602 return tevent_req_post(req, ev);
2604 state->addrs[0] = *pss;
2605 state->num_addrs = 1;
2608 state->called_names = talloc_array(state, const char *, num_addrs);
2609 if (tevent_req_nomem(state->called_names, req)) {
2610 return tevent_req_post(req, ev);
2612 state->called_types = talloc_array(state, int, num_addrs);
2613 if (tevent_req_nomem(state->called_types, req)) {
2614 return tevent_req_post(req, ev);
2616 state->calling_names = talloc_array(state, const char *, num_addrs);
2617 if (tevent_req_nomem(state->calling_names, req)) {
2618 return tevent_req_post(req, ev);
2620 for (i=0; i<state->num_addrs; i++) {
2621 state->called_names[i] = host;
2622 state->called_types[i] = name_type;
2623 state->calling_names[i] = myname;
2626 subreq = smbsock_any_connect_send(
2627 state, ev, state->addrs,
2628 state->called_names, state->called_types, state->calling_names,
2629 NULL, state->num_addrs, port);
2630 if (tevent_req_nomem(subreq, req)) {
2631 return tevent_req_post(req, ev);
2633 tevent_req_set_callback(subreq, cli_connect_sock_done, req);
2637 static void cli_connect_sock_done(struct tevent_req *subreq)
2639 struct tevent_req *req = tevent_req_callback_data(
2640 subreq, struct tevent_req);
2641 struct cli_connect_sock_state *state = tevent_req_data(
2642 req, struct cli_connect_sock_state);
2645 status = smbsock_any_connect_recv(subreq, &state->fd,
2646 &state->chosen_index,
2648 TALLOC_FREE(subreq);
2649 if (tevent_req_nterror(req, status)) {
2652 set_socket_options(state->fd, lp_socket_options());
2653 tevent_req_done(req);
2656 static NTSTATUS cli_connect_sock_recv(struct tevent_req *req,
2658 struct sockaddr_storage *pss,
2661 struct cli_connect_sock_state *state = tevent_req_data(
2662 req, struct cli_connect_sock_state);
2665 if (tevent_req_is_nterror(req, &status)) {
2669 *pss = state->addrs[state->chosen_index];
2670 *pport = state->port;
2671 return NT_STATUS_OK;
2674 struct cli_connect_nb_state {
2675 const char *desthost;
2678 struct cli_state *cli;
2681 static void cli_connect_nb_done(struct tevent_req *subreq);
2683 static struct tevent_req *cli_connect_nb_send(
2684 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2685 const char *host, const struct sockaddr_storage *dest_ss,
2686 uint16_t port, int name_type, const char *myname,
2687 int signing_state, int flags)
2689 struct tevent_req *req, *subreq;
2690 struct cli_connect_nb_state *state;
2692 req = tevent_req_create(mem_ctx, &state, struct cli_connect_nb_state);
2696 state->signing_state = signing_state;
2697 state->flags = flags;
2700 char *p = strchr(host, '#');
2703 name_type = strtol(p+1, NULL, 16);
2704 host = talloc_strndup(state, host, p - host);
2705 if (tevent_req_nomem(host, req)) {
2706 return tevent_req_post(req, ev);
2710 state->desthost = host;
2711 } else if (dest_ss != NULL) {
2712 state->desthost = print_canonical_sockaddr(state, dest_ss);
2713 if (tevent_req_nomem(state->desthost, req)) {
2714 return tevent_req_post(req, ev);
2717 /* No host or dest_ss given. Error out. */
2718 tevent_req_error(req, EINVAL);
2719 return tevent_req_post(req, ev);
2722 subreq = cli_connect_sock_send(state, ev, host, name_type, dest_ss,
2724 if (tevent_req_nomem(subreq, req)) {
2725 return tevent_req_post(req, ev);
2727 tevent_req_set_callback(subreq, cli_connect_nb_done, req);
2731 static void cli_connect_nb_done(struct tevent_req *subreq)
2733 struct tevent_req *req = tevent_req_callback_data(
2734 subreq, struct tevent_req);
2735 struct cli_connect_nb_state *state = tevent_req_data(
2736 req, struct cli_connect_nb_state);
2741 status = cli_connect_sock_recv(subreq, &fd, &port);
2742 TALLOC_FREE(subreq);
2743 if (tevent_req_nterror(req, status)) {
2747 state->cli = cli_state_create(state, fd, state->desthost,
2748 state->signing_state, state->flags);
2749 if (tevent_req_nomem(state->cli, req)) {
2753 tevent_req_done(req);
2756 static NTSTATUS cli_connect_nb_recv(struct tevent_req *req,
2757 struct cli_state **pcli)
2759 struct cli_connect_nb_state *state = tevent_req_data(
2760 req, struct cli_connect_nb_state);
2763 if (tevent_req_is_nterror(req, &status)) {
2766 *pcli = talloc_move(NULL, &state->cli);
2767 return NT_STATUS_OK;
2770 NTSTATUS cli_connect_nb(const char *host, const struct sockaddr_storage *dest_ss,
2771 uint16_t port, int name_type, const char *myname,
2772 int signing_state, int flags, struct cli_state **pcli)
2774 struct tevent_context *ev;
2775 struct tevent_req *req;
2776 NTSTATUS status = NT_STATUS_NO_MEMORY;
2778 ev = samba_tevent_context_init(talloc_tos());
2782 req = cli_connect_nb_send(ev, ev, host, dest_ss, port, name_type,
2783 myname, signing_state, flags);
2787 if (!tevent_req_set_endtime(req, ev, timeval_current_ofs(20, 0))) {
2790 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2793 status = cli_connect_nb_recv(req, pcli);
2799 struct cli_start_connection_state {
2800 struct tevent_context *ev;
2801 struct cli_state *cli;
2806 static void cli_start_connection_connected(struct tevent_req *subreq);
2807 static void cli_start_connection_done(struct tevent_req *subreq);
2810 establishes a connection to after the negprot.
2811 @param output_cli A fully initialised cli structure, non-null only on success
2812 @param dest_host The netbios name of the remote host
2813 @param dest_ss (optional) The the destination IP, NULL for name based lookup
2814 @param port (optional) The destination port (0 for default)
2817 static struct tevent_req *cli_start_connection_send(
2818 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2819 const char *my_name, const char *dest_host,
2820 const struct sockaddr_storage *dest_ss, int port,
2821 int signing_state, int flags)
2823 struct tevent_req *req, *subreq;
2824 struct cli_start_connection_state *state;
2826 req = tevent_req_create(mem_ctx, &state,
2827 struct cli_start_connection_state);
2833 if (signing_state == SMB_SIGNING_IPC_DEFAULT) {
2834 state->min_protocol = lp_client_ipc_min_protocol();
2835 state->max_protocol = lp_client_ipc_max_protocol();
2837 state->min_protocol = lp_client_min_protocol();
2838 state->max_protocol = lp_client_max_protocol();
2841 if (flags & CLI_FULL_CONNECTION_FORCE_SMB1) {
2842 state->max_protocol = MIN(state->max_protocol, PROTOCOL_NT1);
2845 if (flags & CLI_FULL_CONNECTION_DISABLE_SMB1) {
2846 state->min_protocol = MAX(state->max_protocol, PROTOCOL_SMB2_02);
2847 state->max_protocol = MAX(state->max_protocol, PROTOCOL_LATEST);
2850 subreq = cli_connect_nb_send(state, ev, dest_host, dest_ss, port,
2851 0x20, my_name, signing_state, flags);
2852 if (tevent_req_nomem(subreq, req)) {
2853 return tevent_req_post(req, ev);
2855 tevent_req_set_callback(subreq, cli_start_connection_connected, req);
2859 static void cli_start_connection_connected(struct tevent_req *subreq)
2861 struct tevent_req *req = tevent_req_callback_data(
2862 subreq, struct tevent_req);
2863 struct cli_start_connection_state *state = tevent_req_data(
2864 req, struct cli_start_connection_state);
2867 status = cli_connect_nb_recv(subreq, &state->cli);
2868 TALLOC_FREE(subreq);
2869 if (tevent_req_nterror(req, status)) {
2873 subreq = smbXcli_negprot_send(state, state->ev, state->cli->conn,
2874 state->cli->timeout,
2875 state->min_protocol,
2876 state->max_protocol,
2877 WINDOWS_CLIENT_PURE_SMB2_NEGPROT_INITIAL_CREDIT_ASK);
2878 if (tevent_req_nomem(subreq, req)) {
2881 tevent_req_set_callback(subreq, cli_start_connection_done, req);
2884 static void cli_start_connection_done(struct tevent_req *subreq)
2886 struct tevent_req *req = tevent_req_callback_data(
2887 subreq, struct tevent_req);
2888 struct cli_start_connection_state *state = tevent_req_data(
2889 req, struct cli_start_connection_state);
2892 status = smbXcli_negprot_recv(subreq);
2893 TALLOC_FREE(subreq);
2894 if (tevent_req_nterror(req, status)) {
2898 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
2899 /* Ensure we ask for some initial credits. */
2900 smb2cli_conn_set_max_credits(state->cli->conn,
2901 DEFAULT_SMB2_MAX_CREDITS);
2904 tevent_req_done(req);
2907 static NTSTATUS cli_start_connection_recv(struct tevent_req *req,
2908 struct cli_state **output_cli)
2910 struct cli_start_connection_state *state = tevent_req_data(
2911 req, struct cli_start_connection_state);
2914 if (tevent_req_is_nterror(req, &status)) {
2917 *output_cli = state->cli;
2919 return NT_STATUS_OK;
2922 NTSTATUS cli_start_connection(struct cli_state **output_cli,
2923 const char *my_name,
2924 const char *dest_host,
2925 const struct sockaddr_storage *dest_ss, int port,
2926 int signing_state, int flags)
2928 struct tevent_context *ev;
2929 struct tevent_req *req;
2930 NTSTATUS status = NT_STATUS_NO_MEMORY;
2932 ev = samba_tevent_context_init(talloc_tos());
2936 req = cli_start_connection_send(ev, ev, my_name, dest_host, dest_ss,
2937 port, signing_state, flags);
2941 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2944 status = cli_start_connection_recv(req, output_cli);
2950 struct cli_smb1_setup_encryption_blob_state {
2955 uint16_t enc_ctx_id;
2958 static void cli_smb1_setup_encryption_blob_done(struct tevent_req *subreq);
2960 static struct tevent_req *cli_smb1_setup_encryption_blob_send(TALLOC_CTX *mem_ctx,
2961 struct tevent_context *ev,
2962 struct cli_state *cli,
2965 struct tevent_req *req = NULL;
2966 struct cli_smb1_setup_encryption_blob_state *state = NULL;
2967 struct tevent_req *subreq = NULL;
2969 req = tevent_req_create(mem_ctx, &state,
2970 struct cli_smb1_setup_encryption_blob_state);
2975 if (in.length > CLI_BUFFER_SIZE) {
2976 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
2977 return tevent_req_post(req, ev);
2980 SSVAL(state->setup+0, 0, TRANSACT2_SETFSINFO);
2981 SSVAL(state->param, 0, 0);
2982 SSVAL(state->param, 2, SMB_REQUEST_TRANSPORT_ENCRYPTION);
2984 subreq = smb1cli_trans_send(state, ev, cli->conn,
2992 NULL, /* pipe_name */
2998 in.data, in.length, CLI_BUFFER_SIZE);
2999 if (tevent_req_nomem(subreq, req)) {
3000 return tevent_req_post(req, ev);
3002 tevent_req_set_callback(subreq,
3003 cli_smb1_setup_encryption_blob_done,
3009 static void cli_smb1_setup_encryption_blob_done(struct tevent_req *subreq)
3011 struct tevent_req *req =
3012 tevent_req_callback_data(subreq,
3014 struct cli_smb1_setup_encryption_blob_state *state =
3015 tevent_req_data(req,
3016 struct cli_smb1_setup_encryption_blob_state);
3017 uint8_t *rparam=NULL, *rdata=NULL;
3018 uint32_t num_rparam, num_rdata;
3021 status = smb1cli_trans_recv(subreq, state,
3022 NULL, /* recv_flags */
3023 NULL, 0, NULL, /* rsetup */
3024 &rparam, 0, &num_rparam,
3025 &rdata, 0, &num_rdata);
3026 TALLOC_FREE(subreq);
3027 state->status = status;
3028 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
3029 status = NT_STATUS_OK;
3031 if (tevent_req_nterror(req, status)) {
3035 if (num_rparam == 2) {
3036 state->enc_ctx_id = SVAL(rparam, 0);
3038 TALLOC_FREE(rparam);
3040 state->out = data_blob_const(rdata, num_rdata);
3042 tevent_req_done(req);
3045 static NTSTATUS cli_smb1_setup_encryption_blob_recv(struct tevent_req *req,
3046 TALLOC_CTX *mem_ctx,
3048 uint16_t *enc_ctx_id)
3050 struct cli_smb1_setup_encryption_blob_state *state =
3051 tevent_req_data(req,
3052 struct cli_smb1_setup_encryption_blob_state);
3055 if (tevent_req_is_nterror(req, &status)) {
3056 tevent_req_received(req);
3060 status = state->status;
3063 talloc_steal(mem_ctx, out->data);
3065 *enc_ctx_id = state->enc_ctx_id;
3067 tevent_req_received(req);
3071 struct cli_smb1_setup_encryption_state {
3072 struct tevent_context *ev;
3073 struct cli_state *cli;
3074 struct smb_trans_enc_state *es;
3081 static void cli_smb1_setup_encryption_local_next(struct tevent_req *req);
3082 static void cli_smb1_setup_encryption_local_done(struct tevent_req *subreq);
3083 static void cli_smb1_setup_encryption_remote_next(struct tevent_req *req);
3084 static void cli_smb1_setup_encryption_remote_done(struct tevent_req *subreq);
3085 static void cli_smb1_setup_encryption_ready(struct tevent_req *req);
3087 static struct tevent_req *cli_smb1_setup_encryption_send(TALLOC_CTX *mem_ctx,
3088 struct tevent_context *ev,
3089 struct cli_state *cli,
3090 struct cli_credentials *creds)
3092 struct tevent_req *req = NULL;
3093 struct cli_smb1_setup_encryption_state *state = NULL;
3094 struct auth_generic_state *ags = NULL;
3095 const DATA_BLOB *b = NULL;
3096 bool auth_requested = false;
3097 const char *target_service = NULL;
3098 const char *target_hostname = NULL;
3101 req = tevent_req_create(mem_ctx, &state,
3102 struct cli_smb1_setup_encryption_state);
3109 auth_requested = cli_credentials_authentication_requested(creds);
3110 if (!auth_requested) {
3111 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
3112 return tevent_req_post(req, ev);
3115 target_service = "cifs";
3116 target_hostname = smbXcli_conn_remote_name(cli->conn);
3118 status = cli_session_creds_prepare_krb5(cli, creds);
3119 if (tevent_req_nterror(req, status)) {
3120 return tevent_req_post(req, ev);
3123 state->es = talloc_zero(state, struct smb_trans_enc_state);
3124 if (tevent_req_nomem(state->es, req)) {
3125 return tevent_req_post(req, ev);
3128 status = auth_generic_client_prepare(state->es, &ags);
3129 if (tevent_req_nterror(req, status)) {
3130 return tevent_req_post(req, ev);
3133 gensec_want_feature(ags->gensec_security,
3134 GENSEC_FEATURE_SIGN);
3135 gensec_want_feature(ags->gensec_security,
3136 GENSEC_FEATURE_SEAL);
3138 status = auth_generic_set_creds(ags, creds);
3139 if (tevent_req_nterror(req, status)) {
3140 return tevent_req_post(req, ev);
3143 if (target_service != NULL) {
3144 status = gensec_set_target_service(ags->gensec_security,
3146 if (tevent_req_nterror(req, status)) {
3147 return tevent_req_post(req, ev);
3151 if (target_hostname != NULL) {
3152 status = gensec_set_target_hostname(ags->gensec_security,
3154 if (tevent_req_nterror(req, status)) {
3155 return tevent_req_post(req, ev);
3159 gensec_set_max_update_size(ags->gensec_security,
3162 b = smbXcli_conn_server_gss_blob(state->cli->conn);
3164 state->blob_in = *b;
3167 status = auth_generic_client_start(ags, GENSEC_OID_SPNEGO);
3168 if (tevent_req_nterror(req, status)) {
3169 return tevent_req_post(req, ev);
3173 * We only need the gensec_security part from here.
3175 state->es->gensec_security = talloc_move(state->es,
3176 &ags->gensec_security);
3179 cli_smb1_setup_encryption_local_next(req);
3180 if (!tevent_req_is_in_progress(req)) {
3181 return tevent_req_post(req, ev);
3187 static void cli_smb1_setup_encryption_local_next(struct tevent_req *req)
3189 struct cli_smb1_setup_encryption_state *state =
3190 tevent_req_data(req,
3191 struct cli_smb1_setup_encryption_state);
3192 struct tevent_req *subreq = NULL;
3194 if (state->local_ready) {
3195 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3199 subreq = gensec_update_send(state, state->ev,
3200 state->es->gensec_security,
3202 if (tevent_req_nomem(subreq, req)) {
3205 tevent_req_set_callback(subreq, cli_smb1_setup_encryption_local_done, req);
3208 static void cli_smb1_setup_encryption_local_done(struct tevent_req *subreq)
3210 struct tevent_req *req =
3211 tevent_req_callback_data(subreq,
3213 struct cli_smb1_setup_encryption_state *state =
3214 tevent_req_data(req,
3215 struct cli_smb1_setup_encryption_state);
3218 status = gensec_update_recv(subreq, state, &state->blob_out);
3219 TALLOC_FREE(subreq);
3220 state->blob_in = data_blob_null;
3221 if (!NT_STATUS_IS_OK(status) &&
3222 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
3224 tevent_req_nterror(req, status);
3228 if (NT_STATUS_IS_OK(status)) {
3229 state->local_ready = true;
3233 * We always get NT_STATUS_OK from the server even if it is not ready.
3234 * So guess the server is ready when we are ready and already sent
3235 * our last blob to the server.
3237 if (state->local_ready && state->blob_out.length == 0) {
3238 state->remote_ready = true;
3241 if (state->local_ready && state->remote_ready) {
3242 cli_smb1_setup_encryption_ready(req);
3246 cli_smb1_setup_encryption_remote_next(req);
3249 static void cli_smb1_setup_encryption_remote_next(struct tevent_req *req)
3251 struct cli_smb1_setup_encryption_state *state =
3252 tevent_req_data(req,
3253 struct cli_smb1_setup_encryption_state);
3254 struct tevent_req *subreq = NULL;
3256 if (state->remote_ready) {
3257 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3261 subreq = cli_smb1_setup_encryption_blob_send(state, state->ev,
3262 state->cli, state->blob_out);
3263 if (tevent_req_nomem(subreq, req)) {
3266 tevent_req_set_callback(subreq,
3267 cli_smb1_setup_encryption_remote_done,
3271 static void cli_smb1_setup_encryption_remote_done(struct tevent_req *subreq)
3273 struct tevent_req *req =
3274 tevent_req_callback_data(subreq,
3276 struct cli_smb1_setup_encryption_state *state =
3277 tevent_req_data(req,
3278 struct cli_smb1_setup_encryption_state);
3281 status = cli_smb1_setup_encryption_blob_recv(subreq, state,
3283 &state->es->enc_ctx_num);
3284 TALLOC_FREE(subreq);
3285 data_blob_free(&state->blob_out);
3286 if (!NT_STATUS_IS_OK(status) &&
3287 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
3289 tevent_req_nterror(req, status);
3294 * We always get NT_STATUS_OK even if the server is not ready.
3295 * So guess the server is ready when we are ready and sent
3296 * our last blob to the server.
3298 if (state->local_ready) {
3299 state->remote_ready = true;
3302 if (state->local_ready && state->remote_ready) {
3303 cli_smb1_setup_encryption_ready(req);
3307 cli_smb1_setup_encryption_local_next(req);
3310 static void cli_smb1_setup_encryption_ready(struct tevent_req *req)
3312 struct cli_smb1_setup_encryption_state *state =
3313 tevent_req_data(req,
3314 struct cli_smb1_setup_encryption_state);
3315 struct smb_trans_enc_state *es = NULL;
3317 if (state->blob_in.length != 0) {
3318 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3322 if (state->blob_out.length != 0) {
3323 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3327 es = talloc_move(state->cli->conn, &state->es);
3329 smb1cli_conn_set_encryption(state->cli->conn, es);
3332 tevent_req_done(req);
3335 static NTSTATUS cli_smb1_setup_encryption_recv(struct tevent_req *req)
3337 return tevent_req_simple_recv_ntstatus(req);
3340 NTSTATUS cli_smb1_setup_encryption(struct cli_state *cli,
3341 struct cli_credentials *creds)
3343 struct tevent_context *ev = NULL;
3344 struct tevent_req *req = NULL;
3345 NTSTATUS status = NT_STATUS_NO_MEMORY;
3347 ev = samba_tevent_context_init(talloc_tos());
3351 req = cli_smb1_setup_encryption_send(ev, ev, cli, creds);
3355 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
3358 status = cli_smb1_setup_encryption_recv(req);
3365 establishes a connection right up to doing tconX, password specified.
3366 @param output_cli A fully initialised cli structure, non-null only on success
3367 @param dest_host The netbios name of the remote host
3368 @param dest_ip (optional) The the destination IP, NULL for name based lookup
3369 @param port (optional) The destination port (0 for default)
3370 @param service (optional) The share to make the connection to. Should be 'unqualified' in any way.
3371 @param service_type The 'type' of serivice.
3372 @param creds The used user credentials
3375 struct cli_full_connection_creds_state {
3376 struct tevent_context *ev;
3377 const char *service;
3378 const char *service_type;
3379 struct cli_credentials *creds;
3381 struct cli_state *cli;
3384 static int cli_full_connection_creds_state_destructor(
3385 struct cli_full_connection_creds_state *s)
3387 if (s->cli != NULL) {
3388 cli_shutdown(s->cli);
3394 static void cli_full_connection_creds_conn_done(struct tevent_req *subreq);
3395 static void cli_full_connection_creds_sess_start(struct tevent_req *req);
3396 static void cli_full_connection_creds_sess_done(struct tevent_req *subreq);
3397 static void cli_full_connection_creds_tcon_start(struct tevent_req *req);
3398 static void cli_full_connection_creds_tcon_done(struct tevent_req *subreq);
3400 struct tevent_req *cli_full_connection_creds_send(
3401 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
3402 const char *my_name, const char *dest_host,
3403 const struct sockaddr_storage *dest_ss, int port,
3404 const char *service, const char *service_type,
3405 struct cli_credentials *creds,
3406 int flags, int signing_state)
3408 struct tevent_req *req, *subreq;
3409 struct cli_full_connection_creds_state *state;
3410 enum credentials_use_kerberos krb5_state;
3411 uint32_t gensec_features = 0;
3413 req = tevent_req_create(mem_ctx, &state,
3414 struct cli_full_connection_creds_state);
3418 talloc_set_destructor(state, cli_full_connection_creds_state_destructor);
3420 flags &= ~CLI_FULL_CONNECTION_USE_KERBEROS;
3421 flags &= ~CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS;
3422 flags &= ~CLI_FULL_CONNECTION_USE_CCACHE;
3423 flags &= ~CLI_FULL_CONNECTION_USE_NT_HASH;
3425 krb5_state = cli_credentials_get_kerberos_state(creds);
3426 switch (krb5_state) {
3427 case CRED_MUST_USE_KERBEROS:
3428 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
3429 flags &= ~CLI_FULL_CONNECTION_DONT_SPNEGO;
3431 case CRED_AUTO_USE_KERBEROS:
3432 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
3433 flags |= CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS;
3435 case CRED_DONT_USE_KERBEROS:
3439 gensec_features = cli_credentials_get_gensec_features(creds);
3440 if (gensec_features & GENSEC_FEATURE_NTLM_CCACHE) {
3441 flags |= CLI_FULL_CONNECTION_USE_CCACHE;
3445 state->service = service;
3446 state->service_type = service_type;
3447 state->creds = creds;
3448 state->flags = flags;
3450 subreq = cli_start_connection_send(
3451 state, ev, my_name, dest_host, dest_ss, port,
3452 signing_state, flags);
3453 if (tevent_req_nomem(subreq, req)) {
3454 return tevent_req_post(req, ev);
3456 tevent_req_set_callback(subreq,
3457 cli_full_connection_creds_conn_done,
3462 static void cli_full_connection_creds_conn_done(struct tevent_req *subreq)
3464 struct tevent_req *req = tevent_req_callback_data(
3465 subreq, struct tevent_req);
3466 struct cli_full_connection_creds_state *state = tevent_req_data(
3467 req, struct cli_full_connection_creds_state);
3470 status = cli_start_connection_recv(subreq, &state->cli);
3471 TALLOC_FREE(subreq);
3472 if (tevent_req_nterror(req, status)) {
3476 cli_full_connection_creds_sess_start(req);
3479 static void cli_full_connection_creds_sess_start(struct tevent_req *req)
3481 struct cli_full_connection_creds_state *state = tevent_req_data(
3482 req, struct cli_full_connection_creds_state);
3483 struct tevent_req *subreq = NULL;
3485 subreq = cli_session_setup_creds_send(
3486 state, state->ev, state->cli, state->creds);
3487 if (tevent_req_nomem(subreq, req)) {
3490 tevent_req_set_callback(subreq,
3491 cli_full_connection_creds_sess_done,
3495 static void cli_full_connection_creds_sess_done(struct tevent_req *subreq)
3497 struct tevent_req *req = tevent_req_callback_data(
3498 subreq, struct tevent_req);
3499 struct cli_full_connection_creds_state *state = tevent_req_data(
3500 req, struct cli_full_connection_creds_state);
3503 status = cli_session_setup_creds_recv(subreq);
3504 TALLOC_FREE(subreq);
3506 if (!NT_STATUS_IS_OK(status) &&
3507 (state->flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)) {
3509 state->flags &= ~CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
3511 state->creds = cli_credentials_init_anon(state);
3512 if (tevent_req_nomem(state->creds, req)) {
3516 cli_full_connection_creds_sess_start(req);
3520 if (tevent_req_nterror(req, status)) {
3524 cli_full_connection_creds_tcon_start(req);
3527 static void cli_full_connection_creds_tcon_start(struct tevent_req *req)
3529 struct cli_full_connection_creds_state *state = tevent_req_data(
3530 req, struct cli_full_connection_creds_state);
3531 struct tevent_req *subreq = NULL;
3532 const char *password = NULL;
3534 if (state->service == NULL) {
3535 tevent_req_done(req);
3539 password = cli_credentials_get_password(state->creds);
3541 subreq = cli_tree_connect_send(state, state->ev,
3544 state->service_type,
3546 if (tevent_req_nomem(subreq, req)) {
3549 tevent_req_set_callback(subreq,
3550 cli_full_connection_creds_tcon_done,
3554 static void cli_full_connection_creds_tcon_done(struct tevent_req *subreq)
3556 struct tevent_req *req = tevent_req_callback_data(
3557 subreq, struct tevent_req);
3560 status = cli_tree_connect_recv(subreq);
3561 TALLOC_FREE(subreq);
3562 if (tevent_req_nterror(req, status)) {
3566 tevent_req_done(req);
3569 NTSTATUS cli_full_connection_creds_recv(struct tevent_req *req,
3570 struct cli_state **output_cli)
3572 struct cli_full_connection_creds_state *state = tevent_req_data(
3573 req, struct cli_full_connection_creds_state);
3576 if (tevent_req_is_nterror(req, &status)) {
3579 *output_cli = state->cli;
3580 talloc_set_destructor(state, NULL);
3581 return NT_STATUS_OK;
3584 NTSTATUS cli_full_connection_creds(struct cli_state **output_cli,
3585 const char *my_name,
3586 const char *dest_host,
3587 const struct sockaddr_storage *dest_ss, int port,
3588 const char *service, const char *service_type,
3589 struct cli_credentials *creds,
3593 struct tevent_context *ev;
3594 struct tevent_req *req;
3595 NTSTATUS status = NT_STATUS_NO_MEMORY;
3597 ev = samba_tevent_context_init(talloc_tos());
3601 req = cli_full_connection_creds_send(
3602 ev, ev, my_name, dest_host, dest_ss, port, service,
3603 service_type, creds, flags, signing_state);
3607 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
3610 status = cli_full_connection_creds_recv(req, output_cli);
3616 NTSTATUS cli_full_connection(struct cli_state **output_cli,
3617 const char *my_name,
3618 const char *dest_host,
3619 const struct sockaddr_storage *dest_ss, int port,
3620 const char *service, const char *service_type,
3621 const char *user, const char *domain,
3622 const char *password, int flags,
3625 TALLOC_CTX *frame = talloc_stackframe();
3627 bool use_kerberos = false;
3628 bool fallback_after_kerberos = false;
3629 bool use_ccache = false;
3630 bool pw_nt_hash = false;
3631 struct cli_credentials *creds = NULL;
3633 if (flags & CLI_FULL_CONNECTION_USE_KERBEROS) {
3634 use_kerberos = true;
3637 if (flags & CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS) {
3638 fallback_after_kerberos = true;
3641 if (flags & CLI_FULL_CONNECTION_USE_CCACHE) {
3645 if (flags & CLI_FULL_CONNECTION_USE_NT_HASH) {
3649 creds = cli_session_creds_init(frame,
3652 NULL, /* realm (use default) */
3655 fallback_after_kerberos,
3658 if (creds == NULL) {
3660 return NT_STATUS_NO_MEMORY;
3663 status = cli_full_connection_creds(output_cli, my_name,
3664 dest_host, dest_ss, port,
3665 service, service_type,
3666 creds, flags, signing_state);
3667 if (!NT_STATUS_IS_OK(status)) {
3673 return NT_STATUS_OK;
3676 /****************************************************************************
3677 Send an old style tcon.
3678 ****************************************************************************/
3679 struct cli_raw_tcon_state {
3683 static void cli_raw_tcon_done(struct tevent_req *subreq);
3685 static struct tevent_req *cli_raw_tcon_send(
3686 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
3687 const char *service, const char *pass, const char *dev)
3689 struct tevent_req *req, *subreq;
3690 struct cli_raw_tcon_state *state;
3693 req = tevent_req_create(mem_ctx, &state, struct cli_raw_tcon_state);
3698 if (!lp_client_plaintext_auth() && (*pass)) {
3699 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
3700 " or 'client ntlmv2 auth = yes'\n"));
3701 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
3702 return tevent_req_post(req, ev);
3705 TALLOC_FREE(cli->smb1.tcon);
3706 cli->smb1.tcon = smbXcli_tcon_create(cli);
3707 if (tevent_req_nomem(cli->smb1.tcon, req)) {
3708 return tevent_req_post(req, ev);
3710 smb1cli_tcon_set_id(cli->smb1.tcon, UINT16_MAX);
3712 bytes = talloc_array(state, uint8_t, 0);
3713 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3714 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3715 service, strlen(service)+1, NULL);
3716 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3717 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3718 pass, strlen(pass)+1, NULL);
3719 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3720 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3721 dev, strlen(dev)+1, NULL);
3723 if (tevent_req_nomem(bytes, req)) {
3724 return tevent_req_post(req, ev);
3727 subreq = cli_smb_send(state, ev, cli, SMBtcon, 0, 0, 0, NULL,
3728 talloc_get_size(bytes), bytes);
3729 if (tevent_req_nomem(subreq, req)) {
3730 return tevent_req_post(req, ev);
3732 tevent_req_set_callback(subreq, cli_raw_tcon_done, req);
3736 static void cli_raw_tcon_done(struct tevent_req *subreq)
3738 struct tevent_req *req = tevent_req_callback_data(
3739 subreq, struct tevent_req);
3740 struct cli_raw_tcon_state *state = tevent_req_data(
3741 req, struct cli_raw_tcon_state);
3744 status = cli_smb_recv(subreq, state, NULL, 2, NULL, &state->ret_vwv,
3746 TALLOC_FREE(subreq);
3747 if (tevent_req_nterror(req, status)) {
3750 tevent_req_done(req);
3753 static NTSTATUS cli_raw_tcon_recv(struct tevent_req *req,
3754 uint16_t *max_xmit, uint16_t *tid)
3756 struct cli_raw_tcon_state *state = tevent_req_data(
3757 req, struct cli_raw_tcon_state);
3760 if (tevent_req_is_nterror(req, &status)) {
3763 *max_xmit = SVAL(state->ret_vwv + 0, 0);
3764 *tid = SVAL(state->ret_vwv + 1, 0);
3765 return NT_STATUS_OK;
3768 NTSTATUS cli_raw_tcon(struct cli_state *cli,
3769 const char *service, const char *pass, const char *dev,
3770 uint16_t *max_xmit, uint16_t *tid)
3772 struct tevent_context *ev;
3773 struct tevent_req *req;
3774 NTSTATUS status = NT_STATUS_NO_MEMORY;
3776 ev = samba_tevent_context_init(talloc_tos());
3780 req = cli_raw_tcon_send(ev, ev, cli, service, pass, dev);
3784 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
3787 status = cli_raw_tcon_recv(req, max_xmit, tid);
3793 /* Return a cli_state pointing at the IPC$ share for the given server */
3795 struct cli_state *get_ipc_connect(char *server,
3796 struct sockaddr_storage *server_ss,
3797 const struct user_auth_info *user_info)
3799 struct cli_state *cli;
3801 uint32_t flags = CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
3803 if (get_cmdline_auth_info_use_kerberos(user_info)) {
3804 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
3807 flags |= CLI_FULL_CONNECTION_FORCE_SMB1;
3809 nt_status = cli_full_connection(&cli, NULL, server, server_ss, 0, "IPC$", "IPC",
3810 get_cmdline_auth_info_username(user_info),
3812 get_cmdline_auth_info_password(user_info),
3814 SMB_SIGNING_DEFAULT);
3816 if (NT_STATUS_IS_OK(nt_status)) {
3818 } else if (is_ipaddress(server)) {
3819 /* windows 9* needs a correct NMB name for connections */
3820 fstring remote_name;
3822 if (name_status_find("*", 0, 0, server_ss, remote_name)) {
3823 cli = get_ipc_connect(remote_name, server_ss, user_info);
3832 * Given the IP address of a master browser on the network, return its
3833 * workgroup and connect to it.
3835 * This function is provided to allow additional processing beyond what
3836 * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
3837 * browsers and obtain each master browsers' list of domains (in case the
3838 * first master browser is recently on the network and has not yet
3839 * synchronized with other master browsers and therefore does not yet have the
3840 * entire network browse list)
3843 struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx,
3844 struct sockaddr_storage *mb_ip,
3845 const struct user_auth_info *user_info,
3846 char **pp_workgroup_out)
3848 char addr[INET6_ADDRSTRLEN];
3850 struct cli_state *cli;
3851 struct sockaddr_storage server_ss;
3853 *pp_workgroup_out = NULL;
3855 print_sockaddr(addr, sizeof(addr), mb_ip);
3856 DEBUG(99, ("Looking up name of master browser %s\n",
3860 * Do a name status query to find out the name of the master browser.
3861 * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
3862 * master browser will not respond to a wildcard query (or, at least,
3863 * an NT4 server acting as the domain master browser will not).
3865 * We might be able to use ONLY the query on MSBROWSE, but that's not
3866 * yet been tested with all Windows versions, so until it is, leave
3867 * the original wildcard query as the first choice and fall back to
3868 * MSBROWSE if the wildcard query fails.
3870 if (!name_status_find("*", 0, 0x1d, mb_ip, name) &&
3871 !name_status_find(MSBROWSE, 1, 0x1d, mb_ip, name)) {
3873 DEBUG(99, ("Could not retrieve name status for %s\n",
3878 if (!find_master_ip(name, &server_ss)) {
3879 DEBUG(99, ("Could not find master ip for %s\n", name));
3883 *pp_workgroup_out = talloc_strdup(ctx, name);
3885 DEBUG(4, ("found master browser %s, %s\n", name, addr));
3887 print_sockaddr(addr, sizeof(addr), &server_ss);
3888 cli = get_ipc_connect(addr, &server_ss, user_info);
3894 * Return the IP address and workgroup of a master browser on the network, and
3898 struct cli_state *get_ipc_connect_master_ip_bcast(TALLOC_CTX *ctx,
3899 const struct user_auth_info *user_info,
3900 char **pp_workgroup_out)
3902 struct sockaddr_storage *ip_list;
3903 struct cli_state *cli;
3907 *pp_workgroup_out = NULL;
3909 DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
3911 /* Go looking for workgroups by broadcasting on the local network */
3913 status = name_resolve_bcast(MSBROWSE, 1, talloc_tos(),
3915 if (!NT_STATUS_IS_OK(status)) {
3916 DEBUG(99, ("No master browsers responded: %s\n",
3917 nt_errstr(status)));
3921 for (i = 0; i < count; i++) {
3922 char addr[INET6_ADDRSTRLEN];
3923 print_sockaddr(addr, sizeof(addr), &ip_list[i]);
3924 DEBUG(99, ("Found master browser %s\n", addr));
3926 cli = get_ipc_connect_master_ip(ctx, &ip_list[i],
3927 user_info, pp_workgroup_out);