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 "source3/include/client.h"
25 #include "source3/libsmb/proto.h"
26 #include "libads/ads_status.h"
27 #include "libsmb/namequery.h"
28 #include "../libcli/auth/libcli_auth.h"
29 #include "auth/credentials/credentials.h"
30 #include "auth/gensec/gensec.h"
31 #include "auth/ntlmssp/ntlmssp.h"
32 #include "auth_generic.h"
33 #include "../lib/util/tevent_ntstatus.h"
34 #include "async_smb.h"
35 #include "libsmb/nmblib.h"
36 #include "libsmb/smbsock_connect.h"
37 #include "librpc/ndr/libndr.h"
38 #include "../libcli/smb/smbXcli_base.h"
39 #include "../libcli/smb/smb_seal.h"
40 #include "lib/param/param.h"
41 #include "../libcli/smb/smb2_negotiate_context.h"
43 static char *cli_session_setup_get_account(TALLOC_CTX *mem_ctx,
44 const char *principal);
46 struct cli_credentials *cli_session_creds_init(TALLOC_CTX *mem_ctx,
52 bool fallback_after_kerberos,
54 bool password_is_nt_hash)
56 struct loadparm_context *lp_ctx = NULL;
57 struct cli_credentials *creds = NULL;
58 const char *principal = NULL;
59 enum credentials_use_kerberos creds_use_krb;
64 creds = cli_credentials_init(mem_ctx);
69 lp_ctx = loadparm_init_s3(creds, loadparm_s3_helpers());
73 ok = 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
126 if (fallback_after_kerberos) {
128 * Keep what we learned from the
129 * "client use kerberos" option.
131 creds_use_krb = cli_credentials_get_kerberos_state(
134 creds_use_krb = CRED_USE_KERBEROS_REQUIRED;
137 creds_use_krb = CRED_USE_KERBEROS_DISABLED;
140 cli_credentials_set_kerberos_state(creds,
145 cli_credentials_add_gensec_features(creds,
146 GENSEC_FEATURE_NTLM_CCACHE,
149 if (password != NULL && strlen(password) == 0) {
151 * some callers pass "" as no password
153 * GENSEC_FEATURE_NTLM_CCACHE only handles
154 * NULL as no password.
160 ok = cli_credentials_set_username(creds,
167 if (domain != NULL) {
168 ok = cli_credentials_set_domain(creds,
176 if (principal != NULL) {
177 ok = cli_credentials_set_principal(creds,
186 ok = cli_credentials_set_realm(creds,
194 if (password != NULL && strlen(password) > 0) {
195 if (password_is_nt_hash) {
196 struct samr_Password nt_hash;
199 converted = strhex_to_str((char *)nt_hash.hash,
200 sizeof(nt_hash.hash),
203 if (converted != sizeof(nt_hash.hash)) {
207 ok = cli_credentials_set_nt_hash(creds,
214 ok = cli_credentials_set_password(creds,
221 } else if (use_kerberos && !fallback_after_kerberos) {
222 const char *error_string = NULL;
225 rc = cli_credentials_set_ccache(creds,
232 "Warning reading default "
233 "krb5 credentials cache: %s\n",
244 static NTSTATUS cli_state_update_after_sesssetup(struct cli_state *cli,
245 const char *native_os,
246 const char *native_lm,
247 const char *primary_domain)
249 #define _VALID_STR(p) ((p) != NULL && (p)[0] != '\0')
251 if (!_VALID_STR(cli->server_os) && _VALID_STR(native_os)) {
252 cli->server_os = talloc_strdup(cli, native_os);
253 if (cli->server_os == NULL) {
254 return NT_STATUS_NO_MEMORY;
258 if (!_VALID_STR(cli->server_type) && _VALID_STR(native_lm)) {
259 cli->server_type = talloc_strdup(cli, native_lm);
260 if (cli->server_type == NULL) {
261 return NT_STATUS_NO_MEMORY;
265 if (!_VALID_STR(cli->server_domain) && _VALID_STR(primary_domain)) {
266 cli->server_domain = talloc_strdup(cli, primary_domain);
267 if (cli->server_domain == NULL) {
268 return NT_STATUS_NO_MEMORY;
276 /********************************************************
277 Utility function to ensure we always return at least
278 a valid char * pointer to an empty string for the
279 cli->server_os, cli->server_type and cli->server_domain
281 *******************************************************/
283 static NTSTATUS smb_bytes_talloc_string(TALLOC_CTX *mem_ctx,
290 *destlen = pull_string_talloc(mem_ctx,
297 if (*destlen == -1) {
298 return NT_STATUS_NO_MEMORY;
302 *dest = talloc_strdup(mem_ctx, "");
304 return NT_STATUS_NO_MEMORY;
310 /****************************************************************************
311 Work out suitable capabilities to offer the server.
312 ****************************************************************************/
314 static uint32_t cli_session_setup_capabilities(struct cli_state *cli,
315 uint32_t sesssetup_capabilities)
317 uint32_t client_capabilities = smb1cli_conn_capabilities(cli->conn);
320 * We only send capabilities based on the mask for:
321 * - client only flags
322 * - flags used in both directions
324 * We do not echo the server only flags, except some legacy flags.
326 * SMB_CAP_LEGACY_CLIENT_MASK contains CAP_LARGE_READX and
327 * CAP_LARGE_WRITEX in order to allow us to do large reads
328 * against old Samba releases (<= 3.6.x).
330 client_capabilities &= (SMB_CAP_BOTH_MASK | SMB_CAP_LEGACY_CLIENT_MASK);
333 * Session Setup specific flags CAP_DYNAMIC_REAUTH
334 * and CAP_EXTENDED_SECURITY are passed by the caller.
335 * We need that in order to do guest logins even if
336 * CAP_EXTENDED_SECURITY is negotiated.
338 client_capabilities &= ~(CAP_DYNAMIC_REAUTH|CAP_EXTENDED_SECURITY);
339 sesssetup_capabilities &= (CAP_DYNAMIC_REAUTH|CAP_EXTENDED_SECURITY);
340 client_capabilities |= sesssetup_capabilities;
342 return client_capabilities;
345 /****************************************************************************
346 Do a NT1 guest session setup.
347 ****************************************************************************/
349 struct cli_session_setup_guest_state {
350 struct cli_state *cli;
355 static void cli_session_setup_guest_done(struct tevent_req *subreq);
357 struct tevent_req *cli_session_setup_guest_create(TALLOC_CTX *mem_ctx,
358 struct tevent_context *ev,
359 struct cli_state *cli,
360 struct tevent_req **psmbreq)
362 struct tevent_req *req, *subreq;
363 struct cli_session_setup_guest_state *state;
367 req = tevent_req_create(mem_ctx, &state,
368 struct cli_session_setup_guest_state);
375 SCVAL(vwv+0, 0, 0xFF);
378 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
380 SSVAL(vwv+4, 0, cli_state_get_vc_num(cli));
381 SIVAL(vwv+5, 0, smb1cli_conn_server_session_key(cli->conn));
386 SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli, 0));
388 bytes = talloc_array(state, uint8_t, 0);
390 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "", 1, /* username */
392 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "", 1, /* workgroup */
394 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "Unix", 5, NULL);
395 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "Samba", 6, NULL);
402 state->bytes.iov_base = (void *)bytes;
403 state->bytes.iov_len = talloc_get_size(bytes);
405 subreq = cli_smb_req_create(state, ev, cli, SMBsesssetupX, 0, 0, 13,
406 vwv, 1, &state->bytes);
407 if (subreq == NULL) {
411 tevent_req_set_callback(subreq, cli_session_setup_guest_done, req);
416 struct tevent_req *cli_session_setup_guest_send(TALLOC_CTX *mem_ctx,
417 struct tevent_context *ev,
418 struct cli_state *cli)
420 struct tevent_req *req, *subreq;
423 req = cli_session_setup_guest_create(mem_ctx, ev, cli, &subreq);
428 status = smb1cli_req_chain_submit(&subreq, 1);
429 if (!NT_STATUS_IS_OK(status)) {
430 tevent_req_nterror(req, status);
431 return tevent_req_post(req, ev);
436 static void cli_session_setup_guest_done(struct tevent_req *subreq)
438 struct tevent_req *req = tevent_req_callback_data(
439 subreq, struct tevent_req);
440 struct cli_session_setup_guest_state *state = tevent_req_data(
441 req, struct cli_session_setup_guest_state);
442 struct cli_state *cli = state->cli;
453 status = cli_smb_recv(subreq, state, &in, 3, &wct, &vwv,
456 if (!NT_STATUS_IS_OK(status)) {
457 tevent_req_nterror(req, status);
461 inhdr = in + NBT_HDR_SIZE;
464 cli_state_set_uid(state->cli, SVAL(inhdr, HDR_UID));
465 smb1cli_session_set_action(cli->smb1.session, SVAL(vwv+2, 0));
467 status = smb_bytes_talloc_string(cli,
474 if (!NT_STATUS_IS_OK(status)) {
475 tevent_req_nterror(req, status);
480 status = smb_bytes_talloc_string(cli,
487 if (!NT_STATUS_IS_OK(status)) {
488 tevent_req_nterror(req, status);
493 status = smb_bytes_talloc_string(cli,
500 if (!NT_STATUS_IS_OK(status)) {
501 tevent_req_nterror(req, status);
505 tevent_req_done(req);
508 NTSTATUS cli_session_setup_guest_recv(struct tevent_req *req)
510 return tevent_req_simple_recv_ntstatus(req);
513 /* The following is calculated from :
515 * (smb_wcnt * 2) = 24 (smb_wcnt == 12 in cli_session_setup_blob_send() )
516 * (strlen("Unix") + 1 + strlen("Samba") + 1) * 2 = 22 (unicode strings at
520 #define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22)
522 struct cli_sesssetup_blob_state {
523 struct tevent_context *ev;
524 struct cli_state *cli;
526 uint16_t max_blob_size;
529 struct iovec *recv_iov;
532 const uint8_t *inbuf;
539 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state *state,
540 struct tevent_req **psubreq);
541 static void cli_sesssetup_blob_done(struct tevent_req *subreq);
543 static struct tevent_req *cli_sesssetup_blob_send(TALLOC_CTX *mem_ctx,
544 struct tevent_context *ev,
545 struct cli_state *cli,
548 struct tevent_req *req, *subreq;
549 struct cli_sesssetup_blob_state *state;
550 uint32_t usable_space;
552 req = tevent_req_create(mem_ctx, &state,
553 struct cli_sesssetup_blob_state);
561 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
562 usable_space = UINT16_MAX;
564 usable_space = cli_state_available_size(cli,
565 BASE_SESSSETUP_BLOB_PACKET_SIZE);
568 if (usable_space == 0) {
569 DEBUG(1, ("cli_session_setup_blob: cli->max_xmit too small "
570 "(not possible to send %u bytes)\n",
571 BASE_SESSSETUP_BLOB_PACKET_SIZE + 1));
572 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
573 return tevent_req_post(req, ev);
575 state->max_blob_size = MIN(usable_space, 0xFFFF);
577 if (!cli_sesssetup_blob_next(state, &subreq)) {
578 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
579 return tevent_req_post(req, ev);
581 tevent_req_set_callback(subreq, cli_sesssetup_blob_done, req);
585 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state *state,
586 struct tevent_req **psubreq)
588 struct tevent_req *subreq;
591 thistime = MIN(state->blob.length, state->max_blob_size);
593 state->this_blob.data = state->blob.data;
594 state->this_blob.length = thistime;
596 state->blob.data += thistime;
597 state->blob.length -= thistime;
599 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
600 subreq = smb2cli_session_setup_send(state, state->ev,
603 state->cli->smb2.session,
605 SMB2_CAP_DFS, /* in_capabilities */
607 0, /* in_previous_session_id */
609 if (subreq == NULL) {
613 uint16_t in_buf_size = 0;
614 uint16_t in_mpx_max = 0;
615 uint16_t in_vc_num = 0;
616 uint32_t in_sess_key = 0;
617 uint32_t in_capabilities = 0;
618 const char *in_native_os = NULL;
619 const char *in_native_lm = NULL;
621 in_buf_size = CLI_BUFFER_SIZE;
622 in_mpx_max = smbXcli_conn_max_requests(state->cli->conn);
623 in_vc_num = cli_state_get_vc_num(state->cli);
624 in_sess_key = smb1cli_conn_server_session_key(state->cli->conn);
625 in_capabilities = cli_session_setup_capabilities(state->cli,
626 CAP_EXTENDED_SECURITY);
627 in_native_os = "Unix";
628 in_native_lm = "Samba";
631 * For now we keep the same values as before,
632 * we may remove these in a separate commit later.
638 subreq = smb1cli_session_setup_ext_send(state, state->ev,
641 state->cli->smb1.pid,
642 state->cli->smb1.session,
651 if (subreq == NULL) {
659 static void cli_sesssetup_blob_done(struct tevent_req *subreq)
661 struct tevent_req *req = tevent_req_callback_data(
662 subreq, struct tevent_req);
663 struct cli_sesssetup_blob_state *state = tevent_req_data(
664 req, struct cli_sesssetup_blob_state);
667 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
668 status = smb2cli_session_setup_recv(subreq, state,
672 status = smb1cli_session_setup_ext_recv(subreq, state,
676 &state->out_native_os,
677 &state->out_native_lm);
680 if (!NT_STATUS_IS_OK(status)
681 && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
682 tevent_req_nterror(req, status);
686 state->status = status;
688 status = cli_state_update_after_sesssetup(state->cli,
689 state->out_native_os,
690 state->out_native_lm,
692 if (tevent_req_nterror(req, status)) {
696 if (state->blob.length != 0) {
700 if (!cli_sesssetup_blob_next(state, &subreq)) {
704 tevent_req_set_callback(subreq, cli_sesssetup_blob_done, req);
707 tevent_req_done(req);
710 static NTSTATUS cli_sesssetup_blob_recv(struct tevent_req *req,
713 const uint8_t **pinbuf,
714 struct iovec **precv_iov)
716 struct cli_sesssetup_blob_state *state = tevent_req_data(
717 req, struct cli_sesssetup_blob_state);
719 struct iovec *recv_iov;
721 if (tevent_req_is_nterror(req, &status)) {
722 TALLOC_FREE(state->cli->smb2.session);
723 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
724 tevent_req_received(req);
728 recv_iov = talloc_move(mem_ctx, &state->recv_iov);
730 *pblob = state->ret_blob;
732 if (pinbuf != NULL) {
733 *pinbuf = state->inbuf;
735 if (precv_iov != NULL) {
736 *precv_iov = recv_iov;
738 /* could be NT_STATUS_MORE_PROCESSING_REQUIRED */
739 status = state->status;
740 tevent_req_received(req);
744 /****************************************************************************
745 Do a spnego/NTLMSSP encrypted session setup.
746 ****************************************************************************/
748 struct cli_session_setup_gensec_state {
749 struct tevent_context *ev;
750 struct cli_state *cli;
751 struct auth_generic_state *auth_generic;
754 const uint8_t *inbuf;
755 struct iovec *recv_iov;
759 DATA_BLOB session_key;
762 static int cli_session_setup_gensec_state_destructor(
763 struct cli_session_setup_gensec_state *state)
765 TALLOC_FREE(state->auth_generic);
766 data_blob_clear_free(&state->session_key);
770 static void cli_session_setup_gensec_local_next(struct tevent_req *req);
771 static void cli_session_setup_gensec_local_done(struct tevent_req *subreq);
772 static void cli_session_setup_gensec_remote_next(struct tevent_req *req);
773 static void cli_session_setup_gensec_remote_done(struct tevent_req *subreq);
774 static void cli_session_setup_gensec_ready(struct tevent_req *req);
776 static struct tevent_req *cli_session_setup_gensec_send(
777 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
778 struct cli_credentials *creds,
779 const char *target_service,
780 const char *target_hostname)
782 struct tevent_req *req;
783 struct cli_session_setup_gensec_state *state;
785 const DATA_BLOB *b = NULL;
787 req = tevent_req_create(mem_ctx, &state,
788 struct cli_session_setup_gensec_state);
795 talloc_set_destructor(
796 state, cli_session_setup_gensec_state_destructor);
798 status = auth_generic_client_prepare(state, &state->auth_generic);
799 if (tevent_req_nterror(req, status)) {
800 return tevent_req_post(req, ev);
803 status = auth_generic_set_creds(state->auth_generic, creds);
804 if (tevent_req_nterror(req, status)) {
805 return tevent_req_post(req, ev);
808 gensec_want_feature(state->auth_generic->gensec_security,
809 GENSEC_FEATURE_SESSION_KEY);
811 if (target_service != NULL) {
812 status = gensec_set_target_service(
813 state->auth_generic->gensec_security,
815 if (tevent_req_nterror(req, status)) {
816 return tevent_req_post(req, ev);
820 if (target_hostname != NULL) {
821 status = gensec_set_target_hostname(
822 state->auth_generic->gensec_security,
824 if (tevent_req_nterror(req, status)) {
825 return tevent_req_post(req, ev);
829 b = smbXcli_conn_server_gss_blob(cli->conn);
834 state->is_anonymous = cli_credentials_is_anonymous(state->auth_generic->credentials);
836 status = auth_generic_client_start(state->auth_generic,
838 if (tevent_req_nterror(req, status)) {
839 return tevent_req_post(req, ev);
842 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
843 state->cli->smb2.session = smbXcli_session_create(cli,
845 if (tevent_req_nomem(state->cli->smb2.session, req)) {
846 return tevent_req_post(req, ev);
850 cli_session_setup_gensec_local_next(req);
851 if (!tevent_req_is_in_progress(req)) {
852 return tevent_req_post(req, ev);
858 static void cli_session_setup_gensec_local_next(struct tevent_req *req)
860 struct cli_session_setup_gensec_state *state =
862 struct cli_session_setup_gensec_state);
863 struct tevent_req *subreq = NULL;
865 if (state->local_ready) {
866 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
870 subreq = gensec_update_send(state, state->ev,
871 state->auth_generic->gensec_security,
873 if (tevent_req_nomem(subreq, req)) {
876 tevent_req_set_callback(subreq, cli_session_setup_gensec_local_done, req);
879 static void cli_session_setup_gensec_local_done(struct tevent_req *subreq)
881 struct tevent_req *req =
882 tevent_req_callback_data(subreq,
884 struct cli_session_setup_gensec_state *state =
886 struct cli_session_setup_gensec_state);
889 status = gensec_update_recv(subreq, state, &state->blob_out);
891 state->blob_in = data_blob_null;
892 if (!NT_STATUS_IS_OK(status) &&
893 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
895 tevent_req_nterror(req, status);
899 if (NT_STATUS_IS_OK(status)) {
900 state->local_ready = true;
903 if (state->local_ready && state->remote_ready) {
904 cli_session_setup_gensec_ready(req);
908 cli_session_setup_gensec_remote_next(req);
911 static void cli_session_setup_gensec_remote_next(struct tevent_req *req)
913 struct cli_session_setup_gensec_state *state =
915 struct cli_session_setup_gensec_state);
916 struct tevent_req *subreq = NULL;
918 if (state->remote_ready) {
919 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
923 subreq = cli_sesssetup_blob_send(state, state->ev,
924 state->cli, state->blob_out);
925 if (tevent_req_nomem(subreq, req)) {
928 tevent_req_set_callback(subreq,
929 cli_session_setup_gensec_remote_done,
933 static void cli_session_setup_gensec_remote_done(struct tevent_req *subreq)
935 struct tevent_req *req =
936 tevent_req_callback_data(subreq,
938 struct cli_session_setup_gensec_state *state =
940 struct cli_session_setup_gensec_state);
944 TALLOC_FREE(state->recv_iov);
946 status = cli_sesssetup_blob_recv(subreq, state, &state->blob_in,
947 &state->inbuf, &state->recv_iov);
949 data_blob_free(&state->blob_out);
950 if (!NT_STATUS_IS_OK(status) &&
951 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
953 tevent_req_nterror(req, status);
957 if (NT_STATUS_IS_OK(status)) {
958 struct smbXcli_session *session = NULL;
959 bool is_guest = false;
961 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
962 session = state->cli->smb2.session;
964 session = state->cli->smb1.session;
967 is_guest = smbXcli_session_is_guest(session);
970 * We can't finish the gensec handshake, we don't
971 * have a negotiated session key.
973 * So just pretend we are completely done,
974 * we need to continue as anonymous from this point,
975 * as we can't get a session key.
977 * Note that smbXcli_session_is_guest()
978 * always returns false if we require signing.
980 state->blob_in = data_blob_null;
981 state->local_ready = true;
982 state->is_anonymous = true;
985 state->remote_ready = true;
988 if (state->local_ready && state->remote_ready) {
989 cli_session_setup_gensec_ready(req);
993 cli_session_setup_gensec_local_next(req);
996 static void cli_session_setup_gensec_ready(struct tevent_req *req)
998 struct cli_session_setup_gensec_state *state =
1000 struct cli_session_setup_gensec_state);
1001 const char *server_domain = NULL;
1004 if (state->blob_in.length != 0) {
1005 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1009 if (state->blob_out.length != 0) {
1010 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1015 * gensec_ntlmssp_server_domain() returns NULL
1016 * if NTLMSSP is not used.
1018 * We can remove this later
1019 * and leave the server domain empty for SMB2 and above
1020 * in future releases.
1022 server_domain = gensec_ntlmssp_server_domain(
1023 state->auth_generic->gensec_security);
1025 if (state->cli->server_domain[0] == '\0' && server_domain != NULL) {
1026 TALLOC_FREE(state->cli->server_domain);
1027 state->cli->server_domain = talloc_strdup(state->cli,
1029 if (state->cli->server_domain == NULL) {
1030 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1035 if (state->is_anonymous) {
1037 * Windows server does not set the
1038 * SMB2_SESSION_FLAG_IS_NULL flag.
1040 * This fix makes sure we do not try
1041 * to verify a signature on the final
1042 * session setup response.
1044 tevent_req_done(req);
1048 status = gensec_session_key(state->auth_generic->gensec_security,
1049 state, &state->session_key);
1050 if (tevent_req_nterror(req, status)) {
1054 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
1055 struct smbXcli_session *session = state->cli->smb2.session;
1057 status = smb2cli_session_set_session_key(session,
1060 if (tevent_req_nterror(req, status)) {
1063 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB3_00
1064 && lp_debug_encryption())
1066 DATA_BLOB sig, app, enc, dec;
1067 const char *wireshark_keyfile = lp_parm_const_string(
1068 GLOBAL_SECTION_SNUM,
1070 "wireshark keyfile",
1073 status = smb2cli_session_signing_key(session, state, &sig);
1074 if (tevent_req_nterror(req, status)) {
1077 status = smbXcli_session_application_key(session, state, &app);
1078 if (tevent_req_nterror(req, status)) {
1081 status = smb2cli_session_encryption_key(session, state, &enc);
1082 if (tevent_req_nterror(req, status)) {
1085 status = smb2cli_session_decryption_key(session, state, &dec);
1086 if (tevent_req_nterror(req, status)) {
1090 smbXcli_session_dump_keys(smb2cli_session_current_id(session),
1091 &state->session_key,
1092 smb2cli_conn_server_signing_algo(state->cli->conn),
1100 struct smbXcli_session *session = state->cli->smb1.session;
1103 status = smb1cli_session_set_session_key(session,
1104 state->session_key);
1105 if (tevent_req_nterror(req, status)) {
1109 active = smb1cli_conn_activate_signing(state->cli->conn,
1115 ok = smb1cli_conn_check_signing(state->cli->conn,
1118 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1124 tevent_req_done(req);
1127 static NTSTATUS cli_session_setup_gensec_recv(struct tevent_req *req)
1129 struct cli_session_setup_gensec_state *state =
1130 tevent_req_data(req,
1131 struct cli_session_setup_gensec_state);
1134 if (tevent_req_is_nterror(req, &status)) {
1135 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
1138 return NT_STATUS_OK;
1141 static char *cli_session_setup_get_account(TALLOC_CTX *mem_ctx,
1142 const char *principal)
1146 account = talloc_strdup(mem_ctx, principal);
1147 if (account == NULL) {
1150 p = strchr_m(account, '@');
1157 /****************************************************************************
1158 Do a spnego encrypted session setup.
1160 user_domain: The shortname of the domain the user/machine is a member of.
1161 dest_realm: The realm we're connecting to, if NULL we use our default realm.
1162 ****************************************************************************/
1164 struct cli_session_setup_spnego_state {
1168 static void cli_session_setup_spnego_done(struct tevent_req *subreq);
1170 static struct tevent_req *cli_session_setup_spnego_send(
1171 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
1172 struct cli_credentials *creds)
1174 struct tevent_req *req, *subreq;
1175 struct cli_session_setup_spnego_state *state;
1176 const char *target_service = NULL;
1177 const char *target_hostname = NULL;
1179 req = tevent_req_create(mem_ctx, &state,
1180 struct cli_session_setup_spnego_state);
1185 target_service = "cifs";
1186 target_hostname = smbXcli_conn_remote_name(cli->conn);
1188 DBG_INFO("Connect to %s as %s using SPNEGO\n",
1190 cli_credentials_get_principal(creds, talloc_tos()));
1192 subreq = cli_session_setup_gensec_send(state, ev, cli, creds,
1193 target_service, target_hostname);
1194 if (tevent_req_nomem(subreq, req)) {
1195 return tevent_req_post(req, ev);
1197 tevent_req_set_callback(
1198 subreq, cli_session_setup_spnego_done, req);
1202 static void cli_session_setup_spnego_done(struct tevent_req *subreq)
1204 struct tevent_req *req = tevent_req_callback_data(
1205 subreq, struct tevent_req);
1208 status = cli_session_setup_gensec_recv(subreq);
1209 TALLOC_FREE(subreq);
1210 if (tevent_req_nterror(req, status)) {
1214 tevent_req_done(req);
1217 static ADS_STATUS cli_session_setup_spnego_recv(struct tevent_req *req)
1219 struct cli_session_setup_spnego_state *state = tevent_req_data(
1220 req, struct cli_session_setup_spnego_state);
1223 if (tevent_req_is_nterror(req, &status)) {
1224 state->result = ADS_ERROR_NT(status);
1227 return state->result;
1230 struct cli_session_setup_creds_state {
1231 struct cli_state *cli;
1232 DATA_BLOB apassword_blob;
1233 DATA_BLOB upassword_blob;
1234 DATA_BLOB lm_session_key;
1235 DATA_BLOB session_key;
1236 char *out_native_os;
1237 char *out_native_lm;
1238 char *out_primary_domain;
1241 static void cli_session_setup_creds_cleanup(struct tevent_req *req,
1242 enum tevent_req_state req_state)
1244 struct cli_session_setup_creds_state *state = tevent_req_data(
1245 req, struct cli_session_setup_creds_state);
1247 if (req_state != TEVENT_REQ_RECEIVED) {
1252 * We only call data_blob_clear() as
1253 * some of the blobs point to the same memory.
1255 * We let the talloc hierarchy free the memory.
1257 data_blob_clear(&state->apassword_blob);
1258 data_blob_clear(&state->upassword_blob);
1259 data_blob_clear(&state->lm_session_key);
1260 data_blob_clear(&state->session_key);
1261 ZERO_STRUCTP(state);
1264 static void cli_session_setup_creds_done_spnego(struct tevent_req *subreq);
1265 static void cli_session_setup_creds_done_nt1(struct tevent_req *subreq);
1266 static void cli_session_setup_creds_done_lm21(struct tevent_req *subreq);
1268 /****************************************************************************
1269 Send a session setup. The username and workgroup is in UNIX character
1270 format and must be converted to DOS codepage format before sending. If the
1271 password is in plaintext, the same should be done.
1272 ****************************************************************************/
1274 struct tevent_req *cli_session_setup_creds_send(TALLOC_CTX *mem_ctx,
1275 struct tevent_context *ev,
1276 struct cli_state *cli,
1277 struct cli_credentials *creds)
1279 struct tevent_req *req, *subreq;
1280 struct cli_session_setup_creds_state *state;
1281 uint16_t sec_mode = smb1cli_conn_server_security_mode(cli->conn);
1282 bool use_spnego = false;
1284 const char *username = "";
1285 const char *domain = "";
1286 DATA_BLOB target_info = data_blob_null;
1287 DATA_BLOB challenge = data_blob_null;
1288 uint16_t in_buf_size = 0;
1289 uint16_t in_mpx_max = 0;
1290 uint16_t in_vc_num = 0;
1291 uint32_t in_sess_key = 0;
1292 const char *in_native_os = NULL;
1293 const char *in_native_lm = NULL;
1294 enum credentials_use_kerberos krb5_state =
1295 cli_credentials_get_kerberos_state(creds);
1298 req = tevent_req_create(mem_ctx, &state,
1299 struct cli_session_setup_creds_state);
1305 tevent_req_set_cleanup_fn(req, cli_session_setup_creds_cleanup);
1308 * Now work out what sort of session setup we are going to
1309 * do. I have split this into separate functions to make the flow a bit
1310 * easier to understand (tridge).
1312 if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_NT1) {
1314 } else if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
1316 } else if (smb1cli_conn_capabilities(cli->conn) & CAP_EXTENDED_SECURITY) {
1318 * if the server supports extended security then use SPNEGO
1319 * even for anonymous connections.
1327 subreq = cli_session_setup_spnego_send(
1328 state, ev, cli, creds);
1329 if (tevent_req_nomem(subreq, req)) {
1330 return tevent_req_post(req, ev);
1332 tevent_req_set_callback(subreq, cli_session_setup_creds_done_spnego,
1337 if (krb5_state == CRED_USE_KERBEROS_REQUIRED) {
1338 DBG_WARNING("Kerberos authentication requested, but "
1339 "the server does not support SPNEGO authentication\n");
1340 tevent_req_nterror(req, NT_STATUS_NETWORK_CREDENTIAL_CONFLICT);
1341 return tevent_req_post(req, ev);
1344 if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_LANMAN1) {
1346 * SessionSetupAndX was introduced by LANMAN 1.0. So we skip
1347 * this step against older servers.
1349 tevent_req_done(req);
1350 return tevent_req_post(req, ev);
1353 if (cli_credentials_is_anonymous(creds)) {
1355 * Do an anonymous session setup
1357 goto non_spnego_creds_done;
1360 if ((sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0) {
1362 * Do an anonymous session setup,
1363 * the password is passed via the tree connect.
1365 goto non_spnego_creds_done;
1368 cli_credentials_get_ntlm_username_domain(creds, state,
1371 if (tevent_req_nomem(username, req)) {
1372 return tevent_req_post(req, ev);
1374 if (tevent_req_nomem(domain, req)) {
1375 return tevent_req_post(req, ev);
1378 DBG_INFO("Connect to %s as %s using NTLM\n", domain, username);
1380 if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) {
1381 bool use_unicode = smbXcli_conn_use_unicode(cli->conn);
1382 uint8_t *bytes = NULL;
1383 size_t bytes_len = 0;
1384 const char *pw = cli_credentials_get_password(creds);
1390 pw_len = strlen(pw) + 1;
1392 if (!lp_client_plaintext_auth()) {
1393 DEBUG(1, ("Server requested PLAINTEXT password but "
1394 "'client plaintext auth = no'\n"));
1395 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1396 return tevent_req_post(req, ev);
1399 bytes = talloc_array(state, uint8_t, 0);
1400 bytes = trans2_bytes_push_str(bytes, use_unicode,
1401 pw, pw_len, &bytes_len);
1402 if (tevent_req_nomem(bytes, req)) {
1403 return tevent_req_post(req, ev);
1408 * CAP_UNICODE, can only be negotiated by NT1.
1410 state->upassword_blob = data_blob_const(bytes,
1413 state->apassword_blob = data_blob_const(bytes,
1417 goto non_spnego_creds_done;
1420 challenge = data_blob_const(smb1cli_conn_server_challenge(cli->conn), 8);
1422 if (smbXcli_conn_protocol(cli->conn) == PROTOCOL_NT1) {
1423 if (lp_client_ntlmv2_auth() && lp_client_use_spnego()) {
1425 * Don't send an NTLMv2 response without NTLMSSP if we
1426 * want to use spnego support.
1428 DEBUG(1, ("Server does not support EXTENDED_SECURITY "
1429 " but 'client use spnego = yes'"
1430 " and 'client ntlmv2 auth = yes' is set\n"));
1431 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1432 return tevent_req_post(req, ev);
1435 if (lp_client_ntlmv2_auth()) {
1436 flags |= CLI_CRED_NTLMv2_AUTH;
1439 * note that the 'domain' here is a best
1440 * guess - we don't know the server's domain
1441 * at this point. Windows clients also don't
1444 target_info = NTLMv2_generate_names_blob(state,
1447 if (tevent_req_nomem(target_info.data, req)) {
1448 return tevent_req_post(req, ev);
1451 flags |= CLI_CRED_NTLM_AUTH;
1452 if (lp_client_lanman_auth()) {
1453 flags |= CLI_CRED_LANMAN_AUTH;
1457 if (!lp_client_lanman_auth()) {
1458 DEBUG(1, ("Server requested user level LM password but "
1459 "'client lanman auth = no' is set.\n"));
1460 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1461 return tevent_req_post(req, ev);
1464 flags |= CLI_CRED_LANMAN_AUTH;
1467 status = cli_credentials_get_ntlm_response(creds, state, &flags,
1470 &state->apassword_blob,
1471 &state->upassword_blob,
1472 &state->lm_session_key,
1473 &state->session_key);
1474 if (tevent_req_nterror(req, status)) {
1475 return tevent_req_post(req, ev);
1478 non_spnego_creds_done:
1480 in_buf_size = CLI_BUFFER_SIZE;
1481 in_mpx_max = smbXcli_conn_max_requests(cli->conn);
1482 in_vc_num = cli_state_get_vc_num(cli);
1483 in_sess_key = smb1cli_conn_server_session_key(cli->conn);
1484 in_native_os = "Unix";
1485 in_native_lm = "Samba";
1487 if (smbXcli_conn_protocol(cli->conn) == PROTOCOL_NT1) {
1488 uint32_t in_capabilities = 0;
1490 in_capabilities = cli_session_setup_capabilities(cli, 0);
1493 * For now we keep the same values as before,
1494 * we may remove these in a separate commit later.
1498 subreq = smb1cli_session_setup_nt1_send(state, ev,
1509 state->apassword_blob,
1510 state->upassword_blob,
1514 if (tevent_req_nomem(subreq, req)) {
1515 return tevent_req_post(req, ev);
1517 tevent_req_set_callback(subreq, cli_session_setup_creds_done_nt1,
1523 * For now we keep the same values as before,
1524 * we may remove these in a separate commit later.
1529 subreq = smb1cli_session_setup_lm21_send(state, ev,
1540 state->apassword_blob,
1543 if (tevent_req_nomem(subreq, req)) {
1544 return tevent_req_post(req, ev);
1546 tevent_req_set_callback(subreq, cli_session_setup_creds_done_lm21,
1551 static void cli_session_setup_creds_done_spnego(struct tevent_req *subreq)
1553 struct tevent_req *req = tevent_req_callback_data(
1554 subreq, struct tevent_req);
1557 status = cli_session_setup_spnego_recv(subreq);
1558 TALLOC_FREE(subreq);
1559 if (!ADS_ERR_OK(status)) {
1560 DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status)));
1561 tevent_req_nterror(req, ads_ntstatus(status));
1564 tevent_req_done(req);
1567 static void cli_session_setup_creds_done_nt1(struct tevent_req *subreq)
1569 struct tevent_req *req = tevent_req_callback_data(
1570 subreq, struct tevent_req);
1571 struct cli_session_setup_creds_state *state = tevent_req_data(
1572 req, struct cli_session_setup_creds_state);
1573 struct cli_state *cli = state->cli;
1575 struct iovec *recv_iov = NULL;
1576 const uint8_t *inbuf = NULL;
1579 status = smb1cli_session_setup_nt1_recv(subreq, state,
1582 &state->out_native_os,
1583 &state->out_native_lm,
1584 &state->out_primary_domain);
1585 TALLOC_FREE(subreq);
1586 if (tevent_req_nterror(req, status)) {
1587 DEBUG(3, ("NT1 login failed: %s\n", nt_errstr(status)));
1591 status = cli_state_update_after_sesssetup(state->cli,
1592 state->out_native_os,
1593 state->out_native_lm,
1594 state->out_primary_domain);
1595 if (tevent_req_nterror(req, status)) {
1599 ok = smb1cli_conn_activate_signing(cli->conn,
1601 state->upassword_blob);
1603 ok = smb1cli_conn_check_signing(cli->conn, inbuf, 1);
1605 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1610 if (state->session_key.data) {
1611 struct smbXcli_session *session = cli->smb1.session;
1613 status = smb1cli_session_set_session_key(session,
1614 state->session_key);
1615 if (tevent_req_nterror(req, status)) {
1620 tevent_req_done(req);
1623 static void cli_session_setup_creds_done_lm21(struct tevent_req *subreq)
1625 struct tevent_req *req = tevent_req_callback_data(
1626 subreq, struct tevent_req);
1627 struct cli_session_setup_creds_state *state = tevent_req_data(
1628 req, struct cli_session_setup_creds_state);
1631 status = smb1cli_session_setup_lm21_recv(subreq, state,
1632 &state->out_native_os,
1633 &state->out_native_lm);
1634 TALLOC_FREE(subreq);
1635 if (tevent_req_nterror(req, status)) {
1636 DEBUG(3, ("LM21 login failed: %s\n", nt_errstr(status)));
1640 status = cli_state_update_after_sesssetup(state->cli,
1641 state->out_native_os,
1642 state->out_native_lm,
1644 if (tevent_req_nterror(req, status)) {
1648 tevent_req_done(req);
1651 NTSTATUS cli_session_setup_creds_recv(struct tevent_req *req)
1653 return tevent_req_simple_recv_ntstatus(req);
1656 NTSTATUS cli_session_setup_creds(struct cli_state *cli,
1657 struct cli_credentials *creds)
1659 struct tevent_context *ev;
1660 struct tevent_req *req;
1661 NTSTATUS status = NT_STATUS_NO_MEMORY;
1663 if (smbXcli_conn_has_async_calls(cli->conn)) {
1664 return NT_STATUS_INVALID_PARAMETER;
1666 ev = samba_tevent_context_init(talloc_tos());
1670 req = cli_session_setup_creds_send(ev, ev, cli, creds);
1674 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1677 status = cli_session_setup_creds_recv(req);
1683 NTSTATUS cli_session_setup_anon(struct cli_state *cli)
1686 struct cli_credentials *creds = NULL;
1688 creds = cli_credentials_init_anon(cli);
1689 if (creds == NULL) {
1690 return NT_STATUS_NO_MEMORY;
1693 status = cli_session_setup_creds(cli, creds);
1695 if (!NT_STATUS_IS_OK(status)) {
1699 return NT_STATUS_OK;
1702 /****************************************************************************
1704 *****************************************************************************/
1706 struct cli_ulogoff_state {
1707 struct cli_state *cli;
1711 static void cli_ulogoff_done(struct tevent_req *subreq);
1713 static struct tevent_req *cli_ulogoff_send(TALLOC_CTX *mem_ctx,
1714 struct tevent_context *ev,
1715 struct cli_state *cli)
1717 struct tevent_req *req, *subreq;
1718 struct cli_ulogoff_state *state;
1720 req = tevent_req_create(mem_ctx, &state, struct cli_ulogoff_state);
1726 SCVAL(state->vwv+0, 0, 0xFF);
1727 SCVAL(state->vwv+1, 0, 0);
1728 SSVAL(state->vwv+2, 0, 0);
1730 subreq = cli_smb_send(state, ev, cli, SMBulogoffX, 0, 0, 2, state->vwv,
1732 if (tevent_req_nomem(subreq, req)) {
1733 return tevent_req_post(req, ev);
1735 tevent_req_set_callback(subreq, cli_ulogoff_done, req);
1739 static void cli_ulogoff_done(struct tevent_req *subreq)
1741 struct tevent_req *req = tevent_req_callback_data(
1742 subreq, struct tevent_req);
1743 struct cli_ulogoff_state *state = tevent_req_data(
1744 req, struct cli_ulogoff_state);
1747 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
1748 if (tevent_req_nterror(req, status)) {
1751 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
1752 tevent_req_done(req);
1755 static NTSTATUS cli_ulogoff_recv(struct tevent_req *req)
1757 return tevent_req_simple_recv_ntstatus(req);
1760 NTSTATUS cli_ulogoff(struct cli_state *cli)
1762 struct tevent_context *ev;
1763 struct tevent_req *req;
1764 NTSTATUS status = NT_STATUS_NO_MEMORY;
1766 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
1767 status = smb2cli_logoff(cli->conn,
1770 if (!NT_STATUS_IS_OK(status)) {
1773 smb2cli_session_set_id_and_flags(cli->smb2.session,
1775 return NT_STATUS_OK;
1778 if (smbXcli_conn_has_async_calls(cli->conn)) {
1779 return NT_STATUS_INVALID_PARAMETER;
1781 ev = samba_tevent_context_init(talloc_tos());
1785 req = cli_ulogoff_send(ev, ev, cli);
1789 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1792 status = cli_ulogoff_recv(req);
1798 /****************************************************************************
1800 ****************************************************************************/
1802 struct cli_tcon_andx_state {
1803 struct cli_state *cli;
1808 static void cli_tcon_andx_done(struct tevent_req *subreq);
1810 struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx,
1811 struct tevent_context *ev,
1812 struct cli_state *cli,
1813 const char *share, const char *dev,
1814 const char *pass, int passlen,
1815 struct tevent_req **psmbreq)
1817 struct tevent_req *req, *subreq;
1818 struct cli_tcon_andx_state *state;
1823 uint16_t sec_mode = smb1cli_conn_server_security_mode(cli->conn);
1824 uint16_t tcon_flags = 0;
1828 req = tevent_req_create(mem_ctx, &state, struct cli_tcon_andx_state);
1835 TALLOC_FREE(cli->smb1.tcon);
1836 cli->smb1.tcon = smbXcli_tcon_create(cli);
1837 if (tevent_req_nomem(cli->smb1.tcon, req)) {
1838 return tevent_req_post(req, ev);
1840 smb1cli_tcon_set_id(cli->smb1.tcon, UINT16_MAX);
1842 cli->share = talloc_strdup(cli, share);
1847 /* in user level security don't send a password now */
1848 if (sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {
1851 } else if (pass == NULL) {
1852 DEBUG(1, ("Server not using user level security and no "
1853 "password supplied.\n"));
1857 if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) &&
1858 *pass && passlen != 24) {
1859 if (!lp_client_lanman_auth()) {
1860 DEBUG(1, ("Server requested LANMAN password "
1861 "(share-level security) but "
1862 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
1867 * Non-encrypted passwords - convert to DOS codepage before
1870 SMBencrypt(pass, smb1cli_conn_server_challenge(cli->conn), p24);
1872 pass = (const char *)p24;
1874 if((sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL
1875 |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE))
1879 if (!lp_client_plaintext_auth() && (*pass)) {
1880 DEBUG(1, ("Server requested PLAINTEXT "
1882 "'client plaintext auth = no' or 'client ntlmv2 auth = yes'\n"));
1887 * Non-encrypted passwords - convert to DOS codepage
1890 tmp_pass = talloc_array(talloc_tos(), uint8_t, 0);
1891 if (tevent_req_nomem(tmp_pass, req)) {
1892 return tevent_req_post(req, ev);
1894 tmp_pass = trans2_bytes_push_str(tmp_pass,
1895 false, /* always DOS */
1899 if (tevent_req_nomem(tmp_pass, req)) {
1900 return tevent_req_post(req, ev);
1902 pass = (const char *)tmp_pass;
1903 passlen = talloc_get_size(tmp_pass);
1907 tcon_flags |= TCONX_FLAG_EXTENDED_RESPONSE;
1908 tcon_flags |= TCONX_FLAG_EXTENDED_SIGNATURES;
1910 SCVAL(vwv+0, 0, 0xFF);
1913 SSVAL(vwv+2, 0, tcon_flags);
1914 SSVAL(vwv+3, 0, passlen);
1916 if (passlen && pass) {
1917 bytes = (uint8_t *)talloc_memdup(state, pass, passlen);
1919 bytes = talloc_array(state, uint8_t, 0);
1925 tmp = talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
1926 smbXcli_conn_remote_name(cli->conn), share);
1931 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), tmp, strlen(tmp)+1,
1936 * Add the devicetype
1938 tmp = talloc_strdup_upper(talloc_tos(), dev);
1943 bytes = smb_bytes_push_str(bytes, false, tmp, strlen(tmp)+1, NULL);
1946 if (bytes == NULL) {
1951 state->bytes.iov_base = (void *)bytes;
1952 state->bytes.iov_len = talloc_get_size(bytes);
1954 subreq = cli_smb_req_create(state, ev, cli, SMBtconX, 0, 0, 4, vwv,
1956 if (subreq == NULL) {
1960 tevent_req_set_callback(subreq, cli_tcon_andx_done, req);
1965 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1966 return tevent_req_post(req, ev);
1969 struct tevent_req *cli_tcon_andx_send(TALLOC_CTX *mem_ctx,
1970 struct tevent_context *ev,
1971 struct cli_state *cli,
1972 const char *share, const char *dev,
1973 const char *pass, int passlen)
1975 struct tevent_req *req, *subreq;
1978 req = cli_tcon_andx_create(mem_ctx, ev, cli, share, dev, pass, passlen,
1983 if (subreq == NULL) {
1986 status = smb1cli_req_chain_submit(&subreq, 1);
1987 if (tevent_req_nterror(req, status)) {
1988 return tevent_req_post(req, ev);
1993 static void cli_tcon_andx_done(struct tevent_req *subreq)
1995 struct tevent_req *req = tevent_req_callback_data(
1996 subreq, struct tevent_req);
1997 struct cli_tcon_andx_state *state = tevent_req_data(
1998 req, struct cli_tcon_andx_state);
1999 struct cli_state *cli = state->cli;
2007 uint16_t optional_support = 0;
2009 status = cli_smb_recv(subreq, state, &in, 0, &wct, &vwv,
2010 &num_bytes, &bytes);
2011 TALLOC_FREE(subreq);
2012 if (tevent_req_nterror(req, status)) {
2016 inhdr = in + NBT_HDR_SIZE;
2019 if (pull_string_talloc(cli,
2020 (const char *)inhdr,
2021 SVAL(inhdr, HDR_FLG2),
2025 STR_TERMINATE|STR_ASCII) == -1) {
2026 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2030 cli->dev = talloc_strdup(cli, "");
2031 if (tevent_req_nomem(cli->dev, req)) {
2036 if ((smbXcli_conn_protocol(cli->conn) >= PROTOCOL_NT1) && (num_bytes == 3)) {
2037 /* almost certainly win95 - enable bug fixes */
2042 * Make sure that we have the optional support 16-bit field. WCT > 2.
2043 * Avoids issues when connecting to Win9x boxes sharing files
2046 if ((wct > 2) && (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_LANMAN2)) {
2047 optional_support = SVAL(vwv+2, 0);
2050 if (optional_support & SMB_EXTENDED_SIGNATURES) {
2051 smb1cli_session_protect_session_key(cli->smb1.session);
2054 smb1cli_tcon_set_values(cli->smb1.tcon,
2055 SVAL(inhdr, HDR_TID),
2057 0, /* maximal_access */
2058 0, /* guest_maximal_access */
2060 NULL); /* fs_type */
2062 tevent_req_done(req);
2065 NTSTATUS cli_tcon_andx_recv(struct tevent_req *req)
2067 return tevent_req_simple_recv_ntstatus(req);
2070 NTSTATUS cli_tcon_andx(struct cli_state *cli, const char *share,
2071 const char *dev, const char *pass, int passlen)
2073 TALLOC_CTX *frame = talloc_stackframe();
2074 struct tevent_context *ev;
2075 struct tevent_req *req;
2076 NTSTATUS status = NT_STATUS_NO_MEMORY;
2078 if (smbXcli_conn_has_async_calls(cli->conn)) {
2080 * Can't use sync call while an async call is in flight
2082 status = NT_STATUS_INVALID_PARAMETER;
2086 ev = samba_tevent_context_init(frame);
2091 req = cli_tcon_andx_send(frame, ev, cli, share, dev, pass, passlen);
2096 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2100 status = cli_tcon_andx_recv(req);
2106 struct cli_tree_connect_state {
2107 struct cli_state *cli;
2110 static struct tevent_req *cli_raw_tcon_send(
2111 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
2112 const char *service, const char *pass, const char *dev);
2113 static NTSTATUS cli_raw_tcon_recv(struct tevent_req *req,
2114 uint16_t *max_xmit, uint16_t *tid);
2116 static void cli_tree_connect_smb2_done(struct tevent_req *subreq);
2117 static void cli_tree_connect_andx_done(struct tevent_req *subreq);
2118 static void cli_tree_connect_raw_done(struct tevent_req *subreq);
2120 static struct tevent_req *cli_tree_connect_send(
2121 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
2122 const char *share, const char *dev, const char *pass)
2124 struct tevent_req *req, *subreq;
2125 struct cli_tree_connect_state *state;
2131 passlen = strlen(pass) + 1;
2133 req = tevent_req_create(mem_ctx, &state,
2134 struct cli_tree_connect_state);
2140 cli->share = talloc_strdup(cli, share);
2141 if (tevent_req_nomem(cli->share, req)) {
2142 return tevent_req_post(req, ev);
2145 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
2148 TALLOC_FREE(cli->smb2.tcon);
2149 cli->smb2.tcon = smbXcli_tcon_create(cli);
2150 if (tevent_req_nomem(cli->smb2.tcon, req)) {
2151 return tevent_req_post(req, ev);
2154 unc = talloc_asprintf(state, "\\\\%s\\%s",
2155 smbXcli_conn_remote_name(cli->conn),
2157 if (tevent_req_nomem(unc, req)) {
2158 return tevent_req_post(req, ev);
2161 subreq = smb2cli_tcon_send(state, ev, cli->conn, cli->timeout,
2162 cli->smb2.session, cli->smb2.tcon,
2165 if (tevent_req_nomem(subreq, req)) {
2166 return tevent_req_post(req, ev);
2168 tevent_req_set_callback(subreq, cli_tree_connect_smb2_done,
2173 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_LANMAN1) {
2174 subreq = cli_tcon_andx_send(state, ev, cli, share, dev,
2176 if (tevent_req_nomem(subreq, req)) {
2177 return tevent_req_post(req, ev);
2179 tevent_req_set_callback(subreq, cli_tree_connect_andx_done,
2184 subreq = cli_raw_tcon_send(state, ev, cli, share, pass, dev);
2185 if (tevent_req_nomem(subreq, req)) {
2186 return tevent_req_post(req, ev);
2188 tevent_req_set_callback(subreq, cli_tree_connect_raw_done, req);
2193 static void cli_tree_connect_smb2_done(struct tevent_req *subreq)
2195 NTSTATUS status = smb2cli_tcon_recv(subreq);
2196 tevent_req_simple_finish_ntstatus(subreq, status);
2199 static void cli_tree_connect_andx_done(struct tevent_req *subreq)
2201 NTSTATUS status = cli_tcon_andx_recv(subreq);
2202 tevent_req_simple_finish_ntstatus(subreq, status);
2205 static void cli_tree_connect_raw_done(struct tevent_req *subreq)
2207 struct tevent_req *req = tevent_req_callback_data(
2208 subreq, struct tevent_req);
2209 struct cli_tree_connect_state *state = tevent_req_data(
2210 req, struct cli_tree_connect_state);
2212 uint16_t max_xmit = 0;
2215 status = cli_raw_tcon_recv(subreq, &max_xmit, &tid);
2216 if (tevent_req_nterror(req, status)) {
2220 smb1cli_tcon_set_values(state->cli->smb1.tcon,
2222 0, /* optional_support */
2223 0, /* maximal_access */
2224 0, /* guest_maximal_access */
2226 NULL); /* fs_type */
2228 tevent_req_done(req);
2231 static NTSTATUS cli_tree_connect_recv(struct tevent_req *req)
2233 return tevent_req_simple_recv_ntstatus(req);
2236 NTSTATUS cli_tree_connect(struct cli_state *cli, const char *share,
2237 const char *dev, const char *pass)
2239 struct tevent_context *ev;
2240 struct tevent_req *req;
2241 NTSTATUS status = NT_STATUS_NO_MEMORY;
2243 if (smbXcli_conn_has_async_calls(cli->conn)) {
2244 return NT_STATUS_INVALID_PARAMETER;
2246 ev = samba_tevent_context_init(talloc_tos());
2250 req = cli_tree_connect_send(ev, ev, cli, share, dev, pass);
2254 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2257 status = cli_tree_connect_recv(req);
2263 NTSTATUS cli_tree_connect_creds(struct cli_state *cli,
2264 const char *share, const char *dev,
2265 struct cli_credentials *creds)
2267 bool need_pass = false;
2268 const char *pw = NULL;
2271 * We should work out if the protocol
2272 * will make use of a password for share level
2273 * authentication before we may cause
2274 * the password prompt to be called.
2276 if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_SMB2_02) {
2277 uint16_t sec_mode = smb1cli_conn_server_security_mode(cli->conn);
2279 /* in user level security don't send a password now */
2280 if (!(sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) {
2285 if (need_pass && creds != NULL) {
2286 pw = cli_credentials_get_password(creds);
2289 return cli_tree_connect(cli, share, dev, pw);
2292 /****************************************************************************
2293 Send a tree disconnect.
2294 ****************************************************************************/
2296 struct cli_tdis_state {
2297 struct cli_state *cli;
2300 static void cli_tdis_done(struct tevent_req *subreq);
2302 static struct tevent_req *cli_tdis_send(TALLOC_CTX *mem_ctx,
2303 struct tevent_context *ev,
2304 struct cli_state *cli)
2306 struct tevent_req *req, *subreq;
2307 struct cli_tdis_state *state;
2309 req = tevent_req_create(mem_ctx, &state, struct cli_tdis_state);
2315 subreq = cli_smb_send(state, ev, cli, SMBtdis, 0, 0, 0, NULL, 0, NULL);
2316 if (tevent_req_nomem(subreq, req)) {
2317 return tevent_req_post(req, ev);
2319 tevent_req_set_callback(subreq, cli_tdis_done, req);
2323 static void cli_tdis_done(struct tevent_req *subreq)
2325 struct tevent_req *req = tevent_req_callback_data(
2326 subreq, struct tevent_req);
2327 struct cli_tdis_state *state = tevent_req_data(
2328 req, struct cli_tdis_state);
2331 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
2332 TALLOC_FREE(subreq);
2333 if (tevent_req_nterror(req, status)) {
2336 TALLOC_FREE(state->cli->smb1.tcon);
2337 tevent_req_done(req);
2340 static NTSTATUS cli_tdis_recv(struct tevent_req *req)
2342 return tevent_req_simple_recv_ntstatus(req);
2345 NTSTATUS cli_tdis(struct cli_state *cli)
2347 struct tevent_context *ev;
2348 struct tevent_req *req;
2349 NTSTATUS status = NT_STATUS_NO_MEMORY;
2351 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
2352 status = smb2cli_tdis(cli->conn,
2356 if (NT_STATUS_IS_OK(status)) {
2357 TALLOC_FREE(cli->smb2.tcon);
2362 if (smbXcli_conn_has_async_calls(cli->conn)) {
2363 return NT_STATUS_INVALID_PARAMETER;
2365 ev = samba_tevent_context_init(talloc_tos());
2369 req = cli_tdis_send(ev, ev, cli);
2373 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2376 status = cli_tdis_recv(req);
2382 struct cli_connect_sock_state {
2383 struct smb_transports transports;
2384 const char **called_names;
2385 const char **calling_names;
2387 struct smbXcli_transport *transport;
2390 static void cli_connect_sock_done(struct tevent_req *subreq);
2393 * Async only if we don't have to look up the name, i.e. "pss" is set with a
2397 static struct tevent_req *cli_connect_sock_send(
2398 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2399 const char *host, int name_type, const struct sockaddr_storage *pss,
2401 const struct smb_transports *transports)
2403 struct tevent_req *req, *subreq;
2404 struct cli_connect_sock_state *state;
2405 struct loadparm_context *lp_ctx = NULL;
2406 struct sockaddr_storage *addrs = NULL;
2408 unsigned num_addrs = 0;
2411 req = tevent_req_create(mem_ctx, &state,
2412 struct cli_connect_sock_state);
2416 state->transports = *transports;
2418 lp_ctx = loadparm_init_s3(talloc_tos(), loadparm_s3_helpers());
2419 if (tevent_req_nomem(lp_ctx, req)) {
2420 return tevent_req_post(req, ev);
2423 if ((pss == NULL) || is_zero_addr(pss)) {
2426 * Here we cheat. resolve_name_list is not async at all. So
2427 * this call will only be really async if the name lookup has
2428 * been done externally.
2431 status = resolve_name_list(state, host, name_type,
2432 &addrs, &num_addrs);
2433 if (tevent_req_nterror(req, status)) {
2434 return tevent_req_post(req, ev);
2437 addrs = talloc_array(state, struct sockaddr_storage, 1);
2438 if (tevent_req_nomem(addrs, req)) {
2439 return tevent_req_post(req, ev);
2445 state->called_names = talloc_array(state, const char *, num_addrs);
2446 if (tevent_req_nomem(state->called_names, req)) {
2447 return tevent_req_post(req, ev);
2449 state->called_types = talloc_array(state, int, num_addrs);
2450 if (tevent_req_nomem(state->called_types, req)) {
2451 return tevent_req_post(req, ev);
2453 state->calling_names = talloc_array(state, const char *, num_addrs);
2454 if (tevent_req_nomem(state->calling_names, req)) {
2455 return tevent_req_post(req, ev);
2457 for (i=0; i<num_addrs; i++) {
2458 state->called_names[i] = host;
2459 state->called_types[i] = name_type;
2460 state->calling_names[i] = myname;
2463 subreq = smbsock_any_connect_send(
2464 state, ev, lp_ctx, addrs,
2465 state->called_names, state->called_types,
2466 state->calling_names, NULL, num_addrs, &state->transports);
2467 if (tevent_req_nomem(subreq, req)) {
2468 return tevent_req_post(req, ev);
2470 tevent_req_set_callback(subreq, cli_connect_sock_done, req);
2474 static void cli_connect_sock_done(struct tevent_req *subreq)
2476 struct tevent_req *req = tevent_req_callback_data(
2477 subreq, struct tevent_req);
2478 struct cli_connect_sock_state *state = tevent_req_data(
2479 req, struct cli_connect_sock_state);
2482 status = smbsock_any_connect_recv(subreq, state, &state->transport, NULL);
2483 TALLOC_FREE(subreq);
2484 if (tevent_req_nterror(req, status)) {
2488 tevent_req_done(req);
2491 static NTSTATUS cli_connect_sock_recv(struct tevent_req *req,
2492 TALLOC_CTX *mem_ctx,
2493 struct smbXcli_transport **ptransport)
2495 struct cli_connect_sock_state *state = tevent_req_data(
2496 req, struct cli_connect_sock_state);
2499 if (tevent_req_is_nterror(req, &status)) {
2502 *ptransport = talloc_move(mem_ctx, &state->transport);
2503 return NT_STATUS_OK;
2506 struct cli_connect_nb_state {
2507 const char *desthost;
2508 struct smb_transports transports;
2509 enum smb_signing_setting signing_state;
2511 struct cli_state *cli;
2514 static void cli_connect_nb_done(struct tevent_req *subreq);
2516 static struct tevent_req *cli_connect_nb_send(
2517 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2518 const char *host, const struct sockaddr_storage *dest_ss,
2519 const struct smb_transports *transports,
2520 int name_type, const char *myname,
2521 enum smb_signing_setting signing_state, int flags)
2523 struct tevent_req *req, *subreq;
2524 struct cli_connect_nb_state *state;
2526 req = tevent_req_create(mem_ctx, &state, struct cli_connect_nb_state);
2530 state->signing_state = signing_state;
2531 state->flags = flags;
2532 state->transports = *transports;
2535 char *p = strchr(host, '#');
2538 name_type = strtol(p+1, NULL, 16);
2539 host = talloc_strndup(state, host, p - host);
2540 if (tevent_req_nomem(host, req)) {
2541 return tevent_req_post(req, ev);
2545 state->desthost = host;
2546 } else if (dest_ss != NULL) {
2547 state->desthost = print_canonical_sockaddr(state, dest_ss);
2548 if (tevent_req_nomem(state->desthost, req)) {
2549 return tevent_req_post(req, ev);
2552 /* No host or dest_ss given. Error out. */
2553 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
2554 return tevent_req_post(req, ev);
2557 subreq = cli_connect_sock_send(state, ev, host, name_type, dest_ss,
2558 myname, &state->transports);
2559 if (tevent_req_nomem(subreq, req)) {
2560 return tevent_req_post(req, ev);
2562 tevent_req_set_callback(subreq, cli_connect_nb_done, req);
2566 static void cli_connect_nb_done(struct tevent_req *subreq)
2568 struct tevent_req *req = tevent_req_callback_data(
2569 subreq, struct tevent_req);
2570 struct cli_connect_nb_state *state = tevent_req_data(
2571 req, struct cli_connect_nb_state);
2572 struct smbXcli_transport *xtp = NULL;
2575 status = cli_connect_sock_recv(subreq, state, &xtp);
2576 TALLOC_FREE(subreq);
2577 if (tevent_req_nterror(req, status)) {
2581 state->cli = cli_state_create(state, &xtp, state->desthost,
2582 state->signing_state, state->flags);
2583 if (tevent_req_nomem(state->cli, req)) {
2586 tevent_req_done(req);
2589 static NTSTATUS cli_connect_nb_recv(struct tevent_req *req,
2590 TALLOC_CTX *mem_ctx,
2591 struct cli_state **pcli)
2593 struct cli_connect_nb_state *state = tevent_req_data(
2594 req, struct cli_connect_nb_state);
2597 if (tevent_req_is_nterror(req, &status)) {
2600 *pcli = talloc_move(mem_ctx, &state->cli);
2601 return NT_STATUS_OK;
2604 NTSTATUS cli_connect_nb(TALLOC_CTX *mem_ctx,
2606 const struct sockaddr_storage *dest_ss,
2607 const struct smb_transports *transports,
2610 enum smb_signing_setting signing_state,
2612 struct cli_state **pcli)
2614 struct tevent_context *ev;
2615 struct tevent_req *req;
2616 NTSTATUS status = NT_STATUS_NO_MEMORY;
2618 ev = samba_tevent_context_init(mem_ctx);
2622 req = cli_connect_nb_send(ev, ev, host, dest_ss, transports, name_type,
2623 myname, signing_state, flags);
2627 if (!tevent_req_set_endtime(req, ev, timeval_current_ofs(20, 0))) {
2630 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2633 status = cli_connect_nb_recv(req, mem_ctx, pcli);
2639 struct cli_start_connection_state {
2640 struct tevent_context *ev;
2641 struct smb_transports transports;
2642 struct cli_state *cli;
2645 struct smb2_negotiate_contexts *negotiate_contexts;
2648 static void cli_start_connection_connected(struct tevent_req *subreq);
2649 static void cli_start_connection_done(struct tevent_req *subreq);
2652 establishes a connection to after the negprot.
2653 @param output_cli A fully initialised cli structure, non-null only on success
2654 @param dest_host The netbios name of the remote host
2655 @param dest_ss (optional) The destination IP, NULL for name based lookup
2656 @param port (optional) The destination port (0 for default)
2659 static struct tevent_req *cli_start_connection_send(
2660 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2661 const char *my_name, const char *dest_host,
2662 const struct sockaddr_storage *dest_ss,
2663 const struct smb_transports *transports,
2664 enum smb_signing_setting signing_state, int flags,
2665 struct smb2_negotiate_contexts *negotiate_contexts)
2667 struct tevent_req *req, *subreq;
2668 struct cli_start_connection_state *state;
2670 req = tevent_req_create(mem_ctx, &state,
2671 struct cli_start_connection_state);
2676 state->transports = *transports;
2678 if (flags & CLI_FULL_CONNECTION_IPC) {
2679 state->min_protocol = lp_client_ipc_min_protocol();
2680 state->max_protocol = lp_client_ipc_max_protocol();
2682 state->min_protocol = lp_client_min_protocol();
2683 state->max_protocol = lp_client_max_protocol();
2686 if (flags & CLI_FULL_CONNECTION_FORCE_SMB1) {
2687 state->max_protocol = MIN(state->max_protocol,
2689 state->min_protocol = MIN(state->min_protocol,
2690 state->max_protocol);
2693 if (flags & CLI_FULL_CONNECTION_DISABLE_SMB1) {
2694 state->min_protocol = MAX(state->min_protocol,
2696 state->max_protocol = MAX(state->max_protocol,
2697 state->min_protocol);
2700 state->negotiate_contexts = talloc_zero(
2701 state, struct smb2_negotiate_contexts);
2702 if (tevent_req_nomem(state->negotiate_contexts, req)) {
2703 return tevent_req_post(req, ev);
2706 if (flags & CLI_FULL_CONNECTION_REQUEST_POSIX) {
2709 status = smb2_negotiate_context_add(
2710 state->negotiate_contexts,
2711 state->negotiate_contexts,
2712 SMB2_POSIX_EXTENSIONS_AVAILABLE,
2713 (const uint8_t *)SMB2_CREATE_TAG_POSIX,
2714 strlen(SMB2_CREATE_TAG_POSIX));
2715 if (tevent_req_nterror(req, status)) {
2716 return tevent_req_post(req, ev);
2720 if (negotiate_contexts != NULL) {
2723 for (i=0; i<negotiate_contexts->num_contexts; i++) {
2724 struct smb2_negotiate_context *ctx =
2725 &negotiate_contexts->contexts[i];
2728 status = smb2_negotiate_context_add(
2729 state->negotiate_contexts,
2730 state->negotiate_contexts,
2734 if (tevent_req_nterror(req, status)) {
2735 return tevent_req_post(req, ev);
2740 subreq = cli_connect_nb_send(state, ev, dest_host, dest_ss,
2742 0x20, my_name, signing_state, flags);
2743 if (tevent_req_nomem(subreq, req)) {
2744 return tevent_req_post(req, ev);
2746 tevent_req_set_callback(subreq, cli_start_connection_connected, req);
2750 static void cli_start_connection_connected(struct tevent_req *subreq)
2752 struct tevent_req *req = tevent_req_callback_data(
2753 subreq, struct tevent_req);
2754 struct cli_start_connection_state *state = tevent_req_data(
2755 req, struct cli_start_connection_state);
2758 status = cli_connect_nb_recv(subreq, state, &state->cli);
2759 TALLOC_FREE(subreq);
2760 if (tevent_req_nterror(req, status)) {
2764 subreq = smbXcli_negprot_send(
2768 state->cli->timeout,
2769 state->min_protocol,
2770 state->max_protocol,
2771 WINDOWS_CLIENT_PURE_SMB2_NEGPROT_INITIAL_CREDIT_ASK,
2772 state->negotiate_contexts);
2773 if (tevent_req_nomem(subreq, req)) {
2776 tevent_req_set_callback(subreq, cli_start_connection_done, req);
2779 static void cli_start_connection_done(struct tevent_req *subreq)
2781 struct tevent_req *req = tevent_req_callback_data(
2782 subreq, struct tevent_req);
2783 struct cli_start_connection_state *state = tevent_req_data(
2784 req, struct cli_start_connection_state);
2787 status = smbXcli_negprot_recv(subreq, NULL, NULL);
2788 TALLOC_FREE(subreq);
2789 if (tevent_req_nterror(req, status)) {
2793 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
2794 /* Ensure we ask for some initial credits. */
2795 smb2cli_conn_set_max_credits(state->cli->conn,
2796 DEFAULT_SMB2_MAX_CREDITS);
2799 tevent_req_done(req);
2802 static NTSTATUS cli_start_connection_recv(struct tevent_req *req,
2803 TALLOC_CTX *mem_ctx,
2804 struct cli_state **output_cli)
2806 struct cli_start_connection_state *state = tevent_req_data(
2807 req, struct cli_start_connection_state);
2810 if (tevent_req_is_nterror(req, &status)) {
2813 *output_cli = talloc_move(mem_ctx, &state->cli);
2815 return NT_STATUS_OK;
2818 NTSTATUS cli_start_connection(TALLOC_CTX *mem_ctx,
2819 struct cli_state **output_cli,
2820 const char *my_name,
2821 const char *dest_host,
2822 const struct sockaddr_storage *dest_ss,
2823 const struct smb_transports *transports,
2824 enum smb_signing_setting signing_state, int flags)
2826 struct tevent_context *ev;
2827 struct tevent_req *req;
2828 NTSTATUS status = NT_STATUS_NO_MEMORY;
2830 ev = samba_tevent_context_init(mem_ctx);
2834 req = cli_start_connection_send(ev, ev, my_name, dest_host, dest_ss,
2835 transports, signing_state, flags, NULL);
2839 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2842 status = cli_start_connection_recv(req, mem_ctx, output_cli);
2848 struct cli_smb1_setup_encryption_blob_state {
2853 uint16_t enc_ctx_id;
2856 static void cli_smb1_setup_encryption_blob_done(struct tevent_req *subreq);
2858 static struct tevent_req *cli_smb1_setup_encryption_blob_send(TALLOC_CTX *mem_ctx,
2859 struct tevent_context *ev,
2860 struct cli_state *cli,
2863 struct tevent_req *req = NULL;
2864 struct cli_smb1_setup_encryption_blob_state *state = NULL;
2865 struct tevent_req *subreq = NULL;
2867 req = tevent_req_create(mem_ctx, &state,
2868 struct cli_smb1_setup_encryption_blob_state);
2873 if (in.length > CLI_BUFFER_SIZE) {
2874 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
2875 return tevent_req_post(req, ev);
2878 SSVAL(state->setup+0, 0, TRANSACT2_SETFSINFO);
2879 SSVAL(state->param, 0, 0);
2880 SSVAL(state->param, 2, SMB_REQUEST_TRANSPORT_ENCRYPTION);
2882 subreq = smb1cli_trans_send(state, ev, cli->conn,
2890 NULL, /* pipe_name */
2896 in.data, in.length, CLI_BUFFER_SIZE);
2897 if (tevent_req_nomem(subreq, req)) {
2898 return tevent_req_post(req, ev);
2900 tevent_req_set_callback(subreq,
2901 cli_smb1_setup_encryption_blob_done,
2907 static void cli_smb1_setup_encryption_blob_done(struct tevent_req *subreq)
2909 struct tevent_req *req =
2910 tevent_req_callback_data(subreq,
2912 struct cli_smb1_setup_encryption_blob_state *state =
2913 tevent_req_data(req,
2914 struct cli_smb1_setup_encryption_blob_state);
2915 uint8_t *rparam=NULL, *rdata=NULL;
2916 uint32_t num_rparam, num_rdata;
2919 status = smb1cli_trans_recv(subreq, state,
2920 NULL, /* recv_flags */
2921 NULL, 0, NULL, /* rsetup */
2922 &rparam, 0, &num_rparam,
2923 &rdata, 0, &num_rdata);
2924 TALLOC_FREE(subreq);
2925 state->status = status;
2926 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
2927 status = NT_STATUS_OK;
2929 if (tevent_req_nterror(req, status)) {
2933 if (num_rparam == 2) {
2934 state->enc_ctx_id = SVAL(rparam, 0);
2936 TALLOC_FREE(rparam);
2938 state->out = data_blob_const(rdata, num_rdata);
2940 tevent_req_done(req);
2943 static NTSTATUS cli_smb1_setup_encryption_blob_recv(struct tevent_req *req,
2944 TALLOC_CTX *mem_ctx,
2946 uint16_t *enc_ctx_id)
2948 struct cli_smb1_setup_encryption_blob_state *state =
2949 tevent_req_data(req,
2950 struct cli_smb1_setup_encryption_blob_state);
2953 if (tevent_req_is_nterror(req, &status)) {
2954 tevent_req_received(req);
2958 status = state->status;
2961 talloc_steal(mem_ctx, out->data);
2963 *enc_ctx_id = state->enc_ctx_id;
2965 tevent_req_received(req);
2969 struct cli_smb1_setup_encryption_state {
2970 struct tevent_context *ev;
2971 struct cli_state *cli;
2972 struct smb_trans_enc_state *es;
2979 static void cli_smb1_setup_encryption_local_next(struct tevent_req *req);
2980 static void cli_smb1_setup_encryption_local_done(struct tevent_req *subreq);
2981 static void cli_smb1_setup_encryption_remote_next(struct tevent_req *req);
2982 static void cli_smb1_setup_encryption_remote_done(struct tevent_req *subreq);
2983 static void cli_smb1_setup_encryption_ready(struct tevent_req *req);
2985 static struct tevent_req *cli_smb1_setup_encryption_send(TALLOC_CTX *mem_ctx,
2986 struct tevent_context *ev,
2987 struct cli_state *cli,
2988 struct cli_credentials *creds)
2990 struct tevent_req *req = NULL;
2991 struct cli_smb1_setup_encryption_state *state = NULL;
2992 struct auth_generic_state *ags = NULL;
2993 const DATA_BLOB *b = NULL;
2994 bool auth_requested = false;
2995 const char *target_service = NULL;
2996 const char *target_hostname = NULL;
2999 req = tevent_req_create(mem_ctx, &state,
3000 struct cli_smb1_setup_encryption_state);
3007 auth_requested = cli_credentials_authentication_requested(creds);
3008 if (!auth_requested) {
3009 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
3010 return tevent_req_post(req, ev);
3013 target_service = "cifs";
3014 target_hostname = smbXcli_conn_remote_name(cli->conn);
3016 state->es = talloc_zero(state, struct smb_trans_enc_state);
3017 if (tevent_req_nomem(state->es, req)) {
3018 return tevent_req_post(req, ev);
3021 status = auth_generic_client_prepare(state->es, &ags);
3022 if (tevent_req_nterror(req, status)) {
3023 return tevent_req_post(req, ev);
3026 gensec_want_feature(ags->gensec_security,
3027 GENSEC_FEATURE_SIGN);
3028 gensec_want_feature(ags->gensec_security,
3029 GENSEC_FEATURE_SEAL);
3031 status = auth_generic_set_creds(ags, creds);
3032 if (tevent_req_nterror(req, status)) {
3033 return tevent_req_post(req, ev);
3036 if (target_service != NULL) {
3037 status = gensec_set_target_service(ags->gensec_security,
3039 if (tevent_req_nterror(req, status)) {
3040 return tevent_req_post(req, ev);
3044 if (target_hostname != NULL) {
3045 status = gensec_set_target_hostname(ags->gensec_security,
3047 if (tevent_req_nterror(req, status)) {
3048 return tevent_req_post(req, ev);
3052 gensec_set_max_update_size(ags->gensec_security,
3055 b = smbXcli_conn_server_gss_blob(state->cli->conn);
3057 state->blob_in = *b;
3060 status = auth_generic_client_start(ags, GENSEC_OID_SPNEGO);
3061 if (tevent_req_nterror(req, status)) {
3062 return tevent_req_post(req, ev);
3066 * We only need the gensec_security part from here.
3068 state->es->gensec_security = talloc_move(state->es,
3069 &ags->gensec_security);
3072 cli_smb1_setup_encryption_local_next(req);
3073 if (!tevent_req_is_in_progress(req)) {
3074 return tevent_req_post(req, ev);
3080 static void cli_smb1_setup_encryption_local_next(struct tevent_req *req)
3082 struct cli_smb1_setup_encryption_state *state =
3083 tevent_req_data(req,
3084 struct cli_smb1_setup_encryption_state);
3085 struct tevent_req *subreq = NULL;
3087 if (state->local_ready) {
3088 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3092 subreq = gensec_update_send(state, state->ev,
3093 state->es->gensec_security,
3095 if (tevent_req_nomem(subreq, req)) {
3098 tevent_req_set_callback(subreq, cli_smb1_setup_encryption_local_done, req);
3101 static void cli_smb1_setup_encryption_local_done(struct tevent_req *subreq)
3103 struct tevent_req *req =
3104 tevent_req_callback_data(subreq,
3106 struct cli_smb1_setup_encryption_state *state =
3107 tevent_req_data(req,
3108 struct cli_smb1_setup_encryption_state);
3111 status = gensec_update_recv(subreq, state, &state->blob_out);
3112 TALLOC_FREE(subreq);
3113 state->blob_in = data_blob_null;
3114 if (!NT_STATUS_IS_OK(status) &&
3115 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
3117 tevent_req_nterror(req, status);
3121 if (NT_STATUS_IS_OK(status)) {
3122 state->local_ready = true;
3126 * We always get NT_STATUS_OK from the server even if it is not ready.
3127 * So guess the server is ready when we are ready and already sent
3128 * our last blob to the server.
3130 if (state->local_ready && state->blob_out.length == 0) {
3131 state->remote_ready = true;
3134 if (state->local_ready && state->remote_ready) {
3135 cli_smb1_setup_encryption_ready(req);
3139 cli_smb1_setup_encryption_remote_next(req);
3142 static void cli_smb1_setup_encryption_remote_next(struct tevent_req *req)
3144 struct cli_smb1_setup_encryption_state *state =
3145 tevent_req_data(req,
3146 struct cli_smb1_setup_encryption_state);
3147 struct tevent_req *subreq = NULL;
3149 if (state->remote_ready) {
3150 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3154 subreq = cli_smb1_setup_encryption_blob_send(state, state->ev,
3155 state->cli, state->blob_out);
3156 if (tevent_req_nomem(subreq, req)) {
3159 tevent_req_set_callback(subreq,
3160 cli_smb1_setup_encryption_remote_done,
3164 static void cli_smb1_setup_encryption_remote_done(struct tevent_req *subreq)
3166 struct tevent_req *req =
3167 tevent_req_callback_data(subreq,
3169 struct cli_smb1_setup_encryption_state *state =
3170 tevent_req_data(req,
3171 struct cli_smb1_setup_encryption_state);
3174 status = cli_smb1_setup_encryption_blob_recv(subreq, state,
3176 &state->es->enc_ctx_num);
3177 TALLOC_FREE(subreq);
3178 data_blob_free(&state->blob_out);
3179 if (!NT_STATUS_IS_OK(status) &&
3180 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
3182 tevent_req_nterror(req, status);
3187 * We always get NT_STATUS_OK even if the server is not ready.
3188 * So guess the server is ready when we are ready and sent
3189 * our last blob to the server.
3191 if (state->local_ready) {
3192 state->remote_ready = true;
3195 if (state->local_ready && state->remote_ready) {
3196 cli_smb1_setup_encryption_ready(req);
3200 cli_smb1_setup_encryption_local_next(req);
3203 static void cli_smb1_setup_encryption_ready(struct tevent_req *req)
3205 struct cli_smb1_setup_encryption_state *state =
3206 tevent_req_data(req,
3207 struct cli_smb1_setup_encryption_state);
3208 struct smb_trans_enc_state *es = NULL;
3210 if (state->blob_in.length != 0) {
3211 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3215 if (state->blob_out.length != 0) {
3216 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
3220 es = talloc_move(state->cli->conn, &state->es);
3222 smb1cli_conn_set_encryption(state->cli->conn, es);
3225 tevent_req_done(req);
3228 static NTSTATUS cli_smb1_setup_encryption_recv(struct tevent_req *req)
3230 return tevent_req_simple_recv_ntstatus(req);
3233 NTSTATUS cli_smb1_setup_encryption(struct cli_state *cli,
3234 struct cli_credentials *creds)
3236 struct tevent_context *ev = NULL;
3237 struct tevent_req *req = NULL;
3238 NTSTATUS status = NT_STATUS_NO_MEMORY;
3240 ev = samba_tevent_context_init(talloc_tos());
3244 req = cli_smb1_setup_encryption_send(ev, ev, cli, creds);
3248 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
3251 status = cli_smb1_setup_encryption_recv(req);
3258 establishes a connection right up to doing tconX, password specified.
3259 @param output_cli A fully initialised cli structure, non-null only on success
3260 @param dest_host The netbios name of the remote host
3261 @param dest_ip (optional) The the destination IP, NULL for name based lookup
3262 @param port (optional) The destination port (0 for default)
3263 @param service (optional) The share to make the connection to. Should be 'unqualified' in any way.
3264 @param service_type The 'type' of service.
3265 @param creds The used user credentials
3268 struct cli_full_connection_creds_state {
3269 struct tevent_context *ev;
3270 const char *service;
3271 const char *service_type;
3272 struct cli_credentials *creds;
3273 struct smb_transports transports;
3275 struct cli_state *cli;
3278 static int cli_full_connection_creds_state_destructor(
3279 struct cli_full_connection_creds_state *s)
3281 if (s->cli != NULL) {
3282 cli_shutdown(s->cli);
3288 static void cli_full_connection_creds_conn_done(struct tevent_req *subreq);
3289 static void cli_full_connection_creds_sess_done(struct tevent_req *subreq);
3290 static void cli_full_connection_creds_enc_start(struct tevent_req *req);
3291 static void cli_full_connection_creds_enc_tcon(struct tevent_req *subreq);
3292 static void cli_full_connection_creds_enc_ver(struct tevent_req *subreq);
3293 static void cli_full_connection_creds_enc_done(struct tevent_req *subreq);
3294 static void cli_full_connection_creds_enc_tdis(struct tevent_req *req);
3295 static void cli_full_connection_creds_enc_finished(struct tevent_req *subreq);
3296 static void cli_full_connection_creds_tcon_start(struct tevent_req *req);
3297 static void cli_full_connection_creds_tcon_done(struct tevent_req *subreq);
3299 struct tevent_req *cli_full_connection_creds_send(
3300 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
3301 const char *my_name, const char *dest_host,
3302 const struct sockaddr_storage *dest_ss,
3303 const struct smb_transports *transports,
3304 const char *service, const char *service_type,
3305 struct cli_credentials *creds,
3307 struct smb2_negotiate_contexts *negotiate_contexts)
3309 struct tevent_req *req, *subreq;
3310 struct cli_full_connection_creds_state *state;
3311 enum smb_signing_setting signing_state;
3312 enum smb_encryption_setting encryption_state =
3313 cli_credentials_get_smb_encryption(creds);
3315 req = tevent_req_create(mem_ctx, &state,
3316 struct cli_full_connection_creds_state);
3320 talloc_set_destructor(state, cli_full_connection_creds_state_destructor);
3323 state->service = service;
3324 state->service_type = service_type;
3325 state->creds = creds;
3326 state->flags = flags;
3327 state->transports = *transports;
3329 if (flags & CLI_FULL_CONNECTION_IPC) {
3330 signing_state = cli_credentials_get_smb_ipc_signing(creds);
3332 signing_state = cli_credentials_get_smb_signing(creds);
3335 if (encryption_state == SMB_ENCRYPTION_REQUIRED) {
3336 if (flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK) {
3337 encryption_state = SMB_ENCRYPTION_DESIRED;
3341 if (encryption_state >= SMB_ENCRYPTION_DESIRED) {
3342 signing_state = SMB_SIGNING_REQUIRED;
3345 subreq = cli_start_connection_send(
3346 state, ev, my_name, dest_host, dest_ss,
3348 signing_state, flags,
3349 negotiate_contexts);
3350 if (tevent_req_nomem(subreq, req)) {
3351 return tevent_req_post(req, ev);
3353 tevent_req_set_callback(subreq,
3354 cli_full_connection_creds_conn_done,
3359 static void cli_full_connection_creds_conn_done(struct tevent_req *subreq)
3361 struct tevent_req *req = tevent_req_callback_data(
3362 subreq, struct tevent_req);
3363 struct cli_full_connection_creds_state *state = tevent_req_data(
3364 req, struct cli_full_connection_creds_state);
3367 status = cli_start_connection_recv(subreq, state, &state->cli);
3368 TALLOC_FREE(subreq);
3369 if (tevent_req_nterror(req, status)) {
3373 subreq = cli_session_setup_creds_send(
3374 state, state->ev, state->cli, state->creds);
3375 if (tevent_req_nomem(subreq, req)) {
3378 tevent_req_set_callback(subreq,
3379 cli_full_connection_creds_sess_done,
3383 static void cli_full_connection_creds_sess_done(struct tevent_req *subreq)
3385 struct tevent_req *req = tevent_req_callback_data(
3386 subreq, struct tevent_req);
3387 struct cli_full_connection_creds_state *state = tevent_req_data(
3388 req, struct cli_full_connection_creds_state);
3391 status = cli_session_setup_creds_recv(subreq);
3392 TALLOC_FREE(subreq);
3394 if (!NT_STATUS_IS_OK(status) &&
3395 (state->flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)) {
3397 state->flags &= ~CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
3399 state->creds = cli_credentials_init_anon(state);
3400 if (tevent_req_nomem(state->creds, req)) {
3404 subreq = cli_session_setup_creds_send(
3405 state, state->ev, state->cli, state->creds);
3406 if (tevent_req_nomem(subreq, req)) {
3409 tevent_req_set_callback(subreq,
3410 cli_full_connection_creds_sess_done,
3415 if (tevent_req_nterror(req, status)) {
3419 cli_full_connection_creds_enc_start(req);
3422 static void cli_full_connection_creds_enc_start(struct tevent_req *req)
3424 struct cli_full_connection_creds_state *state = tevent_req_data(
3425 req, struct cli_full_connection_creds_state);
3426 enum smb_encryption_setting encryption_state =
3427 cli_credentials_get_smb_encryption(state->creds);
3428 struct tevent_req *subreq = NULL;
3431 if (encryption_state < SMB_ENCRYPTION_DESIRED) {
3432 cli_full_connection_creds_tcon_start(req);
3436 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
3437 status = smb2cli_session_encryption_on(state->cli->smb2.session);
3438 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
3439 if (encryption_state < SMB_ENCRYPTION_REQUIRED) {
3440 cli_full_connection_creds_tcon_start(req);
3443 d_printf("Encryption required and "
3444 "server doesn't support "
3445 "SMB3 encryption - failing connect\n");
3446 tevent_req_nterror(req, status);
3450 if (!NT_STATUS_IS_OK(status)) {
3451 d_printf("Encryption required and "
3452 "setup failed with error %s.\n",
3454 tevent_req_nterror(req, status);
3458 cli_full_connection_creds_tcon_start(req);
3462 if (!SERVER_HAS_UNIX_CIFS(state->cli)) {
3463 if (encryption_state < SMB_ENCRYPTION_REQUIRED) {
3464 cli_full_connection_creds_tcon_start(req);
3468 status = NT_STATUS_NOT_SUPPORTED;
3469 d_printf("Encryption required and "
3470 "server doesn't support "
3471 "SMB1 Unix Extensions - failing connect\n");
3472 tevent_req_nterror(req, status);
3477 * We do a tcon on IPC$ just to setup the encryption,
3478 * the real tcon will be encrypted then.
3480 subreq = cli_tree_connect_send(state, state->ev, state->cli,
3481 "IPC$", "IPC", NULL);
3482 if (tevent_req_nomem(subreq, req)) {
3485 tevent_req_set_callback(subreq, cli_full_connection_creds_enc_tcon, req);
3488 static void cli_full_connection_creds_enc_tcon(struct tevent_req *subreq)
3490 struct tevent_req *req = tevent_req_callback_data(
3491 subreq, struct tevent_req);
3492 struct cli_full_connection_creds_state *state = tevent_req_data(
3493 req, struct cli_full_connection_creds_state);
3496 status = cli_tree_connect_recv(subreq);
3497 TALLOC_FREE(subreq);
3498 if (tevent_req_nterror(req, status)) {
3502 subreq = cli_unix_extensions_version_send(state, state->ev, state->cli);
3503 if (tevent_req_nomem(subreq, req)) {
3506 tevent_req_set_callback(subreq, cli_full_connection_creds_enc_ver, req);
3509 static void cli_full_connection_creds_enc_ver(struct tevent_req *subreq)
3511 struct tevent_req *req = tevent_req_callback_data(
3512 subreq, struct tevent_req);
3513 struct cli_full_connection_creds_state *state = tevent_req_data(
3514 req, struct cli_full_connection_creds_state);
3515 enum smb_encryption_setting encryption_state =
3516 cli_credentials_get_smb_encryption(state->creds);
3517 uint16_t major, minor;
3518 uint32_t caplow, caphigh;
3521 status = cli_unix_extensions_version_recv(subreq,
3525 TALLOC_FREE(subreq);
3526 if (!NT_STATUS_IS_OK(status)) {
3527 if (encryption_state < SMB_ENCRYPTION_REQUIRED) {
3528 /* disconnect ipc$ followed by the real tree connect */
3529 cli_full_connection_creds_enc_tdis(req);
3532 DEBUG(10, ("%s: cli_unix_extensions_version "
3533 "returned %s\n", __func__, nt_errstr(status)));
3534 tevent_req_nterror(req, NT_STATUS_UNKNOWN_REVISION);
3538 if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
3539 if (encryption_state < SMB_ENCRYPTION_REQUIRED) {
3540 /* disconnect ipc$ followed by the real tree connect */
3541 cli_full_connection_creds_enc_tdis(req);
3544 DEBUG(10, ("%s: CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP "
3545 "not supported\n", __func__));
3546 tevent_req_nterror(req, NT_STATUS_UNSUPPORTED_COMPRESSION);
3550 subreq = cli_smb1_setup_encryption_send(state, state->ev,
3553 if (tevent_req_nomem(subreq, req)) {
3556 tevent_req_set_callback(subreq,
3557 cli_full_connection_creds_enc_done,
3561 static void cli_full_connection_creds_enc_done(struct tevent_req *subreq)
3563 struct tevent_req *req = tevent_req_callback_data(
3564 subreq, struct tevent_req);
3567 status = cli_smb1_setup_encryption_recv(subreq);
3568 TALLOC_FREE(subreq);
3569 if (tevent_req_nterror(req, status)) {
3573 /* disconnect ipc$ followed by the real tree connect */
3574 cli_full_connection_creds_enc_tdis(req);
3577 static void cli_full_connection_creds_enc_tdis(struct tevent_req *req)
3579 struct cli_full_connection_creds_state *state = tevent_req_data(
3580 req, struct cli_full_connection_creds_state);
3581 struct tevent_req *subreq = NULL;
3583 subreq = cli_tdis_send(state, state->ev, state->cli);
3584 if (tevent_req_nomem(subreq, req)) {
3587 tevent_req_set_callback(subreq,
3588 cli_full_connection_creds_enc_finished,
3592 static void cli_full_connection_creds_enc_finished(struct tevent_req *subreq)
3594 struct tevent_req *req = tevent_req_callback_data(
3595 subreq, struct tevent_req);
3598 status = cli_tdis_recv(subreq);
3599 TALLOC_FREE(subreq);
3600 if (tevent_req_nterror(req, status)) {
3604 cli_full_connection_creds_tcon_start(req);
3607 static void cli_full_connection_creds_tcon_start(struct tevent_req *req)
3609 struct cli_full_connection_creds_state *state = tevent_req_data(
3610 req, struct cli_full_connection_creds_state);
3611 struct tevent_req *subreq = NULL;
3612 const char *password = NULL;
3614 if (state->service == NULL) {
3615 tevent_req_done(req);
3619 password = cli_credentials_get_password(state->creds);
3621 subreq = cli_tree_connect_send(state, state->ev,
3624 state->service_type,
3626 if (tevent_req_nomem(subreq, req)) {
3629 tevent_req_set_callback(subreq,
3630 cli_full_connection_creds_tcon_done,
3634 static void cli_full_connection_creds_tcon_done(struct tevent_req *subreq)
3636 struct tevent_req *req = tevent_req_callback_data(
3637 subreq, struct tevent_req);
3640 status = cli_tree_connect_recv(subreq);
3641 TALLOC_FREE(subreq);
3642 if (tevent_req_nterror(req, status)) {
3646 tevent_req_done(req);
3649 NTSTATUS cli_full_connection_creds_recv(struct tevent_req *req,
3650 TALLOC_CTX *mem_ctx,
3651 struct cli_state **output_cli)
3653 struct cli_full_connection_creds_state *state = tevent_req_data(
3654 req, struct cli_full_connection_creds_state);
3657 if (tevent_req_is_nterror(req, &status)) {
3660 *output_cli = talloc_move(mem_ctx, &state->cli);
3661 talloc_set_destructor(state, NULL);
3662 return NT_STATUS_OK;
3665 NTSTATUS cli_full_connection_creds(TALLOC_CTX *mem_ctx,
3666 struct cli_state **output_cli,
3667 const char *my_name,
3668 const char *dest_host,
3669 const struct sockaddr_storage *dest_ss,
3670 const struct smb_transports *transports,
3671 const char *service, const char *service_type,
3672 struct cli_credentials *creds,
3675 struct tevent_context *ev;
3676 struct tevent_req *req;
3677 NTSTATUS status = NT_STATUS_NO_MEMORY;
3679 ev = samba_tevent_context_init(mem_ctx);
3683 req = cli_full_connection_creds_send(
3684 ev, ev, my_name, dest_host, dest_ss, transports, service,
3685 service_type, creds, flags,
3690 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
3693 status = cli_full_connection_creds_recv(req, mem_ctx, output_cli);
3699 /****************************************************************************
3700 Send an old style tcon.
3701 ****************************************************************************/
3702 struct cli_raw_tcon_state {
3706 static void cli_raw_tcon_done(struct tevent_req *subreq);
3708 static struct tevent_req *cli_raw_tcon_send(
3709 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
3710 const char *service, const char *pass, const char *dev)
3712 struct tevent_req *req, *subreq;
3713 struct cli_raw_tcon_state *state;
3716 req = tevent_req_create(mem_ctx, &state, struct cli_raw_tcon_state);
3721 if (!lp_client_plaintext_auth() && (*pass)) {
3722 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
3723 " or 'client ntlmv2 auth = yes'\n"));
3724 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
3725 return tevent_req_post(req, ev);
3728 TALLOC_FREE(cli->smb1.tcon);
3729 cli->smb1.tcon = smbXcli_tcon_create(cli);
3730 if (tevent_req_nomem(cli->smb1.tcon, req)) {
3731 return tevent_req_post(req, ev);
3733 smb1cli_tcon_set_id(cli->smb1.tcon, UINT16_MAX);
3735 bytes = talloc_array(state, uint8_t, 0);
3736 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3737 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3738 service, strlen(service)+1, NULL);
3739 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3740 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3741 pass, strlen(pass)+1, NULL);
3742 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3743 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3744 dev, strlen(dev)+1, NULL);
3746 if (tevent_req_nomem(bytes, req)) {
3747 return tevent_req_post(req, ev);
3750 subreq = cli_smb_send(state, ev, cli, SMBtcon, 0, 0, 0, NULL,
3751 talloc_get_size(bytes), bytes);
3752 if (tevent_req_nomem(subreq, req)) {
3753 return tevent_req_post(req, ev);
3755 tevent_req_set_callback(subreq, cli_raw_tcon_done, req);
3759 static void cli_raw_tcon_done(struct tevent_req *subreq)
3761 struct tevent_req *req = tevent_req_callback_data(
3762 subreq, struct tevent_req);
3763 struct cli_raw_tcon_state *state = tevent_req_data(
3764 req, struct cli_raw_tcon_state);
3767 status = cli_smb_recv(subreq, state, NULL, 2, NULL, &state->ret_vwv,
3769 TALLOC_FREE(subreq);
3770 if (tevent_req_nterror(req, status)) {
3773 tevent_req_done(req);
3776 static NTSTATUS cli_raw_tcon_recv(struct tevent_req *req,
3777 uint16_t *max_xmit, uint16_t *tid)
3779 struct cli_raw_tcon_state *state = tevent_req_data(
3780 req, struct cli_raw_tcon_state);
3783 if (tevent_req_is_nterror(req, &status)) {
3786 *max_xmit = SVAL(state->ret_vwv + 0, 0);
3787 *tid = SVAL(state->ret_vwv + 1, 0);
3788 return NT_STATUS_OK;
3791 NTSTATUS cli_raw_tcon(struct cli_state *cli,
3792 const char *service, const char *pass, const char *dev,
3793 uint16_t *max_xmit, uint16_t *tid)
3795 struct tevent_context *ev;
3796 struct tevent_req *req;
3797 NTSTATUS status = NT_STATUS_NO_MEMORY;
3799 ev = samba_tevent_context_init(talloc_tos());
3803 req = cli_raw_tcon_send(ev, ev, cli, service, pass, dev);
3807 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
3810 status = cli_raw_tcon_recv(req, max_xmit, tid);
3816 /* Return a cli_state pointing at the IPC$ share for the given server */
3818 static struct cli_state *get_ipc_connect(TALLOC_CTX *mem_ctx,
3820 struct sockaddr_storage *server_ss,
3821 struct cli_credentials *creds)
3823 struct cli_state *cli;
3825 uint32_t flags = CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
3826 struct smb_transports ts =
3827 smb_transports_parse("client smb transports",
3828 lp_client_smb_transports());
3830 flags |= CLI_FULL_CONNECTION_FORCE_SMB1;
3831 flags |= CLI_FULL_CONNECTION_IPC;
3833 nt_status = cli_full_connection_creds(mem_ctx,
3844 if (NT_STATUS_IS_OK(nt_status)) {
3847 if (is_ipaddress(server)) {
3848 /* windows 9* needs a correct NMB name for connections */
3849 fstring remote_name;
3851 if (name_status_find("*", 0, 0, server_ss, remote_name)) {
3852 cli = get_ipc_connect(mem_ctx, remote_name, server_ss, creds);
3861 * Given the IP address of a master browser on the network, return its
3862 * workgroup and connect to it.
3864 * This function is provided to allow additional processing beyond what
3865 * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
3866 * browsers and obtain each master browsers' list of domains (in case the
3867 * first master browser is recently on the network and has not yet
3868 * synchronized with other master browsers and therefore does not yet have the
3869 * entire network browse list)
3872 struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx,
3873 struct sockaddr_storage *mb_ip,
3874 struct cli_credentials *creds,
3875 char **pp_workgroup_out)
3877 char addr[INET6_ADDRSTRLEN];
3879 struct cli_state *cli;
3880 struct sockaddr_storage server_ss;
3882 *pp_workgroup_out = NULL;
3884 print_sockaddr(addr, sizeof(addr), mb_ip);
3885 DEBUG(99, ("Looking up name of master browser %s\n",
3889 * Do a name status query to find out the name of the master browser.
3890 * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
3891 * master browser will not respond to a wildcard query (or, at least,
3892 * an NT4 server acting as the domain master browser will not).
3894 * We might be able to use ONLY the query on MSBROWSE, but that's not
3895 * yet been tested with all Windows versions, so until it is, leave
3896 * the original wildcard query as the first choice and fall back to
3897 * MSBROWSE if the wildcard query fails.
3899 if (!name_status_find("*", 0, 0x1d, mb_ip, name) &&
3900 !name_status_find(MSBROWSE, 1, 0x1d, mb_ip, name)) {
3902 DEBUG(99, ("Could not retrieve name status for %s\n",
3907 if (!find_master_ip(name, &server_ss)) {
3908 DEBUG(99, ("Could not find master ip for %s\n", name));
3912 *pp_workgroup_out = talloc_strdup(ctx, name);
3914 DEBUG(4, ("found master browser %s, %s\n", name, addr));
3916 print_sockaddr(addr, sizeof(addr), &server_ss);
3917 cli = get_ipc_connect(ctx, addr, &server_ss, creds);