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"
45 #define STAR_SMBSERVER "*SMBSERVER"
47 static char *cli_session_setup_get_account(TALLOC_CTX *mem_ctx,
48 const char *principal);
50 struct cli_credentials *cli_session_creds_init(TALLOC_CTX *mem_ctx,
56 bool fallback_after_kerberos,
58 bool password_is_nt_hash)
60 struct loadparm_context *lp_ctx = NULL;
61 struct cli_credentials *creds = NULL;
62 const char *principal = NULL;
67 creds = cli_credentials_init(mem_ctx);
72 lp_ctx = loadparm_init_s3(creds, loadparm_s3_helpers());
76 cli_credentials_set_conf(creds, lp_ctx);
78 if (username == NULL) {
82 if (strlen(username) == 0) {
83 if (password != NULL && strlen(password) == 0) {
85 * some callers pass "" as no password
87 * gensec only handles NULL as no password.
91 if (password == NULL) {
92 cli_credentials_set_anonymous(creds);
97 tmp = talloc_strdup(creds, username);
103 /* allow for workgroups as part of the username */
104 if ((p = strchr_m(tmp, '\\')) ||
105 (p = strchr_m(tmp, '/')) ||
106 (p = strchr_m(tmp, *lp_winbind_separator()))) {
112 principal = username;
113 username = cli_session_setup_get_account(creds, principal);
114 if (username == NULL) {
117 ok = strequal(username, principal);
120 * Ok still the same, so it's not a principal
125 if (use_kerberos && fallback_after_kerberos) {
126 cli_credentials_set_kerberos_state(creds,
127 CRED_AUTO_USE_KERBEROS);
128 } else if (use_kerberos) {
129 cli_credentials_set_kerberos_state(creds,
130 CRED_MUST_USE_KERBEROS);
132 cli_credentials_set_kerberos_state(creds,
133 CRED_DONT_USE_KERBEROS);
139 features = cli_credentials_get_gensec_features(creds);
140 features |= GENSEC_FEATURE_NTLM_CCACHE;
141 cli_credentials_set_gensec_features(creds, features);
143 if (password != NULL && strlen(password) == 0) {
145 * some callers pass "" as no password
147 * GENSEC_FEATURE_NTLM_CCACHE only handles
148 * NULL as no password.
154 ok = cli_credentials_set_username(creds,
161 if (domain != NULL) {
162 ok = cli_credentials_set_domain(creds,
170 if (principal != NULL) {
171 ok = cli_credentials_set_principal(creds,
180 ok = cli_credentials_set_realm(creds,
188 if (password != NULL && strlen(password) > 0) {
189 if (password_is_nt_hash) {
190 struct samr_Password nt_hash;
193 converted = strhex_to_str((char *)nt_hash.hash,
194 sizeof(nt_hash.hash),
197 if (converted != sizeof(nt_hash.hash)) {
201 ok = cli_credentials_set_nt_hash(creds,
208 ok = cli_credentials_set_password(creds,
223 NTSTATUS cli_session_creds_prepare_krb5(struct cli_state *cli,
224 struct cli_credentials *creds)
226 TALLOC_CTX *frame = talloc_stackframe();
227 const char *user_principal = NULL;
228 const char *user_account = NULL;
229 const char *user_domain = NULL;
230 const char *pass = NULL;
231 const char *target_hostname = NULL;
232 const DATA_BLOB *server_blob = NULL;
233 bool got_kerberos_mechanism = false;
234 enum credentials_use_kerberos krb5_state;
235 bool try_kerberos = false;
236 bool need_kinit = false;
237 bool auth_requested = true;
240 target_hostname = smbXcli_conn_remote_name(cli->conn);
241 server_blob = smbXcli_conn_server_gss_blob(cli->conn);
243 /* the server might not even do spnego */
244 if (server_blob != NULL && server_blob->length != 0) {
245 char *OIDs[ASN1_MAX_OIDS] = { NULL, };
250 * The server sent us the first part of the SPNEGO exchange in the
251 * negprot reply. It is WRONG to depend on the principal sent in the
252 * negprot reply, but right now we do it. If we don't receive one,
253 * we try to best guess, then fall back to NTLM.
255 ok = spnego_parse_negTokenInit(frame,
262 return NT_STATUS_INVALID_PARAMETER;
264 if (OIDs[0] == NULL) {
266 return NT_STATUS_INVALID_PARAMETER;
269 /* make sure the server understands kerberos */
270 for (i = 0; OIDs[i] != NULL; i++) {
272 DEBUG(3,("got OID=%s\n", OIDs[i]));
274 DEBUGADD(3,("got OID=%s\n", OIDs[i]));
277 if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0 ||
278 strcmp(OIDs[i], OID_KERBEROS5) == 0) {
279 got_kerberos_mechanism = true;
285 auth_requested = cli_credentials_authentication_requested(creds);
286 if (auth_requested) {
288 user_principal = cli_credentials_get_principal(creds, frame);
291 return NT_STATUS_NO_MEMORY;
294 user_account = cli_credentials_get_username(creds);
295 user_domain = cli_credentials_get_domain(creds);
296 pass = cli_credentials_get_password(creds);
298 krb5_state = cli_credentials_get_kerberos_state(creds);
300 if (krb5_state != CRED_DONT_USE_KERBEROS) {
304 if (user_principal == NULL) {
305 try_kerberos = false;
308 if (target_hostname == NULL) {
309 try_kerberos = false;
310 } else if (is_ipaddress(target_hostname)) {
311 try_kerberos = false;
312 } else if (strequal(target_hostname, "localhost")) {
313 try_kerberos = false;
314 } else if (strequal(target_hostname, STAR_SMBSERVER)) {
315 try_kerberos = false;
316 } else if (!auth_requested) {
317 try_kerberos = false;
320 if (krb5_state == CRED_MUST_USE_KERBEROS && !try_kerberos) {
321 DEBUG(0, ("Kerberos auth with '%s' (%s\\%s) to access "
322 "'%s' not possible\n",
323 user_principal, user_domain, user_account,
326 return NT_STATUS_ACCESS_DENIED;
329 if (pass == NULL || strlen(pass) == 0) {
331 } else if (krb5_state == CRED_MUST_USE_KERBEROS) {
332 need_kinit = try_kerberos;
333 } else if (!got_kerberos_mechanism) {
335 * Most likely the server doesn't support
336 * Kerberos, don't waste time doing a kinit
340 need_kinit = try_kerberos;
350 * TODO: This should be done within the gensec layer
353 setenv(KRB5_ENV_CCNAME, "MEMORY:cliconnect", 1);
354 ret = kerberos_kinit_password(user_principal, pass,
355 0 /* no time correction for now */,
358 int dbglvl = DBGLVL_NOTICE;
360 if (krb5_state == CRED_MUST_USE_KERBEROS) {
364 DEBUG(dbglvl, ("Kinit for %s to access %s failed: %s\n",
365 user_principal, target_hostname,
366 error_message(ret)));
367 if (krb5_state == CRED_MUST_USE_KERBEROS) {
369 return krb5_to_nt_status(ret);
373 * Ignore the error and hope that NTLM will work
381 static NTSTATUS cli_state_update_after_sesssetup(struct cli_state *cli,
382 const char *native_os,
383 const char *native_lm,
384 const char *primary_domain)
386 #define _VALID_STR(p) ((p) != NULL && (p)[0] != '\0')
388 if (!_VALID_STR(cli->server_os) && _VALID_STR(native_os)) {
389 cli->server_os = talloc_strdup(cli, native_os);
390 if (cli->server_os == NULL) {
391 return NT_STATUS_NO_MEMORY;
395 if (!_VALID_STR(cli->server_type) && _VALID_STR(native_lm)) {
396 cli->server_type = talloc_strdup(cli, native_lm);
397 if (cli->server_type == NULL) {
398 return NT_STATUS_NO_MEMORY;
402 if (!_VALID_STR(cli->server_domain) && _VALID_STR(primary_domain)) {
403 cli->server_domain = talloc_strdup(cli, primary_domain);
404 if (cli->server_domain == NULL) {
405 return NT_STATUS_NO_MEMORY;
413 /********************************************************
414 Utility function to ensure we always return at least
415 a valid char * pointer to an empty string for the
416 cli->server_os, cli->server_type and cli->server_domain
418 *******************************************************/
420 static NTSTATUS smb_bytes_talloc_string(TALLOC_CTX *mem_ctx,
427 *destlen = clistr_pull_talloc(mem_ctx,
434 if (*destlen == -1) {
435 return NT_STATUS_NO_MEMORY;
439 *dest = talloc_strdup(mem_ctx, "");
441 return NT_STATUS_NO_MEMORY;
447 /****************************************************************************
448 Work out suitable capabilities to offer the server.
449 ****************************************************************************/
451 static uint32_t cli_session_setup_capabilities(struct cli_state *cli,
452 uint32_t sesssetup_capabilities)
454 uint32_t client_capabilities = smb1cli_conn_capabilities(cli->conn);
457 * We only send capabilities based on the mask for:
458 * - client only flags
459 * - flags used in both directions
461 * We do not echo the server only flags, except some legacy flags.
463 * SMB_CAP_LEGACY_CLIENT_MASK contains CAP_LARGE_READX and
464 * CAP_LARGE_WRITEX in order to allow us to do large reads
465 * against old Samba releases (<= 3.6.x).
467 client_capabilities &= (SMB_CAP_BOTH_MASK | SMB_CAP_LEGACY_CLIENT_MASK);
470 * Session Setup specific flags CAP_DYNAMIC_REAUTH
471 * and CAP_EXTENDED_SECURITY are passed by the caller.
472 * We need that in order to do guest logins even if
473 * CAP_EXTENDED_SECURITY is negotiated.
475 client_capabilities &= ~(CAP_DYNAMIC_REAUTH|CAP_EXTENDED_SECURITY);
476 sesssetup_capabilities &= (CAP_DYNAMIC_REAUTH|CAP_EXTENDED_SECURITY);
477 client_capabilities |= sesssetup_capabilities;
479 return client_capabilities;
482 /****************************************************************************
483 Do a NT1 guest session setup.
484 ****************************************************************************/
486 struct cli_session_setup_guest_state {
487 struct cli_state *cli;
492 static void cli_session_setup_guest_done(struct tevent_req *subreq);
494 struct tevent_req *cli_session_setup_guest_create(TALLOC_CTX *mem_ctx,
495 struct tevent_context *ev,
496 struct cli_state *cli,
497 struct tevent_req **psmbreq)
499 struct tevent_req *req, *subreq;
500 struct cli_session_setup_guest_state *state;
504 req = tevent_req_create(mem_ctx, &state,
505 struct cli_session_setup_guest_state);
512 SCVAL(vwv+0, 0, 0xFF);
515 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
517 SSVAL(vwv+4, 0, cli_state_get_vc_num(cli));
518 SIVAL(vwv+5, 0, smb1cli_conn_server_session_key(cli->conn));
523 SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli, 0));
525 bytes = talloc_array(state, uint8_t, 0);
527 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "", 1, /* username */
529 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "", 1, /* workgroup */
531 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "Unix", 5, NULL);
532 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "Samba", 6, NULL);
539 state->bytes.iov_base = (void *)bytes;
540 state->bytes.iov_len = talloc_get_size(bytes);
542 subreq = cli_smb_req_create(state, ev, cli, SMBsesssetupX, 0, 0, 13,
543 vwv, 1, &state->bytes);
544 if (subreq == NULL) {
548 tevent_req_set_callback(subreq, cli_session_setup_guest_done, req);
553 struct tevent_req *cli_session_setup_guest_send(TALLOC_CTX *mem_ctx,
554 struct tevent_context *ev,
555 struct cli_state *cli)
557 struct tevent_req *req, *subreq;
560 req = cli_session_setup_guest_create(mem_ctx, ev, cli, &subreq);
565 status = smb1cli_req_chain_submit(&subreq, 1);
566 if (!NT_STATUS_IS_OK(status)) {
567 tevent_req_nterror(req, status);
568 return tevent_req_post(req, ev);
573 static void cli_session_setup_guest_done(struct tevent_req *subreq)
575 struct tevent_req *req = tevent_req_callback_data(
576 subreq, struct tevent_req);
577 struct cli_session_setup_guest_state *state = tevent_req_data(
578 req, struct cli_session_setup_guest_state);
579 struct cli_state *cli = state->cli;
590 status = cli_smb_recv(subreq, state, &in, 3, &wct, &vwv,
593 if (!NT_STATUS_IS_OK(status)) {
594 tevent_req_nterror(req, status);
598 inhdr = in + NBT_HDR_SIZE;
601 cli_state_set_uid(state->cli, SVAL(inhdr, HDR_UID));
602 smb1cli_session_set_action(cli->smb1.session, SVAL(vwv+2, 0));
604 status = smb_bytes_talloc_string(cli,
611 if (!NT_STATUS_IS_OK(status)) {
612 tevent_req_nterror(req, status);
617 status = smb_bytes_talloc_string(cli,
624 if (!NT_STATUS_IS_OK(status)) {
625 tevent_req_nterror(req, status);
630 status = smb_bytes_talloc_string(cli,
637 if (!NT_STATUS_IS_OK(status)) {
638 tevent_req_nterror(req, status);
643 tevent_req_done(req);
646 NTSTATUS cli_session_setup_guest_recv(struct tevent_req *req)
648 return tevent_req_simple_recv_ntstatus(req);
651 /* The following is calculated from :
653 * (smb_wcnt * 2) = 24 (smb_wcnt == 12 in cli_session_setup_blob_send() )
654 * (strlen("Unix") + 1 + strlen("Samba") + 1) * 2 = 22 (unicode strings at
658 #define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22)
660 struct cli_sesssetup_blob_state {
661 struct tevent_context *ev;
662 struct cli_state *cli;
664 uint16_t max_blob_size;
667 struct iovec *recv_iov;
670 const uint8_t *inbuf;
677 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state *state,
678 struct tevent_req **psubreq);
679 static void cli_sesssetup_blob_done(struct tevent_req *subreq);
681 static struct tevent_req *cli_sesssetup_blob_send(TALLOC_CTX *mem_ctx,
682 struct tevent_context *ev,
683 struct cli_state *cli,
686 struct tevent_req *req, *subreq;
687 struct cli_sesssetup_blob_state *state;
688 uint32_t usable_space;
690 req = tevent_req_create(mem_ctx, &state,
691 struct cli_sesssetup_blob_state);
699 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
700 usable_space = UINT16_MAX;
702 usable_space = cli_state_available_size(cli,
703 BASE_SESSSETUP_BLOB_PACKET_SIZE);
706 if (usable_space == 0) {
707 DEBUG(1, ("cli_session_setup_blob: cli->max_xmit too small "
708 "(not possible to send %u bytes)\n",
709 BASE_SESSSETUP_BLOB_PACKET_SIZE + 1));
710 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
711 return tevent_req_post(req, ev);
713 state->max_blob_size = MIN(usable_space, 0xFFFF);
715 if (!cli_sesssetup_blob_next(state, &subreq)) {
716 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
717 return tevent_req_post(req, ev);
719 tevent_req_set_callback(subreq, cli_sesssetup_blob_done, req);
723 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state *state,
724 struct tevent_req **psubreq)
726 struct tevent_req *subreq;
729 thistime = MIN(state->blob.length, state->max_blob_size);
731 state->this_blob.data = state->blob.data;
732 state->this_blob.length = thistime;
734 state->blob.data += thistime;
735 state->blob.length -= thistime;
737 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
738 subreq = smb2cli_session_setup_send(state, state->ev,
741 state->cli->smb2.session,
743 SMB2_CAP_DFS, /* in_capabilities */
745 0, /* in_previous_session_id */
747 if (subreq == NULL) {
751 uint16_t in_buf_size = 0;
752 uint16_t in_mpx_max = 0;
753 uint16_t in_vc_num = 0;
754 uint32_t in_sess_key = 0;
755 uint32_t in_capabilities = 0;
756 const char *in_native_os = NULL;
757 const char *in_native_lm = NULL;
759 in_buf_size = CLI_BUFFER_SIZE;
760 in_mpx_max = smbXcli_conn_max_requests(state->cli->conn);
761 in_vc_num = cli_state_get_vc_num(state->cli);
762 in_sess_key = smb1cli_conn_server_session_key(state->cli->conn);
763 in_capabilities = cli_session_setup_capabilities(state->cli,
764 CAP_EXTENDED_SECURITY);
765 in_native_os = "Unix";
766 in_native_lm = "Samba";
769 * For now we keep the same values as before,
770 * we may remove these in a separate commit later.
776 subreq = smb1cli_session_setup_ext_send(state, state->ev,
779 state->cli->smb1.pid,
780 state->cli->smb1.session,
789 if (subreq == NULL) {
797 static void cli_sesssetup_blob_done(struct tevent_req *subreq)
799 struct tevent_req *req = tevent_req_callback_data(
800 subreq, struct tevent_req);
801 struct cli_sesssetup_blob_state *state = tevent_req_data(
802 req, struct cli_sesssetup_blob_state);
805 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
806 status = smb2cli_session_setup_recv(subreq, state,
810 status = smb1cli_session_setup_ext_recv(subreq, state,
814 &state->out_native_os,
815 &state->out_native_lm);
818 if (!NT_STATUS_IS_OK(status)
819 && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
820 tevent_req_nterror(req, status);
824 state->status = status;
826 status = cli_state_update_after_sesssetup(state->cli,
827 state->out_native_os,
828 state->out_native_lm,
830 if (tevent_req_nterror(req, status)) {
834 if (state->blob.length != 0) {
838 if (!cli_sesssetup_blob_next(state, &subreq)) {
842 tevent_req_set_callback(subreq, cli_sesssetup_blob_done, req);
845 tevent_req_done(req);
848 static NTSTATUS cli_sesssetup_blob_recv(struct tevent_req *req,
851 const uint8_t **pinbuf,
852 struct iovec **precv_iov)
854 struct cli_sesssetup_blob_state *state = tevent_req_data(
855 req, struct cli_sesssetup_blob_state);
857 struct iovec *recv_iov;
859 if (tevent_req_is_nterror(req, &status)) {
860 TALLOC_FREE(state->cli->smb2.session);
861 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
862 tevent_req_received(req);
866 recv_iov = talloc_move(mem_ctx, &state->recv_iov);
868 *pblob = state->ret_blob;
870 if (pinbuf != NULL) {
871 *pinbuf = state->inbuf;
873 if (precv_iov != NULL) {
874 *precv_iov = recv_iov;
876 /* could be NT_STATUS_MORE_PROCESSING_REQUIRED */
877 status = state->status;
878 tevent_req_received(req);
882 /****************************************************************************
883 Do a spnego/NTLMSSP encrypted session setup.
884 ****************************************************************************/
886 struct cli_session_setup_gensec_state {
887 struct tevent_context *ev;
888 struct cli_state *cli;
889 struct auth_generic_state *auth_generic;
892 const uint8_t *inbuf;
893 struct iovec *recv_iov;
897 DATA_BLOB session_key;
900 static int cli_session_setup_gensec_state_destructor(
901 struct cli_session_setup_gensec_state *state)
903 TALLOC_FREE(state->auth_generic);
904 data_blob_clear_free(&state->session_key);
908 static void cli_session_setup_gensec_local_next(struct tevent_req *req);
909 static void cli_session_setup_gensec_local_done(struct tevent_req *subreq);
910 static void cli_session_setup_gensec_remote_next(struct tevent_req *req);
911 static void cli_session_setup_gensec_remote_done(struct tevent_req *subreq);
912 static void cli_session_setup_gensec_ready(struct tevent_req *req);
914 static struct tevent_req *cli_session_setup_gensec_send(
915 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
916 struct cli_credentials *creds,
917 const char *target_service,
918 const char *target_hostname)
920 struct tevent_req *req;
921 struct cli_session_setup_gensec_state *state;
923 const DATA_BLOB *b = NULL;
925 req = tevent_req_create(mem_ctx, &state,
926 struct cli_session_setup_gensec_state);
933 talloc_set_destructor(
934 state, cli_session_setup_gensec_state_destructor);
936 status = auth_generic_client_prepare(state, &state->auth_generic);
937 if (tevent_req_nterror(req, status)) {
938 return tevent_req_post(req, ev);
941 status = auth_generic_set_creds(state->auth_generic, creds);
942 if (tevent_req_nterror(req, status)) {
943 return tevent_req_post(req, ev);
946 gensec_want_feature(state->auth_generic->gensec_security,
947 GENSEC_FEATURE_SESSION_KEY);
949 if (target_service != NULL) {
950 status = gensec_set_target_service(
951 state->auth_generic->gensec_security,
953 if (tevent_req_nterror(req, status)) {
954 return tevent_req_post(req, ev);
958 if (target_hostname != NULL) {
959 status = gensec_set_target_hostname(
960 state->auth_generic->gensec_security,
962 if (tevent_req_nterror(req, status)) {
963 return tevent_req_post(req, ev);
967 b = smbXcli_conn_server_gss_blob(cli->conn);
972 state->is_anonymous = cli_credentials_is_anonymous(state->auth_generic->credentials);
974 status = auth_generic_client_start(state->auth_generic,
976 if (tevent_req_nterror(req, status)) {
977 return tevent_req_post(req, ev);
980 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
981 state->cli->smb2.session = smbXcli_session_create(cli,
983 if (tevent_req_nomem(state->cli->smb2.session, req)) {
984 return tevent_req_post(req, ev);
988 cli_session_setup_gensec_local_next(req);
989 if (!tevent_req_is_in_progress(req)) {
990 return tevent_req_post(req, ev);
996 static void cli_session_setup_gensec_local_next(struct tevent_req *req)
998 struct cli_session_setup_gensec_state *state =
1000 struct cli_session_setup_gensec_state);
1001 struct tevent_req *subreq = NULL;
1003 if (state->local_ready) {
1004 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1008 subreq = gensec_update_send(state, state->ev,
1009 state->auth_generic->gensec_security,
1011 if (tevent_req_nomem(subreq, req)) {
1014 tevent_req_set_callback(subreq, cli_session_setup_gensec_local_done, req);
1017 static void cli_session_setup_gensec_local_done(struct tevent_req *subreq)
1019 struct tevent_req *req =
1020 tevent_req_callback_data(subreq,
1022 struct cli_session_setup_gensec_state *state =
1023 tevent_req_data(req,
1024 struct cli_session_setup_gensec_state);
1027 status = gensec_update_recv(subreq, state, &state->blob_out);
1028 TALLOC_FREE(subreq);
1029 state->blob_in = data_blob_null;
1030 if (!NT_STATUS_IS_OK(status) &&
1031 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
1033 tevent_req_nterror(req, status);
1037 if (NT_STATUS_IS_OK(status)) {
1038 state->local_ready = true;
1041 if (state->local_ready && state->remote_ready) {
1042 cli_session_setup_gensec_ready(req);
1046 cli_session_setup_gensec_remote_next(req);
1049 static void cli_session_setup_gensec_remote_next(struct tevent_req *req)
1051 struct cli_session_setup_gensec_state *state =
1052 tevent_req_data(req,
1053 struct cli_session_setup_gensec_state);
1054 struct tevent_req *subreq = NULL;
1056 if (state->remote_ready) {
1057 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1061 subreq = cli_sesssetup_blob_send(state, state->ev,
1062 state->cli, state->blob_out);
1063 if (tevent_req_nomem(subreq, req)) {
1066 tevent_req_set_callback(subreq,
1067 cli_session_setup_gensec_remote_done,
1071 static void cli_session_setup_gensec_remote_done(struct tevent_req *subreq)
1073 struct tevent_req *req =
1074 tevent_req_callback_data(subreq,
1076 struct cli_session_setup_gensec_state *state =
1077 tevent_req_data(req,
1078 struct cli_session_setup_gensec_state);
1081 state->inbuf = NULL;
1082 TALLOC_FREE(state->recv_iov);
1084 status = cli_sesssetup_blob_recv(subreq, state, &state->blob_in,
1085 &state->inbuf, &state->recv_iov);
1086 TALLOC_FREE(subreq);
1087 data_blob_free(&state->blob_out);
1088 if (!NT_STATUS_IS_OK(status) &&
1089 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
1091 tevent_req_nterror(req, status);
1095 if (NT_STATUS_IS_OK(status)) {
1096 struct smbXcli_session *session = NULL;
1097 bool is_guest = false;
1099 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
1100 session = state->cli->smb2.session;
1102 session = state->cli->smb1.session;
1105 is_guest = smbXcli_session_is_guest(session);
1108 * We can't finish the gensec handshake, we don't
1109 * have a negotiated session key.
1111 * So just pretend we are completely done,
1112 * we need to continue as anonymous from this point,
1113 * as we can't get a session key.
1115 * Note that smbXcli_session_is_guest()
1116 * always returns false if we require signing.
1118 state->blob_in = data_blob_null;
1119 state->local_ready = true;
1120 state->is_anonymous = true;
1123 state->remote_ready = true;
1126 if (state->local_ready && state->remote_ready) {
1127 cli_session_setup_gensec_ready(req);
1131 cli_session_setup_gensec_local_next(req);
1134 static void cli_session_setup_gensec_ready(struct tevent_req *req)
1136 struct cli_session_setup_gensec_state *state =
1137 tevent_req_data(req,
1138 struct cli_session_setup_gensec_state);
1139 const char *server_domain = NULL;
1142 if (state->blob_in.length != 0) {
1143 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1147 if (state->blob_out.length != 0) {
1148 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1153 * gensec_ntlmssp_server_domain() returns NULL
1154 * if NTLMSSP is not used.
1156 * We can remove this later
1157 * and leave the server domain empty for SMB2 and above
1158 * in future releases.
1160 server_domain = gensec_ntlmssp_server_domain(
1161 state->auth_generic->gensec_security);
1163 if (state->cli->server_domain[0] == '\0' && server_domain != NULL) {
1164 TALLOC_FREE(state->cli->server_domain);
1165 state->cli->server_domain = talloc_strdup(state->cli,
1167 if (state->cli->server_domain == NULL) {
1168 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1173 if (state->is_anonymous) {
1175 * Windows server does not set the
1176 * SMB2_SESSION_FLAG_IS_NULL flag.
1178 * This fix makes sure we do not try
1179 * to verify a signature on the final
1180 * session setup response.
1182 tevent_req_done(req);
1186 status = gensec_session_key(state->auth_generic->gensec_security,
1187 state, &state->session_key);
1188 if (tevent_req_nterror(req, status)) {
1192 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
1193 struct smbXcli_session *session = state->cli->smb2.session;
1195 status = smb2cli_session_set_session_key(session,
1198 if (tevent_req_nterror(req, status)) {
1202 struct smbXcli_session *session = state->cli->smb1.session;
1205 status = smb1cli_session_set_session_key(session,
1206 state->session_key);
1207 if (tevent_req_nterror(req, status)) {
1211 active = smb1cli_conn_activate_signing(state->cli->conn,
1217 ok = smb1cli_conn_check_signing(state->cli->conn,
1220 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1226 tevent_req_done(req);
1229 static NTSTATUS cli_session_setup_gensec_recv(struct tevent_req *req)
1231 struct cli_session_setup_gensec_state *state =
1232 tevent_req_data(req,
1233 struct cli_session_setup_gensec_state);
1236 if (tevent_req_is_nterror(req, &status)) {
1237 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
1240 return NT_STATUS_OK;
1243 static char *cli_session_setup_get_account(TALLOC_CTX *mem_ctx,
1244 const char *principal)
1248 account = talloc_strdup(mem_ctx, principal);
1249 if (account == NULL) {
1252 p = strchr_m(account, '@');
1259 /****************************************************************************
1260 Do a spnego encrypted session setup.
1262 user_domain: The shortname of the domain the user/machine is a member of.
1263 dest_realm: The realm we're connecting to, if NULL we use our default realm.
1264 ****************************************************************************/
1266 struct cli_session_setup_spnego_state {
1270 static void cli_session_setup_spnego_done(struct tevent_req *subreq);
1272 static struct tevent_req *cli_session_setup_spnego_send(
1273 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
1274 struct cli_credentials *creds)
1276 struct tevent_req *req, *subreq;
1277 struct cli_session_setup_spnego_state *state;
1278 const char *target_service = NULL;
1279 const char *target_hostname = NULL;
1282 req = tevent_req_create(mem_ctx, &state,
1283 struct cli_session_setup_spnego_state);
1288 target_service = "cifs";
1289 target_hostname = smbXcli_conn_remote_name(cli->conn);
1291 status = cli_session_creds_prepare_krb5(cli, creds);
1292 if (tevent_req_nterror(req, status)) {
1293 return tevent_req_post(req, ev);
1296 subreq = cli_session_setup_gensec_send(state, ev, cli, creds,
1297 target_service, target_hostname);
1298 if (tevent_req_nomem(subreq, req)) {
1299 return tevent_req_post(req, ev);
1301 tevent_req_set_callback(
1302 subreq, cli_session_setup_spnego_done, req);
1306 static void cli_session_setup_spnego_done(struct tevent_req *subreq)
1308 struct tevent_req *req = tevent_req_callback_data(
1309 subreq, struct tevent_req);
1312 status = cli_session_setup_gensec_recv(subreq);
1313 TALLOC_FREE(subreq);
1314 if (tevent_req_nterror(req, status)) {
1318 tevent_req_done(req);
1321 static ADS_STATUS cli_session_setup_spnego_recv(struct tevent_req *req)
1323 struct cli_session_setup_spnego_state *state = tevent_req_data(
1324 req, struct cli_session_setup_spnego_state);
1327 if (tevent_req_is_nterror(req, &status)) {
1328 state->result = ADS_ERROR_NT(status);
1331 return state->result;
1334 struct cli_session_setup_creds_state {
1335 struct cli_state *cli;
1336 DATA_BLOB apassword_blob;
1337 DATA_BLOB upassword_blob;
1338 DATA_BLOB lm_session_key;
1339 DATA_BLOB session_key;
1340 char *out_native_os;
1341 char *out_native_lm;
1342 char *out_primary_domain;
1345 static void cli_session_setup_creds_cleanup(struct tevent_req *req,
1346 enum tevent_req_state req_state)
1348 struct cli_session_setup_creds_state *state = tevent_req_data(
1349 req, struct cli_session_setup_creds_state);
1351 if (req_state != TEVENT_REQ_RECEIVED) {
1356 * We only call data_blob_clear() as
1357 * some of the blobs point to the same memory.
1359 * We let the talloc hierachy free the memory.
1361 data_blob_clear(&state->apassword_blob);
1362 data_blob_clear(&state->upassword_blob);
1363 data_blob_clear(&state->lm_session_key);
1364 data_blob_clear(&state->session_key);
1365 ZERO_STRUCTP(state);
1368 static void cli_session_setup_creds_done_spnego(struct tevent_req *subreq);
1369 static void cli_session_setup_creds_done_nt1(struct tevent_req *subreq);
1370 static void cli_session_setup_creds_done_lm21(struct tevent_req *subreq);
1372 /****************************************************************************
1373 Send a session setup. The username and workgroup is in UNIX character
1374 format and must be converted to DOS codepage format before sending. If the
1375 password is in plaintext, the same should be done.
1376 ****************************************************************************/
1378 struct tevent_req *cli_session_setup_creds_send(TALLOC_CTX *mem_ctx,
1379 struct tevent_context *ev,
1380 struct cli_state *cli,
1381 struct cli_credentials *creds)
1383 struct tevent_req *req, *subreq;
1384 struct cli_session_setup_creds_state *state;
1385 uint16_t sec_mode = smb1cli_conn_server_security_mode(cli->conn);
1386 bool use_spnego = false;
1388 enum credentials_use_kerberos krb5_state;
1389 uint32_t gensec_features;
1390 const char *username = "";
1391 const char *domain = "";
1392 DATA_BLOB target_info = data_blob_null;
1393 DATA_BLOB challenge = data_blob_null;
1394 uint16_t in_buf_size = 0;
1395 uint16_t in_mpx_max = 0;
1396 uint16_t in_vc_num = 0;
1397 uint32_t in_sess_key = 0;
1398 const char *in_native_os = NULL;
1399 const char *in_native_lm = NULL;
1402 req = tevent_req_create(mem_ctx, &state,
1403 struct cli_session_setup_creds_state);
1409 tevent_req_set_cleanup_fn(req, cli_session_setup_creds_cleanup);
1411 krb5_state = cli_credentials_get_kerberos_state(creds);
1412 gensec_features = cli_credentials_get_gensec_features(creds);
1414 switch (krb5_state) {
1415 case CRED_MUST_USE_KERBEROS:
1416 cli->use_kerberos = true;
1417 cli->fallback_after_kerberos = false;
1419 case CRED_AUTO_USE_KERBEROS:
1420 cli->use_kerberos = true;
1421 cli->fallback_after_kerberos = true;
1423 case CRED_DONT_USE_KERBEROS:
1424 cli->use_kerberos = false;
1425 cli->fallback_after_kerberos = false;
1429 if (gensec_features & GENSEC_FEATURE_NTLM_CCACHE) {
1430 cli->use_ccache = true;
1432 cli->use_ccache = false;
1436 * Now work out what sort of session setup we are going to
1437 * do. I have split this into separate functions to make the flow a bit
1438 * easier to understand (tridge).
1440 if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_NT1) {
1442 } else if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
1444 } else if (smb1cli_conn_capabilities(cli->conn) & CAP_EXTENDED_SECURITY) {
1446 * if the server supports extended security then use SPNEGO
1447 * even for anonymous connections.
1455 subreq = cli_session_setup_spnego_send(
1456 state, ev, cli, creds);
1457 if (tevent_req_nomem(subreq, req)) {
1458 return tevent_req_post(req, ev);
1460 tevent_req_set_callback(subreq, cli_session_setup_creds_done_spnego,
1465 if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_LANMAN1) {
1467 * SessionSetupAndX was introduced by LANMAN 1.0. So we skip
1468 * this step against older servers.
1470 tevent_req_done(req);
1471 return tevent_req_post(req, ev);
1474 if (cli_credentials_is_anonymous(creds)) {
1476 * Do an anonymous session setup
1478 goto non_spnego_creds_done;
1481 if ((sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0) {
1483 * Do an anonymous session setup,
1484 * the password is passed via the tree connect.
1486 goto non_spnego_creds_done;
1489 cli_credentials_get_ntlm_username_domain(creds, state,
1492 if (tevent_req_nomem(username, req)) {
1493 return tevent_req_post(req, ev);
1495 if (tevent_req_nomem(domain, req)) {
1496 return tevent_req_post(req, ev);
1499 if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) {
1500 bool use_unicode = smbXcli_conn_use_unicode(cli->conn);
1501 uint8_t *bytes = NULL;
1502 size_t bytes_len = 0;
1503 const char *pw = cli_credentials_get_password(creds);
1509 pw_len = strlen(pw) + 1;
1511 if (!lp_client_plaintext_auth()) {
1512 DEBUG(1, ("Server requested PLAINTEXT password but "
1513 "'client plaintext auth = no'\n"));
1514 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1515 return tevent_req_post(req, ev);
1518 bytes = talloc_array(state, uint8_t, 0);
1519 bytes = trans2_bytes_push_str(bytes, use_unicode,
1520 pw, pw_len, &bytes_len);
1521 if (tevent_req_nomem(bytes, req)) {
1522 return tevent_req_post(req, ev);
1527 * CAP_UNICODE, can only be negotiated by NT1.
1529 state->upassword_blob = data_blob_const(bytes,
1532 state->apassword_blob = data_blob_const(bytes,
1536 goto non_spnego_creds_done;
1539 challenge = data_blob_const(smb1cli_conn_server_challenge(cli->conn), 8);
1541 if (smbXcli_conn_protocol(cli->conn) == PROTOCOL_NT1) {
1542 if (lp_client_ntlmv2_auth() && lp_client_use_spnego()) {
1544 * Don't send an NTLMv2 response without NTLMSSP if we
1545 * want to use spnego support.
1547 DEBUG(1, ("Server does not support EXTENDED_SECURITY "
1548 " but 'client use spnego = yes'"
1549 " and 'client ntlmv2 auth = yes' is set\n"));
1550 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1551 return tevent_req_post(req, ev);
1554 if (lp_client_ntlmv2_auth()) {
1555 flags |= CLI_CRED_NTLMv2_AUTH;
1558 * note that the 'domain' here is a best
1559 * guess - we don't know the server's domain
1560 * at this point. Windows clients also don't
1563 target_info = NTLMv2_generate_names_blob(state,
1566 if (tevent_req_nomem(target_info.data, req)) {
1567 return tevent_req_post(req, ev);
1570 flags |= CLI_CRED_NTLM_AUTH;
1571 if (lp_client_lanman_auth()) {
1572 flags |= CLI_CRED_LANMAN_AUTH;
1576 if (!lp_client_lanman_auth()) {
1577 DEBUG(1, ("Server requested user level LM password but "
1578 "'client lanman auth = no' is set.\n"));
1579 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1580 return tevent_req_post(req, ev);
1583 flags |= CLI_CRED_LANMAN_AUTH;
1586 status = cli_credentials_get_ntlm_response(creds, state, &flags,
1589 &state->apassword_blob,
1590 &state->upassword_blob,
1591 &state->lm_session_key,
1592 &state->session_key);
1593 if (tevent_req_nterror(req, status)) {
1594 return tevent_req_post(req, ev);
1597 non_spnego_creds_done:
1599 in_buf_size = CLI_BUFFER_SIZE;
1600 in_mpx_max = smbXcli_conn_max_requests(cli->conn);
1601 in_vc_num = cli_state_get_vc_num(cli);
1602 in_sess_key = smb1cli_conn_server_session_key(cli->conn);
1603 in_native_os = "Unix";
1604 in_native_lm = "Samba";
1606 if (smbXcli_conn_protocol(cli->conn) == PROTOCOL_NT1) {
1607 uint32_t in_capabilities = 0;
1609 in_capabilities = cli_session_setup_capabilities(cli, 0);
1612 * For now we keep the same values as before,
1613 * we may remove these in a separate commit later.
1617 subreq = smb1cli_session_setup_nt1_send(state, ev,
1628 state->apassword_blob,
1629 state->upassword_blob,
1633 if (tevent_req_nomem(subreq, req)) {
1634 return tevent_req_post(req, ev);
1636 tevent_req_set_callback(subreq, cli_session_setup_creds_done_nt1,
1642 * For now we keep the same values as before,
1643 * we may remove these in a separate commit later.
1648 subreq = smb1cli_session_setup_lm21_send(state, ev,
1659 state->apassword_blob,
1662 if (tevent_req_nomem(subreq, req)) {
1663 return tevent_req_post(req, ev);
1665 tevent_req_set_callback(subreq, cli_session_setup_creds_done_lm21,
1670 static void cli_session_setup_creds_done_spnego(struct tevent_req *subreq)
1672 struct tevent_req *req = tevent_req_callback_data(
1673 subreq, struct tevent_req);
1676 status = cli_session_setup_spnego_recv(subreq);
1677 TALLOC_FREE(subreq);
1678 if (!ADS_ERR_OK(status)) {
1679 DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status)));
1680 tevent_req_nterror(req, ads_ntstatus(status));
1683 tevent_req_done(req);
1686 static void cli_session_setup_creds_done_nt1(struct tevent_req *subreq)
1688 struct tevent_req *req = tevent_req_callback_data(
1689 subreq, struct tevent_req);
1690 struct cli_session_setup_creds_state *state = tevent_req_data(
1691 req, struct cli_session_setup_creds_state);
1692 struct cli_state *cli = state->cli;
1694 struct iovec *recv_iov = NULL;
1695 const uint8_t *inbuf = NULL;
1698 status = smb1cli_session_setup_nt1_recv(subreq, state,
1701 &state->out_native_os,
1702 &state->out_native_lm,
1703 &state->out_primary_domain);
1704 TALLOC_FREE(subreq);
1705 if (!NT_STATUS_IS_OK(status)) {
1706 DEBUG(3, ("NT1 login failed: %s\n", nt_errstr(status)));
1707 tevent_req_nterror(req, status);
1711 status = cli_state_update_after_sesssetup(state->cli,
1712 state->out_native_os,
1713 state->out_native_lm,
1714 state->out_primary_domain);
1715 if (tevent_req_nterror(req, status)) {
1719 ok = smb1cli_conn_activate_signing(cli->conn,
1721 state->upassword_blob);
1723 ok = smb1cli_conn_check_signing(cli->conn, inbuf, 1);
1725 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1730 if (state->session_key.data) {
1731 struct smbXcli_session *session = cli->smb1.session;
1733 status = smb1cli_session_set_session_key(session,
1734 state->session_key);
1735 if (tevent_req_nterror(req, status)) {
1740 tevent_req_done(req);
1743 static void cli_session_setup_creds_done_lm21(struct tevent_req *subreq)
1745 struct tevent_req *req = tevent_req_callback_data(
1746 subreq, struct tevent_req);
1747 struct cli_session_setup_creds_state *state = tevent_req_data(
1748 req, struct cli_session_setup_creds_state);
1751 status = smb1cli_session_setup_lm21_recv(subreq, state,
1752 &state->out_native_os,
1753 &state->out_native_lm);
1754 TALLOC_FREE(subreq);
1755 if (!NT_STATUS_IS_OK(status)) {
1756 DEBUG(3, ("LM21 login failed: %s\n", nt_errstr(status)));
1757 tevent_req_nterror(req, status);
1761 status = cli_state_update_after_sesssetup(state->cli,
1762 state->out_native_os,
1763 state->out_native_lm,
1765 if (tevent_req_nterror(req, status)) {
1769 tevent_req_done(req);
1772 NTSTATUS cli_session_setup_creds_recv(struct tevent_req *req)
1774 return tevent_req_simple_recv_ntstatus(req);
1777 NTSTATUS cli_session_setup_creds(struct cli_state *cli,
1778 struct cli_credentials *creds)
1780 struct tevent_context *ev;
1781 struct tevent_req *req;
1782 NTSTATUS status = NT_STATUS_NO_MEMORY;
1784 if (smbXcli_conn_has_async_calls(cli->conn)) {
1785 return NT_STATUS_INVALID_PARAMETER;
1787 ev = samba_tevent_context_init(talloc_tos());
1791 req = cli_session_setup_creds_send(ev, ev, cli, creds);
1795 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1798 status = cli_session_setup_creds_recv(req);
1804 NTSTATUS cli_session_setup_anon(struct cli_state *cli)
1806 NTSTATUS status = NT_STATUS_NO_MEMORY;
1807 struct cli_credentials *creds = NULL;
1809 creds = cli_credentials_init_anon(cli);
1810 if (creds == NULL) {
1811 return NT_STATUS_NO_MEMORY;
1814 status = cli_session_setup_creds(cli, creds);
1816 if (!NT_STATUS_IS_OK(status)) {
1820 return NT_STATUS_OK;
1823 /****************************************************************************
1825 *****************************************************************************/
1827 struct cli_ulogoff_state {
1828 struct cli_state *cli;
1832 static void cli_ulogoff_done(struct tevent_req *subreq);
1834 static struct tevent_req *cli_ulogoff_send(TALLOC_CTX *mem_ctx,
1835 struct tevent_context *ev,
1836 struct cli_state *cli)
1838 struct tevent_req *req, *subreq;
1839 struct cli_ulogoff_state *state;
1841 req = tevent_req_create(mem_ctx, &state, struct cli_ulogoff_state);
1847 SCVAL(state->vwv+0, 0, 0xFF);
1848 SCVAL(state->vwv+1, 0, 0);
1849 SSVAL(state->vwv+2, 0, 0);
1851 subreq = cli_smb_send(state, ev, cli, SMBulogoffX, 0, 0, 2, state->vwv,
1853 if (tevent_req_nomem(subreq, req)) {
1854 return tevent_req_post(req, ev);
1856 tevent_req_set_callback(subreq, cli_ulogoff_done, req);
1860 static void cli_ulogoff_done(struct tevent_req *subreq)
1862 struct tevent_req *req = tevent_req_callback_data(
1863 subreq, struct tevent_req);
1864 struct cli_ulogoff_state *state = tevent_req_data(
1865 req, struct cli_ulogoff_state);
1868 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
1869 if (!NT_STATUS_IS_OK(status)) {
1870 tevent_req_nterror(req, status);
1873 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
1874 tevent_req_done(req);
1877 static NTSTATUS cli_ulogoff_recv(struct tevent_req *req)
1879 return tevent_req_simple_recv_ntstatus(req);
1882 NTSTATUS cli_ulogoff(struct cli_state *cli)
1884 struct tevent_context *ev;
1885 struct tevent_req *req;
1886 NTSTATUS status = NT_STATUS_NO_MEMORY;
1888 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
1889 status = smb2cli_logoff(cli->conn,
1892 if (!NT_STATUS_IS_OK(status)) {
1895 smb2cli_session_set_id_and_flags(cli->smb2.session,
1897 return NT_STATUS_OK;
1900 if (smbXcli_conn_has_async_calls(cli->conn)) {
1901 return NT_STATUS_INVALID_PARAMETER;
1903 ev = samba_tevent_context_init(talloc_tos());
1907 req = cli_ulogoff_send(ev, ev, cli);
1911 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1914 status = cli_ulogoff_recv(req);
1920 /****************************************************************************
1922 ****************************************************************************/
1924 struct cli_tcon_andx_state {
1925 struct cli_state *cli;
1930 static void cli_tcon_andx_done(struct tevent_req *subreq);
1932 struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx,
1933 struct tevent_context *ev,
1934 struct cli_state *cli,
1935 const char *share, const char *dev,
1936 const char *pass, int passlen,
1937 struct tevent_req **psmbreq)
1939 struct tevent_req *req, *subreq;
1940 struct cli_tcon_andx_state *state;
1945 uint16_t sec_mode = smb1cli_conn_server_security_mode(cli->conn);
1946 uint16_t tcon_flags = 0;
1950 req = tevent_req_create(mem_ctx, &state, struct cli_tcon_andx_state);
1957 TALLOC_FREE(cli->smb1.tcon);
1958 cli->smb1.tcon = smbXcli_tcon_create(cli);
1959 if (tevent_req_nomem(cli->smb1.tcon, req)) {
1960 return tevent_req_post(req, ev);
1962 smb1cli_tcon_set_id(cli->smb1.tcon, UINT16_MAX);
1964 cli->share = talloc_strdup(cli, share);
1969 /* in user level security don't send a password now */
1970 if (sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {
1973 } else if (pass == NULL) {
1974 DEBUG(1, ("Server not using user level security and no "
1975 "password supplied.\n"));
1979 if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) &&
1980 *pass && passlen != 24) {
1981 if (!lp_client_lanman_auth()) {
1982 DEBUG(1, ("Server requested LANMAN password "
1983 "(share-level security) but "
1984 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
1989 * Non-encrypted passwords - convert to DOS codepage before
1992 SMBencrypt(pass, smb1cli_conn_server_challenge(cli->conn), p24);
1994 pass = (const char *)p24;
1996 if((sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL
1997 |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE))
2001 if (!lp_client_plaintext_auth() && (*pass)) {
2002 DEBUG(1, ("Server requested PLAINTEXT "
2004 "'client plaintext auth = no' or 'client ntlmv2 auth = yes'\n"));
2009 * Non-encrypted passwords - convert to DOS codepage
2012 tmp_pass = talloc_array(talloc_tos(), uint8_t, 0);
2013 if (tevent_req_nomem(tmp_pass, req)) {
2014 return tevent_req_post(req, ev);
2016 tmp_pass = trans2_bytes_push_str(tmp_pass,
2017 false, /* always DOS */
2021 if (tevent_req_nomem(tmp_pass, req)) {
2022 return tevent_req_post(req, ev);
2024 pass = (const char *)tmp_pass;
2025 passlen = talloc_get_size(tmp_pass);
2029 tcon_flags |= TCONX_FLAG_EXTENDED_RESPONSE;
2030 tcon_flags |= TCONX_FLAG_EXTENDED_SIGNATURES;
2032 SCVAL(vwv+0, 0, 0xFF);
2035 SSVAL(vwv+2, 0, tcon_flags);
2036 SSVAL(vwv+3, 0, passlen);
2038 if (passlen && pass) {
2039 bytes = (uint8_t *)talloc_memdup(state, pass, passlen);
2041 bytes = talloc_array(state, uint8_t, 0);
2047 tmp = talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
2048 smbXcli_conn_remote_name(cli->conn), share);
2053 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), tmp, strlen(tmp)+1,
2058 * Add the devicetype
2060 tmp = talloc_strdup_upper(talloc_tos(), dev);
2065 bytes = smb_bytes_push_str(bytes, false, tmp, strlen(tmp)+1, NULL);
2068 if (bytes == NULL) {
2073 state->bytes.iov_base = (void *)bytes;
2074 state->bytes.iov_len = talloc_get_size(bytes);
2076 subreq = cli_smb_req_create(state, ev, cli, SMBtconX, 0, 0, 4, vwv,
2078 if (subreq == NULL) {
2082 tevent_req_set_callback(subreq, cli_tcon_andx_done, req);
2087 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
2088 return tevent_req_post(req, ev);
2091 struct tevent_req *cli_tcon_andx_send(TALLOC_CTX *mem_ctx,
2092 struct tevent_context *ev,
2093 struct cli_state *cli,
2094 const char *share, const char *dev,
2095 const char *pass, int passlen)
2097 struct tevent_req *req, *subreq;
2100 req = cli_tcon_andx_create(mem_ctx, ev, cli, share, dev, pass, passlen,
2105 if (subreq == NULL) {
2108 status = smb1cli_req_chain_submit(&subreq, 1);
2109 if (!NT_STATUS_IS_OK(status)) {
2110 tevent_req_nterror(req, status);
2111 return tevent_req_post(req, ev);
2116 static void cli_tcon_andx_done(struct tevent_req *subreq)
2118 struct tevent_req *req = tevent_req_callback_data(
2119 subreq, struct tevent_req);
2120 struct cli_tcon_andx_state *state = tevent_req_data(
2121 req, struct cli_tcon_andx_state);
2122 struct cli_state *cli = state->cli;
2130 uint16_t optional_support = 0;
2132 status = cli_smb_recv(subreq, state, &in, 0, &wct, &vwv,
2133 &num_bytes, &bytes);
2134 TALLOC_FREE(subreq);
2135 if (!NT_STATUS_IS_OK(status)) {
2136 tevent_req_nterror(req, status);
2140 inhdr = in + NBT_HDR_SIZE;
2143 if (clistr_pull_talloc(cli,
2144 (const char *)inhdr,
2145 SVAL(inhdr, HDR_FLG2),
2149 STR_TERMINATE|STR_ASCII) == -1) {
2150 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2154 cli->dev = talloc_strdup(cli, "");
2155 if (cli->dev == NULL) {
2156 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2161 if ((smbXcli_conn_protocol(cli->conn) >= PROTOCOL_NT1) && (num_bytes == 3)) {
2162 /* almost certainly win95 - enable bug fixes */
2167 * Make sure that we have the optional support 16-bit field. WCT > 2.
2168 * Avoids issues when connecting to Win9x boxes sharing files
2171 if ((wct > 2) && (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_LANMAN2)) {
2172 optional_support = SVAL(vwv+2, 0);
2175 if (optional_support & SMB_EXTENDED_SIGNATURES) {
2176 smb1cli_session_protect_session_key(cli->smb1.session);
2179 smb1cli_tcon_set_values(state->cli->smb1.tcon,
2180 SVAL(inhdr, HDR_TID),
2182 0, /* maximal_access */
2183 0, /* guest_maximal_access */
2185 NULL); /* fs_type */
2187 tevent_req_done(req);
2190 NTSTATUS cli_tcon_andx_recv(struct tevent_req *req)
2192 return tevent_req_simple_recv_ntstatus(req);
2195 NTSTATUS cli_tcon_andx(struct cli_state *cli, const char *share,
2196 const char *dev, const char *pass, int passlen)
2198 TALLOC_CTX *frame = talloc_stackframe();
2199 struct tevent_context *ev;
2200 struct tevent_req *req;
2201 NTSTATUS status = NT_STATUS_NO_MEMORY;
2203 if (smbXcli_conn_has_async_calls(cli->conn)) {
2205 * Can't use sync call while an async call is in flight
2207 status = NT_STATUS_INVALID_PARAMETER;
2211 ev = samba_tevent_context_init(frame);
2216 req = cli_tcon_andx_send(frame, ev, cli, share, dev, pass, passlen);
2221 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2225 status = cli_tcon_andx_recv(req);
2231 struct cli_tree_connect_state {
2232 struct cli_state *cli;
2235 static struct tevent_req *cli_raw_tcon_send(
2236 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
2237 const char *service, const char *pass, const char *dev);
2238 static NTSTATUS cli_raw_tcon_recv(struct tevent_req *req,
2239 uint16_t *max_xmit, uint16_t *tid);
2241 static void cli_tree_connect_smb2_done(struct tevent_req *subreq);
2242 static void cli_tree_connect_andx_done(struct tevent_req *subreq);
2243 static void cli_tree_connect_raw_done(struct tevent_req *subreq);
2245 static struct tevent_req *cli_tree_connect_send(
2246 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
2247 const char *share, const char *dev, const char *pass)
2249 struct tevent_req *req, *subreq;
2250 struct cli_tree_connect_state *state;
2256 passlen = strlen(pass) + 1;
2258 req = tevent_req_create(mem_ctx, &state,
2259 struct cli_tree_connect_state);
2265 cli->share = talloc_strdup(cli, share);
2266 if (tevent_req_nomem(cli->share, req)) {
2267 return tevent_req_post(req, ev);
2270 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
2273 TALLOC_FREE(cli->smb2.tcon);
2274 cli->smb2.tcon = smbXcli_tcon_create(cli);
2275 if (tevent_req_nomem(cli->smb2.tcon, req)) {
2276 return tevent_req_post(req, ev);
2279 unc = talloc_asprintf(state, "\\\\%s\\%s",
2280 smbXcli_conn_remote_name(cli->conn),
2282 if (tevent_req_nomem(unc, req)) {
2283 return tevent_req_post(req, ev);
2286 subreq = smb2cli_tcon_send(state, ev, cli->conn, cli->timeout,
2287 cli->smb2.session, cli->smb2.tcon,
2290 if (tevent_req_nomem(subreq, req)) {
2291 return tevent_req_post(req, ev);
2293 tevent_req_set_callback(subreq, cli_tree_connect_smb2_done,
2298 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_LANMAN1) {
2299 subreq = cli_tcon_andx_send(state, ev, cli, share, dev,
2301 if (tevent_req_nomem(subreq, req)) {
2302 return tevent_req_post(req, ev);
2304 tevent_req_set_callback(subreq, cli_tree_connect_andx_done,
2309 subreq = cli_raw_tcon_send(state, ev, cli, share, pass, dev);
2310 if (tevent_req_nomem(subreq, req)) {
2311 return tevent_req_post(req, ev);
2313 tevent_req_set_callback(subreq, cli_tree_connect_raw_done, req);
2318 static void cli_tree_connect_smb2_done(struct tevent_req *subreq)
2320 tevent_req_simple_finish_ntstatus(
2321 subreq, smb2cli_tcon_recv(subreq));
2324 static void cli_tree_connect_andx_done(struct tevent_req *subreq)
2326 tevent_req_simple_finish_ntstatus(
2327 subreq, cli_tcon_andx_recv(subreq));
2330 static void cli_tree_connect_raw_done(struct tevent_req *subreq)
2332 struct tevent_req *req = tevent_req_callback_data(
2333 subreq, struct tevent_req);
2334 struct cli_tree_connect_state *state = tevent_req_data(
2335 req, struct cli_tree_connect_state);
2337 uint16_t max_xmit = 0;
2340 status = cli_raw_tcon_recv(subreq, &max_xmit, &tid);
2341 if (tevent_req_nterror(req, status)) {
2345 smb1cli_tcon_set_values(state->cli->smb1.tcon,
2347 0, /* optional_support */
2348 0, /* maximal_access */
2349 0, /* guest_maximal_access */
2351 NULL); /* fs_type */
2353 tevent_req_done(req);
2356 static NTSTATUS cli_tree_connect_recv(struct tevent_req *req)
2358 return tevent_req_simple_recv_ntstatus(req);
2361 NTSTATUS cli_tree_connect(struct cli_state *cli, const char *share,
2362 const char *dev, const char *pass)
2364 struct tevent_context *ev;
2365 struct tevent_req *req;
2366 NTSTATUS status = NT_STATUS_NO_MEMORY;
2368 if (smbXcli_conn_has_async_calls(cli->conn)) {
2369 return NT_STATUS_INVALID_PARAMETER;
2371 ev = samba_tevent_context_init(talloc_tos());
2375 req = cli_tree_connect_send(ev, ev, cli, share, dev, pass);
2379 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2382 status = cli_tree_connect_recv(req);
2388 NTSTATUS cli_tree_connect_creds(struct cli_state *cli,
2389 const char *share, const char *dev,
2390 struct cli_credentials *creds)
2392 const char *pw = NULL;
2394 if (creds != NULL) {
2395 pw = cli_credentials_get_password(creds);
2398 return cli_tree_connect(cli, share, dev, pw);
2401 /****************************************************************************
2402 Send a tree disconnect.
2403 ****************************************************************************/
2405 struct cli_tdis_state {
2406 struct cli_state *cli;
2409 static void cli_tdis_done(struct tevent_req *subreq);
2411 static struct tevent_req *cli_tdis_send(TALLOC_CTX *mem_ctx,
2412 struct tevent_context *ev,
2413 struct cli_state *cli)
2415 struct tevent_req *req, *subreq;
2416 struct cli_tdis_state *state;
2418 req = tevent_req_create(mem_ctx, &state, struct cli_tdis_state);
2424 subreq = cli_smb_send(state, ev, cli, SMBtdis, 0, 0, 0, NULL, 0, NULL);
2425 if (tevent_req_nomem(subreq, req)) {
2426 return tevent_req_post(req, ev);
2428 tevent_req_set_callback(subreq, cli_tdis_done, req);
2432 static void cli_tdis_done(struct tevent_req *subreq)
2434 struct tevent_req *req = tevent_req_callback_data(
2435 subreq, struct tevent_req);
2436 struct cli_tdis_state *state = tevent_req_data(
2437 req, struct cli_tdis_state);
2440 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
2441 TALLOC_FREE(subreq);
2442 if (!NT_STATUS_IS_OK(status)) {
2443 tevent_req_nterror(req, status);
2446 TALLOC_FREE(state->cli->smb1.tcon);
2447 tevent_req_done(req);
2450 static NTSTATUS cli_tdis_recv(struct tevent_req *req)
2452 return tevent_req_simple_recv_ntstatus(req);
2455 NTSTATUS cli_tdis(struct cli_state *cli)
2457 struct tevent_context *ev;
2458 struct tevent_req *req;
2459 NTSTATUS status = NT_STATUS_NO_MEMORY;
2461 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
2462 status = smb2cli_tdis(cli->conn,
2466 if (NT_STATUS_IS_OK(status)) {
2467 TALLOC_FREE(cli->smb2.tcon);
2472 if (smbXcli_conn_has_async_calls(cli->conn)) {
2473 return NT_STATUS_INVALID_PARAMETER;
2475 ev = samba_tevent_context_init(talloc_tos());
2479 req = cli_tdis_send(ev, ev, cli);
2483 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2486 status = cli_tdis_recv(req);
2492 struct cli_connect_sock_state {
2493 const char **called_names;
2494 const char **calling_names;
2500 static void cli_connect_sock_done(struct tevent_req *subreq);
2503 * Async only if we don't have to look up the name, i.e. "pss" is set with a
2507 static struct tevent_req *cli_connect_sock_send(
2508 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2509 const char *host, int name_type, const struct sockaddr_storage *pss,
2510 const char *myname, uint16_t port)
2512 struct tevent_req *req, *subreq;
2513 struct cli_connect_sock_state *state;
2514 struct sockaddr_storage *addrs;
2515 unsigned i, num_addrs;
2518 req = tevent_req_create(mem_ctx, &state,
2519 struct cli_connect_sock_state);
2524 if ((pss == NULL) || is_zero_addr(pss)) {
2527 * Here we cheat. resolve_name_list is not async at all. So
2528 * this call will only be really async if the name lookup has
2529 * been done externally.
2532 status = resolve_name_list(state, host, name_type,
2533 &addrs, &num_addrs);
2534 if (!NT_STATUS_IS_OK(status)) {
2535 tevent_req_nterror(req, status);
2536 return tevent_req_post(req, ev);
2539 addrs = talloc_array(state, struct sockaddr_storage, 1);
2540 if (tevent_req_nomem(addrs, req)) {
2541 return tevent_req_post(req, ev);
2547 state->called_names = talloc_array(state, const char *, num_addrs);
2548 if (tevent_req_nomem(state->called_names, req)) {
2549 return tevent_req_post(req, ev);
2551 state->called_types = talloc_array(state, int, num_addrs);
2552 if (tevent_req_nomem(state->called_types, req)) {
2553 return tevent_req_post(req, ev);
2555 state->calling_names = talloc_array(state, const char *, num_addrs);
2556 if (tevent_req_nomem(state->calling_names, req)) {
2557 return tevent_req_post(req, ev);
2559 for (i=0; i<num_addrs; i++) {
2560 state->called_names[i] = host;
2561 state->called_types[i] = name_type;
2562 state->calling_names[i] = myname;
2565 subreq = smbsock_any_connect_send(
2566 state, ev, addrs, state->called_names, state->called_types,
2567 state->calling_names, NULL, num_addrs, port);
2568 if (tevent_req_nomem(subreq, req)) {
2569 return tevent_req_post(req, ev);
2571 tevent_req_set_callback(subreq, cli_connect_sock_done, req);
2575 static void cli_connect_sock_done(struct tevent_req *subreq)
2577 struct tevent_req *req = tevent_req_callback_data(
2578 subreq, struct tevent_req);
2579 struct cli_connect_sock_state *state = tevent_req_data(
2580 req, struct cli_connect_sock_state);
2583 status = smbsock_any_connect_recv(subreq, &state->fd, NULL,
2585 TALLOC_FREE(subreq);
2586 if (tevent_req_nterror(req, status)) {
2589 set_socket_options(state->fd, lp_socket_options());
2590 tevent_req_done(req);
2593 static NTSTATUS cli_connect_sock_recv(struct tevent_req *req,
2594 int *pfd, uint16_t *pport)
2596 struct cli_connect_sock_state *state = tevent_req_data(
2597 req, struct cli_connect_sock_state);
2600 if (tevent_req_is_nterror(req, &status)) {
2604 *pport = state->port;
2605 return NT_STATUS_OK;
2608 struct cli_connect_nb_state {
2609 const char *desthost;
2612 struct cli_state *cli;
2615 static void cli_connect_nb_done(struct tevent_req *subreq);
2617 static struct tevent_req *cli_connect_nb_send(
2618 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2619 const char *host, const struct sockaddr_storage *dest_ss,
2620 uint16_t port, int name_type, const char *myname,
2621 int signing_state, int flags)
2623 struct tevent_req *req, *subreq;
2624 struct cli_connect_nb_state *state;
2626 req = tevent_req_create(mem_ctx, &state, struct cli_connect_nb_state);
2630 state->signing_state = signing_state;
2631 state->flags = flags;
2634 char *p = strchr(host, '#');
2637 name_type = strtol(p+1, NULL, 16);
2638 host = talloc_strndup(state, host, p - host);
2639 if (tevent_req_nomem(host, req)) {
2640 return tevent_req_post(req, ev);
2644 state->desthost = host;
2645 } else if (dest_ss != NULL) {
2646 state->desthost = print_canonical_sockaddr(state, dest_ss);
2647 if (tevent_req_nomem(state->desthost, req)) {
2648 return tevent_req_post(req, ev);
2651 /* No host or dest_ss given. Error out. */
2652 tevent_req_error(req, EINVAL);
2653 return tevent_req_post(req, ev);
2656 subreq = cli_connect_sock_send(state, ev, host, name_type, dest_ss,
2658 if (tevent_req_nomem(subreq, req)) {
2659 return tevent_req_post(req, ev);
2661 tevent_req_set_callback(subreq, cli_connect_nb_done, req);
2665 static void cli_connect_nb_done(struct tevent_req *subreq)
2667 struct tevent_req *req = tevent_req_callback_data(
2668 subreq, struct tevent_req);
2669 struct cli_connect_nb_state *state = tevent_req_data(
2670 req, struct cli_connect_nb_state);
2675 status = cli_connect_sock_recv(subreq, &fd, &port);
2676 TALLOC_FREE(subreq);
2677 if (tevent_req_nterror(req, status)) {
2681 state->cli = cli_state_create(state, fd, state->desthost,
2682 state->signing_state, state->flags);
2683 if (tevent_req_nomem(state->cli, req)) {
2687 tevent_req_done(req);
2690 static NTSTATUS cli_connect_nb_recv(struct tevent_req *req,
2691 struct cli_state **pcli)
2693 struct cli_connect_nb_state *state = tevent_req_data(
2694 req, struct cli_connect_nb_state);
2697 if (tevent_req_is_nterror(req, &status)) {
2700 *pcli = talloc_move(NULL, &state->cli);
2701 return NT_STATUS_OK;
2704 NTSTATUS cli_connect_nb(const char *host, const struct sockaddr_storage *dest_ss,
2705 uint16_t port, int name_type, const char *myname,
2706 int signing_state, int flags, struct cli_state **pcli)
2708 struct tevent_context *ev;
2709 struct tevent_req *req;
2710 NTSTATUS status = NT_STATUS_NO_MEMORY;
2712 ev = samba_tevent_context_init(talloc_tos());
2716 req = cli_connect_nb_send(ev, ev, host, dest_ss, port, name_type,
2717 myname, signing_state, flags);
2721 if (!tevent_req_set_endtime(req, ev, timeval_current_ofs(20, 0))) {
2724 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2727 status = cli_connect_nb_recv(req, pcli);
2733 struct cli_start_connection_state {
2734 struct tevent_context *ev;
2735 struct cli_state *cli;
2740 static void cli_start_connection_connected(struct tevent_req *subreq);
2741 static void cli_start_connection_done(struct tevent_req *subreq);
2744 establishes a connection to after the negprot.
2745 @param output_cli A fully initialised cli structure, non-null only on success
2746 @param dest_host The netbios name of the remote host
2747 @param dest_ss (optional) The the destination IP, NULL for name based lookup
2748 @param port (optional) The destination port (0 for default)
2751 static struct tevent_req *cli_start_connection_send(
2752 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2753 const char *my_name, const char *dest_host,
2754 const struct sockaddr_storage *dest_ss, int port,
2755 int signing_state, int flags)
2757 struct tevent_req *req, *subreq;
2758 struct cli_start_connection_state *state;
2760 req = tevent_req_create(mem_ctx, &state,
2761 struct cli_start_connection_state);
2767 if (signing_state == SMB_SIGNING_IPC_DEFAULT) {
2768 state->min_protocol = lp_client_ipc_min_protocol();
2769 state->max_protocol = lp_client_ipc_max_protocol();
2771 state->min_protocol = lp_client_min_protocol();
2772 state->max_protocol = lp_client_max_protocol();
2775 if (flags & CLI_FULL_CONNECTION_FORCE_SMB1) {
2776 state->max_protocol = MIN(state->max_protocol, PROTOCOL_NT1);
2779 if (flags & CLI_FULL_CONNECTION_DISABLE_SMB1) {
2780 state->min_protocol = MAX(state->max_protocol, PROTOCOL_SMB2_02);
2781 state->max_protocol = MAX(state->max_protocol, PROTOCOL_LATEST);
2784 subreq = cli_connect_nb_send(state, ev, dest_host, dest_ss, port,
2785 0x20, my_name, signing_state, flags);
2786 if (tevent_req_nomem(subreq, req)) {
2787 return tevent_req_post(req, ev);
2789 tevent_req_set_callback(subreq, cli_start_connection_connected, req);
2793 static void cli_start_connection_connected(struct tevent_req *subreq)
2795 struct tevent_req *req = tevent_req_callback_data(
2796 subreq, struct tevent_req);
2797 struct cli_start_connection_state *state = tevent_req_data(
2798 req, struct cli_start_connection_state);
2801 status = cli_connect_nb_recv(subreq, &state->cli);
2802 TALLOC_FREE(subreq);
2803 if (tevent_req_nterror(req, status)) {
2807 subreq = smbXcli_negprot_send(state, state->ev, state->cli->conn,
2808 state->cli->timeout,
2809 state->min_protocol,
2810 state->max_protocol,
2811 WINDOWS_CLIENT_PURE_SMB2_NEGPROT_INITIAL_CREDIT_ASK);
2812 if (tevent_req_nomem(subreq, req)) {
2815 tevent_req_set_callback(subreq, cli_start_connection_done, req);
2818 static void cli_start_connection_done(struct tevent_req *subreq)
2820 struct tevent_req *req = tevent_req_callback_data(
2821 subreq, struct tevent_req);
2822 struct cli_start_connection_state *state = tevent_req_data(
2823 req, struct cli_start_connection_state);
2826 status = smbXcli_negprot_recv(subreq);
2827 TALLOC_FREE(subreq);
2828 if (tevent_req_nterror(req, status)) {
2832 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
2833 /* Ensure we ask for some initial credits. */
2834 smb2cli_conn_set_max_credits(state->cli->conn,
2835 DEFAULT_SMB2_MAX_CREDITS);
2838 tevent_req_done(req);
2841 static NTSTATUS cli_start_connection_recv(struct tevent_req *req,
2842 struct cli_state **output_cli)
2844 struct cli_start_connection_state *state = tevent_req_data(
2845 req, struct cli_start_connection_state);
2848 if (tevent_req_is_nterror(req, &status)) {
2851 *output_cli = state->cli;
2853 return NT_STATUS_OK;
2856 NTSTATUS cli_start_connection(struct cli_state **output_cli,
2857 const char *my_name,
2858 const char *dest_host,
2859 const struct sockaddr_storage *dest_ss, int port,
2860 int signing_state, int flags)
2862 struct tevent_context *ev;
2863 struct tevent_req *req;
2864 NTSTATUS status = NT_STATUS_NO_MEMORY;
2866 ev = samba_tevent_context_init(talloc_tos());
2870 req = cli_start_connection_send(ev, ev, my_name, dest_host, dest_ss,
2871 port, signing_state, flags);
2875 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2878 status = cli_start_connection_recv(req, output_cli);
2884 struct cli_smb1_setup_encryption_blob_state {
2889 uint16_t enc_ctx_id;
2892 static void cli_smb1_setup_encryption_blob_done(struct tevent_req *subreq);
2894 static struct tevent_req *cli_smb1_setup_encryption_blob_send(TALLOC_CTX *mem_ctx,
2895 struct tevent_context *ev,
2896 struct cli_state *cli,
2899 struct tevent_req *req = NULL;
2900 struct cli_smb1_setup_encryption_blob_state *state = NULL;
2901 struct tevent_req *subreq = NULL;
2903 req = tevent_req_create(mem_ctx, &state,
2904 struct cli_smb1_setup_encryption_blob_state);
2909 if (in.length > CLI_BUFFER_SIZE) {
2910 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
2911 return tevent_req_post(req, ev);
2914 SSVAL(state->setup+0, 0, TRANSACT2_SETFSINFO);
2915 SSVAL(state->param, 0, 0);
2916 SSVAL(state->param, 2, SMB_REQUEST_TRANSPORT_ENCRYPTION);
2918 subreq = smb1cli_trans_send(state, ev, cli->conn,
2926 NULL, /* pipe_name */
2932 in.data, in.length, CLI_BUFFER_SIZE);
2933 if (tevent_req_nomem(subreq, req)) {
2934 return tevent_req_post(req, ev);
2936 tevent_req_set_callback(subreq,
2937 cli_smb1_setup_encryption_blob_done,
2943 static void cli_smb1_setup_encryption_blob_done(struct tevent_req *subreq)
2945 struct tevent_req *req =
2946 tevent_req_callback_data(subreq,
2948 struct cli_smb1_setup_encryption_blob_state *state =
2949 tevent_req_data(req,
2950 struct cli_smb1_setup_encryption_blob_state);
2951 uint8_t *rparam=NULL, *rdata=NULL;
2952 uint32_t num_rparam, num_rdata;
2955 status = smb1cli_trans_recv(subreq, state,
2956 NULL, /* recv_flags */
2957 NULL, 0, NULL, /* rsetup */
2958 &rparam, 0, &num_rparam,
2959 &rdata, 0, &num_rdata);
2960 TALLOC_FREE(subreq);
2961 state->status = status;
2962 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
2963 status = NT_STATUS_OK;
2965 if (tevent_req_nterror(req, status)) {
2969 if (num_rparam == 2) {
2970 state->enc_ctx_id = SVAL(rparam, 0);
2972 TALLOC_FREE(rparam);
2974 state->out = data_blob_const(rdata, num_rdata);
2976 tevent_req_done(req);
2979 static NTSTATUS cli_smb1_setup_encryption_blob_recv(struct tevent_req *req,
2980 TALLOC_CTX *mem_ctx,
2982 uint16_t *enc_ctx_id)
2984 struct cli_smb1_setup_encryption_blob_state *state =
2985 tevent_req_data(req,
2986 struct cli_smb1_setup_encryption_blob_state);
2989 if (tevent_req_is_nterror(req, &status)) {
2990 tevent_req_received(req);
2994 status = state->status;
2997 talloc_steal(mem_ctx, out->data);
2999 *enc_ctx_id = state->enc_ctx_id;
3001 tevent_req_received(req);
3005 struct cli_smb1_setup_encryption_state {
3006 struct tevent_context *ev;
3007 struct cli_state *cli;
3008 struct smb_trans_enc_state *es;
3015 static void cli_smb1_setup_encryption_local_next(struct tevent_req *req);
3016 static void cli_smb1_setup_encryption_local_done(struct tevent_req *subreq);
3017 static void cli_smb1_setup_encryption_remote_next(struct tevent_req *req);
3018 static void cli_smb1_setup_encryption_remote_done(struct tevent_req *subreq);
3019 static void cli_smb1_setup_encryption_ready(struct tevent_req *req);
3021 static struct tevent_req *cli_smb1_setup_encryption_send(TALLOC_CTX *mem_ctx,
3022 struct tevent_context *ev,
3023 struct cli_state *cli,
3024 struct cli_credentials *creds)
3026 struct tevent_req *req = NULL;
3027 struct cli_smb1_setup_encryption_state *state = NULL;
3028 struct auth_generic_state *ags = NULL;
3029 const DATA_BLOB *b = NULL;
3030 bool auth_requested = false;
3031 const char *target_service = NULL;
3032 const char *target_hostname = NULL;
3035 req = tevent_req_create(mem_ctx, &state,
3036 struct cli_smb1_setup_encryption_state);
3043 auth_requested = cli_credentials_authentication_requested(creds);
3044 if (!auth_requested) {
3045 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
3046 return tevent_req_post(req, ev);
3049 target_service = "cifs";
3050 target_hostname = smbXcli_conn_remote_name(cli->conn);
3052 status = cli_session_creds_prepare_krb5(cli, creds);
3053 if (tevent_req_nterror(req, status)) {
3054 return tevent_req_post(req, ev);
3057 state->es = talloc_zero(state, struct smb_trans_enc_state);
3058 if (tevent_req_nomem(state->es, req)) {
3059 return tevent_req_post(req, ev);
3062 status = auth_generic_client_prepare(state->es, &ags);
3063 if (tevent_req_nterror(req, status)) {
3064 return tevent_req_post(req, ev);
3067 gensec_want_feature(ags->gensec_security,
3068 GENSEC_FEATURE_SIGN);
3069 gensec_want_feature(ags->gensec_security,
3070 GENSEC_FEATURE_SEAL);
3072 status = auth_generic_set_creds(ags, creds);
3073 if (tevent_req_nterror(req, status)) {
3074 return tevent_req_post(req, ev);
3077 if (target_service != NULL) {
3078 status = gensec_set_target_service(ags->gensec_security,
3080 if (tevent_req_nterror(req, status)) {
3081 return tevent_req_post(req, ev);
3085 if (target_hostname != NULL) {
3086 status = gensec_set_target_hostname(ags->gensec_security,
3088 if (tevent_req_nterror(req, status)) {
3089 return tevent_req_post(req, ev);
3093 gensec_set_max_update_size(ags->gensec_security,
3096 b = smbXcli_conn_server_gss_blob(state->cli->conn);
3098 state->blob_in = *b;
3101 status = auth_generic_client_start(ags, GENSEC_OID_SPNEGO);
3102 if (tevent_req_nterror(req, status)) {
3103 return tevent_req_post(req, ev);
3107 * We only need the gensec_security part from here.
3109 state->es->gensec_security = talloc_move(state->es,
3110 &ags->gensec_security);
3113 cli_smb1_setup_encryption_local_next(req);
3114 if (!tevent_req_is_in_progress(req)) {
3115 return tevent_req_post(req, ev);
3121 static void cli_smb1_setup_encryption_local_next(struct tevent_req *req)
3123 struct cli_smb1_setup_encryption_state *state =
3124 tevent_req_data(req,
3125 struct cli_smb1_setup_encryption_state);
3126 struct tevent_req *subreq = NULL;
3128 if (state->local_ready) {
3129 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3133 subreq = gensec_update_send(state, state->ev,
3134 state->es->gensec_security,
3136 if (tevent_req_nomem(subreq, req)) {
3139 tevent_req_set_callback(subreq, cli_smb1_setup_encryption_local_done, req);
3142 static void cli_smb1_setup_encryption_local_done(struct tevent_req *subreq)
3144 struct tevent_req *req =
3145 tevent_req_callback_data(subreq,
3147 struct cli_smb1_setup_encryption_state *state =
3148 tevent_req_data(req,
3149 struct cli_smb1_setup_encryption_state);
3152 status = gensec_update_recv(subreq, state, &state->blob_out);
3153 TALLOC_FREE(subreq);
3154 state->blob_in = data_blob_null;
3155 if (!NT_STATUS_IS_OK(status) &&
3156 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
3158 tevent_req_nterror(req, status);
3162 if (NT_STATUS_IS_OK(status)) {
3163 state->local_ready = true;
3167 * We always get NT_STATUS_OK from the server even if it is not ready.
3168 * So guess the server is ready when we are ready and already sent
3169 * our last blob to the server.
3171 if (state->local_ready && state->blob_out.length == 0) {
3172 state->remote_ready = true;
3175 if (state->local_ready && state->remote_ready) {
3176 cli_smb1_setup_encryption_ready(req);
3180 cli_smb1_setup_encryption_remote_next(req);
3183 static void cli_smb1_setup_encryption_remote_next(struct tevent_req *req)
3185 struct cli_smb1_setup_encryption_state *state =
3186 tevent_req_data(req,
3187 struct cli_smb1_setup_encryption_state);
3188 struct tevent_req *subreq = NULL;
3190 if (state->remote_ready) {
3191 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3195 subreq = cli_smb1_setup_encryption_blob_send(state, state->ev,
3196 state->cli, state->blob_out);
3197 if (tevent_req_nomem(subreq, req)) {
3200 tevent_req_set_callback(subreq,
3201 cli_smb1_setup_encryption_remote_done,
3205 static void cli_smb1_setup_encryption_remote_done(struct tevent_req *subreq)
3207 struct tevent_req *req =
3208 tevent_req_callback_data(subreq,
3210 struct cli_smb1_setup_encryption_state *state =
3211 tevent_req_data(req,
3212 struct cli_smb1_setup_encryption_state);
3215 status = cli_smb1_setup_encryption_blob_recv(subreq, state,
3217 &state->es->enc_ctx_num);
3218 TALLOC_FREE(subreq);
3219 data_blob_free(&state->blob_out);
3220 if (!NT_STATUS_IS_OK(status) &&
3221 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
3223 tevent_req_nterror(req, status);
3228 * We always get NT_STATUS_OK even if the server is not ready.
3229 * So guess the server is ready when we are ready and sent
3230 * our last blob to the server.
3232 if (state->local_ready) {
3233 state->remote_ready = true;
3236 if (state->local_ready && state->remote_ready) {
3237 cli_smb1_setup_encryption_ready(req);
3241 cli_smb1_setup_encryption_local_next(req);
3244 static void cli_smb1_setup_encryption_ready(struct tevent_req *req)
3246 struct cli_smb1_setup_encryption_state *state =
3247 tevent_req_data(req,
3248 struct cli_smb1_setup_encryption_state);
3249 struct smb_trans_enc_state *es = NULL;
3251 if (state->blob_in.length != 0) {
3252 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3256 if (state->blob_out.length != 0) {
3257 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3261 es = talloc_move(state->cli->conn, &state->es);
3263 smb1cli_conn_set_encryption(state->cli->conn, es);
3266 tevent_req_done(req);
3269 static NTSTATUS cli_smb1_setup_encryption_recv(struct tevent_req *req)
3271 return tevent_req_simple_recv_ntstatus(req);
3274 NTSTATUS cli_smb1_setup_encryption(struct cli_state *cli,
3275 struct cli_credentials *creds)
3277 struct tevent_context *ev = NULL;
3278 struct tevent_req *req = NULL;
3279 NTSTATUS status = NT_STATUS_NO_MEMORY;
3281 ev = samba_tevent_context_init(talloc_tos());
3285 req = cli_smb1_setup_encryption_send(ev, ev, cli, creds);
3289 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
3292 status = cli_smb1_setup_encryption_recv(req);
3299 establishes a connection right up to doing tconX, password specified.
3300 @param output_cli A fully initialised cli structure, non-null only on success
3301 @param dest_host The netbios name of the remote host
3302 @param dest_ip (optional) The the destination IP, NULL for name based lookup
3303 @param port (optional) The destination port (0 for default)
3304 @param service (optional) The share to make the connection to. Should be 'unqualified' in any way.
3305 @param service_type The 'type' of serivice.
3306 @param creds The used user credentials
3309 struct cli_full_connection_creds_state {
3310 struct tevent_context *ev;
3311 const char *service;
3312 const char *service_type;
3313 struct cli_credentials *creds;
3315 struct cli_state *cli;
3318 static int cli_full_connection_creds_state_destructor(
3319 struct cli_full_connection_creds_state *s)
3321 if (s->cli != NULL) {
3322 cli_shutdown(s->cli);
3328 static void cli_full_connection_creds_conn_done(struct tevent_req *subreq);
3329 static void cli_full_connection_creds_sess_start(struct tevent_req *req);
3330 static void cli_full_connection_creds_sess_done(struct tevent_req *subreq);
3331 static void cli_full_connection_creds_tcon_start(struct tevent_req *req);
3332 static void cli_full_connection_creds_tcon_done(struct tevent_req *subreq);
3334 struct tevent_req *cli_full_connection_creds_send(
3335 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
3336 const char *my_name, const char *dest_host,
3337 const struct sockaddr_storage *dest_ss, int port,
3338 const char *service, const char *service_type,
3339 struct cli_credentials *creds,
3340 int flags, int signing_state)
3342 struct tevent_req *req, *subreq;
3343 struct cli_full_connection_creds_state *state;
3344 enum credentials_use_kerberos krb5_state;
3345 uint32_t gensec_features = 0;
3347 req = tevent_req_create(mem_ctx, &state,
3348 struct cli_full_connection_creds_state);
3352 talloc_set_destructor(state, cli_full_connection_creds_state_destructor);
3354 flags &= ~CLI_FULL_CONNECTION_USE_KERBEROS;
3355 flags &= ~CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS;
3356 flags &= ~CLI_FULL_CONNECTION_USE_CCACHE;
3357 flags &= ~CLI_FULL_CONNECTION_USE_NT_HASH;
3359 krb5_state = cli_credentials_get_kerberos_state(creds);
3360 switch (krb5_state) {
3361 case CRED_MUST_USE_KERBEROS:
3362 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
3363 flags &= ~CLI_FULL_CONNECTION_DONT_SPNEGO;
3365 case CRED_AUTO_USE_KERBEROS:
3366 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
3367 flags |= CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS;
3369 case CRED_DONT_USE_KERBEROS:
3373 gensec_features = cli_credentials_get_gensec_features(creds);
3374 if (gensec_features & GENSEC_FEATURE_NTLM_CCACHE) {
3375 flags |= CLI_FULL_CONNECTION_USE_CCACHE;
3379 state->service = service;
3380 state->service_type = service_type;
3381 state->creds = creds;
3382 state->flags = flags;
3384 subreq = cli_start_connection_send(
3385 state, ev, my_name, dest_host, dest_ss, port,
3386 signing_state, flags);
3387 if (tevent_req_nomem(subreq, req)) {
3388 return tevent_req_post(req, ev);
3390 tevent_req_set_callback(subreq,
3391 cli_full_connection_creds_conn_done,
3396 static void cli_full_connection_creds_conn_done(struct tevent_req *subreq)
3398 struct tevent_req *req = tevent_req_callback_data(
3399 subreq, struct tevent_req);
3400 struct cli_full_connection_creds_state *state = tevent_req_data(
3401 req, struct cli_full_connection_creds_state);
3404 status = cli_start_connection_recv(subreq, &state->cli);
3405 TALLOC_FREE(subreq);
3406 if (tevent_req_nterror(req, status)) {
3410 cli_full_connection_creds_sess_start(req);
3413 static void cli_full_connection_creds_sess_start(struct tevent_req *req)
3415 struct cli_full_connection_creds_state *state = tevent_req_data(
3416 req, struct cli_full_connection_creds_state);
3417 struct tevent_req *subreq = NULL;
3419 subreq = cli_session_setup_creds_send(
3420 state, state->ev, state->cli, state->creds);
3421 if (tevent_req_nomem(subreq, req)) {
3424 tevent_req_set_callback(subreq,
3425 cli_full_connection_creds_sess_done,
3429 static void cli_full_connection_creds_sess_done(struct tevent_req *subreq)
3431 struct tevent_req *req = tevent_req_callback_data(
3432 subreq, struct tevent_req);
3433 struct cli_full_connection_creds_state *state = tevent_req_data(
3434 req, struct cli_full_connection_creds_state);
3437 status = cli_session_setup_creds_recv(subreq);
3438 TALLOC_FREE(subreq);
3440 if (!NT_STATUS_IS_OK(status) &&
3441 (state->flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)) {
3443 state->flags &= ~CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
3445 state->creds = cli_credentials_init_anon(state);
3446 if (tevent_req_nomem(state->creds, req)) {
3450 cli_full_connection_creds_sess_start(req);
3454 if (tevent_req_nterror(req, status)) {
3458 cli_full_connection_creds_tcon_start(req);
3461 static void cli_full_connection_creds_tcon_start(struct tevent_req *req)
3463 struct cli_full_connection_creds_state *state = tevent_req_data(
3464 req, struct cli_full_connection_creds_state);
3465 struct tevent_req *subreq = NULL;
3466 const char *password = NULL;
3468 if (state->service == NULL) {
3469 tevent_req_done(req);
3473 password = cli_credentials_get_password(state->creds);
3475 subreq = cli_tree_connect_send(state, state->ev,
3478 state->service_type,
3480 if (tevent_req_nomem(subreq, req)) {
3483 tevent_req_set_callback(subreq,
3484 cli_full_connection_creds_tcon_done,
3488 static void cli_full_connection_creds_tcon_done(struct tevent_req *subreq)
3490 struct tevent_req *req = tevent_req_callback_data(
3491 subreq, struct tevent_req);
3494 status = cli_tree_connect_recv(subreq);
3495 TALLOC_FREE(subreq);
3496 if (tevent_req_nterror(req, status)) {
3500 tevent_req_done(req);
3503 NTSTATUS cli_full_connection_creds_recv(struct tevent_req *req,
3504 struct cli_state **output_cli)
3506 struct cli_full_connection_creds_state *state = tevent_req_data(
3507 req, struct cli_full_connection_creds_state);
3510 if (tevent_req_is_nterror(req, &status)) {
3513 *output_cli = state->cli;
3514 talloc_set_destructor(state, NULL);
3515 return NT_STATUS_OK;
3518 NTSTATUS cli_full_connection_creds(struct cli_state **output_cli,
3519 const char *my_name,
3520 const char *dest_host,
3521 const struct sockaddr_storage *dest_ss, int port,
3522 const char *service, const char *service_type,
3523 struct cli_credentials *creds,
3527 struct tevent_context *ev;
3528 struct tevent_req *req;
3529 NTSTATUS status = NT_STATUS_NO_MEMORY;
3531 ev = samba_tevent_context_init(talloc_tos());
3535 req = cli_full_connection_creds_send(
3536 ev, ev, my_name, dest_host, dest_ss, port, service,
3537 service_type, creds, flags, signing_state);
3541 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
3544 status = cli_full_connection_creds_recv(req, output_cli);
3550 NTSTATUS cli_full_connection(struct cli_state **output_cli,
3551 const char *my_name,
3552 const char *dest_host,
3553 const struct sockaddr_storage *dest_ss, int port,
3554 const char *service, const char *service_type,
3555 const char *user, const char *domain,
3556 const char *password, int flags,
3559 TALLOC_CTX *frame = talloc_stackframe();
3561 bool use_kerberos = false;
3562 bool fallback_after_kerberos = false;
3563 bool use_ccache = false;
3564 bool pw_nt_hash = false;
3565 struct cli_credentials *creds = NULL;
3567 if (flags & CLI_FULL_CONNECTION_USE_KERBEROS) {
3568 use_kerberos = true;
3571 if (flags & CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS) {
3572 fallback_after_kerberos = true;
3575 if (flags & CLI_FULL_CONNECTION_USE_CCACHE) {
3579 if (flags & CLI_FULL_CONNECTION_USE_NT_HASH) {
3583 creds = cli_session_creds_init(frame,
3586 NULL, /* realm (use default) */
3589 fallback_after_kerberos,
3592 if (creds == NULL) {
3594 return NT_STATUS_NO_MEMORY;
3597 status = cli_full_connection_creds(output_cli, my_name,
3598 dest_host, dest_ss, port,
3599 service, service_type,
3600 creds, flags, signing_state);
3601 if (!NT_STATUS_IS_OK(status)) {
3607 return NT_STATUS_OK;
3610 /****************************************************************************
3611 Send an old style tcon.
3612 ****************************************************************************/
3613 struct cli_raw_tcon_state {
3617 static void cli_raw_tcon_done(struct tevent_req *subreq);
3619 static struct tevent_req *cli_raw_tcon_send(
3620 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
3621 const char *service, const char *pass, const char *dev)
3623 struct tevent_req *req, *subreq;
3624 struct cli_raw_tcon_state *state;
3627 req = tevent_req_create(mem_ctx, &state, struct cli_raw_tcon_state);
3632 if (!lp_client_plaintext_auth() && (*pass)) {
3633 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
3634 " or 'client ntlmv2 auth = yes'\n"));
3635 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
3636 return tevent_req_post(req, ev);
3639 TALLOC_FREE(cli->smb1.tcon);
3640 cli->smb1.tcon = smbXcli_tcon_create(cli);
3641 if (tevent_req_nomem(cli->smb1.tcon, req)) {
3642 return tevent_req_post(req, ev);
3644 smb1cli_tcon_set_id(cli->smb1.tcon, UINT16_MAX);
3646 bytes = talloc_array(state, uint8_t, 0);
3647 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3648 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3649 service, strlen(service)+1, NULL);
3650 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3651 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3652 pass, strlen(pass)+1, NULL);
3653 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3654 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3655 dev, strlen(dev)+1, NULL);
3657 if (tevent_req_nomem(bytes, req)) {
3658 return tevent_req_post(req, ev);
3661 subreq = cli_smb_send(state, ev, cli, SMBtcon, 0, 0, 0, NULL,
3662 talloc_get_size(bytes), bytes);
3663 if (tevent_req_nomem(subreq, req)) {
3664 return tevent_req_post(req, ev);
3666 tevent_req_set_callback(subreq, cli_raw_tcon_done, req);
3670 static void cli_raw_tcon_done(struct tevent_req *subreq)
3672 struct tevent_req *req = tevent_req_callback_data(
3673 subreq, struct tevent_req);
3674 struct cli_raw_tcon_state *state = tevent_req_data(
3675 req, struct cli_raw_tcon_state);
3678 status = cli_smb_recv(subreq, state, NULL, 2, NULL, &state->ret_vwv,
3680 TALLOC_FREE(subreq);
3681 if (tevent_req_nterror(req, status)) {
3684 tevent_req_done(req);
3687 static NTSTATUS cli_raw_tcon_recv(struct tevent_req *req,
3688 uint16_t *max_xmit, uint16_t *tid)
3690 struct cli_raw_tcon_state *state = tevent_req_data(
3691 req, struct cli_raw_tcon_state);
3694 if (tevent_req_is_nterror(req, &status)) {
3697 *max_xmit = SVAL(state->ret_vwv + 0, 0);
3698 *tid = SVAL(state->ret_vwv + 1, 0);
3699 return NT_STATUS_OK;
3702 NTSTATUS cli_raw_tcon(struct cli_state *cli,
3703 const char *service, const char *pass, const char *dev,
3704 uint16_t *max_xmit, uint16_t *tid)
3706 struct tevent_context *ev;
3707 struct tevent_req *req;
3708 NTSTATUS status = NT_STATUS_NO_MEMORY;
3710 ev = samba_tevent_context_init(talloc_tos());
3714 req = cli_raw_tcon_send(ev, ev, cli, service, pass, dev);
3718 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
3721 status = cli_raw_tcon_recv(req, max_xmit, tid);
3727 /* Return a cli_state pointing at the IPC$ share for the given server */
3729 struct cli_state *get_ipc_connect(char *server,
3730 struct sockaddr_storage *server_ss,
3731 const struct user_auth_info *user_info)
3733 struct cli_state *cli;
3735 uint32_t flags = CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
3737 if (get_cmdline_auth_info_use_kerberos(user_info)) {
3738 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
3741 flags |= CLI_FULL_CONNECTION_FORCE_SMB1;
3743 nt_status = cli_full_connection(&cli, NULL, server, server_ss, 0, "IPC$", "IPC",
3744 get_cmdline_auth_info_username(user_info),
3746 get_cmdline_auth_info_password(user_info),
3748 SMB_SIGNING_DEFAULT);
3750 if (NT_STATUS_IS_OK(nt_status)) {
3752 } else if (is_ipaddress(server)) {
3753 /* windows 9* needs a correct NMB name for connections */
3754 fstring remote_name;
3756 if (name_status_find("*", 0, 0, server_ss, remote_name)) {
3757 cli = get_ipc_connect(remote_name, server_ss, user_info);
3766 * Given the IP address of a master browser on the network, return its
3767 * workgroup and connect to it.
3769 * This function is provided to allow additional processing beyond what
3770 * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
3771 * browsers and obtain each master browsers' list of domains (in case the
3772 * first master browser is recently on the network and has not yet
3773 * synchronized with other master browsers and therefore does not yet have the
3774 * entire network browse list)
3777 struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx,
3778 struct sockaddr_storage *mb_ip,
3779 const struct user_auth_info *user_info,
3780 char **pp_workgroup_out)
3782 char addr[INET6_ADDRSTRLEN];
3784 struct cli_state *cli;
3785 struct sockaddr_storage server_ss;
3787 *pp_workgroup_out = NULL;
3789 print_sockaddr(addr, sizeof(addr), mb_ip);
3790 DEBUG(99, ("Looking up name of master browser %s\n",
3794 * Do a name status query to find out the name of the master browser.
3795 * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
3796 * master browser will not respond to a wildcard query (or, at least,
3797 * an NT4 server acting as the domain master browser will not).
3799 * We might be able to use ONLY the query on MSBROWSE, but that's not
3800 * yet been tested with all Windows versions, so until it is, leave
3801 * the original wildcard query as the first choice and fall back to
3802 * MSBROWSE if the wildcard query fails.
3804 if (!name_status_find("*", 0, 0x1d, mb_ip, name) &&
3805 !name_status_find(MSBROWSE, 1, 0x1d, mb_ip, name)) {
3807 DEBUG(99, ("Could not retrieve name status for %s\n",
3812 if (!find_master_ip(name, &server_ss)) {
3813 DEBUG(99, ("Could not find master ip for %s\n", name));
3817 *pp_workgroup_out = talloc_strdup(ctx, name);
3819 DEBUG(4, ("found master browser %s, %s\n", name, addr));
3821 print_sockaddr(addr, sizeof(addr), &server_ss);
3822 cli = get_ipc_connect(addr, &server_ss, user_info);
3828 * Return the IP address and workgroup of a master browser on the network, and
3832 struct cli_state *get_ipc_connect_master_ip_bcast(TALLOC_CTX *ctx,
3833 const struct user_auth_info *user_info,
3834 char **pp_workgroup_out)
3836 struct sockaddr_storage *ip_list;
3837 struct cli_state *cli;
3841 *pp_workgroup_out = NULL;
3843 DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
3845 /* Go looking for workgroups by broadcasting on the local network */
3847 status = name_resolve_bcast(MSBROWSE, 1, talloc_tos(),
3849 if (!NT_STATUS_IS_OK(status)) {
3850 DEBUG(99, ("No master browsers responded: %s\n",
3851 nt_errstr(status)));
3855 for (i = 0; i < count; i++) {
3856 char addr[INET6_ADDRSTRLEN];
3857 print_sockaddr(addr, sizeof(addr), &ip_list[i]);
3858 DEBUG(99, ("Found master browser %s\n", addr));
3860 cli = get_ipc_connect_master_ip(ctx, &ip_list[i],
3861 user_info, pp_workgroup_out);