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 char *canon_principal = NULL;
233 char *canon_realm = NULL;
234 const char *target_hostname = NULL;
235 const DATA_BLOB *server_blob = NULL;
236 bool got_kerberos_mechanism = false;
237 enum credentials_use_kerberos krb5_state;
238 bool try_kerberos = false;
239 bool need_kinit = false;
240 bool auth_requested = true;
244 target_hostname = smbXcli_conn_remote_name(cli->conn);
245 server_blob = smbXcli_conn_server_gss_blob(cli->conn);
247 /* the server might not even do spnego */
248 if (server_blob != NULL && server_blob->length != 0) {
249 char *OIDs[ASN1_MAX_OIDS] = { NULL, };
253 * The server sent us the first part of the SPNEGO exchange in the
254 * negprot reply. It is WRONG to depend on the principal sent in the
255 * negprot reply, but right now we do it. If we don't receive one,
256 * we try to best guess, then fall back to NTLM.
258 ok = spnego_parse_negTokenInit(frame,
265 return NT_STATUS_INVALID_PARAMETER;
267 if (OIDs[0] == NULL) {
269 return NT_STATUS_INVALID_PARAMETER;
272 /* make sure the server understands kerberos */
273 for (i = 0; OIDs[i] != NULL; i++) {
275 DEBUG(3,("got OID=%s\n", OIDs[i]));
277 DEBUGADD(3,("got OID=%s\n", OIDs[i]));
280 if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0 ||
281 strcmp(OIDs[i], OID_KERBEROS5) == 0) {
282 got_kerberos_mechanism = true;
288 auth_requested = cli_credentials_authentication_requested(creds);
289 if (auth_requested) {
291 user_principal = cli_credentials_get_principal(creds, frame);
294 return NT_STATUS_NO_MEMORY;
297 user_account = cli_credentials_get_username(creds);
298 user_domain = cli_credentials_get_domain(creds);
299 pass = cli_credentials_get_password(creds);
301 krb5_state = cli_credentials_get_kerberos_state(creds);
303 if (krb5_state != CRED_DONT_USE_KERBEROS) {
307 if (user_principal == NULL) {
308 try_kerberos = false;
311 if (target_hostname == NULL) {
312 try_kerberos = false;
313 } else if (is_ipaddress(target_hostname)) {
314 try_kerberos = false;
315 } else if (strequal(target_hostname, "localhost")) {
316 try_kerberos = false;
317 } else if (strequal(target_hostname, STAR_SMBSERVER)) {
318 try_kerberos = false;
319 } else if (!auth_requested) {
320 try_kerberos = false;
323 if (krb5_state == CRED_MUST_USE_KERBEROS && !try_kerberos) {
324 DEBUG(0, ("Kerberos auth with '%s' (%s\\%s) to access "
325 "'%s' not possible\n",
326 user_principal, user_domain, user_account,
329 return NT_STATUS_ACCESS_DENIED;
332 if (pass == NULL || strlen(pass) == 0) {
334 } else if (krb5_state == CRED_MUST_USE_KERBEROS) {
335 need_kinit = try_kerberos;
336 } else if (!got_kerberos_mechanism) {
338 * Most likely the server doesn't support
339 * Kerberos, don't waste time doing a kinit
343 need_kinit = try_kerberos;
351 DBG_INFO("Doing kinit for %s to access %s\n",
352 user_principal, target_hostname);
355 * TODO: This should be done within the gensec layer
358 setenv(KRB5_ENV_CCNAME, "MEMORY:cliconnect", 1);
359 ret = kerberos_kinit_password_ext(user_principal,
373 int dbglvl = DBGLVL_NOTICE;
375 if (krb5_state == CRED_MUST_USE_KERBEROS) {
379 DEBUG(dbglvl, ("Kinit for %s to access %s failed: %s\n",
380 user_principal, target_hostname,
381 error_message(ret)));
382 if (krb5_state == CRED_MUST_USE_KERBEROS) {
384 return krb5_to_nt_status(ret);
388 * Ignore the error and hope that NTLM will work
394 ok = cli_credentials_set_principal(creds,
399 return NT_STATUS_NO_MEMORY;
402 ok = cli_credentials_set_realm(creds,
407 return NT_STATUS_NO_MEMORY;
410 DBG_DEBUG("Successfully authenticated as %s (%s) to access %s using "
420 static NTSTATUS cli_state_update_after_sesssetup(struct cli_state *cli,
421 const char *native_os,
422 const char *native_lm,
423 const char *primary_domain)
425 #define _VALID_STR(p) ((p) != NULL && (p)[0] != '\0')
427 if (!_VALID_STR(cli->server_os) && _VALID_STR(native_os)) {
428 cli->server_os = talloc_strdup(cli, native_os);
429 if (cli->server_os == NULL) {
430 return NT_STATUS_NO_MEMORY;
434 if (!_VALID_STR(cli->server_type) && _VALID_STR(native_lm)) {
435 cli->server_type = talloc_strdup(cli, native_lm);
436 if (cli->server_type == NULL) {
437 return NT_STATUS_NO_MEMORY;
441 if (!_VALID_STR(cli->server_domain) && _VALID_STR(primary_domain)) {
442 cli->server_domain = talloc_strdup(cli, primary_domain);
443 if (cli->server_domain == NULL) {
444 return NT_STATUS_NO_MEMORY;
452 /********************************************************
453 Utility function to ensure we always return at least
454 a valid char * pointer to an empty string for the
455 cli->server_os, cli->server_type and cli->server_domain
457 *******************************************************/
459 static NTSTATUS smb_bytes_talloc_string(TALLOC_CTX *mem_ctx,
466 *destlen = clistr_pull_talloc(mem_ctx,
473 if (*destlen == -1) {
474 return NT_STATUS_NO_MEMORY;
478 *dest = talloc_strdup(mem_ctx, "");
480 return NT_STATUS_NO_MEMORY;
486 /****************************************************************************
487 Work out suitable capabilities to offer the server.
488 ****************************************************************************/
490 static uint32_t cli_session_setup_capabilities(struct cli_state *cli,
491 uint32_t sesssetup_capabilities)
493 uint32_t client_capabilities = smb1cli_conn_capabilities(cli->conn);
496 * We only send capabilities based on the mask for:
497 * - client only flags
498 * - flags used in both directions
500 * We do not echo the server only flags, except some legacy flags.
502 * SMB_CAP_LEGACY_CLIENT_MASK contains CAP_LARGE_READX and
503 * CAP_LARGE_WRITEX in order to allow us to do large reads
504 * against old Samba releases (<= 3.6.x).
506 client_capabilities &= (SMB_CAP_BOTH_MASK | SMB_CAP_LEGACY_CLIENT_MASK);
509 * Session Setup specific flags CAP_DYNAMIC_REAUTH
510 * and CAP_EXTENDED_SECURITY are passed by the caller.
511 * We need that in order to do guest logins even if
512 * CAP_EXTENDED_SECURITY is negotiated.
514 client_capabilities &= ~(CAP_DYNAMIC_REAUTH|CAP_EXTENDED_SECURITY);
515 sesssetup_capabilities &= (CAP_DYNAMIC_REAUTH|CAP_EXTENDED_SECURITY);
516 client_capabilities |= sesssetup_capabilities;
518 return client_capabilities;
521 /****************************************************************************
522 Do a NT1 guest session setup.
523 ****************************************************************************/
525 struct cli_session_setup_guest_state {
526 struct cli_state *cli;
531 static void cli_session_setup_guest_done(struct tevent_req *subreq);
533 struct tevent_req *cli_session_setup_guest_create(TALLOC_CTX *mem_ctx,
534 struct tevent_context *ev,
535 struct cli_state *cli,
536 struct tevent_req **psmbreq)
538 struct tevent_req *req, *subreq;
539 struct cli_session_setup_guest_state *state;
543 req = tevent_req_create(mem_ctx, &state,
544 struct cli_session_setup_guest_state);
551 SCVAL(vwv+0, 0, 0xFF);
554 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
556 SSVAL(vwv+4, 0, cli_state_get_vc_num(cli));
557 SIVAL(vwv+5, 0, smb1cli_conn_server_session_key(cli->conn));
562 SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli, 0));
564 bytes = talloc_array(state, uint8_t, 0);
566 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "", 1, /* username */
568 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "", 1, /* workgroup */
570 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "Unix", 5, NULL);
571 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "Samba", 6, NULL);
578 state->bytes.iov_base = (void *)bytes;
579 state->bytes.iov_len = talloc_get_size(bytes);
581 subreq = cli_smb_req_create(state, ev, cli, SMBsesssetupX, 0, 0, 13,
582 vwv, 1, &state->bytes);
583 if (subreq == NULL) {
587 tevent_req_set_callback(subreq, cli_session_setup_guest_done, req);
592 struct tevent_req *cli_session_setup_guest_send(TALLOC_CTX *mem_ctx,
593 struct tevent_context *ev,
594 struct cli_state *cli)
596 struct tevent_req *req, *subreq;
599 req = cli_session_setup_guest_create(mem_ctx, ev, cli, &subreq);
604 status = smb1cli_req_chain_submit(&subreq, 1);
605 if (!NT_STATUS_IS_OK(status)) {
606 tevent_req_nterror(req, status);
607 return tevent_req_post(req, ev);
612 static void cli_session_setup_guest_done(struct tevent_req *subreq)
614 struct tevent_req *req = tevent_req_callback_data(
615 subreq, struct tevent_req);
616 struct cli_session_setup_guest_state *state = tevent_req_data(
617 req, struct cli_session_setup_guest_state);
618 struct cli_state *cli = state->cli;
629 status = cli_smb_recv(subreq, state, &in, 3, &wct, &vwv,
632 if (!NT_STATUS_IS_OK(status)) {
633 tevent_req_nterror(req, status);
637 inhdr = in + NBT_HDR_SIZE;
640 cli_state_set_uid(state->cli, SVAL(inhdr, HDR_UID));
641 smb1cli_session_set_action(cli->smb1.session, SVAL(vwv+2, 0));
643 status = smb_bytes_talloc_string(cli,
650 if (!NT_STATUS_IS_OK(status)) {
651 tevent_req_nterror(req, status);
656 status = smb_bytes_talloc_string(cli,
663 if (!NT_STATUS_IS_OK(status)) {
664 tevent_req_nterror(req, status);
669 status = smb_bytes_talloc_string(cli,
676 if (!NT_STATUS_IS_OK(status)) {
677 tevent_req_nterror(req, status);
681 tevent_req_done(req);
684 NTSTATUS cli_session_setup_guest_recv(struct tevent_req *req)
686 return tevent_req_simple_recv_ntstatus(req);
689 /* The following is calculated from :
691 * (smb_wcnt * 2) = 24 (smb_wcnt == 12 in cli_session_setup_blob_send() )
692 * (strlen("Unix") + 1 + strlen("Samba") + 1) * 2 = 22 (unicode strings at
696 #define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22)
698 struct cli_sesssetup_blob_state {
699 struct tevent_context *ev;
700 struct cli_state *cli;
702 uint16_t max_blob_size;
705 struct iovec *recv_iov;
708 const uint8_t *inbuf;
715 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state *state,
716 struct tevent_req **psubreq);
717 static void cli_sesssetup_blob_done(struct tevent_req *subreq);
719 static struct tevent_req *cli_sesssetup_blob_send(TALLOC_CTX *mem_ctx,
720 struct tevent_context *ev,
721 struct cli_state *cli,
724 struct tevent_req *req, *subreq;
725 struct cli_sesssetup_blob_state *state;
726 uint32_t usable_space;
728 req = tevent_req_create(mem_ctx, &state,
729 struct cli_sesssetup_blob_state);
737 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
738 usable_space = UINT16_MAX;
740 usable_space = cli_state_available_size(cli,
741 BASE_SESSSETUP_BLOB_PACKET_SIZE);
744 if (usable_space == 0) {
745 DEBUG(1, ("cli_session_setup_blob: cli->max_xmit too small "
746 "(not possible to send %u bytes)\n",
747 BASE_SESSSETUP_BLOB_PACKET_SIZE + 1));
748 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
749 return tevent_req_post(req, ev);
751 state->max_blob_size = MIN(usable_space, 0xFFFF);
753 if (!cli_sesssetup_blob_next(state, &subreq)) {
754 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
755 return tevent_req_post(req, ev);
757 tevent_req_set_callback(subreq, cli_sesssetup_blob_done, req);
761 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state *state,
762 struct tevent_req **psubreq)
764 struct tevent_req *subreq;
767 thistime = MIN(state->blob.length, state->max_blob_size);
769 state->this_blob.data = state->blob.data;
770 state->this_blob.length = thistime;
772 state->blob.data += thistime;
773 state->blob.length -= thistime;
775 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
776 subreq = smb2cli_session_setup_send(state, state->ev,
779 state->cli->smb2.session,
781 SMB2_CAP_DFS, /* in_capabilities */
783 0, /* in_previous_session_id */
785 if (subreq == NULL) {
789 uint16_t in_buf_size = 0;
790 uint16_t in_mpx_max = 0;
791 uint16_t in_vc_num = 0;
792 uint32_t in_sess_key = 0;
793 uint32_t in_capabilities = 0;
794 const char *in_native_os = NULL;
795 const char *in_native_lm = NULL;
797 in_buf_size = CLI_BUFFER_SIZE;
798 in_mpx_max = smbXcli_conn_max_requests(state->cli->conn);
799 in_vc_num = cli_state_get_vc_num(state->cli);
800 in_sess_key = smb1cli_conn_server_session_key(state->cli->conn);
801 in_capabilities = cli_session_setup_capabilities(state->cli,
802 CAP_EXTENDED_SECURITY);
803 in_native_os = "Unix";
804 in_native_lm = "Samba";
807 * For now we keep the same values as before,
808 * we may remove these in a separate commit later.
814 subreq = smb1cli_session_setup_ext_send(state, state->ev,
817 state->cli->smb1.pid,
818 state->cli->smb1.session,
827 if (subreq == NULL) {
835 static void cli_sesssetup_blob_done(struct tevent_req *subreq)
837 struct tevent_req *req = tevent_req_callback_data(
838 subreq, struct tevent_req);
839 struct cli_sesssetup_blob_state *state = tevent_req_data(
840 req, struct cli_sesssetup_blob_state);
843 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
844 status = smb2cli_session_setup_recv(subreq, state,
848 status = smb1cli_session_setup_ext_recv(subreq, state,
852 &state->out_native_os,
853 &state->out_native_lm);
856 if (!NT_STATUS_IS_OK(status)
857 && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
858 tevent_req_nterror(req, status);
862 state->status = status;
864 status = cli_state_update_after_sesssetup(state->cli,
865 state->out_native_os,
866 state->out_native_lm,
868 if (tevent_req_nterror(req, status)) {
872 if (state->blob.length != 0) {
876 if (!cli_sesssetup_blob_next(state, &subreq)) {
880 tevent_req_set_callback(subreq, cli_sesssetup_blob_done, req);
883 tevent_req_done(req);
886 static NTSTATUS cli_sesssetup_blob_recv(struct tevent_req *req,
889 const uint8_t **pinbuf,
890 struct iovec **precv_iov)
892 struct cli_sesssetup_blob_state *state = tevent_req_data(
893 req, struct cli_sesssetup_blob_state);
895 struct iovec *recv_iov;
897 if (tevent_req_is_nterror(req, &status)) {
898 TALLOC_FREE(state->cli->smb2.session);
899 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
900 tevent_req_received(req);
904 recv_iov = talloc_move(mem_ctx, &state->recv_iov);
906 *pblob = state->ret_blob;
908 if (pinbuf != NULL) {
909 *pinbuf = state->inbuf;
911 if (precv_iov != NULL) {
912 *precv_iov = recv_iov;
914 /* could be NT_STATUS_MORE_PROCESSING_REQUIRED */
915 status = state->status;
916 tevent_req_received(req);
920 /****************************************************************************
921 Do a spnego/NTLMSSP encrypted session setup.
922 ****************************************************************************/
924 struct cli_session_setup_gensec_state {
925 struct tevent_context *ev;
926 struct cli_state *cli;
927 struct auth_generic_state *auth_generic;
930 const uint8_t *inbuf;
931 struct iovec *recv_iov;
935 DATA_BLOB session_key;
938 static int cli_session_setup_gensec_state_destructor(
939 struct cli_session_setup_gensec_state *state)
941 TALLOC_FREE(state->auth_generic);
942 data_blob_clear_free(&state->session_key);
946 static void cli_session_setup_gensec_local_next(struct tevent_req *req);
947 static void cli_session_setup_gensec_local_done(struct tevent_req *subreq);
948 static void cli_session_setup_gensec_remote_next(struct tevent_req *req);
949 static void cli_session_setup_gensec_remote_done(struct tevent_req *subreq);
950 static void cli_session_setup_gensec_ready(struct tevent_req *req);
952 static struct tevent_req *cli_session_setup_gensec_send(
953 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
954 struct cli_credentials *creds,
955 const char *target_service,
956 const char *target_hostname)
958 struct tevent_req *req;
959 struct cli_session_setup_gensec_state *state;
961 const DATA_BLOB *b = NULL;
963 req = tevent_req_create(mem_ctx, &state,
964 struct cli_session_setup_gensec_state);
971 talloc_set_destructor(
972 state, cli_session_setup_gensec_state_destructor);
974 status = auth_generic_client_prepare(state, &state->auth_generic);
975 if (tevent_req_nterror(req, status)) {
976 return tevent_req_post(req, ev);
979 status = auth_generic_set_creds(state->auth_generic, creds);
980 if (tevent_req_nterror(req, status)) {
981 return tevent_req_post(req, ev);
984 gensec_want_feature(state->auth_generic->gensec_security,
985 GENSEC_FEATURE_SESSION_KEY);
987 if (target_service != NULL) {
988 status = gensec_set_target_service(
989 state->auth_generic->gensec_security,
991 if (tevent_req_nterror(req, status)) {
992 return tevent_req_post(req, ev);
996 if (target_hostname != NULL) {
997 status = gensec_set_target_hostname(
998 state->auth_generic->gensec_security,
1000 if (tevent_req_nterror(req, status)) {
1001 return tevent_req_post(req, ev);
1005 b = smbXcli_conn_server_gss_blob(cli->conn);
1007 state->blob_in = *b;
1010 state->is_anonymous = cli_credentials_is_anonymous(state->auth_generic->credentials);
1012 status = auth_generic_client_start(state->auth_generic,
1014 if (tevent_req_nterror(req, status)) {
1015 return tevent_req_post(req, ev);
1018 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
1019 state->cli->smb2.session = smbXcli_session_create(cli,
1021 if (tevent_req_nomem(state->cli->smb2.session, req)) {
1022 return tevent_req_post(req, ev);
1026 cli_session_setup_gensec_local_next(req);
1027 if (!tevent_req_is_in_progress(req)) {
1028 return tevent_req_post(req, ev);
1034 static void cli_session_setup_gensec_local_next(struct tevent_req *req)
1036 struct cli_session_setup_gensec_state *state =
1037 tevent_req_data(req,
1038 struct cli_session_setup_gensec_state);
1039 struct tevent_req *subreq = NULL;
1041 if (state->local_ready) {
1042 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1046 subreq = gensec_update_send(state, state->ev,
1047 state->auth_generic->gensec_security,
1049 if (tevent_req_nomem(subreq, req)) {
1052 tevent_req_set_callback(subreq, cli_session_setup_gensec_local_done, req);
1055 static void cli_session_setup_gensec_local_done(struct tevent_req *subreq)
1057 struct tevent_req *req =
1058 tevent_req_callback_data(subreq,
1060 struct cli_session_setup_gensec_state *state =
1061 tevent_req_data(req,
1062 struct cli_session_setup_gensec_state);
1065 status = gensec_update_recv(subreq, state, &state->blob_out);
1066 TALLOC_FREE(subreq);
1067 state->blob_in = data_blob_null;
1068 if (!NT_STATUS_IS_OK(status) &&
1069 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
1071 tevent_req_nterror(req, status);
1075 if (NT_STATUS_IS_OK(status)) {
1076 state->local_ready = true;
1079 if (state->local_ready && state->remote_ready) {
1080 cli_session_setup_gensec_ready(req);
1084 cli_session_setup_gensec_remote_next(req);
1087 static void cli_session_setup_gensec_remote_next(struct tevent_req *req)
1089 struct cli_session_setup_gensec_state *state =
1090 tevent_req_data(req,
1091 struct cli_session_setup_gensec_state);
1092 struct tevent_req *subreq = NULL;
1094 if (state->remote_ready) {
1095 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1099 subreq = cli_sesssetup_blob_send(state, state->ev,
1100 state->cli, state->blob_out);
1101 if (tevent_req_nomem(subreq, req)) {
1104 tevent_req_set_callback(subreq,
1105 cli_session_setup_gensec_remote_done,
1109 static void cli_session_setup_gensec_remote_done(struct tevent_req *subreq)
1111 struct tevent_req *req =
1112 tevent_req_callback_data(subreq,
1114 struct cli_session_setup_gensec_state *state =
1115 tevent_req_data(req,
1116 struct cli_session_setup_gensec_state);
1119 state->inbuf = NULL;
1120 TALLOC_FREE(state->recv_iov);
1122 status = cli_sesssetup_blob_recv(subreq, state, &state->blob_in,
1123 &state->inbuf, &state->recv_iov);
1124 TALLOC_FREE(subreq);
1125 data_blob_free(&state->blob_out);
1126 if (!NT_STATUS_IS_OK(status) &&
1127 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
1129 tevent_req_nterror(req, status);
1133 if (NT_STATUS_IS_OK(status)) {
1134 struct smbXcli_session *session = NULL;
1135 bool is_guest = false;
1137 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
1138 session = state->cli->smb2.session;
1140 session = state->cli->smb1.session;
1143 is_guest = smbXcli_session_is_guest(session);
1146 * We can't finish the gensec handshake, we don't
1147 * have a negotiated session key.
1149 * So just pretend we are completely done,
1150 * we need to continue as anonymous from this point,
1151 * as we can't get a session key.
1153 * Note that smbXcli_session_is_guest()
1154 * always returns false if we require signing.
1156 state->blob_in = data_blob_null;
1157 state->local_ready = true;
1158 state->is_anonymous = true;
1161 state->remote_ready = true;
1164 if (state->local_ready && state->remote_ready) {
1165 cli_session_setup_gensec_ready(req);
1169 cli_session_setup_gensec_local_next(req);
1172 static void cli_session_dump_keys(TALLOC_CTX *mem_ctx,
1173 struct smbXcli_session *session,
1174 DATA_BLOB session_key)
1177 DATA_BLOB sig = data_blob_null;
1178 DATA_BLOB app = data_blob_null;
1179 DATA_BLOB enc = data_blob_null;
1180 DATA_BLOB dec = data_blob_null;
1181 uint64_t sid = smb2cli_session_current_id(session);
1183 status = smb2cli_session_signing_key(session, mem_ctx, &sig);
1184 if (!NT_STATUS_IS_OK(status)) {
1187 status = smbXcli_session_application_key(session, mem_ctx, &app);
1188 if (!NT_STATUS_IS_OK(status)) {
1191 status = smb2cli_session_encryption_key(session, mem_ctx, &enc);
1192 if (!NT_STATUS_IS_OK(status)) {
1195 status = smb2cli_session_decryption_key(session, mem_ctx, &dec);
1196 if (!NT_STATUS_IS_OK(status)) {
1200 DEBUG(0, ("debug encryption: dumping generated session keys\n"));
1201 DEBUGADD(0, ("Session Id "));
1202 dump_data(0, (uint8_t*)&sid, sizeof(sid));
1203 DEBUGADD(0, ("Session Key "));
1204 dump_data(0, session_key.data, session_key.length);
1205 DEBUGADD(0, ("Signing Key "));
1206 dump_data(0, sig.data, sig.length);
1207 DEBUGADD(0, ("App Key "));
1208 dump_data(0, app.data, app.length);
1210 /* In client code, ServerIn is the encryption key */
1212 DEBUGADD(0, ("ServerIn Key "));
1213 dump_data(0, enc.data, enc.length);
1214 DEBUGADD(0, ("ServerOut Key "));
1215 dump_data(0, dec.data, dec.length);
1218 data_blob_clear_free(&sig);
1219 data_blob_clear_free(&app);
1220 data_blob_clear_free(&enc);
1221 data_blob_clear_free(&dec);
1224 static void cli_session_setup_gensec_ready(struct tevent_req *req)
1226 struct cli_session_setup_gensec_state *state =
1227 tevent_req_data(req,
1228 struct cli_session_setup_gensec_state);
1229 const char *server_domain = NULL;
1232 if (state->blob_in.length != 0) {
1233 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1237 if (state->blob_out.length != 0) {
1238 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1243 * gensec_ntlmssp_server_domain() returns NULL
1244 * if NTLMSSP is not used.
1246 * We can remove this later
1247 * and leave the server domain empty for SMB2 and above
1248 * in future releases.
1250 server_domain = gensec_ntlmssp_server_domain(
1251 state->auth_generic->gensec_security);
1253 if (state->cli->server_domain[0] == '\0' && server_domain != NULL) {
1254 TALLOC_FREE(state->cli->server_domain);
1255 state->cli->server_domain = talloc_strdup(state->cli,
1257 if (state->cli->server_domain == NULL) {
1258 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1263 if (state->is_anonymous) {
1265 * Windows server does not set the
1266 * SMB2_SESSION_FLAG_IS_NULL flag.
1268 * This fix makes sure we do not try
1269 * to verify a signature on the final
1270 * session setup response.
1272 tevent_req_done(req);
1276 status = gensec_session_key(state->auth_generic->gensec_security,
1277 state, &state->session_key);
1278 if (tevent_req_nterror(req, status)) {
1282 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
1283 struct smbXcli_session *session = state->cli->smb2.session;
1285 status = smb2cli_session_set_session_key(session,
1288 if (tevent_req_nterror(req, status)) {
1291 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB3_00
1292 && lp_debug_encryption())
1294 cli_session_dump_keys(state, session, state->session_key);
1297 struct smbXcli_session *session = state->cli->smb1.session;
1300 status = smb1cli_session_set_session_key(session,
1301 state->session_key);
1302 if (tevent_req_nterror(req, status)) {
1306 active = smb1cli_conn_activate_signing(state->cli->conn,
1312 ok = smb1cli_conn_check_signing(state->cli->conn,
1315 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1321 tevent_req_done(req);
1324 static NTSTATUS cli_session_setup_gensec_recv(struct tevent_req *req)
1326 struct cli_session_setup_gensec_state *state =
1327 tevent_req_data(req,
1328 struct cli_session_setup_gensec_state);
1331 if (tevent_req_is_nterror(req, &status)) {
1332 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
1335 return NT_STATUS_OK;
1338 static char *cli_session_setup_get_account(TALLOC_CTX *mem_ctx,
1339 const char *principal)
1343 account = talloc_strdup(mem_ctx, principal);
1344 if (account == NULL) {
1347 p = strchr_m(account, '@');
1354 /****************************************************************************
1355 Do a spnego encrypted session setup.
1357 user_domain: The shortname of the domain the user/machine is a member of.
1358 dest_realm: The realm we're connecting to, if NULL we use our default realm.
1359 ****************************************************************************/
1361 struct cli_session_setup_spnego_state {
1365 static void cli_session_setup_spnego_done(struct tevent_req *subreq);
1367 static struct tevent_req *cli_session_setup_spnego_send(
1368 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
1369 struct cli_credentials *creds)
1371 struct tevent_req *req, *subreq;
1372 struct cli_session_setup_spnego_state *state;
1373 const char *target_service = NULL;
1374 const char *target_hostname = NULL;
1377 req = tevent_req_create(mem_ctx, &state,
1378 struct cli_session_setup_spnego_state);
1383 target_service = "cifs";
1384 target_hostname = smbXcli_conn_remote_name(cli->conn);
1386 status = cli_session_creds_prepare_krb5(cli, creds);
1387 if (tevent_req_nterror(req, status)) {
1388 return tevent_req_post(req, ev);
1391 DBG_INFO("Connect to %s as %s using SPNEGO\n",
1393 cli_credentials_get_principal(creds, talloc_tos()));
1395 subreq = cli_session_setup_gensec_send(state, ev, cli, creds,
1396 target_service, target_hostname);
1397 if (tevent_req_nomem(subreq, req)) {
1398 return tevent_req_post(req, ev);
1400 tevent_req_set_callback(
1401 subreq, cli_session_setup_spnego_done, req);
1405 static void cli_session_setup_spnego_done(struct tevent_req *subreq)
1407 struct tevent_req *req = tevent_req_callback_data(
1408 subreq, struct tevent_req);
1411 status = cli_session_setup_gensec_recv(subreq);
1412 TALLOC_FREE(subreq);
1413 if (tevent_req_nterror(req, status)) {
1417 tevent_req_done(req);
1420 static ADS_STATUS cli_session_setup_spnego_recv(struct tevent_req *req)
1422 struct cli_session_setup_spnego_state *state = tevent_req_data(
1423 req, struct cli_session_setup_spnego_state);
1426 if (tevent_req_is_nterror(req, &status)) {
1427 state->result = ADS_ERROR_NT(status);
1430 return state->result;
1433 struct cli_session_setup_creds_state {
1434 struct cli_state *cli;
1435 DATA_BLOB apassword_blob;
1436 DATA_BLOB upassword_blob;
1437 DATA_BLOB lm_session_key;
1438 DATA_BLOB session_key;
1439 char *out_native_os;
1440 char *out_native_lm;
1441 char *out_primary_domain;
1444 static void cli_session_setup_creds_cleanup(struct tevent_req *req,
1445 enum tevent_req_state req_state)
1447 struct cli_session_setup_creds_state *state = tevent_req_data(
1448 req, struct cli_session_setup_creds_state);
1450 if (req_state != TEVENT_REQ_RECEIVED) {
1455 * We only call data_blob_clear() as
1456 * some of the blobs point to the same memory.
1458 * We let the talloc hierarchy free the memory.
1460 data_blob_clear(&state->apassword_blob);
1461 data_blob_clear(&state->upassword_blob);
1462 data_blob_clear(&state->lm_session_key);
1463 data_blob_clear(&state->session_key);
1464 ZERO_STRUCTP(state);
1467 static void cli_session_setup_creds_done_spnego(struct tevent_req *subreq);
1468 static void cli_session_setup_creds_done_nt1(struct tevent_req *subreq);
1469 static void cli_session_setup_creds_done_lm21(struct tevent_req *subreq);
1471 /****************************************************************************
1472 Send a session setup. The username and workgroup is in UNIX character
1473 format and must be converted to DOS codepage format before sending. If the
1474 password is in plaintext, the same should be done.
1475 ****************************************************************************/
1477 struct tevent_req *cli_session_setup_creds_send(TALLOC_CTX *mem_ctx,
1478 struct tevent_context *ev,
1479 struct cli_state *cli,
1480 struct cli_credentials *creds)
1482 struct tevent_req *req, *subreq;
1483 struct cli_session_setup_creds_state *state;
1484 uint16_t sec_mode = smb1cli_conn_server_security_mode(cli->conn);
1485 bool use_spnego = false;
1487 enum credentials_use_kerberos krb5_state;
1488 uint32_t gensec_features;
1489 const char *username = "";
1490 const char *domain = "";
1491 DATA_BLOB target_info = data_blob_null;
1492 DATA_BLOB challenge = data_blob_null;
1493 uint16_t in_buf_size = 0;
1494 uint16_t in_mpx_max = 0;
1495 uint16_t in_vc_num = 0;
1496 uint32_t in_sess_key = 0;
1497 const char *in_native_os = NULL;
1498 const char *in_native_lm = NULL;
1501 req = tevent_req_create(mem_ctx, &state,
1502 struct cli_session_setup_creds_state);
1508 tevent_req_set_cleanup_fn(req, cli_session_setup_creds_cleanup);
1510 krb5_state = cli_credentials_get_kerberos_state(creds);
1511 gensec_features = cli_credentials_get_gensec_features(creds);
1513 switch (krb5_state) {
1514 case CRED_MUST_USE_KERBEROS:
1515 cli->use_kerberos = true;
1516 cli->fallback_after_kerberos = false;
1518 case CRED_AUTO_USE_KERBEROS:
1519 cli->use_kerberos = true;
1520 cli->fallback_after_kerberos = true;
1522 case CRED_DONT_USE_KERBEROS:
1523 cli->use_kerberos = false;
1524 cli->fallback_after_kerberos = false;
1528 if (gensec_features & GENSEC_FEATURE_NTLM_CCACHE) {
1529 cli->use_ccache = true;
1531 cli->use_ccache = false;
1535 * Now work out what sort of session setup we are going to
1536 * do. I have split this into separate functions to make the flow a bit
1537 * easier to understand (tridge).
1539 if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_NT1) {
1541 } else if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
1543 } else if (smb1cli_conn_capabilities(cli->conn) & CAP_EXTENDED_SECURITY) {
1545 * if the server supports extended security then use SPNEGO
1546 * even for anonymous connections.
1554 subreq = cli_session_setup_spnego_send(
1555 state, ev, cli, creds);
1556 if (tevent_req_nomem(subreq, req)) {
1557 return tevent_req_post(req, ev);
1559 tevent_req_set_callback(subreq, cli_session_setup_creds_done_spnego,
1564 if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_LANMAN1) {
1566 * SessionSetupAndX was introduced by LANMAN 1.0. So we skip
1567 * this step against older servers.
1569 tevent_req_done(req);
1570 return tevent_req_post(req, ev);
1573 if (cli_credentials_is_anonymous(creds)) {
1575 * Do an anonymous session setup
1577 goto non_spnego_creds_done;
1580 if ((sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0) {
1582 * Do an anonymous session setup,
1583 * the password is passed via the tree connect.
1585 goto non_spnego_creds_done;
1588 cli_credentials_get_ntlm_username_domain(creds, state,
1591 if (tevent_req_nomem(username, req)) {
1592 return tevent_req_post(req, ev);
1594 if (tevent_req_nomem(domain, req)) {
1595 return tevent_req_post(req, ev);
1598 DBG_INFO("Connect to %s as %s using NTLM\n", domain, username);
1600 if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) {
1601 bool use_unicode = smbXcli_conn_use_unicode(cli->conn);
1602 uint8_t *bytes = NULL;
1603 size_t bytes_len = 0;
1604 const char *pw = cli_credentials_get_password(creds);
1610 pw_len = strlen(pw) + 1;
1612 if (!lp_client_plaintext_auth()) {
1613 DEBUG(1, ("Server requested PLAINTEXT password but "
1614 "'client plaintext auth = no'\n"));
1615 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1616 return tevent_req_post(req, ev);
1619 bytes = talloc_array(state, uint8_t, 0);
1620 bytes = trans2_bytes_push_str(bytes, use_unicode,
1621 pw, pw_len, &bytes_len);
1622 if (tevent_req_nomem(bytes, req)) {
1623 return tevent_req_post(req, ev);
1628 * CAP_UNICODE, can only be negotiated by NT1.
1630 state->upassword_blob = data_blob_const(bytes,
1633 state->apassword_blob = data_blob_const(bytes,
1637 goto non_spnego_creds_done;
1640 challenge = data_blob_const(smb1cli_conn_server_challenge(cli->conn), 8);
1642 if (smbXcli_conn_protocol(cli->conn) == PROTOCOL_NT1) {
1643 if (lp_client_ntlmv2_auth() && lp_client_use_spnego()) {
1645 * Don't send an NTLMv2 response without NTLMSSP if we
1646 * want to use spnego support.
1648 DEBUG(1, ("Server does not support EXTENDED_SECURITY "
1649 " but 'client use spnego = yes'"
1650 " and 'client ntlmv2 auth = yes' is set\n"));
1651 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1652 return tevent_req_post(req, ev);
1655 if (lp_client_ntlmv2_auth()) {
1656 flags |= CLI_CRED_NTLMv2_AUTH;
1659 * note that the 'domain' here is a best
1660 * guess - we don't know the server's domain
1661 * at this point. Windows clients also don't
1664 target_info = NTLMv2_generate_names_blob(state,
1667 if (tevent_req_nomem(target_info.data, req)) {
1668 return tevent_req_post(req, ev);
1671 flags |= CLI_CRED_NTLM_AUTH;
1672 if (lp_client_lanman_auth()) {
1673 flags |= CLI_CRED_LANMAN_AUTH;
1677 if (!lp_client_lanman_auth()) {
1678 DEBUG(1, ("Server requested user level LM password but "
1679 "'client lanman auth = no' is set.\n"));
1680 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1681 return tevent_req_post(req, ev);
1684 flags |= CLI_CRED_LANMAN_AUTH;
1687 status = cli_credentials_get_ntlm_response(creds, state, &flags,
1690 &state->apassword_blob,
1691 &state->upassword_blob,
1692 &state->lm_session_key,
1693 &state->session_key);
1694 if (tevent_req_nterror(req, status)) {
1695 return tevent_req_post(req, ev);
1698 non_spnego_creds_done:
1700 in_buf_size = CLI_BUFFER_SIZE;
1701 in_mpx_max = smbXcli_conn_max_requests(cli->conn);
1702 in_vc_num = cli_state_get_vc_num(cli);
1703 in_sess_key = smb1cli_conn_server_session_key(cli->conn);
1704 in_native_os = "Unix";
1705 in_native_lm = "Samba";
1707 if (smbXcli_conn_protocol(cli->conn) == PROTOCOL_NT1) {
1708 uint32_t in_capabilities = 0;
1710 in_capabilities = cli_session_setup_capabilities(cli, 0);
1713 * For now we keep the same values as before,
1714 * we may remove these in a separate commit later.
1718 subreq = smb1cli_session_setup_nt1_send(state, ev,
1729 state->apassword_blob,
1730 state->upassword_blob,
1734 if (tevent_req_nomem(subreq, req)) {
1735 return tevent_req_post(req, ev);
1737 tevent_req_set_callback(subreq, cli_session_setup_creds_done_nt1,
1743 * For now we keep the same values as before,
1744 * we may remove these in a separate commit later.
1749 subreq = smb1cli_session_setup_lm21_send(state, ev,
1760 state->apassword_blob,
1763 if (tevent_req_nomem(subreq, req)) {
1764 return tevent_req_post(req, ev);
1766 tevent_req_set_callback(subreq, cli_session_setup_creds_done_lm21,
1771 static void cli_session_setup_creds_done_spnego(struct tevent_req *subreq)
1773 struct tevent_req *req = tevent_req_callback_data(
1774 subreq, struct tevent_req);
1777 status = cli_session_setup_spnego_recv(subreq);
1778 TALLOC_FREE(subreq);
1779 if (!ADS_ERR_OK(status)) {
1780 DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status)));
1781 tevent_req_nterror(req, ads_ntstatus(status));
1784 tevent_req_done(req);
1787 static void cli_session_setup_creds_done_nt1(struct tevent_req *subreq)
1789 struct tevent_req *req = tevent_req_callback_data(
1790 subreq, struct tevent_req);
1791 struct cli_session_setup_creds_state *state = tevent_req_data(
1792 req, struct cli_session_setup_creds_state);
1793 struct cli_state *cli = state->cli;
1795 struct iovec *recv_iov = NULL;
1796 const uint8_t *inbuf = NULL;
1799 status = smb1cli_session_setup_nt1_recv(subreq, state,
1802 &state->out_native_os,
1803 &state->out_native_lm,
1804 &state->out_primary_domain);
1805 TALLOC_FREE(subreq);
1806 if (!NT_STATUS_IS_OK(status)) {
1807 DEBUG(3, ("NT1 login failed: %s\n", nt_errstr(status)));
1808 tevent_req_nterror(req, status);
1812 status = cli_state_update_after_sesssetup(state->cli,
1813 state->out_native_os,
1814 state->out_native_lm,
1815 state->out_primary_domain);
1816 if (tevent_req_nterror(req, status)) {
1820 ok = smb1cli_conn_activate_signing(cli->conn,
1822 state->upassword_blob);
1824 ok = smb1cli_conn_check_signing(cli->conn, inbuf, 1);
1826 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1831 if (state->session_key.data) {
1832 struct smbXcli_session *session = cli->smb1.session;
1834 status = smb1cli_session_set_session_key(session,
1835 state->session_key);
1836 if (tevent_req_nterror(req, status)) {
1841 tevent_req_done(req);
1844 static void cli_session_setup_creds_done_lm21(struct tevent_req *subreq)
1846 struct tevent_req *req = tevent_req_callback_data(
1847 subreq, struct tevent_req);
1848 struct cli_session_setup_creds_state *state = tevent_req_data(
1849 req, struct cli_session_setup_creds_state);
1852 status = smb1cli_session_setup_lm21_recv(subreq, state,
1853 &state->out_native_os,
1854 &state->out_native_lm);
1855 TALLOC_FREE(subreq);
1856 if (!NT_STATUS_IS_OK(status)) {
1857 DEBUG(3, ("LM21 login failed: %s\n", nt_errstr(status)));
1858 tevent_req_nterror(req, status);
1862 status = cli_state_update_after_sesssetup(state->cli,
1863 state->out_native_os,
1864 state->out_native_lm,
1866 if (tevent_req_nterror(req, status)) {
1870 tevent_req_done(req);
1873 NTSTATUS cli_session_setup_creds_recv(struct tevent_req *req)
1875 return tevent_req_simple_recv_ntstatus(req);
1878 NTSTATUS cli_session_setup_creds(struct cli_state *cli,
1879 struct cli_credentials *creds)
1881 struct tevent_context *ev;
1882 struct tevent_req *req;
1883 NTSTATUS status = NT_STATUS_NO_MEMORY;
1885 if (smbXcli_conn_has_async_calls(cli->conn)) {
1886 return NT_STATUS_INVALID_PARAMETER;
1888 ev = samba_tevent_context_init(talloc_tos());
1892 req = cli_session_setup_creds_send(ev, ev, cli, creds);
1896 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1899 status = cli_session_setup_creds_recv(req);
1905 NTSTATUS cli_session_setup_anon(struct cli_state *cli)
1908 struct cli_credentials *creds = NULL;
1910 creds = cli_credentials_init_anon(cli);
1911 if (creds == NULL) {
1912 return NT_STATUS_NO_MEMORY;
1915 status = cli_session_setup_creds(cli, creds);
1917 if (!NT_STATUS_IS_OK(status)) {
1921 return NT_STATUS_OK;
1924 /****************************************************************************
1926 *****************************************************************************/
1928 struct cli_ulogoff_state {
1929 struct cli_state *cli;
1933 static void cli_ulogoff_done(struct tevent_req *subreq);
1935 static struct tevent_req *cli_ulogoff_send(TALLOC_CTX *mem_ctx,
1936 struct tevent_context *ev,
1937 struct cli_state *cli)
1939 struct tevent_req *req, *subreq;
1940 struct cli_ulogoff_state *state;
1942 req = tevent_req_create(mem_ctx, &state, struct cli_ulogoff_state);
1948 SCVAL(state->vwv+0, 0, 0xFF);
1949 SCVAL(state->vwv+1, 0, 0);
1950 SSVAL(state->vwv+2, 0, 0);
1952 subreq = cli_smb_send(state, ev, cli, SMBulogoffX, 0, 0, 2, state->vwv,
1954 if (tevent_req_nomem(subreq, req)) {
1955 return tevent_req_post(req, ev);
1957 tevent_req_set_callback(subreq, cli_ulogoff_done, req);
1961 static void cli_ulogoff_done(struct tevent_req *subreq)
1963 struct tevent_req *req = tevent_req_callback_data(
1964 subreq, struct tevent_req);
1965 struct cli_ulogoff_state *state = tevent_req_data(
1966 req, struct cli_ulogoff_state);
1969 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
1970 if (!NT_STATUS_IS_OK(status)) {
1971 tevent_req_nterror(req, status);
1974 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
1975 tevent_req_done(req);
1978 static NTSTATUS cli_ulogoff_recv(struct tevent_req *req)
1980 return tevent_req_simple_recv_ntstatus(req);
1983 NTSTATUS cli_ulogoff(struct cli_state *cli)
1985 struct tevent_context *ev;
1986 struct tevent_req *req;
1987 NTSTATUS status = NT_STATUS_NO_MEMORY;
1989 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
1990 status = smb2cli_logoff(cli->conn,
1993 if (!NT_STATUS_IS_OK(status)) {
1996 smb2cli_session_set_id_and_flags(cli->smb2.session,
1998 return NT_STATUS_OK;
2001 if (smbXcli_conn_has_async_calls(cli->conn)) {
2002 return NT_STATUS_INVALID_PARAMETER;
2004 ev = samba_tevent_context_init(talloc_tos());
2008 req = cli_ulogoff_send(ev, ev, cli);
2012 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2015 status = cli_ulogoff_recv(req);
2021 /****************************************************************************
2023 ****************************************************************************/
2025 struct cli_tcon_andx_state {
2026 struct cli_state *cli;
2031 static void cli_tcon_andx_done(struct tevent_req *subreq);
2033 struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx,
2034 struct tevent_context *ev,
2035 struct cli_state *cli,
2036 const char *share, const char *dev,
2037 const char *pass, int passlen,
2038 struct tevent_req **psmbreq)
2040 struct tevent_req *req, *subreq;
2041 struct cli_tcon_andx_state *state;
2046 uint16_t sec_mode = smb1cli_conn_server_security_mode(cli->conn);
2047 uint16_t tcon_flags = 0;
2051 req = tevent_req_create(mem_ctx, &state, struct cli_tcon_andx_state);
2058 TALLOC_FREE(cli->smb1.tcon);
2059 cli->smb1.tcon = smbXcli_tcon_create(cli);
2060 if (tevent_req_nomem(cli->smb1.tcon, req)) {
2061 return tevent_req_post(req, ev);
2063 smb1cli_tcon_set_id(cli->smb1.tcon, UINT16_MAX);
2065 cli->share = talloc_strdup(cli, share);
2070 /* in user level security don't send a password now */
2071 if (sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {
2074 } else if (pass == NULL) {
2075 DEBUG(1, ("Server not using user level security and no "
2076 "password supplied.\n"));
2080 if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) &&
2081 *pass && passlen != 24) {
2082 if (!lp_client_lanman_auth()) {
2083 DEBUG(1, ("Server requested LANMAN password "
2084 "(share-level security) but "
2085 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2090 * Non-encrypted passwords - convert to DOS codepage before
2093 SMBencrypt(pass, smb1cli_conn_server_challenge(cli->conn), p24);
2095 pass = (const char *)p24;
2097 if((sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL
2098 |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE))
2102 if (!lp_client_plaintext_auth() && (*pass)) {
2103 DEBUG(1, ("Server requested PLAINTEXT "
2105 "'client plaintext auth = no' or 'client ntlmv2 auth = yes'\n"));
2110 * Non-encrypted passwords - convert to DOS codepage
2113 tmp_pass = talloc_array(talloc_tos(), uint8_t, 0);
2114 if (tevent_req_nomem(tmp_pass, req)) {
2115 return tevent_req_post(req, ev);
2117 tmp_pass = trans2_bytes_push_str(tmp_pass,
2118 false, /* always DOS */
2122 if (tevent_req_nomem(tmp_pass, req)) {
2123 return tevent_req_post(req, ev);
2125 pass = (const char *)tmp_pass;
2126 passlen = talloc_get_size(tmp_pass);
2130 tcon_flags |= TCONX_FLAG_EXTENDED_RESPONSE;
2131 tcon_flags |= TCONX_FLAG_EXTENDED_SIGNATURES;
2133 SCVAL(vwv+0, 0, 0xFF);
2136 SSVAL(vwv+2, 0, tcon_flags);
2137 SSVAL(vwv+3, 0, passlen);
2139 if (passlen && pass) {
2140 bytes = (uint8_t *)talloc_memdup(state, pass, passlen);
2142 bytes = talloc_array(state, uint8_t, 0);
2148 tmp = talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
2149 smbXcli_conn_remote_name(cli->conn), share);
2154 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), tmp, strlen(tmp)+1,
2159 * Add the devicetype
2161 tmp = talloc_strdup_upper(talloc_tos(), dev);
2166 bytes = smb_bytes_push_str(bytes, false, tmp, strlen(tmp)+1, NULL);
2169 if (bytes == NULL) {
2174 state->bytes.iov_base = (void *)bytes;
2175 state->bytes.iov_len = talloc_get_size(bytes);
2177 subreq = cli_smb_req_create(state, ev, cli, SMBtconX, 0, 0, 4, vwv,
2179 if (subreq == NULL) {
2183 tevent_req_set_callback(subreq, cli_tcon_andx_done, req);
2188 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
2189 return tevent_req_post(req, ev);
2192 struct tevent_req *cli_tcon_andx_send(TALLOC_CTX *mem_ctx,
2193 struct tevent_context *ev,
2194 struct cli_state *cli,
2195 const char *share, const char *dev,
2196 const char *pass, int passlen)
2198 struct tevent_req *req, *subreq;
2201 req = cli_tcon_andx_create(mem_ctx, ev, cli, share, dev, pass, passlen,
2206 if (subreq == NULL) {
2209 status = smb1cli_req_chain_submit(&subreq, 1);
2210 if (!NT_STATUS_IS_OK(status)) {
2211 tevent_req_nterror(req, status);
2212 return tevent_req_post(req, ev);
2217 static void cli_tcon_andx_done(struct tevent_req *subreq)
2219 struct tevent_req *req = tevent_req_callback_data(
2220 subreq, struct tevent_req);
2221 struct cli_tcon_andx_state *state = tevent_req_data(
2222 req, struct cli_tcon_andx_state);
2223 struct cli_state *cli = state->cli;
2231 uint16_t optional_support = 0;
2233 status = cli_smb_recv(subreq, state, &in, 0, &wct, &vwv,
2234 &num_bytes, &bytes);
2235 TALLOC_FREE(subreq);
2236 if (!NT_STATUS_IS_OK(status)) {
2237 tevent_req_nterror(req, status);
2241 inhdr = in + NBT_HDR_SIZE;
2244 if (clistr_pull_talloc(cli,
2245 (const char *)inhdr,
2246 SVAL(inhdr, HDR_FLG2),
2250 STR_TERMINATE|STR_ASCII) == -1) {
2251 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2255 cli->dev = talloc_strdup(cli, "");
2256 if (cli->dev == NULL) {
2257 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2262 if ((smbXcli_conn_protocol(cli->conn) >= PROTOCOL_NT1) && (num_bytes == 3)) {
2263 /* almost certainly win95 - enable bug fixes */
2268 * Make sure that we have the optional support 16-bit field. WCT > 2.
2269 * Avoids issues when connecting to Win9x boxes sharing files
2272 if ((wct > 2) && (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_LANMAN2)) {
2273 optional_support = SVAL(vwv+2, 0);
2276 if (optional_support & SMB_EXTENDED_SIGNATURES) {
2277 smb1cli_session_protect_session_key(cli->smb1.session);
2280 smb1cli_tcon_set_values(state->cli->smb1.tcon,
2281 SVAL(inhdr, HDR_TID),
2283 0, /* maximal_access */
2284 0, /* guest_maximal_access */
2286 NULL); /* fs_type */
2288 tevent_req_done(req);
2291 NTSTATUS cli_tcon_andx_recv(struct tevent_req *req)
2293 return tevent_req_simple_recv_ntstatus(req);
2296 NTSTATUS cli_tcon_andx(struct cli_state *cli, const char *share,
2297 const char *dev, const char *pass, int passlen)
2299 TALLOC_CTX *frame = talloc_stackframe();
2300 struct tevent_context *ev;
2301 struct tevent_req *req;
2302 NTSTATUS status = NT_STATUS_NO_MEMORY;
2304 if (smbXcli_conn_has_async_calls(cli->conn)) {
2306 * Can't use sync call while an async call is in flight
2308 status = NT_STATUS_INVALID_PARAMETER;
2312 ev = samba_tevent_context_init(frame);
2317 req = cli_tcon_andx_send(frame, ev, cli, share, dev, pass, passlen);
2322 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2326 status = cli_tcon_andx_recv(req);
2332 struct cli_tree_connect_state {
2333 struct cli_state *cli;
2336 static struct tevent_req *cli_raw_tcon_send(
2337 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
2338 const char *service, const char *pass, const char *dev);
2339 static NTSTATUS cli_raw_tcon_recv(struct tevent_req *req,
2340 uint16_t *max_xmit, uint16_t *tid);
2342 static void cli_tree_connect_smb2_done(struct tevent_req *subreq);
2343 static void cli_tree_connect_andx_done(struct tevent_req *subreq);
2344 static void cli_tree_connect_raw_done(struct tevent_req *subreq);
2346 static struct tevent_req *cli_tree_connect_send(
2347 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
2348 const char *share, const char *dev, const char *pass)
2350 struct tevent_req *req, *subreq;
2351 struct cli_tree_connect_state *state;
2357 passlen = strlen(pass) + 1;
2359 req = tevent_req_create(mem_ctx, &state,
2360 struct cli_tree_connect_state);
2366 cli->share = talloc_strdup(cli, share);
2367 if (tevent_req_nomem(cli->share, req)) {
2368 return tevent_req_post(req, ev);
2371 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
2374 TALLOC_FREE(cli->smb2.tcon);
2375 cli->smb2.tcon = smbXcli_tcon_create(cli);
2376 if (tevent_req_nomem(cli->smb2.tcon, req)) {
2377 return tevent_req_post(req, ev);
2380 unc = talloc_asprintf(state, "\\\\%s\\%s",
2381 smbXcli_conn_remote_name(cli->conn),
2383 if (tevent_req_nomem(unc, req)) {
2384 return tevent_req_post(req, ev);
2387 subreq = smb2cli_tcon_send(state, ev, cli->conn, cli->timeout,
2388 cli->smb2.session, cli->smb2.tcon,
2391 if (tevent_req_nomem(subreq, req)) {
2392 return tevent_req_post(req, ev);
2394 tevent_req_set_callback(subreq, cli_tree_connect_smb2_done,
2399 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_LANMAN1) {
2400 subreq = cli_tcon_andx_send(state, ev, cli, share, dev,
2402 if (tevent_req_nomem(subreq, req)) {
2403 return tevent_req_post(req, ev);
2405 tevent_req_set_callback(subreq, cli_tree_connect_andx_done,
2410 subreq = cli_raw_tcon_send(state, ev, cli, share, pass, dev);
2411 if (tevent_req_nomem(subreq, req)) {
2412 return tevent_req_post(req, ev);
2414 tevent_req_set_callback(subreq, cli_tree_connect_raw_done, req);
2419 static void cli_tree_connect_smb2_done(struct tevent_req *subreq)
2421 tevent_req_simple_finish_ntstatus(
2422 subreq, smb2cli_tcon_recv(subreq));
2425 static void cli_tree_connect_andx_done(struct tevent_req *subreq)
2427 tevent_req_simple_finish_ntstatus(
2428 subreq, cli_tcon_andx_recv(subreq));
2431 static void cli_tree_connect_raw_done(struct tevent_req *subreq)
2433 struct tevent_req *req = tevent_req_callback_data(
2434 subreq, struct tevent_req);
2435 struct cli_tree_connect_state *state = tevent_req_data(
2436 req, struct cli_tree_connect_state);
2438 uint16_t max_xmit = 0;
2441 status = cli_raw_tcon_recv(subreq, &max_xmit, &tid);
2442 if (tevent_req_nterror(req, status)) {
2446 smb1cli_tcon_set_values(state->cli->smb1.tcon,
2448 0, /* optional_support */
2449 0, /* maximal_access */
2450 0, /* guest_maximal_access */
2452 NULL); /* fs_type */
2454 tevent_req_done(req);
2457 static NTSTATUS cli_tree_connect_recv(struct tevent_req *req)
2459 return tevent_req_simple_recv_ntstatus(req);
2462 NTSTATUS cli_tree_connect(struct cli_state *cli, const char *share,
2463 const char *dev, const char *pass)
2465 struct tevent_context *ev;
2466 struct tevent_req *req;
2467 NTSTATUS status = NT_STATUS_NO_MEMORY;
2469 if (smbXcli_conn_has_async_calls(cli->conn)) {
2470 return NT_STATUS_INVALID_PARAMETER;
2472 ev = samba_tevent_context_init(talloc_tos());
2476 req = cli_tree_connect_send(ev, ev, cli, share, dev, pass);
2480 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2483 status = cli_tree_connect_recv(req);
2489 NTSTATUS cli_tree_connect_creds(struct cli_state *cli,
2490 const char *share, const char *dev,
2491 struct cli_credentials *creds)
2493 const char *pw = NULL;
2495 if (creds != NULL) {
2496 pw = cli_credentials_get_password(creds);
2499 return cli_tree_connect(cli, share, dev, pw);
2502 /****************************************************************************
2503 Send a tree disconnect.
2504 ****************************************************************************/
2506 struct cli_tdis_state {
2507 struct cli_state *cli;
2510 static void cli_tdis_done(struct tevent_req *subreq);
2512 static struct tevent_req *cli_tdis_send(TALLOC_CTX *mem_ctx,
2513 struct tevent_context *ev,
2514 struct cli_state *cli)
2516 struct tevent_req *req, *subreq;
2517 struct cli_tdis_state *state;
2519 req = tevent_req_create(mem_ctx, &state, struct cli_tdis_state);
2525 subreq = cli_smb_send(state, ev, cli, SMBtdis, 0, 0, 0, NULL, 0, NULL);
2526 if (tevent_req_nomem(subreq, req)) {
2527 return tevent_req_post(req, ev);
2529 tevent_req_set_callback(subreq, cli_tdis_done, req);
2533 static void cli_tdis_done(struct tevent_req *subreq)
2535 struct tevent_req *req = tevent_req_callback_data(
2536 subreq, struct tevent_req);
2537 struct cli_tdis_state *state = tevent_req_data(
2538 req, struct cli_tdis_state);
2541 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
2542 TALLOC_FREE(subreq);
2543 if (!NT_STATUS_IS_OK(status)) {
2544 tevent_req_nterror(req, status);
2547 TALLOC_FREE(state->cli->smb1.tcon);
2548 tevent_req_done(req);
2551 static NTSTATUS cli_tdis_recv(struct tevent_req *req)
2553 return tevent_req_simple_recv_ntstatus(req);
2556 NTSTATUS cli_tdis(struct cli_state *cli)
2558 struct tevent_context *ev;
2559 struct tevent_req *req;
2560 NTSTATUS status = NT_STATUS_NO_MEMORY;
2562 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
2563 status = smb2cli_tdis(cli->conn,
2567 if (NT_STATUS_IS_OK(status)) {
2568 TALLOC_FREE(cli->smb2.tcon);
2573 if (smbXcli_conn_has_async_calls(cli->conn)) {
2574 return NT_STATUS_INVALID_PARAMETER;
2576 ev = samba_tevent_context_init(talloc_tos());
2580 req = cli_tdis_send(ev, ev, cli);
2584 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2587 status = cli_tdis_recv(req);
2593 struct cli_connect_sock_state {
2594 const char **called_names;
2595 const char **calling_names;
2601 static void cli_connect_sock_done(struct tevent_req *subreq);
2604 * Async only if we don't have to look up the name, i.e. "pss" is set with a
2608 static struct tevent_req *cli_connect_sock_send(
2609 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2610 const char *host, int name_type, const struct sockaddr_storage *pss,
2611 const char *myname, uint16_t port)
2613 struct tevent_req *req, *subreq;
2614 struct cli_connect_sock_state *state;
2615 struct sockaddr_storage *addrs;
2616 unsigned i, num_addrs;
2619 req = tevent_req_create(mem_ctx, &state,
2620 struct cli_connect_sock_state);
2625 if ((pss == NULL) || is_zero_addr(pss)) {
2628 * Here we cheat. resolve_name_list is not async at all. So
2629 * this call will only be really async if the name lookup has
2630 * been done externally.
2633 status = resolve_name_list(state, host, name_type,
2634 &addrs, &num_addrs);
2635 if (!NT_STATUS_IS_OK(status)) {
2636 tevent_req_nterror(req, status);
2637 return tevent_req_post(req, ev);
2640 addrs = talloc_array(state, struct sockaddr_storage, 1);
2641 if (tevent_req_nomem(addrs, req)) {
2642 return tevent_req_post(req, ev);
2648 state->called_names = talloc_array(state, const char *, num_addrs);
2649 if (tevent_req_nomem(state->called_names, req)) {
2650 return tevent_req_post(req, ev);
2652 state->called_types = talloc_array(state, int, num_addrs);
2653 if (tevent_req_nomem(state->called_types, req)) {
2654 return tevent_req_post(req, ev);
2656 state->calling_names = talloc_array(state, const char *, num_addrs);
2657 if (tevent_req_nomem(state->calling_names, req)) {
2658 return tevent_req_post(req, ev);
2660 for (i=0; i<num_addrs; i++) {
2661 state->called_names[i] = host;
2662 state->called_types[i] = name_type;
2663 state->calling_names[i] = myname;
2666 subreq = smbsock_any_connect_send(
2667 state, ev, addrs, state->called_names, state->called_types,
2668 state->calling_names, NULL, num_addrs, port);
2669 if (tevent_req_nomem(subreq, req)) {
2670 return tevent_req_post(req, ev);
2672 tevent_req_set_callback(subreq, cli_connect_sock_done, req);
2676 static void cli_connect_sock_done(struct tevent_req *subreq)
2678 struct tevent_req *req = tevent_req_callback_data(
2679 subreq, struct tevent_req);
2680 struct cli_connect_sock_state *state = tevent_req_data(
2681 req, struct cli_connect_sock_state);
2684 status = smbsock_any_connect_recv(subreq, &state->fd, NULL,
2686 TALLOC_FREE(subreq);
2687 if (tevent_req_nterror(req, status)) {
2690 set_socket_options(state->fd, lp_socket_options());
2691 tevent_req_done(req);
2694 static NTSTATUS cli_connect_sock_recv(struct tevent_req *req,
2695 int *pfd, uint16_t *pport)
2697 struct cli_connect_sock_state *state = tevent_req_data(
2698 req, struct cli_connect_sock_state);
2701 if (tevent_req_is_nterror(req, &status)) {
2705 *pport = state->port;
2706 return NT_STATUS_OK;
2709 struct cli_connect_nb_state {
2710 const char *desthost;
2713 struct cli_state *cli;
2716 static void cli_connect_nb_done(struct tevent_req *subreq);
2718 static struct tevent_req *cli_connect_nb_send(
2719 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2720 const char *host, const struct sockaddr_storage *dest_ss,
2721 uint16_t port, int name_type, const char *myname,
2722 int signing_state, int flags)
2724 struct tevent_req *req, *subreq;
2725 struct cli_connect_nb_state *state;
2727 req = tevent_req_create(mem_ctx, &state, struct cli_connect_nb_state);
2731 state->signing_state = signing_state;
2732 state->flags = flags;
2735 char *p = strchr(host, '#');
2738 name_type = strtol(p+1, NULL, 16);
2739 host = talloc_strndup(state, host, p - host);
2740 if (tevent_req_nomem(host, req)) {
2741 return tevent_req_post(req, ev);
2745 state->desthost = host;
2746 } else if (dest_ss != NULL) {
2747 state->desthost = print_canonical_sockaddr(state, dest_ss);
2748 if (tevent_req_nomem(state->desthost, req)) {
2749 return tevent_req_post(req, ev);
2752 /* No host or dest_ss given. Error out. */
2753 tevent_req_error(req, EINVAL);
2754 return tevent_req_post(req, ev);
2757 subreq = cli_connect_sock_send(state, ev, host, name_type, dest_ss,
2759 if (tevent_req_nomem(subreq, req)) {
2760 return tevent_req_post(req, ev);
2762 tevent_req_set_callback(subreq, cli_connect_nb_done, req);
2766 static void cli_connect_nb_done(struct tevent_req *subreq)
2768 struct tevent_req *req = tevent_req_callback_data(
2769 subreq, struct tevent_req);
2770 struct cli_connect_nb_state *state = tevent_req_data(
2771 req, struct cli_connect_nb_state);
2776 status = cli_connect_sock_recv(subreq, &fd, &port);
2777 TALLOC_FREE(subreq);
2778 if (tevent_req_nterror(req, status)) {
2782 state->cli = cli_state_create(state, fd, state->desthost,
2783 state->signing_state, state->flags);
2784 if (tevent_req_nomem(state->cli, req)) {
2788 tevent_req_done(req);
2791 static NTSTATUS cli_connect_nb_recv(struct tevent_req *req,
2792 struct cli_state **pcli)
2794 struct cli_connect_nb_state *state = tevent_req_data(
2795 req, struct cli_connect_nb_state);
2798 if (tevent_req_is_nterror(req, &status)) {
2801 *pcli = talloc_move(NULL, &state->cli);
2802 return NT_STATUS_OK;
2805 NTSTATUS cli_connect_nb(const char *host, const struct sockaddr_storage *dest_ss,
2806 uint16_t port, int name_type, const char *myname,
2807 int signing_state, int flags, struct cli_state **pcli)
2809 struct tevent_context *ev;
2810 struct tevent_req *req;
2811 NTSTATUS status = NT_STATUS_NO_MEMORY;
2813 ev = samba_tevent_context_init(talloc_tos());
2817 req = cli_connect_nb_send(ev, ev, host, dest_ss, port, name_type,
2818 myname, signing_state, flags);
2822 if (!tevent_req_set_endtime(req, ev, timeval_current_ofs(20, 0))) {
2825 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2828 status = cli_connect_nb_recv(req, pcli);
2834 struct cli_start_connection_state {
2835 struct tevent_context *ev;
2836 struct cli_state *cli;
2841 static void cli_start_connection_connected(struct tevent_req *subreq);
2842 static void cli_start_connection_done(struct tevent_req *subreq);
2845 establishes a connection to after the negprot.
2846 @param output_cli A fully initialised cli structure, non-null only on success
2847 @param dest_host The netbios name of the remote host
2848 @param dest_ss (optional) The the destination IP, NULL for name based lookup
2849 @param port (optional) The destination port (0 for default)
2852 static struct tevent_req *cli_start_connection_send(
2853 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2854 const char *my_name, const char *dest_host,
2855 const struct sockaddr_storage *dest_ss, int port,
2856 int signing_state, int flags)
2858 struct tevent_req *req, *subreq;
2859 struct cli_start_connection_state *state;
2861 req = tevent_req_create(mem_ctx, &state,
2862 struct cli_start_connection_state);
2868 if (signing_state == SMB_SIGNING_IPC_DEFAULT) {
2869 state->min_protocol = lp_client_ipc_min_protocol();
2870 state->max_protocol = lp_client_ipc_max_protocol();
2872 state->min_protocol = lp_client_min_protocol();
2873 state->max_protocol = lp_client_max_protocol();
2876 if (flags & CLI_FULL_CONNECTION_FORCE_SMB1) {
2877 state->max_protocol = MIN(state->max_protocol, PROTOCOL_NT1);
2880 if (flags & CLI_FULL_CONNECTION_DISABLE_SMB1) {
2881 state->min_protocol = MAX(state->max_protocol, PROTOCOL_SMB2_02);
2882 state->max_protocol = MAX(state->max_protocol, PROTOCOL_LATEST);
2885 subreq = cli_connect_nb_send(state, ev, dest_host, dest_ss, port,
2886 0x20, my_name, signing_state, flags);
2887 if (tevent_req_nomem(subreq, req)) {
2888 return tevent_req_post(req, ev);
2890 tevent_req_set_callback(subreq, cli_start_connection_connected, req);
2894 static void cli_start_connection_connected(struct tevent_req *subreq)
2896 struct tevent_req *req = tevent_req_callback_data(
2897 subreq, struct tevent_req);
2898 struct cli_start_connection_state *state = tevent_req_data(
2899 req, struct cli_start_connection_state);
2902 status = cli_connect_nb_recv(subreq, &state->cli);
2903 TALLOC_FREE(subreq);
2904 if (tevent_req_nterror(req, status)) {
2908 subreq = smbXcli_negprot_send(state, state->ev, state->cli->conn,
2909 state->cli->timeout,
2910 state->min_protocol,
2911 state->max_protocol,
2912 WINDOWS_CLIENT_PURE_SMB2_NEGPROT_INITIAL_CREDIT_ASK);
2913 if (tevent_req_nomem(subreq, req)) {
2916 tevent_req_set_callback(subreq, cli_start_connection_done, req);
2919 static void cli_start_connection_done(struct tevent_req *subreq)
2921 struct tevent_req *req = tevent_req_callback_data(
2922 subreq, struct tevent_req);
2923 struct cli_start_connection_state *state = tevent_req_data(
2924 req, struct cli_start_connection_state);
2927 status = smbXcli_negprot_recv(subreq);
2928 TALLOC_FREE(subreq);
2929 if (tevent_req_nterror(req, status)) {
2933 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
2934 /* Ensure we ask for some initial credits. */
2935 smb2cli_conn_set_max_credits(state->cli->conn,
2936 DEFAULT_SMB2_MAX_CREDITS);
2939 tevent_req_done(req);
2942 static NTSTATUS cli_start_connection_recv(struct tevent_req *req,
2943 struct cli_state **output_cli)
2945 struct cli_start_connection_state *state = tevent_req_data(
2946 req, struct cli_start_connection_state);
2949 if (tevent_req_is_nterror(req, &status)) {
2952 *output_cli = state->cli;
2954 return NT_STATUS_OK;
2957 NTSTATUS cli_start_connection(struct cli_state **output_cli,
2958 const char *my_name,
2959 const char *dest_host,
2960 const struct sockaddr_storage *dest_ss, int port,
2961 int signing_state, int flags)
2963 struct tevent_context *ev;
2964 struct tevent_req *req;
2965 NTSTATUS status = NT_STATUS_NO_MEMORY;
2967 ev = samba_tevent_context_init(talloc_tos());
2971 req = cli_start_connection_send(ev, ev, my_name, dest_host, dest_ss,
2972 port, signing_state, flags);
2976 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2979 status = cli_start_connection_recv(req, output_cli);
2985 struct cli_smb1_setup_encryption_blob_state {
2990 uint16_t enc_ctx_id;
2993 static void cli_smb1_setup_encryption_blob_done(struct tevent_req *subreq);
2995 static struct tevent_req *cli_smb1_setup_encryption_blob_send(TALLOC_CTX *mem_ctx,
2996 struct tevent_context *ev,
2997 struct cli_state *cli,
3000 struct tevent_req *req = NULL;
3001 struct cli_smb1_setup_encryption_blob_state *state = NULL;
3002 struct tevent_req *subreq = NULL;
3004 req = tevent_req_create(mem_ctx, &state,
3005 struct cli_smb1_setup_encryption_blob_state);
3010 if (in.length > CLI_BUFFER_SIZE) {
3011 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
3012 return tevent_req_post(req, ev);
3015 SSVAL(state->setup+0, 0, TRANSACT2_SETFSINFO);
3016 SSVAL(state->param, 0, 0);
3017 SSVAL(state->param, 2, SMB_REQUEST_TRANSPORT_ENCRYPTION);
3019 subreq = smb1cli_trans_send(state, ev, cli->conn,
3027 NULL, /* pipe_name */
3033 in.data, in.length, CLI_BUFFER_SIZE);
3034 if (tevent_req_nomem(subreq, req)) {
3035 return tevent_req_post(req, ev);
3037 tevent_req_set_callback(subreq,
3038 cli_smb1_setup_encryption_blob_done,
3044 static void cli_smb1_setup_encryption_blob_done(struct tevent_req *subreq)
3046 struct tevent_req *req =
3047 tevent_req_callback_data(subreq,
3049 struct cli_smb1_setup_encryption_blob_state *state =
3050 tevent_req_data(req,
3051 struct cli_smb1_setup_encryption_blob_state);
3052 uint8_t *rparam=NULL, *rdata=NULL;
3053 uint32_t num_rparam, num_rdata;
3056 status = smb1cli_trans_recv(subreq, state,
3057 NULL, /* recv_flags */
3058 NULL, 0, NULL, /* rsetup */
3059 &rparam, 0, &num_rparam,
3060 &rdata, 0, &num_rdata);
3061 TALLOC_FREE(subreq);
3062 state->status = status;
3063 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
3064 status = NT_STATUS_OK;
3066 if (tevent_req_nterror(req, status)) {
3070 if (num_rparam == 2) {
3071 state->enc_ctx_id = SVAL(rparam, 0);
3073 TALLOC_FREE(rparam);
3075 state->out = data_blob_const(rdata, num_rdata);
3077 tevent_req_done(req);
3080 static NTSTATUS cli_smb1_setup_encryption_blob_recv(struct tevent_req *req,
3081 TALLOC_CTX *mem_ctx,
3083 uint16_t *enc_ctx_id)
3085 struct cli_smb1_setup_encryption_blob_state *state =
3086 tevent_req_data(req,
3087 struct cli_smb1_setup_encryption_blob_state);
3090 if (tevent_req_is_nterror(req, &status)) {
3091 tevent_req_received(req);
3095 status = state->status;
3098 talloc_steal(mem_ctx, out->data);
3100 *enc_ctx_id = state->enc_ctx_id;
3102 tevent_req_received(req);
3106 struct cli_smb1_setup_encryption_state {
3107 struct tevent_context *ev;
3108 struct cli_state *cli;
3109 struct smb_trans_enc_state *es;
3116 static void cli_smb1_setup_encryption_local_next(struct tevent_req *req);
3117 static void cli_smb1_setup_encryption_local_done(struct tevent_req *subreq);
3118 static void cli_smb1_setup_encryption_remote_next(struct tevent_req *req);
3119 static void cli_smb1_setup_encryption_remote_done(struct tevent_req *subreq);
3120 static void cli_smb1_setup_encryption_ready(struct tevent_req *req);
3122 static struct tevent_req *cli_smb1_setup_encryption_send(TALLOC_CTX *mem_ctx,
3123 struct tevent_context *ev,
3124 struct cli_state *cli,
3125 struct cli_credentials *creds)
3127 struct tevent_req *req = NULL;
3128 struct cli_smb1_setup_encryption_state *state = NULL;
3129 struct auth_generic_state *ags = NULL;
3130 const DATA_BLOB *b = NULL;
3131 bool auth_requested = false;
3132 const char *target_service = NULL;
3133 const char *target_hostname = NULL;
3136 req = tevent_req_create(mem_ctx, &state,
3137 struct cli_smb1_setup_encryption_state);
3144 auth_requested = cli_credentials_authentication_requested(creds);
3145 if (!auth_requested) {
3146 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
3147 return tevent_req_post(req, ev);
3150 target_service = "cifs";
3151 target_hostname = smbXcli_conn_remote_name(cli->conn);
3153 status = cli_session_creds_prepare_krb5(cli, creds);
3154 if (tevent_req_nterror(req, status)) {
3155 return tevent_req_post(req, ev);
3158 state->es = talloc_zero(state, struct smb_trans_enc_state);
3159 if (tevent_req_nomem(state->es, req)) {
3160 return tevent_req_post(req, ev);
3163 status = auth_generic_client_prepare(state->es, &ags);
3164 if (tevent_req_nterror(req, status)) {
3165 return tevent_req_post(req, ev);
3168 gensec_want_feature(ags->gensec_security,
3169 GENSEC_FEATURE_SIGN);
3170 gensec_want_feature(ags->gensec_security,
3171 GENSEC_FEATURE_SEAL);
3173 status = auth_generic_set_creds(ags, creds);
3174 if (tevent_req_nterror(req, status)) {
3175 return tevent_req_post(req, ev);
3178 if (target_service != NULL) {
3179 status = gensec_set_target_service(ags->gensec_security,
3181 if (tevent_req_nterror(req, status)) {
3182 return tevent_req_post(req, ev);
3186 if (target_hostname != NULL) {
3187 status = gensec_set_target_hostname(ags->gensec_security,
3189 if (tevent_req_nterror(req, status)) {
3190 return tevent_req_post(req, ev);
3194 gensec_set_max_update_size(ags->gensec_security,
3197 b = smbXcli_conn_server_gss_blob(state->cli->conn);
3199 state->blob_in = *b;
3202 status = auth_generic_client_start(ags, GENSEC_OID_SPNEGO);
3203 if (tevent_req_nterror(req, status)) {
3204 return tevent_req_post(req, ev);
3208 * We only need the gensec_security part from here.
3210 state->es->gensec_security = talloc_move(state->es,
3211 &ags->gensec_security);
3214 cli_smb1_setup_encryption_local_next(req);
3215 if (!tevent_req_is_in_progress(req)) {
3216 return tevent_req_post(req, ev);
3222 static void cli_smb1_setup_encryption_local_next(struct tevent_req *req)
3224 struct cli_smb1_setup_encryption_state *state =
3225 tevent_req_data(req,
3226 struct cli_smb1_setup_encryption_state);
3227 struct tevent_req *subreq = NULL;
3229 if (state->local_ready) {
3230 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3234 subreq = gensec_update_send(state, state->ev,
3235 state->es->gensec_security,
3237 if (tevent_req_nomem(subreq, req)) {
3240 tevent_req_set_callback(subreq, cli_smb1_setup_encryption_local_done, req);
3243 static void cli_smb1_setup_encryption_local_done(struct tevent_req *subreq)
3245 struct tevent_req *req =
3246 tevent_req_callback_data(subreq,
3248 struct cli_smb1_setup_encryption_state *state =
3249 tevent_req_data(req,
3250 struct cli_smb1_setup_encryption_state);
3253 status = gensec_update_recv(subreq, state, &state->blob_out);
3254 TALLOC_FREE(subreq);
3255 state->blob_in = data_blob_null;
3256 if (!NT_STATUS_IS_OK(status) &&
3257 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
3259 tevent_req_nterror(req, status);
3263 if (NT_STATUS_IS_OK(status)) {
3264 state->local_ready = true;
3268 * We always get NT_STATUS_OK from the server even if it is not ready.
3269 * So guess the server is ready when we are ready and already sent
3270 * our last blob to the server.
3272 if (state->local_ready && state->blob_out.length == 0) {
3273 state->remote_ready = true;
3276 if (state->local_ready && state->remote_ready) {
3277 cli_smb1_setup_encryption_ready(req);
3281 cli_smb1_setup_encryption_remote_next(req);
3284 static void cli_smb1_setup_encryption_remote_next(struct tevent_req *req)
3286 struct cli_smb1_setup_encryption_state *state =
3287 tevent_req_data(req,
3288 struct cli_smb1_setup_encryption_state);
3289 struct tevent_req *subreq = NULL;
3291 if (state->remote_ready) {
3292 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3296 subreq = cli_smb1_setup_encryption_blob_send(state, state->ev,
3297 state->cli, state->blob_out);
3298 if (tevent_req_nomem(subreq, req)) {
3301 tevent_req_set_callback(subreq,
3302 cli_smb1_setup_encryption_remote_done,
3306 static void cli_smb1_setup_encryption_remote_done(struct tevent_req *subreq)
3308 struct tevent_req *req =
3309 tevent_req_callback_data(subreq,
3311 struct cli_smb1_setup_encryption_state *state =
3312 tevent_req_data(req,
3313 struct cli_smb1_setup_encryption_state);
3316 status = cli_smb1_setup_encryption_blob_recv(subreq, state,
3318 &state->es->enc_ctx_num);
3319 TALLOC_FREE(subreq);
3320 data_blob_free(&state->blob_out);
3321 if (!NT_STATUS_IS_OK(status) &&
3322 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
3324 tevent_req_nterror(req, status);
3329 * We always get NT_STATUS_OK even if the server is not ready.
3330 * So guess the server is ready when we are ready and sent
3331 * our last blob to the server.
3333 if (state->local_ready) {
3334 state->remote_ready = true;
3337 if (state->local_ready && state->remote_ready) {
3338 cli_smb1_setup_encryption_ready(req);
3342 cli_smb1_setup_encryption_local_next(req);
3345 static void cli_smb1_setup_encryption_ready(struct tevent_req *req)
3347 struct cli_smb1_setup_encryption_state *state =
3348 tevent_req_data(req,
3349 struct cli_smb1_setup_encryption_state);
3350 struct smb_trans_enc_state *es = NULL;
3352 if (state->blob_in.length != 0) {
3353 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3357 if (state->blob_out.length != 0) {
3358 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3362 es = talloc_move(state->cli->conn, &state->es);
3364 smb1cli_conn_set_encryption(state->cli->conn, es);
3367 tevent_req_done(req);
3370 static NTSTATUS cli_smb1_setup_encryption_recv(struct tevent_req *req)
3372 return tevent_req_simple_recv_ntstatus(req);
3375 NTSTATUS cli_smb1_setup_encryption(struct cli_state *cli,
3376 struct cli_credentials *creds)
3378 struct tevent_context *ev = NULL;
3379 struct tevent_req *req = NULL;
3380 NTSTATUS status = NT_STATUS_NO_MEMORY;
3382 ev = samba_tevent_context_init(talloc_tos());
3386 req = cli_smb1_setup_encryption_send(ev, ev, cli, creds);
3390 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
3393 status = cli_smb1_setup_encryption_recv(req);
3400 establishes a connection right up to doing tconX, password specified.
3401 @param output_cli A fully initialised cli structure, non-null only on success
3402 @param dest_host The netbios name of the remote host
3403 @param dest_ip (optional) The the destination IP, NULL for name based lookup
3404 @param port (optional) The destination port (0 for default)
3405 @param service (optional) The share to make the connection to. Should be 'unqualified' in any way.
3406 @param service_type The 'type' of serivice.
3407 @param creds The used user credentials
3410 struct cli_full_connection_creds_state {
3411 struct tevent_context *ev;
3412 const char *service;
3413 const char *service_type;
3414 struct cli_credentials *creds;
3416 struct cli_state *cli;
3419 static int cli_full_connection_creds_state_destructor(
3420 struct cli_full_connection_creds_state *s)
3422 if (s->cli != NULL) {
3423 cli_shutdown(s->cli);
3429 static void cli_full_connection_creds_conn_done(struct tevent_req *subreq);
3430 static void cli_full_connection_creds_sess_start(struct tevent_req *req);
3431 static void cli_full_connection_creds_sess_done(struct tevent_req *subreq);
3432 static void cli_full_connection_creds_tcon_start(struct tevent_req *req);
3433 static void cli_full_connection_creds_tcon_done(struct tevent_req *subreq);
3435 struct tevent_req *cli_full_connection_creds_send(
3436 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
3437 const char *my_name, const char *dest_host,
3438 const struct sockaddr_storage *dest_ss, int port,
3439 const char *service, const char *service_type,
3440 struct cli_credentials *creds,
3441 int flags, int signing_state)
3443 struct tevent_req *req, *subreq;
3444 struct cli_full_connection_creds_state *state;
3445 enum credentials_use_kerberos krb5_state;
3446 uint32_t gensec_features = 0;
3448 req = tevent_req_create(mem_ctx, &state,
3449 struct cli_full_connection_creds_state);
3453 talloc_set_destructor(state, cli_full_connection_creds_state_destructor);
3455 flags &= ~CLI_FULL_CONNECTION_USE_KERBEROS;
3456 flags &= ~CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS;
3457 flags &= ~CLI_FULL_CONNECTION_USE_CCACHE;
3458 flags &= ~CLI_FULL_CONNECTION_USE_NT_HASH;
3460 krb5_state = cli_credentials_get_kerberos_state(creds);
3461 switch (krb5_state) {
3462 case CRED_MUST_USE_KERBEROS:
3463 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
3464 flags &= ~CLI_FULL_CONNECTION_DONT_SPNEGO;
3466 case CRED_AUTO_USE_KERBEROS:
3467 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
3468 flags |= CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS;
3470 case CRED_DONT_USE_KERBEROS:
3474 gensec_features = cli_credentials_get_gensec_features(creds);
3475 if (gensec_features & GENSEC_FEATURE_NTLM_CCACHE) {
3476 flags |= CLI_FULL_CONNECTION_USE_CCACHE;
3480 state->service = service;
3481 state->service_type = service_type;
3482 state->creds = creds;
3483 state->flags = flags;
3485 subreq = cli_start_connection_send(
3486 state, ev, my_name, dest_host, dest_ss, port,
3487 signing_state, flags);
3488 if (tevent_req_nomem(subreq, req)) {
3489 return tevent_req_post(req, ev);
3491 tevent_req_set_callback(subreq,
3492 cli_full_connection_creds_conn_done,
3497 static void cli_full_connection_creds_conn_done(struct tevent_req *subreq)
3499 struct tevent_req *req = tevent_req_callback_data(
3500 subreq, struct tevent_req);
3501 struct cli_full_connection_creds_state *state = tevent_req_data(
3502 req, struct cli_full_connection_creds_state);
3505 status = cli_start_connection_recv(subreq, &state->cli);
3506 TALLOC_FREE(subreq);
3507 if (tevent_req_nterror(req, status)) {
3511 cli_full_connection_creds_sess_start(req);
3514 static void cli_full_connection_creds_sess_start(struct tevent_req *req)
3516 struct cli_full_connection_creds_state *state = tevent_req_data(
3517 req, struct cli_full_connection_creds_state);
3518 struct tevent_req *subreq = NULL;
3520 subreq = cli_session_setup_creds_send(
3521 state, state->ev, state->cli, state->creds);
3522 if (tevent_req_nomem(subreq, req)) {
3525 tevent_req_set_callback(subreq,
3526 cli_full_connection_creds_sess_done,
3530 static void cli_full_connection_creds_sess_done(struct tevent_req *subreq)
3532 struct tevent_req *req = tevent_req_callback_data(
3533 subreq, struct tevent_req);
3534 struct cli_full_connection_creds_state *state = tevent_req_data(
3535 req, struct cli_full_connection_creds_state);
3538 status = cli_session_setup_creds_recv(subreq);
3539 TALLOC_FREE(subreq);
3541 if (!NT_STATUS_IS_OK(status) &&
3542 (state->flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)) {
3544 state->flags &= ~CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
3546 state->creds = cli_credentials_init_anon(state);
3547 if (tevent_req_nomem(state->creds, req)) {
3551 cli_full_connection_creds_sess_start(req);
3555 if (tevent_req_nterror(req, status)) {
3559 cli_full_connection_creds_tcon_start(req);
3562 static void cli_full_connection_creds_tcon_start(struct tevent_req *req)
3564 struct cli_full_connection_creds_state *state = tevent_req_data(
3565 req, struct cli_full_connection_creds_state);
3566 struct tevent_req *subreq = NULL;
3567 const char *password = NULL;
3569 if (state->service == NULL) {
3570 tevent_req_done(req);
3574 password = cli_credentials_get_password(state->creds);
3576 subreq = cli_tree_connect_send(state, state->ev,
3579 state->service_type,
3581 if (tevent_req_nomem(subreq, req)) {
3584 tevent_req_set_callback(subreq,
3585 cli_full_connection_creds_tcon_done,
3589 static void cli_full_connection_creds_tcon_done(struct tevent_req *subreq)
3591 struct tevent_req *req = tevent_req_callback_data(
3592 subreq, struct tevent_req);
3595 status = cli_tree_connect_recv(subreq);
3596 TALLOC_FREE(subreq);
3597 if (tevent_req_nterror(req, status)) {
3601 tevent_req_done(req);
3604 NTSTATUS cli_full_connection_creds_recv(struct tevent_req *req,
3605 struct cli_state **output_cli)
3607 struct cli_full_connection_creds_state *state = tevent_req_data(
3608 req, struct cli_full_connection_creds_state);
3611 if (tevent_req_is_nterror(req, &status)) {
3614 *output_cli = state->cli;
3615 talloc_set_destructor(state, NULL);
3616 return NT_STATUS_OK;
3619 NTSTATUS cli_full_connection_creds(struct cli_state **output_cli,
3620 const char *my_name,
3621 const char *dest_host,
3622 const struct sockaddr_storage *dest_ss, int port,
3623 const char *service, const char *service_type,
3624 struct cli_credentials *creds,
3628 struct tevent_context *ev;
3629 struct tevent_req *req;
3630 NTSTATUS status = NT_STATUS_NO_MEMORY;
3632 ev = samba_tevent_context_init(talloc_tos());
3636 req = cli_full_connection_creds_send(
3637 ev, ev, my_name, dest_host, dest_ss, port, service,
3638 service_type, creds, flags, signing_state);
3642 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
3645 status = cli_full_connection_creds_recv(req, output_cli);
3651 NTSTATUS cli_full_connection(struct cli_state **output_cli,
3652 const char *my_name,
3653 const char *dest_host,
3654 const struct sockaddr_storage *dest_ss, int port,
3655 const char *service, const char *service_type,
3656 const char *user, const char *domain,
3657 const char *password, int flags,
3660 TALLOC_CTX *frame = talloc_stackframe();
3662 bool use_kerberos = false;
3663 bool fallback_after_kerberos = false;
3664 bool use_ccache = false;
3665 bool pw_nt_hash = false;
3666 struct cli_credentials *creds = NULL;
3668 if (flags & CLI_FULL_CONNECTION_USE_KERBEROS) {
3669 use_kerberos = true;
3672 if (flags & CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS) {
3673 fallback_after_kerberos = true;
3676 if (flags & CLI_FULL_CONNECTION_USE_CCACHE) {
3680 if (flags & CLI_FULL_CONNECTION_USE_NT_HASH) {
3684 creds = cli_session_creds_init(frame,
3687 NULL, /* realm (use default) */
3690 fallback_after_kerberos,
3693 if (creds == NULL) {
3695 return NT_STATUS_NO_MEMORY;
3698 status = cli_full_connection_creds(output_cli, my_name,
3699 dest_host, dest_ss, port,
3700 service, service_type,
3701 creds, flags, signing_state);
3702 if (!NT_STATUS_IS_OK(status)) {
3708 return NT_STATUS_OK;
3711 /****************************************************************************
3712 Send an old style tcon.
3713 ****************************************************************************/
3714 struct cli_raw_tcon_state {
3718 static void cli_raw_tcon_done(struct tevent_req *subreq);
3720 static struct tevent_req *cli_raw_tcon_send(
3721 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
3722 const char *service, const char *pass, const char *dev)
3724 struct tevent_req *req, *subreq;
3725 struct cli_raw_tcon_state *state;
3728 req = tevent_req_create(mem_ctx, &state, struct cli_raw_tcon_state);
3733 if (!lp_client_plaintext_auth() && (*pass)) {
3734 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
3735 " or 'client ntlmv2 auth = yes'\n"));
3736 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
3737 return tevent_req_post(req, ev);
3740 TALLOC_FREE(cli->smb1.tcon);
3741 cli->smb1.tcon = smbXcli_tcon_create(cli);
3742 if (tevent_req_nomem(cli->smb1.tcon, req)) {
3743 return tevent_req_post(req, ev);
3745 smb1cli_tcon_set_id(cli->smb1.tcon, UINT16_MAX);
3747 bytes = talloc_array(state, uint8_t, 0);
3748 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3749 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3750 service, strlen(service)+1, NULL);
3751 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3752 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3753 pass, strlen(pass)+1, NULL);
3754 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3755 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3756 dev, strlen(dev)+1, NULL);
3758 if (tevent_req_nomem(bytes, req)) {
3759 return tevent_req_post(req, ev);
3762 subreq = cli_smb_send(state, ev, cli, SMBtcon, 0, 0, 0, NULL,
3763 talloc_get_size(bytes), bytes);
3764 if (tevent_req_nomem(subreq, req)) {
3765 return tevent_req_post(req, ev);
3767 tevent_req_set_callback(subreq, cli_raw_tcon_done, req);
3771 static void cli_raw_tcon_done(struct tevent_req *subreq)
3773 struct tevent_req *req = tevent_req_callback_data(
3774 subreq, struct tevent_req);
3775 struct cli_raw_tcon_state *state = tevent_req_data(
3776 req, struct cli_raw_tcon_state);
3779 status = cli_smb_recv(subreq, state, NULL, 2, NULL, &state->ret_vwv,
3781 TALLOC_FREE(subreq);
3782 if (tevent_req_nterror(req, status)) {
3785 tevent_req_done(req);
3788 static NTSTATUS cli_raw_tcon_recv(struct tevent_req *req,
3789 uint16_t *max_xmit, uint16_t *tid)
3791 struct cli_raw_tcon_state *state = tevent_req_data(
3792 req, struct cli_raw_tcon_state);
3795 if (tevent_req_is_nterror(req, &status)) {
3798 *max_xmit = SVAL(state->ret_vwv + 0, 0);
3799 *tid = SVAL(state->ret_vwv + 1, 0);
3800 return NT_STATUS_OK;
3803 NTSTATUS cli_raw_tcon(struct cli_state *cli,
3804 const char *service, const char *pass, const char *dev,
3805 uint16_t *max_xmit, uint16_t *tid)
3807 struct tevent_context *ev;
3808 struct tevent_req *req;
3809 NTSTATUS status = NT_STATUS_NO_MEMORY;
3811 ev = samba_tevent_context_init(talloc_tos());
3815 req = cli_raw_tcon_send(ev, ev, cli, service, pass, dev);
3819 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
3822 status = cli_raw_tcon_recv(req, max_xmit, tid);
3828 /* Return a cli_state pointing at the IPC$ share for the given server */
3830 struct cli_state *get_ipc_connect(char *server,
3831 struct sockaddr_storage *server_ss,
3832 const struct user_auth_info *user_info)
3834 struct cli_state *cli;
3836 uint32_t flags = CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
3838 if (get_cmdline_auth_info_use_kerberos(user_info)) {
3839 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
3842 flags |= CLI_FULL_CONNECTION_FORCE_SMB1;
3844 nt_status = cli_full_connection(&cli, NULL, server, server_ss, 0, "IPC$", "IPC",
3845 get_cmdline_auth_info_username(user_info),
3847 get_cmdline_auth_info_password(user_info),
3849 SMB_SIGNING_DEFAULT);
3851 if (NT_STATUS_IS_OK(nt_status)) {
3853 } else if (is_ipaddress(server)) {
3854 /* windows 9* needs a correct NMB name for connections */
3855 fstring remote_name;
3857 if (name_status_find("*", 0, 0, server_ss, remote_name)) {
3858 cli = get_ipc_connect(remote_name, server_ss, user_info);
3867 * Given the IP address of a master browser on the network, return its
3868 * workgroup and connect to it.
3870 * This function is provided to allow additional processing beyond what
3871 * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
3872 * browsers and obtain each master browsers' list of domains (in case the
3873 * first master browser is recently on the network and has not yet
3874 * synchronized with other master browsers and therefore does not yet have the
3875 * entire network browse list)
3878 struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx,
3879 struct sockaddr_storage *mb_ip,
3880 const struct user_auth_info *user_info,
3881 char **pp_workgroup_out)
3883 char addr[INET6_ADDRSTRLEN];
3885 struct cli_state *cli;
3886 struct sockaddr_storage server_ss;
3888 *pp_workgroup_out = NULL;
3890 print_sockaddr(addr, sizeof(addr), mb_ip);
3891 DEBUG(99, ("Looking up name of master browser %s\n",
3895 * Do a name status query to find out the name of the master browser.
3896 * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
3897 * master browser will not respond to a wildcard query (or, at least,
3898 * an NT4 server acting as the domain master browser will not).
3900 * We might be able to use ONLY the query on MSBROWSE, but that's not
3901 * yet been tested with all Windows versions, so until it is, leave
3902 * the original wildcard query as the first choice and fall back to
3903 * MSBROWSE if the wildcard query fails.
3905 if (!name_status_find("*", 0, 0x1d, mb_ip, name) &&
3906 !name_status_find(MSBROWSE, 1, 0x1d, mb_ip, name)) {
3908 DEBUG(99, ("Could not retrieve name status for %s\n",
3913 if (!find_master_ip(name, &server_ss)) {
3914 DEBUG(99, ("Could not find master ip for %s\n", name));
3918 *pp_workgroup_out = talloc_strdup(ctx, name);
3920 DEBUG(4, ("found master browser %s, %s\n", name, addr));
3922 print_sockaddr(addr, sizeof(addr), &server_ss);
3923 cli = get_ipc_connect(addr, &server_ss, user_info);
3929 * Return the IP address and workgroup of a master browser on the network, and
3933 struct cli_state *get_ipc_connect_master_ip_bcast(TALLOC_CTX *ctx,
3934 const struct user_auth_info *user_info,
3935 char **pp_workgroup_out)
3937 struct sockaddr_storage *ip_list;
3938 struct cli_state *cli;
3942 *pp_workgroup_out = NULL;
3944 DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
3946 /* Go looking for workgroups by broadcasting on the local network */
3948 status = name_resolve_bcast(MSBROWSE, 1, talloc_tos(),
3950 if (!NT_STATUS_IS_OK(status)) {
3951 DEBUG(99, ("No master browsers responded: %s\n",
3952 nt_errstr(status)));
3956 for (i = 0; i < count; i++) {
3957 char addr[INET6_ADDRSTRLEN];
3958 print_sockaddr(addr, sizeof(addr), &ip_list[i]);
3959 DEBUG(99, ("Found master browser %s\n", addr));
3961 cli = get_ipc_connect_master_ip(ctx, &ip_list[i],
3962 user_info, pp_workgroup_out);