2 Unix SMB/CIFS implementation.
3 client connect/disconnect routines
4 Copyright (C) Andrew Tridgell 1994-1998
5 Copyright (C) Andrew Bartlett 2001-2003
6 Copyright (C) Volker Lendecke 2011
7 Copyright (C) Jeremy Allison 2011
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "libsmb/libsmb.h"
25 #include "auth_info.h"
26 #include "../libcli/auth/libcli_auth.h"
27 #include "../libcli/auth/spnego.h"
29 #include "../auth/ntlmssp/ntlmssp.h"
30 #include "libads/kerberos_proto.h"
32 #include "../lib/util/tevent_ntstatus.h"
33 #include "async_smb.h"
34 #include "libsmb/nmblib.h"
35 #include "librpc/ndr/libndr.h"
36 #include "../libcli/smb/smbXcli_base.h"
39 #define STAR_SMBSERVER "*SMBSERVER"
41 /********************************************************
42 Utility function to ensure we always return at least
43 a valid char * pointer to an empty string for the
44 cli->server_os, cli->server_type and cli->server_domain
46 *******************************************************/
48 static NTSTATUS
smb_bytes_talloc_string(TALLOC_CTX
*mem_ctx
,
55 *destlen
= clistr_pull_talloc(mem_ctx
,
63 return NT_STATUS_NO_MEMORY
;
67 *dest
= talloc_strdup(mem_ctx
, "");
69 return NT_STATUS_NO_MEMORY
;
75 /****************************************************************************
76 Do an old lanman2 style session setup.
77 ****************************************************************************/
79 struct cli_session_setup_lanman2_state
{
80 struct cli_state
*cli
;
85 static void cli_session_setup_lanman2_done(struct tevent_req
*subreq
);
87 static struct tevent_req
*cli_session_setup_lanman2_send(
88 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
89 struct cli_state
*cli
, const char *user
,
90 const char *pass
, size_t passlen
,
91 const char *workgroup
)
93 struct tevent_req
*req
, *subreq
;
94 struct cli_session_setup_lanman2_state
*state
;
95 DATA_BLOB lm_response
= data_blob_null
;
99 uint16_t sec_mode
= smb1cli_conn_server_security_mode(cli
->conn
);
101 req
= tevent_req_create(mem_ctx
, &state
,
102 struct cli_session_setup_lanman2_state
);
111 * if in share level security then don't send a password now
113 if (!(sec_mode
& NEGOTIATE_SECURITY_USER_LEVEL
)) {
118 && (sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
)
121 * Encrypted mode needed, and non encrypted password
124 lm_response
= data_blob(NULL
, 24);
125 if (tevent_req_nomem(lm_response
.data
, req
)) {
126 return tevent_req_post(req
, ev
);
129 if (!SMBencrypt(pass
, smb1cli_conn_server_challenge(cli
->conn
),
130 (uint8_t *)lm_response
.data
)) {
131 DEBUG(1, ("Password is > 14 chars in length, and is "
132 "therefore incompatible with Lanman "
133 "authentication\n"));
134 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
135 return tevent_req_post(req
, ev
);
137 } else if ((sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
)
140 * Encrypted mode needed, and encrypted password
143 lm_response
= data_blob(pass
, passlen
);
144 if (tevent_req_nomem(lm_response
.data
, req
)) {
145 return tevent_req_post(req
, ev
);
147 } else if (passlen
> 0) {
149 size_t converted_size
;
151 * Plaintext mode needed, assume plaintext supplied.
153 buf
= talloc_array(talloc_tos(), uint8_t, 0);
154 buf
= smb_bytes_push_str(buf
, smbXcli_conn_use_unicode(cli
->conn
), pass
, passlen
+1,
156 if (tevent_req_nomem(buf
, req
)) {
157 return tevent_req_post(req
, ev
);
159 lm_response
= data_blob(pass
, passlen
);
161 if (tevent_req_nomem(lm_response
.data
, req
)) {
162 return tevent_req_post(req
, ev
);
166 SCVAL(vwv
+0, 0, 0xff);
169 SSVAL(vwv
+2, 0, CLI_BUFFER_SIZE
);
172 SIVAL(vwv
+5, 0, smb1cli_conn_server_session_key(cli
->conn
));
173 SSVAL(vwv
+7, 0, lm_response
.length
);
175 bytes
= talloc_array(state
, uint8_t, lm_response
.length
);
176 if (tevent_req_nomem(bytes
, req
)) {
177 return tevent_req_post(req
, ev
);
179 if (lm_response
.length
!= 0) {
180 memcpy(bytes
, lm_response
.data
, lm_response
.length
);
182 data_blob_free(&lm_response
);
184 tmp
= talloc_strdup_upper(talloc_tos(), user
);
185 if (tevent_req_nomem(tmp
, req
)) {
186 return tevent_req_post(req
, ev
);
188 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), tmp
, strlen(tmp
)+1,
192 tmp
= talloc_strdup_upper(talloc_tos(), workgroup
);
193 if (tevent_req_nomem(tmp
, req
)) {
194 return tevent_req_post(req
, ev
);
196 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), tmp
, strlen(tmp
)+1,
198 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "Unix", 5, NULL
);
199 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "Samba", 6, NULL
);
201 if (tevent_req_nomem(bytes
, req
)) {
202 return tevent_req_post(req
, ev
);
205 subreq
= cli_smb_send(state
, ev
, cli
, SMBsesssetupX
, 0, 10, vwv
,
206 talloc_get_size(bytes
), bytes
);
207 if (tevent_req_nomem(subreq
, req
)) {
208 return tevent_req_post(req
, ev
);
210 tevent_req_set_callback(subreq
, cli_session_setup_lanman2_done
, req
);
214 static void cli_session_setup_lanman2_done(struct tevent_req
*subreq
)
216 struct tevent_req
*req
= tevent_req_callback_data(
217 subreq
, struct tevent_req
);
218 struct cli_session_setup_lanman2_state
*state
= tevent_req_data(
219 req
, struct cli_session_setup_lanman2_state
);
220 struct cli_state
*cli
= state
->cli
;
231 status
= cli_smb_recv(subreq
, state
, &in
, 3, &wct
, &vwv
,
234 if (!NT_STATUS_IS_OK(status
)) {
235 tevent_req_nterror(req
, status
);
239 inhdr
= in
+ NBT_HDR_SIZE
;
242 cli_state_set_uid(state
->cli
, SVAL(inhdr
, HDR_UID
));
244 status
= smb_bytes_talloc_string(cli
,
251 if (!NT_STATUS_IS_OK(status
)) {
252 tevent_req_nterror(req
, status
);
257 status
= smb_bytes_talloc_string(cli
,
264 if (!NT_STATUS_IS_OK(status
)) {
265 tevent_req_nterror(req
, status
);
270 status
= smb_bytes_talloc_string(cli
,
277 if (!NT_STATUS_IS_OK(status
)) {
278 tevent_req_nterror(req
, status
);
283 status
= cli_set_username(cli
, state
->user
);
284 if (tevent_req_nterror(req
, status
)) {
287 tevent_req_done(req
);
290 static NTSTATUS
cli_session_setup_lanman2_recv(struct tevent_req
*req
)
292 return tevent_req_simple_recv_ntstatus(req
);
295 /****************************************************************************
296 Work out suitable capabilities to offer the server.
297 ****************************************************************************/
299 static uint32_t cli_session_setup_capabilities(struct cli_state
*cli
,
300 uint32_t sesssetup_capabilities
)
302 uint32_t client_capabilities
= smb1cli_conn_capabilities(cli
->conn
);
305 * We only send capabilities based on the mask for:
306 * - client only flags
307 * - flags used in both directions
309 * We do not echo the server only flags, except some legacy flags.
311 * SMB_CAP_LEGACY_CLIENT_MASK contains CAP_LARGE_READX and
312 * CAP_LARGE_WRITEX in order to allow us to do large reads
313 * against old Samba releases (<= 3.6.x).
315 client_capabilities
&= (SMB_CAP_BOTH_MASK
| SMB_CAP_LEGACY_CLIENT_MASK
);
318 * Session Setup specific flags CAP_DYNAMIC_REAUTH
319 * and CAP_EXTENDED_SECURITY are passed by the caller.
320 * We need that in order to do guest logins even if
321 * CAP_EXTENDED_SECURITY is negotiated.
323 client_capabilities
&= ~(CAP_DYNAMIC_REAUTH
|CAP_EXTENDED_SECURITY
);
324 sesssetup_capabilities
&= (CAP_DYNAMIC_REAUTH
|CAP_EXTENDED_SECURITY
);
325 client_capabilities
|= sesssetup_capabilities
;
327 return client_capabilities
;
330 /****************************************************************************
331 Do a NT1 guest session setup.
332 ****************************************************************************/
334 struct cli_session_setup_guest_state
{
335 struct cli_state
*cli
;
340 static void cli_session_setup_guest_done(struct tevent_req
*subreq
);
342 struct tevent_req
*cli_session_setup_guest_create(TALLOC_CTX
*mem_ctx
,
343 struct tevent_context
*ev
,
344 struct cli_state
*cli
,
345 struct tevent_req
**psmbreq
)
347 struct tevent_req
*req
, *subreq
;
348 struct cli_session_setup_guest_state
*state
;
352 req
= tevent_req_create(mem_ctx
, &state
,
353 struct cli_session_setup_guest_state
);
360 SCVAL(vwv
+0, 0, 0xFF);
363 SSVAL(vwv
+2, 0, CLI_BUFFER_SIZE
);
365 SSVAL(vwv
+4, 0, cli_state_get_vc_num(cli
));
366 SIVAL(vwv
+5, 0, smb1cli_conn_server_session_key(cli
->conn
));
371 SIVAL(vwv
+11, 0, cli_session_setup_capabilities(cli
, 0));
373 bytes
= talloc_array(state
, uint8_t, 0);
375 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "", 1, /* username */
377 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "", 1, /* workgroup */
379 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "Unix", 5, NULL
);
380 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "Samba", 6, NULL
);
387 state
->bytes
.iov_base
= (void *)bytes
;
388 state
->bytes
.iov_len
= talloc_get_size(bytes
);
390 subreq
= cli_smb_req_create(state
, ev
, cli
, SMBsesssetupX
, 0, 13, vwv
,
392 if (subreq
== NULL
) {
396 tevent_req_set_callback(subreq
, cli_session_setup_guest_done
, req
);
401 struct tevent_req
*cli_session_setup_guest_send(TALLOC_CTX
*mem_ctx
,
402 struct tevent_context
*ev
,
403 struct cli_state
*cli
)
405 struct tevent_req
*req
, *subreq
;
408 req
= cli_session_setup_guest_create(mem_ctx
, ev
, cli
, &subreq
);
413 status
= smb1cli_req_chain_submit(&subreq
, 1);
414 if (!NT_STATUS_IS_OK(status
)) {
415 tevent_req_nterror(req
, status
);
416 return tevent_req_post(req
, ev
);
421 static void cli_session_setup_guest_done(struct tevent_req
*subreq
)
423 struct tevent_req
*req
= tevent_req_callback_data(
424 subreq
, struct tevent_req
);
425 struct cli_session_setup_guest_state
*state
= tevent_req_data(
426 req
, struct cli_session_setup_guest_state
);
427 struct cli_state
*cli
= state
->cli
;
438 status
= cli_smb_recv(subreq
, state
, &in
, 3, &wct
, &vwv
,
441 if (!NT_STATUS_IS_OK(status
)) {
442 tevent_req_nterror(req
, status
);
446 inhdr
= in
+ NBT_HDR_SIZE
;
449 cli_state_set_uid(state
->cli
, SVAL(inhdr
, HDR_UID
));
451 status
= smb_bytes_talloc_string(cli
,
458 if (!NT_STATUS_IS_OK(status
)) {
459 tevent_req_nterror(req
, status
);
464 status
= smb_bytes_talloc_string(cli
,
471 if (!NT_STATUS_IS_OK(status
)) {
472 tevent_req_nterror(req
, status
);
477 status
= smb_bytes_talloc_string(cli
,
484 if (!NT_STATUS_IS_OK(status
)) {
485 tevent_req_nterror(req
, status
);
490 status
= cli_set_username(cli
, "");
491 if (!NT_STATUS_IS_OK(status
)) {
492 tevent_req_nterror(req
, status
);
495 tevent_req_done(req
);
498 NTSTATUS
cli_session_setup_guest_recv(struct tevent_req
*req
)
500 return tevent_req_simple_recv_ntstatus(req
);
503 /****************************************************************************
504 Do a NT1 plaintext session setup.
505 ****************************************************************************/
507 struct cli_session_setup_plain_state
{
508 struct cli_state
*cli
;
513 static void cli_session_setup_plain_done(struct tevent_req
*subreq
);
515 static struct tevent_req
*cli_session_setup_plain_send(
516 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
517 struct cli_state
*cli
,
518 const char *user
, const char *pass
, const char *workgroup
)
520 struct tevent_req
*req
, *subreq
;
521 struct cli_session_setup_plain_state
*state
;
527 req
= tevent_req_create(mem_ctx
, &state
,
528 struct cli_session_setup_plain_state
);
536 SCVAL(vwv
+0, 0, 0xff);
539 SSVAL(vwv
+2, 0, CLI_BUFFER_SIZE
);
541 SSVAL(vwv
+4, 0, cli_state_get_vc_num(cli
));
542 SIVAL(vwv
+5, 0, smb1cli_conn_server_session_key(cli
->conn
));
547 SIVAL(vwv
+11, 0, cli_session_setup_capabilities(cli
, 0));
549 bytes
= talloc_array(state
, uint8_t, 0);
550 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), pass
, strlen(pass
)+1,
552 if (tevent_req_nomem(bytes
, req
)) {
553 return tevent_req_post(req
, ev
);
555 SSVAL(vwv
+ (smbXcli_conn_use_unicode(cli
->conn
) ? 8 : 7), 0, passlen
);
557 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
558 user
, strlen(user
)+1, NULL
);
559 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
560 workgroup
, strlen(workgroup
)+1, NULL
);
561 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
564 version
= talloc_asprintf(talloc_tos(), "Samba %s",
565 samba_version_string());
566 if (tevent_req_nomem(version
, req
)){
567 return tevent_req_post(req
, ev
);
569 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
570 version
, strlen(version
)+1, NULL
);
571 TALLOC_FREE(version
);
573 if (tevent_req_nomem(bytes
, req
)) {
574 return tevent_req_post(req
, ev
);
577 subreq
= cli_smb_send(state
, ev
, cli
, SMBsesssetupX
, 0, 13, vwv
,
578 talloc_get_size(bytes
), bytes
);
579 if (tevent_req_nomem(subreq
, req
)) {
580 return tevent_req_post(req
, ev
);
582 tevent_req_set_callback(subreq
, cli_session_setup_plain_done
, req
);
586 static void cli_session_setup_plain_done(struct tevent_req
*subreq
)
588 struct tevent_req
*req
= tevent_req_callback_data(
589 subreq
, struct tevent_req
);
590 struct cli_session_setup_plain_state
*state
= tevent_req_data(
591 req
, struct cli_session_setup_plain_state
);
592 struct cli_state
*cli
= state
->cli
;
603 status
= cli_smb_recv(subreq
, state
, &in
, 3, &wct
, &vwv
,
606 if (tevent_req_nterror(req
, status
)) {
610 inhdr
= in
+ NBT_HDR_SIZE
;
613 cli_state_set_uid(state
->cli
, SVAL(inhdr
, HDR_UID
));
615 status
= smb_bytes_talloc_string(cli
,
622 if (!NT_STATUS_IS_OK(status
)) {
623 tevent_req_nterror(req
, status
);
628 status
= smb_bytes_talloc_string(cli
,
635 if (!NT_STATUS_IS_OK(status
)) {
636 tevent_req_nterror(req
, status
);
641 status
= smb_bytes_talloc_string(cli
,
648 if (!NT_STATUS_IS_OK(status
)) {
649 tevent_req_nterror(req
, status
);
654 status
= cli_set_username(cli
, state
->user
);
655 if (tevent_req_nterror(req
, status
)) {
659 tevent_req_done(req
);
662 static NTSTATUS
cli_session_setup_plain_recv(struct tevent_req
*req
)
664 return tevent_req_simple_recv_ntstatus(req
);
667 /****************************************************************************
668 do a NT1 NTLM/LM encrypted session setup - for when extended security
670 @param cli client state to create do session setup on
672 @param pass *either* cleartext password (passlen !=24) or LM response.
673 @param ntpass NT response, implies ntpasslen >=24, implies pass is not clear
674 @param workgroup The user's domain.
675 ****************************************************************************/
677 struct cli_session_setup_nt1_state
{
678 struct cli_state
*cli
;
681 DATA_BLOB session_key
;
685 static void cli_session_setup_nt1_done(struct tevent_req
*subreq
);
687 static struct tevent_req
*cli_session_setup_nt1_send(
688 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
689 struct cli_state
*cli
, const char *user
,
690 const char *pass
, size_t passlen
,
691 const char *ntpass
, size_t ntpasslen
,
692 const char *workgroup
)
694 struct tevent_req
*req
, *subreq
;
695 struct cli_session_setup_nt1_state
*state
;
696 DATA_BLOB lm_response
= data_blob_null
;
697 DATA_BLOB nt_response
= data_blob_null
;
698 DATA_BLOB session_key
= data_blob_null
;
701 char *workgroup_upper
;
703 req
= tevent_req_create(mem_ctx
, &state
,
704 struct cli_session_setup_nt1_state
);
713 /* do nothing - guest login */
714 } else if (passlen
!= 24) {
715 if (lp_client_ntlmv2_auth()) {
716 DATA_BLOB server_chal
;
717 DATA_BLOB names_blob
;
720 data_blob_const(smb1cli_conn_server_challenge(cli
->conn
),
724 * note that the 'workgroup' here is a best
725 * guess - we don't know the server's domain
726 * at this point. Windows clients also don't
729 names_blob
= NTLMv2_generate_names_blob(
730 NULL
, NULL
, workgroup
);
732 if (tevent_req_nomem(names_blob
.data
, req
)) {
733 return tevent_req_post(req
, ev
);
736 if (!SMBNTLMv2encrypt(NULL
, user
, workgroup
, pass
,
737 &server_chal
, &names_blob
,
738 &lm_response
, &nt_response
,
739 NULL
, &session_key
)) {
740 data_blob_free(&names_blob
);
742 req
, NT_STATUS_ACCESS_DENIED
);
743 return tevent_req_post(req
, ev
);
745 data_blob_free(&names_blob
);
749 E_md4hash(pass
, nt_hash
);
752 nt_response
= data_blob_null
;
754 nt_response
= data_blob(NULL
, 24);
755 if (tevent_req_nomem(nt_response
.data
, req
)) {
756 return tevent_req_post(req
, ev
);
759 SMBNTencrypt(pass
, smb1cli_conn_server_challenge(cli
->conn
),
762 /* non encrypted password supplied. Ignore ntpass. */
763 if (lp_client_lanman_auth()) {
765 lm_response
= data_blob(NULL
, 24);
766 if (tevent_req_nomem(lm_response
.data
, req
)) {
767 return tevent_req_post(req
, ev
);
770 if (!SMBencrypt(pass
,
771 smb1cli_conn_server_challenge(cli
->conn
),
774 * Oops, the LM response is
775 * invalid, just put the NT
776 * response there instead
778 data_blob_free(&lm_response
);
779 lm_response
= data_blob(
785 * LM disabled, place NT# in LM field
788 lm_response
= data_blob(
789 nt_response
.data
, nt_response
.length
);
792 if (tevent_req_nomem(lm_response
.data
, req
)) {
793 return tevent_req_post(req
, ev
);
796 session_key
= data_blob(NULL
, 16);
797 if (tevent_req_nomem(session_key
.data
, req
)) {
798 return tevent_req_post(req
, ev
);
801 E_deshash(pass
, session_key
.data
);
802 memset(&session_key
.data
[8], '\0', 8);
804 SMBsesskeygen_ntv1(nt_hash
, session_key
.data
);
808 /* pre-encrypted password supplied. Only used for
809 security=server, can't do
810 signing because we don't have original key */
812 lm_response
= data_blob(pass
, passlen
);
813 if (tevent_req_nomem(lm_response
.data
, req
)) {
814 return tevent_req_post(req
, ev
);
817 nt_response
= data_blob(ntpass
, ntpasslen
);
818 if (tevent_req_nomem(nt_response
.data
, req
)) {
819 return tevent_req_post(req
, ev
);
824 state
->response
= data_blob_talloc(
825 state
, lm_response
.data
, lm_response
.length
);
827 state
->response
= data_blob_talloc(
828 state
, nt_response
.data
, nt_response
.length
);
830 if (tevent_req_nomem(state
->response
.data
, req
)) {
831 return tevent_req_post(req
, ev
);
834 if (session_key
.data
) {
835 state
->session_key
= data_blob_talloc(
836 state
, session_key
.data
, session_key
.length
);
837 if (tevent_req_nomem(state
->session_key
.data
, req
)) {
838 return tevent_req_post(req
, ev
);
841 data_blob_free(&session_key
);
843 SCVAL(vwv
+0, 0, 0xff);
846 SSVAL(vwv
+2, 0, CLI_BUFFER_SIZE
);
848 SSVAL(vwv
+4, 0, cli_state_get_vc_num(cli
));
849 SIVAL(vwv
+5, 0, smb1cli_conn_server_session_key(cli
->conn
));
850 SSVAL(vwv
+7, 0, lm_response
.length
);
851 SSVAL(vwv
+8, 0, nt_response
.length
);
854 SIVAL(vwv
+11, 0, cli_session_setup_capabilities(cli
, 0));
856 bytes
= talloc_array(state
, uint8_t,
857 lm_response
.length
+ nt_response
.length
);
858 if (tevent_req_nomem(bytes
, req
)) {
859 return tevent_req_post(req
, ev
);
861 if (lm_response
.length
!= 0) {
862 memcpy(bytes
, lm_response
.data
, lm_response
.length
);
864 if (nt_response
.length
!= 0) {
865 memcpy(bytes
+ lm_response
.length
,
866 nt_response
.data
, nt_response
.length
);
868 data_blob_free(&lm_response
);
869 data_blob_free(&nt_response
);
871 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
872 user
, strlen(user
)+1, NULL
);
875 * Upper case here might help some NTLMv2 implementations
877 workgroup_upper
= talloc_strdup_upper(talloc_tos(), workgroup
);
878 if (tevent_req_nomem(workgroup_upper
, req
)) {
879 return tevent_req_post(req
, ev
);
881 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
882 workgroup_upper
, strlen(workgroup_upper
)+1,
884 TALLOC_FREE(workgroup_upper
);
886 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "Unix", 5, NULL
);
887 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "Samba", 6, NULL
);
888 if (tevent_req_nomem(bytes
, req
)) {
889 return tevent_req_post(req
, ev
);
892 subreq
= cli_smb_send(state
, ev
, cli
, SMBsesssetupX
, 0, 13, vwv
,
893 talloc_get_size(bytes
), bytes
);
894 if (tevent_req_nomem(subreq
, req
)) {
895 return tevent_req_post(req
, ev
);
897 tevent_req_set_callback(subreq
, cli_session_setup_nt1_done
, req
);
901 static void cli_session_setup_nt1_done(struct tevent_req
*subreq
)
903 struct tevent_req
*req
= tevent_req_callback_data(
904 subreq
, struct tevent_req
);
905 struct cli_session_setup_nt1_state
*state
= tevent_req_data(
906 req
, struct cli_session_setup_nt1_state
);
907 struct cli_state
*cli
= state
->cli
;
918 status
= cli_smb_recv(subreq
, state
, &in
, 3, &wct
, &vwv
,
921 if (!NT_STATUS_IS_OK(status
)) {
922 tevent_req_nterror(req
, status
);
926 inhdr
= in
+ NBT_HDR_SIZE
;
929 cli_state_set_uid(state
->cli
, SVAL(inhdr
, HDR_UID
));
931 status
= smb_bytes_talloc_string(cli
,
937 if (!NT_STATUS_IS_OK(status
)) {
938 tevent_req_nterror(req
, status
);
943 status
= smb_bytes_talloc_string(cli
,
949 if (!NT_STATUS_IS_OK(status
)) {
950 tevent_req_nterror(req
, status
);
955 status
= smb_bytes_talloc_string(cli
,
961 if (!NT_STATUS_IS_OK(status
)) {
962 tevent_req_nterror(req
, status
);
967 status
= cli_set_username(cli
, state
->user
);
968 if (tevent_req_nterror(req
, status
)) {
971 if (smb1cli_conn_activate_signing(cli
->conn
, state
->session_key
, state
->response
)
972 && !smb1cli_conn_check_signing(cli
->conn
, (uint8_t *)in
, 1)) {
973 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
976 if (state
->session_key
.data
) {
977 struct smbXcli_session
*session
= state
->cli
->smb1
.session
;
979 status
= smb1cli_session_set_session_key(session
,
981 if (tevent_req_nterror(req
, status
)) {
985 tevent_req_done(req
);
988 static NTSTATUS
cli_session_setup_nt1_recv(struct tevent_req
*req
)
990 return tevent_req_simple_recv_ntstatus(req
);
993 /* The following is calculated from :
995 * (smb_wcnt * 2) = 24 (smb_wcnt == 12 in cli_session_setup_blob_send() )
996 * (strlen("Unix") + 1 + strlen("Samba") + 1) * 2 = 22 (unicode strings at
1000 #define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22)
1002 struct cli_sesssetup_blob_state
{
1003 struct tevent_context
*ev
;
1004 struct cli_state
*cli
;
1006 uint16_t max_blob_size
;
1010 DATA_BLOB smb2_blob
;
1011 struct iovec
*recv_iov
;
1018 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state
*state
,
1019 struct tevent_req
**psubreq
);
1020 static void cli_sesssetup_blob_done(struct tevent_req
*subreq
);
1022 static struct tevent_req
*cli_sesssetup_blob_send(TALLOC_CTX
*mem_ctx
,
1023 struct tevent_context
*ev
,
1024 struct cli_state
*cli
,
1027 struct tevent_req
*req
, *subreq
;
1028 struct cli_sesssetup_blob_state
*state
;
1029 uint32_t usable_space
;
1031 req
= tevent_req_create(mem_ctx
, &state
,
1032 struct cli_sesssetup_blob_state
);
1040 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
1041 usable_space
= UINT16_MAX
;
1043 usable_space
= cli_state_available_size(cli
,
1044 BASE_SESSSETUP_BLOB_PACKET_SIZE
);
1047 if (usable_space
== 0) {
1048 DEBUG(1, ("cli_session_setup_blob: cli->max_xmit too small "
1049 "(not possible to send %u bytes)\n",
1050 BASE_SESSSETUP_BLOB_PACKET_SIZE
+ 1));
1051 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1052 return tevent_req_post(req
, ev
);
1054 state
->max_blob_size
= MIN(usable_space
, 0xFFFF);
1056 if (!cli_sesssetup_blob_next(state
, &subreq
)) {
1057 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
1058 return tevent_req_post(req
, ev
);
1060 tevent_req_set_callback(subreq
, cli_sesssetup_blob_done
, req
);
1064 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state
*state
,
1065 struct tevent_req
**psubreq
)
1067 struct tevent_req
*subreq
;
1070 thistime
= MIN(state
->blob
.length
, state
->max_blob_size
);
1072 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
1074 state
->smb2_blob
.data
= state
->blob
.data
;
1075 state
->smb2_blob
.length
= thistime
;
1077 state
->blob
.data
+= thistime
;
1078 state
->blob
.length
-= thistime
;
1080 subreq
= smb2cli_session_setup_send(state
, state
->ev
,
1082 state
->cli
->timeout
,
1083 state
->cli
->smb2
.session
,
1085 SMB2_CAP_DFS
, /* in_capabilities */
1087 0, /* in_previous_session_id */
1089 if (subreq
== NULL
) {
1096 SCVAL(state
->vwv
+0, 0, 0xFF);
1097 SCVAL(state
->vwv
+0, 1, 0);
1098 SSVAL(state
->vwv
+1, 0, 0);
1099 SSVAL(state
->vwv
+2, 0, CLI_BUFFER_SIZE
);
1100 SSVAL(state
->vwv
+3, 0, 2);
1101 SSVAL(state
->vwv
+4, 0, 1);
1102 SIVAL(state
->vwv
+5, 0, 0);
1104 SSVAL(state
->vwv
+7, 0, thistime
);
1106 SSVAL(state
->vwv
+8, 0, 0);
1107 SSVAL(state
->vwv
+9, 0, 0);
1108 SIVAL(state
->vwv
+10, 0,
1109 cli_session_setup_capabilities(state
->cli
, CAP_EXTENDED_SECURITY
));
1111 state
->buf
= (uint8_t *)talloc_memdup(state
, state
->blob
.data
,
1113 if (state
->buf
== NULL
) {
1116 state
->blob
.data
+= thistime
;
1117 state
->blob
.length
-= thistime
;
1119 state
->buf
= smb_bytes_push_str(state
->buf
, smbXcli_conn_use_unicode(state
->cli
->conn
),
1121 state
->buf
= smb_bytes_push_str(state
->buf
, smbXcli_conn_use_unicode(state
->cli
->conn
),
1123 if (state
->buf
== NULL
) {
1126 subreq
= cli_smb_send(state
, state
->ev
, state
->cli
, SMBsesssetupX
, 0,
1128 talloc_get_size(state
->buf
), state
->buf
);
1129 if (subreq
== NULL
) {
1136 static void cli_sesssetup_blob_done(struct tevent_req
*subreq
)
1138 struct tevent_req
*req
= tevent_req_callback_data(
1139 subreq
, struct tevent_req
);
1140 struct cli_sesssetup_blob_state
*state
= tevent_req_data(
1141 req
, struct cli_sesssetup_blob_state
);
1142 struct cli_state
*cli
= state
->cli
;
1149 uint16_t blob_length
;
1154 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
1155 status
= smb2cli_session_setup_recv(subreq
, state
,
1159 status
= cli_smb_recv(subreq
, state
, &in
, 4, &wct
, &vwv
,
1160 &num_bytes
, &bytes
);
1161 TALLOC_FREE(state
->buf
);
1163 TALLOC_FREE(subreq
);
1164 if (!NT_STATUS_IS_OK(status
)
1165 && !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1166 tevent_req_nterror(req
, status
);
1170 state
->status
= status
;
1172 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
1177 inhdr
= in
+ NBT_HDR_SIZE
;
1178 cli_state_set_uid(state
->cli
, SVAL(inhdr
, HDR_UID
));
1180 blob_length
= SVAL(vwv
+3, 0);
1181 if (blob_length
> num_bytes
) {
1182 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
1185 state
->ret_blob
= data_blob_const(bytes
, blob_length
);
1187 p
= bytes
+ blob_length
;
1189 status
= smb_bytes_talloc_string(cli
,
1196 if (!NT_STATUS_IS_OK(status
)) {
1197 tevent_req_nterror(req
, status
);
1202 status
= smb_bytes_talloc_string(cli
,
1209 if (!NT_STATUS_IS_OK(status
)) {
1210 tevent_req_nterror(req
, status
);
1215 status
= smb_bytes_talloc_string(cli
,
1217 &cli
->server_domain
,
1222 if (!NT_STATUS_IS_OK(status
)) {
1223 tevent_req_nterror(req
, status
);
1229 if (state
->blob
.length
!= 0) {
1233 if (!cli_sesssetup_blob_next(state
, &subreq
)) {
1234 tevent_req_oom(req
);
1237 tevent_req_set_callback(subreq
, cli_sesssetup_blob_done
, req
);
1240 tevent_req_done(req
);
1243 static NTSTATUS
cli_sesssetup_blob_recv(struct tevent_req
*req
,
1244 TALLOC_CTX
*mem_ctx
,
1247 struct iovec
**precv_iov
)
1249 struct cli_sesssetup_blob_state
*state
= tevent_req_data(
1250 req
, struct cli_sesssetup_blob_state
);
1253 struct iovec
*recv_iov
;
1255 if (tevent_req_is_nterror(req
, &status
)) {
1256 TALLOC_FREE(state
->cli
->smb2
.session
);
1257 cli_state_set_uid(state
->cli
, UID_FIELD_INVALID
);
1261 inbuf
= talloc_move(mem_ctx
, &state
->inbuf
);
1262 recv_iov
= talloc_move(mem_ctx
, &state
->recv_iov
);
1263 if (pblob
!= NULL
) {
1264 *pblob
= state
->ret_blob
;
1266 if (pinbuf
!= NULL
) {
1269 if (precv_iov
!= NULL
) {
1270 *precv_iov
= recv_iov
;
1272 /* could be NT_STATUS_MORE_PROCESSING_REQUIRED */
1273 return state
->status
;
1278 /****************************************************************************
1279 Use in-memory credentials cache
1280 ****************************************************************************/
1282 static void use_in_memory_ccache(void) {
1283 setenv(KRB5_ENV_CCNAME
, "MEMORY:cliconnect", 1);
1286 /****************************************************************************
1287 Do a spnego/kerberos encrypted session setup.
1288 ****************************************************************************/
1290 struct cli_session_setup_kerberos_state
{
1291 struct cli_state
*cli
;
1292 DATA_BLOB negTokenTarg
;
1293 DATA_BLOB session_key_krb5
;
1294 ADS_STATUS ads_status
;
1297 static void cli_session_setup_kerberos_done(struct tevent_req
*subreq
);
1299 static struct tevent_req
*cli_session_setup_kerberos_send(
1300 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
1301 const char *principal
)
1303 struct tevent_req
*req
, *subreq
;
1304 struct cli_session_setup_kerberos_state
*state
;
1307 DEBUG(2,("Doing kerberos session setup\n"));
1309 req
= tevent_req_create(mem_ctx
, &state
,
1310 struct cli_session_setup_kerberos_state
);
1315 state
->ads_status
= ADS_SUCCESS
;
1318 * Ok, this is cheating: spnego_gen_krb5_negTokenInit can block if
1319 * we have to acquire a ticket. To be fixed later :-)
1321 rc
= spnego_gen_krb5_negTokenInit(state
, principal
, 0, &state
->negTokenTarg
,
1322 &state
->session_key_krb5
, 0, NULL
, NULL
);
1324 DEBUG(1, ("cli_session_setup_kerberos: "
1325 "spnego_gen_krb5_negTokenInit failed: %s\n",
1326 error_message(rc
)));
1327 state
->ads_status
= ADS_ERROR_KRB5(rc
);
1328 tevent_req_nterror(req
, NT_STATUS_UNSUCCESSFUL
);
1329 return tevent_req_post(req
, ev
);
1333 file_save("negTokenTarg.dat", state
->negTokenTarg
.data
,
1334 state
->negTokenTarg
.length
);
1337 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
1338 state
->cli
->smb2
.session
= smbXcli_session_create(cli
,
1340 if (tevent_req_nomem(state
->cli
->smb2
.session
, req
)) {
1341 return tevent_req_post(req
, ev
);
1345 subreq
= cli_sesssetup_blob_send(state
, ev
, cli
, state
->negTokenTarg
);
1346 if (tevent_req_nomem(subreq
, req
)) {
1347 return tevent_req_post(req
, ev
);
1349 tevent_req_set_callback(subreq
, cli_session_setup_kerberos_done
, req
);
1353 static void cli_session_setup_kerberos_done(struct tevent_req
*subreq
)
1355 struct tevent_req
*req
= tevent_req_callback_data(
1356 subreq
, struct tevent_req
);
1357 struct cli_session_setup_kerberos_state
*state
= tevent_req_data(
1358 req
, struct cli_session_setup_kerberos_state
);
1359 uint8_t *inbuf
= NULL
;
1360 struct iovec
*recv_iov
= NULL
;
1363 status
= cli_sesssetup_blob_recv(subreq
, state
,
1364 NULL
, &inbuf
, &recv_iov
);
1365 TALLOC_FREE(subreq
);
1366 if (!NT_STATUS_IS_OK(status
)) {
1367 tevent_req_nterror(req
, status
);
1371 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
1372 struct smbXcli_session
*session
= state
->cli
->smb2
.session
;
1373 status
= smb2cli_session_set_session_key(session
,
1374 state
->session_key_krb5
,
1376 if (tevent_req_nterror(req
, status
)) {
1380 struct smbXcli_session
*session
= state
->cli
->smb1
.session
;
1382 status
= smb1cli_session_set_session_key(session
,
1383 state
->session_key_krb5
);
1384 if (tevent_req_nterror(req
, status
)) {
1388 if (smb1cli_conn_activate_signing(state
->cli
->conn
, state
->session_key_krb5
,
1390 && !smb1cli_conn_check_signing(state
->cli
->conn
, inbuf
, 1)) {
1391 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1396 tevent_req_done(req
);
1399 static ADS_STATUS
cli_session_setup_kerberos_recv(struct tevent_req
*req
)
1401 struct cli_session_setup_kerberos_state
*state
= tevent_req_data(
1402 req
, struct cli_session_setup_kerberos_state
);
1405 if (tevent_req_is_nterror(req
, &status
)) {
1406 return ADS_ERROR_NT(status
);
1408 return state
->ads_status
;
1411 #endif /* HAVE_KRB5 */
1413 /****************************************************************************
1414 Do a spnego/NTLMSSP encrypted session setup.
1415 ****************************************************************************/
1417 struct cli_session_setup_ntlmssp_state
{
1418 struct tevent_context
*ev
;
1419 struct cli_state
*cli
;
1420 struct ntlmssp_state
*ntlmssp_state
;
1425 static int cli_session_setup_ntlmssp_state_destructor(
1426 struct cli_session_setup_ntlmssp_state
*state
)
1428 if (state
->ntlmssp_state
!= NULL
) {
1429 TALLOC_FREE(state
->ntlmssp_state
);
1434 static void cli_session_setup_ntlmssp_done(struct tevent_req
*req
);
1436 static struct tevent_req
*cli_session_setup_ntlmssp_send(
1437 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
1438 const char *user
, const char *pass
, const char *domain
)
1440 struct tevent_req
*req
, *subreq
;
1441 struct cli_session_setup_ntlmssp_state
*state
;
1444 const char *OIDs_ntlm
[] = {OID_NTLMSSP
, NULL
};
1446 req
= tevent_req_create(mem_ctx
, &state
,
1447 struct cli_session_setup_ntlmssp_state
);
1455 state
->ntlmssp_state
= NULL
;
1456 talloc_set_destructor(
1457 state
, cli_session_setup_ntlmssp_state_destructor
);
1459 status
= ntlmssp_client_start(state
,
1462 lp_client_ntlmv2_auth(),
1463 &state
->ntlmssp_state
);
1464 if (!NT_STATUS_IS_OK(status
)) {
1467 ntlmssp_want_feature(state
->ntlmssp_state
,
1468 NTLMSSP_FEATURE_SESSION_KEY
);
1469 if (cli
->use_ccache
) {
1470 ntlmssp_want_feature(state
->ntlmssp_state
,
1471 NTLMSSP_FEATURE_CCACHE
);
1473 status
= ntlmssp_set_username(state
->ntlmssp_state
, user
);
1474 if (!NT_STATUS_IS_OK(status
)) {
1477 status
= ntlmssp_set_domain(state
->ntlmssp_state
, domain
);
1478 if (!NT_STATUS_IS_OK(status
)) {
1481 if (cli
->pw_nt_hash
) {
1482 status
= ntlmssp_set_password_hash(state
->ntlmssp_state
, pass
);
1484 status
= ntlmssp_set_password(state
->ntlmssp_state
, pass
);
1486 if (!NT_STATUS_IS_OK(status
)) {
1489 status
= ntlmssp_update(state
->ntlmssp_state
, data_blob_null
,
1491 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1495 state
->blob_out
= spnego_gen_negTokenInit(state
, OIDs_ntlm
, &blob_out
, NULL
);
1496 data_blob_free(&blob_out
);
1498 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
1499 state
->cli
->smb2
.session
= smbXcli_session_create(cli
,
1501 if (tevent_req_nomem(state
->cli
->smb2
.session
, req
)) {
1502 return tevent_req_post(req
, ev
);
1506 subreq
= cli_sesssetup_blob_send(state
, ev
, cli
, state
->blob_out
);
1507 if (tevent_req_nomem(subreq
, req
)) {
1508 return tevent_req_post(req
, ev
);
1510 tevent_req_set_callback(subreq
, cli_session_setup_ntlmssp_done
, req
);
1513 tevent_req_nterror(req
, status
);
1514 return tevent_req_post(req
, ev
);
1517 static void cli_session_setup_ntlmssp_done(struct tevent_req
*subreq
)
1519 struct tevent_req
*req
= tevent_req_callback_data(
1520 subreq
, struct tevent_req
);
1521 struct cli_session_setup_ntlmssp_state
*state
= tevent_req_data(
1522 req
, struct cli_session_setup_ntlmssp_state
);
1523 DATA_BLOB blob_in
, msg_in
, blob_out
;
1524 uint8_t *inbuf
= NULL
;
1525 struct iovec
*recv_iov
= NULL
;
1529 status
= cli_sesssetup_blob_recv(subreq
, talloc_tos(), &blob_in
,
1531 TALLOC_FREE(subreq
);
1532 data_blob_free(&state
->blob_out
);
1534 if (NT_STATUS_IS_OK(status
)) {
1535 if (state
->cli
->server_domain
[0] == '\0') {
1536 TALLOC_FREE(state
->cli
->server_domain
);
1537 state
->cli
->server_domain
= talloc_strdup(state
->cli
,
1538 state
->ntlmssp_state
->server
.netbios_domain
);
1539 if (state
->cli
->server_domain
== NULL
) {
1540 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
1545 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
1546 struct smbXcli_session
*session
= state
->cli
->smb2
.session
;
1548 if (ntlmssp_is_anonymous(state
->ntlmssp_state
)) {
1550 * Windows server does not set the
1551 * SMB2_SESSION_FLAG_IS_GUEST nor
1552 * SMB2_SESSION_FLAG_IS_NULL flag.
1554 * This fix makes sure we do not try
1555 * to verify a signature on the final
1556 * session setup response.
1558 TALLOC_FREE(state
->ntlmssp_state
);
1559 tevent_req_done(req
);
1563 status
= smb2cli_session_set_session_key(session
,
1564 state
->ntlmssp_state
->session_key
,
1566 if (tevent_req_nterror(req
, status
)) {
1570 struct smbXcli_session
*session
= state
->cli
->smb1
.session
;
1572 status
= smb1cli_session_set_session_key(session
,
1573 state
->ntlmssp_state
->session_key
);
1574 if (tevent_req_nterror(req
, status
)) {
1578 if (smb1cli_conn_activate_signing(
1579 state
->cli
->conn
, state
->ntlmssp_state
->session_key
,
1581 && !smb1cli_conn_check_signing(state
->cli
->conn
, inbuf
, 1)) {
1582 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1586 TALLOC_FREE(state
->ntlmssp_state
);
1587 tevent_req_done(req
);
1590 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1591 tevent_req_nterror(req
, status
);
1595 if (blob_in
.length
== 0) {
1596 tevent_req_nterror(req
, NT_STATUS_UNSUCCESSFUL
);
1600 if ((state
->turn
== 1)
1601 && NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1602 DATA_BLOB tmp_blob
= data_blob_null
;
1603 /* the server might give us back two challenges */
1604 parse_ret
= spnego_parse_challenge(state
, blob_in
, &msg_in
,
1606 data_blob_free(&tmp_blob
);
1608 parse_ret
= spnego_parse_auth_response(state
, blob_in
, status
,
1609 OID_NTLMSSP
, &msg_in
);
1614 DEBUG(3,("Failed to parse auth response\n"));
1615 if (NT_STATUS_IS_OK(status
)
1616 || NT_STATUS_EQUAL(status
,
1617 NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1619 req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
1624 status
= ntlmssp_update(state
->ntlmssp_state
, msg_in
, &blob_out
);
1626 if (!NT_STATUS_IS_OK(status
)
1627 && !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1628 TALLOC_FREE(state
->ntlmssp_state
);
1629 tevent_req_nterror(req
, status
);
1633 state
->blob_out
= spnego_gen_auth(state
, blob_out
);
1634 if (tevent_req_nomem(state
->blob_out
.data
, req
)) {
1638 subreq
= cli_sesssetup_blob_send(state
, state
->ev
, state
->cli
,
1640 if (tevent_req_nomem(subreq
, req
)) {
1643 tevent_req_set_callback(subreq
, cli_session_setup_ntlmssp_done
, req
);
1646 static NTSTATUS
cli_session_setup_ntlmssp_recv(struct tevent_req
*req
)
1648 struct cli_session_setup_ntlmssp_state
*state
= tevent_req_data(
1649 req
, struct cli_session_setup_ntlmssp_state
);
1652 if (tevent_req_is_nterror(req
, &status
)) {
1653 cli_state_set_uid(state
->cli
, UID_FIELD_INVALID
);
1656 return NT_STATUS_OK
;
1661 static char *cli_session_setup_get_principal(
1662 TALLOC_CTX
*mem_ctx
, const char *spnego_principal
,
1663 const char *remote_name
, const char *dest_realm
)
1665 char *principal
= NULL
;
1667 if (!lp_client_use_spnego_principal() ||
1668 strequal(principal
, ADS_IGNORE_PRINCIPAL
)) {
1669 spnego_principal
= NULL
;
1671 if (spnego_principal
!= NULL
) {
1672 DEBUG(3, ("cli_session_setup_spnego: using spnego provided "
1673 "principal %s\n", spnego_principal
));
1674 return talloc_strdup(mem_ctx
, spnego_principal
);
1676 if (is_ipaddress(remote_name
) ||
1677 strequal(remote_name
, STAR_SMBSERVER
)) {
1681 DEBUG(3, ("cli_session_setup_spnego: using target "
1682 "hostname not SPNEGO principal\n"));
1685 char *realm
= strupper_talloc(talloc_tos(), dest_realm
);
1686 if (realm
== NULL
) {
1689 principal
= talloc_asprintf(talloc_tos(), "cifs/%s@%s",
1690 remote_name
, realm
);
1693 principal
= kerberos_get_principal_from_service_hostname(
1694 talloc_tos(), "cifs", remote_name
, lp_realm());
1696 DEBUG(3, ("cli_session_setup_spnego: guessed server principal=%s\n",
1697 principal
? principal
: "<null>"));
1703 static char *cli_session_setup_get_account(TALLOC_CTX
*mem_ctx
,
1704 const char *principal
)
1708 account
= talloc_strdup(mem_ctx
, principal
);
1709 if (account
== NULL
) {
1712 p
= strchr_m(account
, '@');
1719 /****************************************************************************
1720 Do a spnego encrypted session setup.
1722 user_domain: The shortname of the domain the user/machine is a member of.
1723 dest_realm: The realm we're connecting to, if NULL we use our default realm.
1724 ****************************************************************************/
1726 struct cli_session_setup_spnego_state
{
1727 struct tevent_context
*ev
;
1728 struct cli_state
*cli
;
1730 const char *account
;
1732 const char *user_domain
;
1733 const char *dest_realm
;
1738 static void cli_session_setup_spnego_done_krb(struct tevent_req
*subreq
);
1741 static void cli_session_setup_spnego_done_ntlmssp(struct tevent_req
*subreq
);
1743 static struct tevent_req
*cli_session_setup_spnego_send(
1744 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
1745 const char *user
, const char *pass
, const char *user_domain
,
1746 const char *dest_realm
)
1748 struct tevent_req
*req
, *subreq
;
1749 struct cli_session_setup_spnego_state
*state
;
1750 char *principal
= NULL
;
1751 char *OIDs
[ASN1_MAX_OIDS
];
1753 const DATA_BLOB
*server_blob
;
1756 req
= tevent_req_create(mem_ctx
, &state
,
1757 struct cli_session_setup_spnego_state
);
1765 state
->user_domain
= user_domain
;
1766 state
->dest_realm
= dest_realm
;
1768 state
->account
= cli_session_setup_get_account(state
, user
);
1769 if (tevent_req_nomem(state
->account
, req
)) {
1770 return tevent_req_post(req
, ev
);
1773 server_blob
= smbXcli_conn_server_gss_blob(cli
->conn
);
1775 DEBUG(3,("Doing spnego session setup (blob length=%lu)\n",
1776 (unsigned long)server_blob
->length
));
1778 /* the server might not even do spnego */
1779 if (server_blob
->length
== 0) {
1780 DEBUG(3,("server didn't supply a full spnego negprot\n"));
1785 file_save("negprot.dat", cli
->secblob
.data
, cli
->secblob
.length
);
1788 /* The server sent us the first part of the SPNEGO exchange in the
1789 * negprot reply. It is WRONG to depend on the principal sent in the
1790 * negprot reply, but right now we do it. If we don't receive one,
1791 * we try to best guess, then fall back to NTLM. */
1792 if (!spnego_parse_negTokenInit(state
, *server_blob
, OIDs
,
1793 &principal
, NULL
) ||
1795 state
->result
= ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
1796 tevent_req_done(req
);
1797 return tevent_req_post(req
, ev
);
1800 /* make sure the server understands kerberos */
1801 for (i
=0;OIDs
[i
];i
++) {
1803 DEBUG(3,("got OID=%s\n", OIDs
[i
]));
1805 DEBUGADD(3,("got OID=%s\n", OIDs
[i
]));
1806 if (strcmp(OIDs
[i
], OID_KERBEROS5_OLD
) == 0 ||
1807 strcmp(OIDs
[i
], OID_KERBEROS5
) == 0) {
1808 cli
->got_kerberos_mechanism
= True
;
1810 talloc_free(OIDs
[i
]);
1813 DEBUG(3,("got principal=%s\n", principal
? principal
: "<null>"));
1815 status
= cli_set_username(cli
, user
);
1816 if (!NT_STATUS_IS_OK(status
)) {
1817 state
->result
= ADS_ERROR_NT(status
);
1818 tevent_req_done(req
);
1819 return tevent_req_post(req
, ev
);
1823 /* If password is set we reauthenticate to kerberos server
1824 * and do not store results */
1826 if (user
&& *user
&& cli
->got_kerberos_mechanism
&& cli
->use_kerberos
) {
1827 const char *remote_name
= smbXcli_conn_remote_name(cli
->conn
);
1830 if (pass
&& *pass
) {
1833 use_in_memory_ccache();
1834 ret
= kerberos_kinit_password(user
, pass
, 0 /* no time correction for now */, NULL
);
1837 TALLOC_FREE(principal
);
1838 DEBUG(0, ("Kinit failed: %s\n", error_message(ret
)));
1839 if (cli
->fallback_after_kerberos
)
1841 state
->result
= ADS_ERROR_KRB5(ret
);
1842 tevent_req_done(req
);
1843 return tevent_req_post(req
, ev
);
1847 tmp
= cli_session_setup_get_principal(
1848 talloc_tos(), principal
, remote_name
, dest_realm
);
1849 TALLOC_FREE(principal
);
1853 subreq
= cli_session_setup_kerberos_send(
1854 state
, ev
, cli
, principal
);
1855 if (tevent_req_nomem(subreq
, req
)) {
1856 return tevent_req_post(req
, ev
);
1858 tevent_req_set_callback(
1859 subreq
, cli_session_setup_spnego_done_krb
,
1867 subreq
= cli_session_setup_ntlmssp_send(
1868 state
, ev
, cli
, state
->account
, pass
, user_domain
);
1869 if (tevent_req_nomem(subreq
, req
)) {
1870 return tevent_req_post(req
, ev
);
1872 tevent_req_set_callback(
1873 subreq
, cli_session_setup_spnego_done_ntlmssp
, req
);
1878 static void cli_session_setup_spnego_done_krb(struct tevent_req
*subreq
)
1880 struct tevent_req
*req
= tevent_req_callback_data(
1881 subreq
, struct tevent_req
);
1882 struct cli_session_setup_spnego_state
*state
= tevent_req_data(
1883 req
, struct cli_session_setup_spnego_state
);
1885 state
->result
= cli_session_setup_kerberos_recv(subreq
);
1886 TALLOC_FREE(subreq
);
1888 if (ADS_ERR_OK(state
->result
) ||
1889 !state
->cli
->fallback_after_kerberos
) {
1890 tevent_req_done(req
);
1894 subreq
= cli_session_setup_ntlmssp_send(
1895 state
, state
->ev
, state
->cli
, state
->account
, state
->pass
,
1896 state
->user_domain
);
1897 if (tevent_req_nomem(subreq
, req
)) {
1900 tevent_req_set_callback(subreq
, cli_session_setup_spnego_done_ntlmssp
,
1905 static void cli_session_setup_spnego_done_ntlmssp(struct tevent_req
*subreq
)
1907 struct tevent_req
*req
= tevent_req_callback_data(
1908 subreq
, struct tevent_req
);
1909 struct cli_session_setup_spnego_state
*state
= tevent_req_data(
1910 req
, struct cli_session_setup_spnego_state
);
1913 status
= cli_session_setup_ntlmssp_recv(subreq
);
1914 TALLOC_FREE(subreq
);
1915 state
->result
= ADS_ERROR_NT(status
);
1916 tevent_req_done(req
);
1919 static ADS_STATUS
cli_session_setup_spnego_recv(struct tevent_req
*req
)
1921 struct cli_session_setup_spnego_state
*state
= tevent_req_data(
1922 req
, struct cli_session_setup_spnego_state
);
1924 return state
->result
;
1927 struct cli_session_setup_state
{
1931 static void cli_session_setup_done_lanman2(struct tevent_req
*subreq
);
1932 static void cli_session_setup_done_spnego(struct tevent_req
*subreq
);
1933 static void cli_session_setup_done_guest(struct tevent_req
*subreq
);
1934 static void cli_session_setup_done_plain(struct tevent_req
*subreq
);
1935 static void cli_session_setup_done_nt1(struct tevent_req
*subreq
);
1937 /****************************************************************************
1938 Send a session setup. The username and workgroup is in UNIX character
1939 format and must be converted to DOS codepage format before sending. If the
1940 password is in plaintext, the same should be done.
1941 ****************************************************************************/
1943 struct tevent_req
*cli_session_setup_send(TALLOC_CTX
*mem_ctx
,
1944 struct tevent_context
*ev
,
1945 struct cli_state
*cli
,
1947 const char *pass
, int passlen
,
1948 const char *ntpass
, int ntpasslen
,
1949 const char *workgroup
)
1951 struct tevent_req
*req
, *subreq
;
1952 struct cli_session_setup_state
*state
;
1955 uint16_t sec_mode
= smb1cli_conn_server_security_mode(cli
->conn
);
1957 req
= tevent_req_create(mem_ctx
, &state
,
1958 struct cli_session_setup_state
);
1964 user2
= talloc_strdup(state
, user
);
1966 user2
= talloc_strdup(state
, "");
1968 if (user2
== NULL
) {
1969 tevent_req_oom(req
);
1970 return tevent_req_post(req
, ev
);
1977 /* allow for workgroups as part of the username */
1978 if ((p
=strchr_m(user2
,'\\')) || (p
=strchr_m(user2
,'/')) ||
1979 (p
=strchr_m(user2
,*lp_winbind_separator()))) {
1982 if (!strupper_m(user2
)) {
1983 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1984 return tevent_req_post(req
, ev
);
1989 if (smbXcli_conn_protocol(cli
->conn
) < PROTOCOL_LANMAN1
) {
1990 tevent_req_done(req
);
1991 return tevent_req_post(req
, ev
);
1994 /* now work out what sort of session setup we are going to
1995 do. I have split this into separate functions to make the
1996 flow a bit easier to understand (tridge) */
1998 /* if its an older server then we have to use the older request format */
2000 if (smbXcli_conn_protocol(cli
->conn
) < PROTOCOL_NT1
) {
2001 if (!lp_client_lanman_auth() && passlen
!= 24 && (*pass
)) {
2002 DEBUG(1, ("Server requested LM password but 'client lanman auth = no'"
2003 " or 'client ntlmv2 auth = yes'\n"));
2004 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
2005 return tevent_req_post(req
, ev
);
2008 if ((sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
) == 0 &&
2009 !lp_client_plaintext_auth() && (*pass
)) {
2010 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
2011 " or 'client ntlmv2 auth = yes'\n"));
2012 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
2013 return tevent_req_post(req
, ev
);
2016 subreq
= cli_session_setup_lanman2_send(
2017 state
, ev
, cli
, user
, pass
, passlen
, workgroup
);
2018 if (tevent_req_nomem(subreq
, req
)) {
2019 return tevent_req_post(req
, ev
);
2021 tevent_req_set_callback(subreq
, cli_session_setup_done_lanman2
,
2026 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
2027 const char *remote_realm
= cli_state_remote_realm(cli
);
2029 subreq
= cli_session_setup_spnego_send(
2030 state
, ev
, cli
, user
, pass
, workgroup
, remote_realm
);
2031 if (tevent_req_nomem(subreq
, req
)) {
2032 return tevent_req_post(req
, ev
);
2034 tevent_req_set_callback(subreq
, cli_session_setup_done_spnego
,
2039 /* if no user is supplied then we have to do an anonymous connection.
2040 passwords are ignored */
2042 if (!user
|| !*user
) {
2043 subreq
= cli_session_setup_guest_send(state
, ev
, cli
);
2044 if (tevent_req_nomem(subreq
, req
)) {
2045 return tevent_req_post(req
, ev
);
2047 tevent_req_set_callback(subreq
, cli_session_setup_done_guest
,
2052 /* if the server is share level then send a plaintext null
2053 password at this point. The password is sent in the tree
2056 if ((sec_mode
& NEGOTIATE_SECURITY_USER_LEVEL
) == 0) {
2057 subreq
= cli_session_setup_plain_send(
2058 state
, ev
, cli
, user
, "", workgroup
);
2059 if (tevent_req_nomem(subreq
, req
)) {
2060 return tevent_req_post(req
, ev
);
2062 tevent_req_set_callback(subreq
, cli_session_setup_done_plain
,
2067 /* if the server doesn't support encryption then we have to use
2068 plaintext. The second password is ignored */
2070 if ((sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
) == 0) {
2071 if (!lp_client_plaintext_auth() && (*pass
)) {
2072 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
2073 " or 'client ntlmv2 auth = yes'\n"));
2074 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
2075 return tevent_req_post(req
, ev
);
2077 subreq
= cli_session_setup_plain_send(
2078 state
, ev
, cli
, user
, pass
, workgroup
);
2079 if (tevent_req_nomem(subreq
, req
)) {
2080 return tevent_req_post(req
, ev
);
2082 tevent_req_set_callback(subreq
, cli_session_setup_done_plain
,
2087 /* if the server supports extended security then use SPNEGO */
2089 if (smb1cli_conn_capabilities(cli
->conn
) & CAP_EXTENDED_SECURITY
) {
2090 const char *remote_realm
= cli_state_remote_realm(cli
);
2092 subreq
= cli_session_setup_spnego_send(
2093 state
, ev
, cli
, user
, pass
, workgroup
, remote_realm
);
2094 if (tevent_req_nomem(subreq
, req
)) {
2095 return tevent_req_post(req
, ev
);
2097 tevent_req_set_callback(subreq
, cli_session_setup_done_spnego
,
2101 /* otherwise do a NT1 style session setup */
2103 subreq
= cli_session_setup_nt1_send(
2104 state
, ev
, cli
, user
, pass
, passlen
, ntpass
, ntpasslen
,
2106 if (tevent_req_nomem(subreq
, req
)) {
2107 return tevent_req_post(req
, ev
);
2109 tevent_req_set_callback(subreq
, cli_session_setup_done_nt1
,
2114 tevent_req_done(req
);
2115 return tevent_req_post(req
, ev
);
2118 static void cli_session_setup_done_lanman2(struct tevent_req
*subreq
)
2120 struct tevent_req
*req
= tevent_req_callback_data(
2121 subreq
, struct tevent_req
);
2124 status
= cli_session_setup_lanman2_recv(subreq
);
2125 TALLOC_FREE(subreq
);
2126 if (!NT_STATUS_IS_OK(status
)) {
2127 tevent_req_nterror(req
, status
);
2130 tevent_req_done(req
);
2133 static void cli_session_setup_done_spnego(struct tevent_req
*subreq
)
2135 struct tevent_req
*req
= tevent_req_callback_data(
2136 subreq
, struct tevent_req
);
2139 status
= cli_session_setup_spnego_recv(subreq
);
2140 TALLOC_FREE(subreq
);
2141 if (!ADS_ERR_OK(status
)) {
2142 DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status
)));
2143 tevent_req_nterror(req
, ads_ntstatus(status
));
2146 tevent_req_done(req
);
2149 static void cli_session_setup_done_guest(struct tevent_req
*subreq
)
2151 struct tevent_req
*req
= tevent_req_callback_data(
2152 subreq
, struct tevent_req
);
2155 status
= cli_session_setup_guest_recv(subreq
);
2156 TALLOC_FREE(subreq
);
2157 if (!NT_STATUS_IS_OK(status
)) {
2158 tevent_req_nterror(req
, status
);
2161 tevent_req_done(req
);
2164 static void cli_session_setup_done_plain(struct tevent_req
*subreq
)
2166 struct tevent_req
*req
= tevent_req_callback_data(
2167 subreq
, struct tevent_req
);
2170 status
= cli_session_setup_plain_recv(subreq
);
2171 TALLOC_FREE(subreq
);
2172 if (!NT_STATUS_IS_OK(status
)) {
2173 tevent_req_nterror(req
, status
);
2176 tevent_req_done(req
);
2179 static void cli_session_setup_done_nt1(struct tevent_req
*subreq
)
2181 struct tevent_req
*req
= tevent_req_callback_data(
2182 subreq
, struct tevent_req
);
2185 status
= cli_session_setup_nt1_recv(subreq
);
2186 TALLOC_FREE(subreq
);
2187 if (!NT_STATUS_IS_OK(status
)) {
2188 DEBUG(3, ("cli_session_setup: NT1 session setup "
2189 "failed: %s\n", nt_errstr(status
)));
2190 tevent_req_nterror(req
, status
);
2193 tevent_req_done(req
);
2196 NTSTATUS
cli_session_setup_recv(struct tevent_req
*req
)
2198 return tevent_req_simple_recv_ntstatus(req
);
2201 NTSTATUS
cli_session_setup(struct cli_state
*cli
,
2203 const char *pass
, int passlen
,
2204 const char *ntpass
, int ntpasslen
,
2205 const char *workgroup
)
2207 struct tevent_context
*ev
;
2208 struct tevent_req
*req
;
2209 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2211 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
2212 return NT_STATUS_INVALID_PARAMETER
;
2214 ev
= samba_tevent_context_init(talloc_tos());
2218 req
= cli_session_setup_send(ev
, ev
, cli
, user
, pass
, passlen
,
2219 ntpass
, ntpasslen
, workgroup
);
2223 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2226 status
= cli_session_setup_recv(req
);
2232 /****************************************************************************
2234 *****************************************************************************/
2236 struct cli_ulogoff_state
{
2237 struct cli_state
*cli
;
2241 static void cli_ulogoff_done(struct tevent_req
*subreq
);
2243 static struct tevent_req
*cli_ulogoff_send(TALLOC_CTX
*mem_ctx
,
2244 struct tevent_context
*ev
,
2245 struct cli_state
*cli
)
2247 struct tevent_req
*req
, *subreq
;
2248 struct cli_ulogoff_state
*state
;
2250 req
= tevent_req_create(mem_ctx
, &state
, struct cli_ulogoff_state
);
2256 SCVAL(state
->vwv
+0, 0, 0xFF);
2257 SCVAL(state
->vwv
+1, 0, 0);
2258 SSVAL(state
->vwv
+2, 0, 0);
2260 subreq
= cli_smb_send(state
, ev
, cli
, SMBulogoffX
, 0, 2, state
->vwv
,
2262 if (tevent_req_nomem(subreq
, req
)) {
2263 return tevent_req_post(req
, ev
);
2265 tevent_req_set_callback(subreq
, cli_ulogoff_done
, req
);
2269 static void cli_ulogoff_done(struct tevent_req
*subreq
)
2271 struct tevent_req
*req
= tevent_req_callback_data(
2272 subreq
, struct tevent_req
);
2273 struct cli_ulogoff_state
*state
= tevent_req_data(
2274 req
, struct cli_ulogoff_state
);
2277 status
= cli_smb_recv(subreq
, NULL
, NULL
, 0, NULL
, NULL
, NULL
, NULL
);
2278 if (!NT_STATUS_IS_OK(status
)) {
2279 tevent_req_nterror(req
, status
);
2282 cli_state_set_uid(state
->cli
, UID_FIELD_INVALID
);
2283 tevent_req_done(req
);
2286 static NTSTATUS
cli_ulogoff_recv(struct tevent_req
*req
)
2288 return tevent_req_simple_recv_ntstatus(req
);
2291 NTSTATUS
cli_ulogoff(struct cli_state
*cli
)
2293 struct tevent_context
*ev
;
2294 struct tevent_req
*req
;
2295 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2297 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
2298 status
= smb2cli_logoff(cli
->conn
,
2301 if (!NT_STATUS_IS_OK(status
)) {
2304 smb2cli_session_set_id_and_flags(cli
->smb2
.session
,
2306 return NT_STATUS_OK
;
2309 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
2310 return NT_STATUS_INVALID_PARAMETER
;
2312 ev
= samba_tevent_context_init(talloc_tos());
2316 req
= cli_ulogoff_send(ev
, ev
, cli
);
2320 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2323 status
= cli_ulogoff_recv(req
);
2329 /****************************************************************************
2331 ****************************************************************************/
2333 struct cli_tcon_andx_state
{
2334 struct cli_state
*cli
;
2339 static void cli_tcon_andx_done(struct tevent_req
*subreq
);
2341 struct tevent_req
*cli_tcon_andx_create(TALLOC_CTX
*mem_ctx
,
2342 struct tevent_context
*ev
,
2343 struct cli_state
*cli
,
2344 const char *share
, const char *dev
,
2345 const char *pass
, int passlen
,
2346 struct tevent_req
**psmbreq
)
2348 struct tevent_req
*req
, *subreq
;
2349 struct cli_tcon_andx_state
*state
;
2354 uint16_t sec_mode
= smb1cli_conn_server_security_mode(cli
->conn
);
2355 uint16_t tcon_flags
= 0;
2359 req
= tevent_req_create(mem_ctx
, &state
, struct cli_tcon_andx_state
);
2366 cli
->share
= talloc_strdup(cli
, share
);
2371 /* in user level security don't send a password now */
2372 if (sec_mode
& NEGOTIATE_SECURITY_USER_LEVEL
) {
2375 } else if (pass
== NULL
) {
2376 DEBUG(1, ("Server not using user level security and no "
2377 "password supplied.\n"));
2381 if ((sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
) &&
2382 *pass
&& passlen
!= 24) {
2383 if (!lp_client_lanman_auth()) {
2384 DEBUG(1, ("Server requested LANMAN password "
2385 "(share-level security) but "
2386 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2391 * Non-encrypted passwords - convert to DOS codepage before
2394 SMBencrypt(pass
, smb1cli_conn_server_challenge(cli
->conn
), p24
);
2396 pass
= (const char *)p24
;
2398 if((sec_mode
& (NEGOTIATE_SECURITY_USER_LEVEL
2399 |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
))
2403 if (!lp_client_plaintext_auth() && (*pass
)) {
2404 DEBUG(1, ("Server requested PLAINTEXT "
2406 "'client plaintext auth = no' or 'client ntlmv2 auth = yes'\n"));
2411 * Non-encrypted passwords - convert to DOS codepage
2414 tmp_pass
= talloc_array(talloc_tos(), uint8
, 0);
2415 if (tevent_req_nomem(tmp_pass
, req
)) {
2416 return tevent_req_post(req
, ev
);
2418 tmp_pass
= trans2_bytes_push_str(tmp_pass
,
2419 false, /* always DOS */
2423 if (tevent_req_nomem(tmp_pass
, req
)) {
2424 return tevent_req_post(req
, ev
);
2426 pass
= (const char *)tmp_pass
;
2427 passlen
= talloc_get_size(tmp_pass
);
2431 tcon_flags
|= TCONX_FLAG_EXTENDED_RESPONSE
;
2432 tcon_flags
|= TCONX_FLAG_EXTENDED_SIGNATURES
;
2434 SCVAL(vwv
+0, 0, 0xFF);
2437 SSVAL(vwv
+2, 0, tcon_flags
);
2438 SSVAL(vwv
+3, 0, passlen
);
2440 if (passlen
&& pass
) {
2441 bytes
= (uint8_t *)talloc_memdup(state
, pass
, passlen
);
2443 bytes
= talloc_array(state
, uint8_t, 0);
2449 tmp
= talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
2450 smbXcli_conn_remote_name(cli
->conn
), share
);
2455 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), tmp
, strlen(tmp
)+1,
2460 * Add the devicetype
2462 tmp
= talloc_strdup_upper(talloc_tos(), dev
);
2467 bytes
= smb_bytes_push_str(bytes
, false, tmp
, strlen(tmp
)+1, NULL
);
2470 if (bytes
== NULL
) {
2475 state
->bytes
.iov_base
= (void *)bytes
;
2476 state
->bytes
.iov_len
= talloc_get_size(bytes
);
2478 subreq
= cli_smb_req_create(state
, ev
, cli
, SMBtconX
, 0, 4, vwv
,
2480 if (subreq
== NULL
) {
2484 tevent_req_set_callback(subreq
, cli_tcon_andx_done
, req
);
2489 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
2490 return tevent_req_post(req
, ev
);
2493 struct tevent_req
*cli_tcon_andx_send(TALLOC_CTX
*mem_ctx
,
2494 struct tevent_context
*ev
,
2495 struct cli_state
*cli
,
2496 const char *share
, const char *dev
,
2497 const char *pass
, int passlen
)
2499 struct tevent_req
*req
, *subreq
;
2502 req
= cli_tcon_andx_create(mem_ctx
, ev
, cli
, share
, dev
, pass
, passlen
,
2507 if (subreq
== NULL
) {
2510 status
= smb1cli_req_chain_submit(&subreq
, 1);
2511 if (!NT_STATUS_IS_OK(status
)) {
2512 tevent_req_nterror(req
, status
);
2513 return tevent_req_post(req
, ev
);
2518 static void cli_tcon_andx_done(struct tevent_req
*subreq
)
2520 struct tevent_req
*req
= tevent_req_callback_data(
2521 subreq
, struct tevent_req
);
2522 struct cli_tcon_andx_state
*state
= tevent_req_data(
2523 req
, struct cli_tcon_andx_state
);
2524 struct cli_state
*cli
= state
->cli
;
2532 uint16_t optional_support
= 0;
2534 status
= cli_smb_recv(subreq
, state
, &in
, 0, &wct
, &vwv
,
2535 &num_bytes
, &bytes
);
2536 TALLOC_FREE(subreq
);
2537 if (!NT_STATUS_IS_OK(status
)) {
2538 tevent_req_nterror(req
, status
);
2542 inhdr
= in
+ NBT_HDR_SIZE
;
2545 if (clistr_pull_talloc(cli
,
2546 (const char *)inhdr
,
2547 SVAL(inhdr
, HDR_FLG2
),
2551 STR_TERMINATE
|STR_ASCII
) == -1) {
2552 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
2556 cli
->dev
= talloc_strdup(cli
, "");
2557 if (cli
->dev
== NULL
) {
2558 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
2563 if ((smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_NT1
) && (num_bytes
== 3)) {
2564 /* almost certainly win95 - enable bug fixes */
2569 * Make sure that we have the optional support 16-bit field. WCT > 2.
2570 * Avoids issues when connecting to Win9x boxes sharing files
2573 if ((wct
> 2) && (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_LANMAN2
)) {
2574 optional_support
= SVAL(vwv
+2, 0);
2577 if (optional_support
& SMB_EXTENDED_SIGNATURES
) {
2578 smb1cli_session_protect_session_key(cli
->smb1
.session
);
2581 smb1cli_tcon_set_values(state
->cli
->smb1
.tcon
,
2582 SVAL(inhdr
, HDR_TID
),
2584 0, /* maximal_access */
2585 0, /* guest_maximal_access */
2587 NULL
); /* fs_type */
2589 tevent_req_done(req
);
2592 NTSTATUS
cli_tcon_andx_recv(struct tevent_req
*req
)
2594 return tevent_req_simple_recv_ntstatus(req
);
2597 NTSTATUS
cli_tcon_andx(struct cli_state
*cli
, const char *share
,
2598 const char *dev
, const char *pass
, int passlen
)
2600 TALLOC_CTX
*frame
= talloc_stackframe();
2601 struct tevent_context
*ev
;
2602 struct tevent_req
*req
;
2603 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2605 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
2607 * Can't use sync call while an async call is in flight
2609 status
= NT_STATUS_INVALID_PARAMETER
;
2613 ev
= samba_tevent_context_init(frame
);
2618 req
= cli_tcon_andx_send(frame
, ev
, cli
, share
, dev
, pass
, passlen
);
2623 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2627 status
= cli_tcon_andx_recv(req
);
2633 struct cli_tree_connect_state
{
2634 struct cli_state
*cli
;
2637 static struct tevent_req
*cli_raw_tcon_send(
2638 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
2639 const char *service
, const char *pass
, const char *dev
);
2640 static NTSTATUS
cli_raw_tcon_recv(struct tevent_req
*req
,
2641 uint16
*max_xmit
, uint16
*tid
);
2643 static void cli_tree_connect_smb2_done(struct tevent_req
*subreq
);
2644 static void cli_tree_connect_andx_done(struct tevent_req
*subreq
);
2645 static void cli_tree_connect_raw_done(struct tevent_req
*subreq
);
2647 static struct tevent_req
*cli_tree_connect_send(
2648 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
2649 const char *share
, const char *dev
, const char *pass
, int passlen
)
2651 struct tevent_req
*req
, *subreq
;
2652 struct cli_tree_connect_state
*state
;
2654 req
= tevent_req_create(mem_ctx
, &state
,
2655 struct cli_tree_connect_state
);
2661 cli
->share
= talloc_strdup(cli
, share
);
2662 if (tevent_req_nomem(cli
->share
, req
)) {
2663 return tevent_req_post(req
, ev
);
2666 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
2667 subreq
= smb2cli_tcon_send(state
, ev
, cli
, share
);
2668 if (tevent_req_nomem(subreq
, req
)) {
2669 return tevent_req_post(req
, ev
);
2671 tevent_req_set_callback(subreq
, cli_tree_connect_smb2_done
,
2676 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_LANMAN1
) {
2677 subreq
= cli_tcon_andx_send(state
, ev
, cli
, share
, dev
,
2679 if (tevent_req_nomem(subreq
, req
)) {
2680 return tevent_req_post(req
, ev
);
2682 tevent_req_set_callback(subreq
, cli_tree_connect_andx_done
,
2687 subreq
= cli_raw_tcon_send(state
, ev
, cli
, share
, pass
, dev
);
2688 if (tevent_req_nomem(subreq
, req
)) {
2689 return tevent_req_post(req
, ev
);
2691 tevent_req_set_callback(subreq
, cli_tree_connect_raw_done
, req
);
2696 static void cli_tree_connect_smb2_done(struct tevent_req
*subreq
)
2698 tevent_req_simple_finish_ntstatus(
2699 subreq
, smb2cli_tcon_recv(subreq
));
2702 static void cli_tree_connect_andx_done(struct tevent_req
*subreq
)
2704 tevent_req_simple_finish_ntstatus(
2705 subreq
, cli_tcon_andx_recv(subreq
));
2708 static void cli_tree_connect_raw_done(struct tevent_req
*subreq
)
2710 struct tevent_req
*req
= tevent_req_callback_data(
2711 subreq
, struct tevent_req
);
2712 struct cli_tree_connect_state
*state
= tevent_req_data(
2713 req
, struct cli_tree_connect_state
);
2715 uint16_t max_xmit
= 0;
2718 status
= cli_raw_tcon_recv(subreq
, &max_xmit
, &tid
);
2719 if (tevent_req_nterror(req
, status
)) {
2723 smb1cli_tcon_set_values(state
->cli
->smb1
.tcon
,
2725 0, /* optional_support */
2726 0, /* maximal_access */
2727 0, /* guest_maximal_access */
2729 NULL
); /* fs_type */
2731 tevent_req_done(req
);
2734 static NTSTATUS
cli_tree_connect_recv(struct tevent_req
*req
)
2736 return tevent_req_simple_recv_ntstatus(req
);
2739 NTSTATUS
cli_tree_connect(struct cli_state
*cli
, const char *share
,
2740 const char *dev
, const char *pass
, int passlen
)
2742 struct tevent_context
*ev
;
2743 struct tevent_req
*req
;
2744 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2746 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
2747 return NT_STATUS_INVALID_PARAMETER
;
2749 ev
= samba_tevent_context_init(talloc_tos());
2753 req
= cli_tree_connect_send(ev
, ev
, cli
, share
, dev
, pass
, passlen
);
2757 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2760 status
= cli_tree_connect_recv(req
);
2766 /****************************************************************************
2767 Send a tree disconnect.
2768 ****************************************************************************/
2770 struct cli_tdis_state
{
2771 struct cli_state
*cli
;
2774 static void cli_tdis_done(struct tevent_req
*subreq
);
2776 static struct tevent_req
*cli_tdis_send(TALLOC_CTX
*mem_ctx
,
2777 struct tevent_context
*ev
,
2778 struct cli_state
*cli
)
2780 struct tevent_req
*req
, *subreq
;
2781 struct cli_tdis_state
*state
;
2783 req
= tevent_req_create(mem_ctx
, &state
, struct cli_tdis_state
);
2789 subreq
= cli_smb_send(state
, ev
, cli
, SMBtdis
, 0, 0, NULL
, 0, NULL
);
2790 if (tevent_req_nomem(subreq
, req
)) {
2791 return tevent_req_post(req
, ev
);
2793 tevent_req_set_callback(subreq
, cli_tdis_done
, req
);
2797 static void cli_tdis_done(struct tevent_req
*subreq
)
2799 struct tevent_req
*req
= tevent_req_callback_data(
2800 subreq
, struct tevent_req
);
2801 struct cli_tdis_state
*state
= tevent_req_data(
2802 req
, struct cli_tdis_state
);
2805 status
= cli_smb_recv(subreq
, NULL
, NULL
, 0, NULL
, NULL
, NULL
, NULL
);
2806 TALLOC_FREE(subreq
);
2807 if (!NT_STATUS_IS_OK(status
)) {
2808 tevent_req_nterror(req
, status
);
2811 cli_state_set_tid(state
->cli
, UINT16_MAX
);
2812 tevent_req_done(req
);
2815 static NTSTATUS
cli_tdis_recv(struct tevent_req
*req
)
2817 return tevent_req_simple_recv_ntstatus(req
);
2820 NTSTATUS
cli_tdis(struct cli_state
*cli
)
2822 struct tevent_context
*ev
;
2823 struct tevent_req
*req
;
2824 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2826 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
2827 return smb2cli_tdis(cli
);
2830 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
2831 return NT_STATUS_INVALID_PARAMETER
;
2833 ev
= samba_tevent_context_init(talloc_tos());
2837 req
= cli_tdis_send(ev
, ev
, cli
);
2841 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2844 status
= cli_tdis_recv(req
);
2850 struct cli_connect_sock_state
{
2851 const char **called_names
;
2852 const char **calling_names
;
2858 static void cli_connect_sock_done(struct tevent_req
*subreq
);
2861 * Async only if we don't have to look up the name, i.e. "pss" is set with a
2865 static struct tevent_req
*cli_connect_sock_send(
2866 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
2867 const char *host
, int name_type
, const struct sockaddr_storage
*pss
,
2868 const char *myname
, uint16_t port
)
2870 struct tevent_req
*req
, *subreq
;
2871 struct cli_connect_sock_state
*state
;
2873 struct sockaddr_storage
*addrs
;
2874 unsigned i
, num_addrs
;
2877 req
= tevent_req_create(mem_ctx
, &state
,
2878 struct cli_connect_sock_state
);
2883 prog
= getenv("LIBSMB_PROG");
2885 state
->fd
= sock_exec(prog
);
2886 if (state
->fd
== -1) {
2887 status
= map_nt_error_from_unix(errno
);
2888 tevent_req_nterror(req
, status
);
2891 tevent_req_done(req
);
2893 return tevent_req_post(req
, ev
);
2896 if ((pss
== NULL
) || is_zero_addr(pss
)) {
2899 * Here we cheat. resolve_name_list is not async at all. So
2900 * this call will only be really async if the name lookup has
2901 * been done externally.
2904 status
= resolve_name_list(state
, host
, name_type
,
2905 &addrs
, &num_addrs
);
2906 if (!NT_STATUS_IS_OK(status
)) {
2907 tevent_req_nterror(req
, status
);
2908 return tevent_req_post(req
, ev
);
2911 addrs
= talloc_array(state
, struct sockaddr_storage
, 1);
2912 if (tevent_req_nomem(addrs
, req
)) {
2913 return tevent_req_post(req
, ev
);
2919 state
->called_names
= talloc_array(state
, const char *, num_addrs
);
2920 if (tevent_req_nomem(state
->called_names
, req
)) {
2921 return tevent_req_post(req
, ev
);
2923 state
->called_types
= talloc_array(state
, int, num_addrs
);
2924 if (tevent_req_nomem(state
->called_types
, req
)) {
2925 return tevent_req_post(req
, ev
);
2927 state
->calling_names
= talloc_array(state
, const char *, num_addrs
);
2928 if (tevent_req_nomem(state
->calling_names
, req
)) {
2929 return tevent_req_post(req
, ev
);
2931 for (i
=0; i
<num_addrs
; i
++) {
2932 state
->called_names
[i
] = host
;
2933 state
->called_types
[i
] = name_type
;
2934 state
->calling_names
[i
] = myname
;
2937 subreq
= smbsock_any_connect_send(
2938 state
, ev
, addrs
, state
->called_names
, state
->called_types
,
2939 state
->calling_names
, NULL
, num_addrs
, port
);
2940 if (tevent_req_nomem(subreq
, req
)) {
2941 return tevent_req_post(req
, ev
);
2943 tevent_req_set_callback(subreq
, cli_connect_sock_done
, req
);
2947 static void cli_connect_sock_done(struct tevent_req
*subreq
)
2949 struct tevent_req
*req
= tevent_req_callback_data(
2950 subreq
, struct tevent_req
);
2951 struct cli_connect_sock_state
*state
= tevent_req_data(
2952 req
, struct cli_connect_sock_state
);
2955 status
= smbsock_any_connect_recv(subreq
, &state
->fd
, NULL
,
2957 TALLOC_FREE(subreq
);
2958 if (tevent_req_nterror(req
, status
)) {
2961 set_socket_options(state
->fd
, lp_socket_options());
2962 tevent_req_done(req
);
2965 static NTSTATUS
cli_connect_sock_recv(struct tevent_req
*req
,
2966 int *pfd
, uint16_t *pport
)
2968 struct cli_connect_sock_state
*state
= tevent_req_data(
2969 req
, struct cli_connect_sock_state
);
2972 if (tevent_req_is_nterror(req
, &status
)) {
2976 *pport
= state
->port
;
2977 return NT_STATUS_OK
;
2980 struct cli_connect_nb_state
{
2981 const char *desthost
;
2984 struct cli_state
*cli
;
2987 static void cli_connect_nb_done(struct tevent_req
*subreq
);
2989 static struct tevent_req
*cli_connect_nb_send(
2990 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
2991 const char *host
, const struct sockaddr_storage
*dest_ss
,
2992 uint16_t port
, int name_type
, const char *myname
,
2993 int signing_state
, int flags
)
2995 struct tevent_req
*req
, *subreq
;
2996 struct cli_connect_nb_state
*state
;
2999 req
= tevent_req_create(mem_ctx
, &state
, struct cli_connect_nb_state
);
3003 state
->desthost
= host
;
3004 state
->signing_state
= signing_state
;
3005 state
->flags
= flags
;
3007 p
= strchr(host
, '#');
3009 name_type
= strtol(p
+1, NULL
, 16);
3010 host
= talloc_strndup(state
, host
, p
- host
);
3011 if (tevent_req_nomem(host
, req
)) {
3012 return tevent_req_post(req
, ev
);
3016 subreq
= cli_connect_sock_send(state
, ev
, host
, name_type
, dest_ss
,
3018 if (tevent_req_nomem(subreq
, req
)) {
3019 return tevent_req_post(req
, ev
);
3021 tevent_req_set_callback(subreq
, cli_connect_nb_done
, req
);
3025 static void cli_connect_nb_done(struct tevent_req
*subreq
)
3027 struct tevent_req
*req
= tevent_req_callback_data(
3028 subreq
, struct tevent_req
);
3029 struct cli_connect_nb_state
*state
= tevent_req_data(
3030 req
, struct cli_connect_nb_state
);
3035 status
= cli_connect_sock_recv(subreq
, &fd
, &port
);
3036 TALLOC_FREE(subreq
);
3037 if (tevent_req_nterror(req
, status
)) {
3041 state
->cli
= cli_state_create(state
, fd
, state
->desthost
, NULL
,
3042 state
->signing_state
, state
->flags
);
3043 if (tevent_req_nomem(state
->cli
, req
)) {
3047 tevent_req_done(req
);
3050 static NTSTATUS
cli_connect_nb_recv(struct tevent_req
*req
,
3051 struct cli_state
**pcli
)
3053 struct cli_connect_nb_state
*state
= tevent_req_data(
3054 req
, struct cli_connect_nb_state
);
3057 if (tevent_req_is_nterror(req
, &status
)) {
3060 *pcli
= talloc_move(NULL
, &state
->cli
);
3061 return NT_STATUS_OK
;
3064 NTSTATUS
cli_connect_nb(const char *host
, const struct sockaddr_storage
*dest_ss
,
3065 uint16_t port
, int name_type
, const char *myname
,
3066 int signing_state
, int flags
, struct cli_state
**pcli
)
3068 struct tevent_context
*ev
;
3069 struct tevent_req
*req
;
3070 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
3072 ev
= samba_tevent_context_init(talloc_tos());
3076 req
= cli_connect_nb_send(ev
, ev
, host
, dest_ss
, port
, name_type
,
3077 myname
, signing_state
, flags
);
3081 if (!tevent_req_set_endtime(req
, ev
, timeval_current_ofs(20, 0))) {
3084 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
3087 status
= cli_connect_nb_recv(req
, pcli
);
3093 struct cli_start_connection_state
{
3094 struct tevent_context
*ev
;
3095 struct cli_state
*cli
;
3098 static void cli_start_connection_connected(struct tevent_req
*subreq
);
3099 static void cli_start_connection_done(struct tevent_req
*subreq
);
3102 establishes a connection to after the negprot.
3103 @param output_cli A fully initialised cli structure, non-null only on success
3104 @param dest_host The netbios name of the remote host
3105 @param dest_ss (optional) The the destination IP, NULL for name based lookup
3106 @param port (optional) The destination port (0 for default)
3109 static struct tevent_req
*cli_start_connection_send(
3110 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
3111 const char *my_name
, const char *dest_host
,
3112 const struct sockaddr_storage
*dest_ss
, int port
,
3113 int signing_state
, int flags
)
3115 struct tevent_req
*req
, *subreq
;
3116 struct cli_start_connection_state
*state
;
3118 req
= tevent_req_create(mem_ctx
, &state
,
3119 struct cli_start_connection_state
);
3125 subreq
= cli_connect_nb_send(state
, ev
, dest_host
, dest_ss
, port
,
3126 0x20, my_name
, signing_state
, flags
);
3127 if (tevent_req_nomem(subreq
, req
)) {
3128 return tevent_req_post(req
, ev
);
3130 tevent_req_set_callback(subreq
, cli_start_connection_connected
, req
);
3134 static void cli_start_connection_connected(struct tevent_req
*subreq
)
3136 struct tevent_req
*req
= tevent_req_callback_data(
3137 subreq
, struct tevent_req
);
3138 struct cli_start_connection_state
*state
= tevent_req_data(
3139 req
, struct cli_start_connection_state
);
3142 status
= cli_connect_nb_recv(subreq
, &state
->cli
);
3143 TALLOC_FREE(subreq
);
3144 if (tevent_req_nterror(req
, status
)) {
3148 subreq
= smbXcli_negprot_send(state
, state
->ev
, state
->cli
->conn
,
3149 state
->cli
->timeout
,
3150 lp_client_min_protocol(),
3151 lp_client_max_protocol());
3152 if (tevent_req_nomem(subreq
, req
)) {
3155 tevent_req_set_callback(subreq
, cli_start_connection_done
, req
);
3158 static void cli_start_connection_done(struct tevent_req
*subreq
)
3160 struct tevent_req
*req
= tevent_req_callback_data(
3161 subreq
, struct tevent_req
);
3162 struct cli_start_connection_state
*state
= tevent_req_data(
3163 req
, struct cli_start_connection_state
);
3166 status
= smbXcli_negprot_recv(subreq
);
3167 TALLOC_FREE(subreq
);
3168 if (tevent_req_nterror(req
, status
)) {
3172 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
3173 /* Ensure we ask for some initial credits. */
3174 smb2cli_conn_set_max_credits(state
->cli
->conn
,
3175 DEFAULT_SMB2_MAX_CREDITS
);
3178 tevent_req_done(req
);
3181 static NTSTATUS
cli_start_connection_recv(struct tevent_req
*req
,
3182 struct cli_state
**output_cli
)
3184 struct cli_start_connection_state
*state
= tevent_req_data(
3185 req
, struct cli_start_connection_state
);
3188 if (tevent_req_is_nterror(req
, &status
)) {
3191 *output_cli
= state
->cli
;
3193 return NT_STATUS_OK
;
3196 NTSTATUS
cli_start_connection(struct cli_state
**output_cli
,
3197 const char *my_name
,
3198 const char *dest_host
,
3199 const struct sockaddr_storage
*dest_ss
, int port
,
3200 int signing_state
, int flags
)
3202 struct tevent_context
*ev
;
3203 struct tevent_req
*req
;
3204 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
3206 ev
= samba_tevent_context_init(talloc_tos());
3210 req
= cli_start_connection_send(ev
, ev
, my_name
, dest_host
, dest_ss
,
3211 port
, signing_state
, flags
);
3215 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
3218 status
= cli_start_connection_recv(req
, output_cli
);
3225 establishes a connection right up to doing tconX, password specified.
3226 @param output_cli A fully initialised cli structure, non-null only on success
3227 @param dest_host The netbios name of the remote host
3228 @param dest_ip (optional) The the destination IP, NULL for name based lookup
3229 @param port (optional) The destination port (0 for default)
3230 @param service (optional) The share to make the connection to. Should be 'unqualified' in any way.
3231 @param service_type The 'type' of serivice.
3232 @param user Username, unix string
3233 @param domain User's domain
3234 @param password User's password, unencrypted unix string.
3237 struct cli_full_connection_state
{
3238 struct tevent_context
*ev
;
3239 const char *service
;
3240 const char *service_type
;
3243 const char *password
;
3246 struct cli_state
*cli
;
3249 static int cli_full_connection_state_destructor(
3250 struct cli_full_connection_state
*s
);
3251 static void cli_full_connection_started(struct tevent_req
*subreq
);
3252 static void cli_full_connection_sess_set_up(struct tevent_req
*subreq
);
3253 static void cli_full_connection_done(struct tevent_req
*subreq
);
3255 struct tevent_req
*cli_full_connection_send(
3256 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
3257 const char *my_name
, const char *dest_host
,
3258 const struct sockaddr_storage
*dest_ss
, int port
,
3259 const char *service
, const char *service_type
,
3260 const char *user
, const char *domain
,
3261 const char *password
, int flags
, int signing_state
)
3263 struct tevent_req
*req
, *subreq
;
3264 struct cli_full_connection_state
*state
;
3266 req
= tevent_req_create(mem_ctx
, &state
,
3267 struct cli_full_connection_state
);
3271 talloc_set_destructor(state
, cli_full_connection_state_destructor
);
3274 state
->service
= service
;
3275 state
->service_type
= service_type
;
3277 state
->domain
= domain
;
3278 state
->password
= password
;
3279 state
->flags
= flags
;
3281 state
->pw_len
= state
->password
? strlen(state
->password
)+1 : 0;
3282 if (state
->password
== NULL
) {
3283 state
->password
= "";
3286 subreq
= cli_start_connection_send(
3287 state
, ev
, my_name
, dest_host
, dest_ss
, port
,
3288 signing_state
, flags
);
3289 if (tevent_req_nomem(subreq
, req
)) {
3290 return tevent_req_post(req
, ev
);
3292 tevent_req_set_callback(subreq
, cli_full_connection_started
, req
);
3296 static int cli_full_connection_state_destructor(
3297 struct cli_full_connection_state
*s
)
3299 if (s
->cli
!= NULL
) {
3300 cli_shutdown(s
->cli
);
3306 static void cli_full_connection_started(struct tevent_req
*subreq
)
3308 struct tevent_req
*req
= tevent_req_callback_data(
3309 subreq
, struct tevent_req
);
3310 struct cli_full_connection_state
*state
= tevent_req_data(
3311 req
, struct cli_full_connection_state
);
3314 status
= cli_start_connection_recv(subreq
, &state
->cli
);
3315 TALLOC_FREE(subreq
);
3316 if (tevent_req_nterror(req
, status
)) {
3319 subreq
= cli_session_setup_send(
3320 state
, state
->ev
, state
->cli
, state
->user
,
3321 state
->password
, state
->pw_len
, state
->password
, state
->pw_len
,
3323 if (tevent_req_nomem(subreq
, req
)) {
3326 tevent_req_set_callback(subreq
, cli_full_connection_sess_set_up
, req
);
3329 static void cli_full_connection_sess_set_up(struct tevent_req
*subreq
)
3331 struct tevent_req
*req
= tevent_req_callback_data(
3332 subreq
, struct tevent_req
);
3333 struct cli_full_connection_state
*state
= tevent_req_data(
3334 req
, struct cli_full_connection_state
);
3337 status
= cli_session_setup_recv(subreq
);
3338 TALLOC_FREE(subreq
);
3340 if (!NT_STATUS_IS_OK(status
) &&
3341 (state
->flags
& CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK
)) {
3343 state
->flags
&= ~CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK
;
3345 subreq
= cli_session_setup_send(
3346 state
, state
->ev
, state
->cli
, "", "", 0, "", 0,
3348 if (tevent_req_nomem(subreq
, req
)) {
3351 tevent_req_set_callback(
3352 subreq
, cli_full_connection_sess_set_up
, req
);
3356 if (tevent_req_nterror(req
, status
)) {
3360 if (state
->service
!= NULL
) {
3361 subreq
= cli_tree_connect_send(
3362 state
, state
->ev
, state
->cli
,
3363 state
->service
, state
->service_type
,
3364 state
->password
, state
->pw_len
);
3365 if (tevent_req_nomem(subreq
, req
)) {
3368 tevent_req_set_callback(subreq
, cli_full_connection_done
, req
);
3372 status
= cli_init_creds(state
->cli
, state
->user
, state
->domain
,
3374 if (tevent_req_nterror(req
, status
)) {
3377 tevent_req_done(req
);
3380 static void cli_full_connection_done(struct tevent_req
*subreq
)
3382 struct tevent_req
*req
= tevent_req_callback_data(
3383 subreq
, struct tevent_req
);
3384 struct cli_full_connection_state
*state
= tevent_req_data(
3385 req
, struct cli_full_connection_state
);
3388 status
= cli_tree_connect_recv(subreq
);
3389 TALLOC_FREE(subreq
);
3390 if (tevent_req_nterror(req
, status
)) {
3393 status
= cli_init_creds(state
->cli
, state
->user
, state
->domain
,
3395 if (tevent_req_nterror(req
, status
)) {
3398 tevent_req_done(req
);
3401 NTSTATUS
cli_full_connection_recv(struct tevent_req
*req
,
3402 struct cli_state
**output_cli
)
3404 struct cli_full_connection_state
*state
= tevent_req_data(
3405 req
, struct cli_full_connection_state
);
3408 if (tevent_req_is_nterror(req
, &status
)) {
3411 *output_cli
= state
->cli
;
3412 talloc_set_destructor(state
, NULL
);
3413 return NT_STATUS_OK
;
3416 NTSTATUS
cli_full_connection(struct cli_state
**output_cli
,
3417 const char *my_name
,
3418 const char *dest_host
,
3419 const struct sockaddr_storage
*dest_ss
, int port
,
3420 const char *service
, const char *service_type
,
3421 const char *user
, const char *domain
,
3422 const char *password
, int flags
,
3425 struct tevent_context
*ev
;
3426 struct tevent_req
*req
;
3427 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
3429 ev
= samba_tevent_context_init(talloc_tos());
3433 req
= cli_full_connection_send(
3434 ev
, ev
, my_name
, dest_host
, dest_ss
, port
, service
,
3435 service_type
, user
, domain
, password
, flags
, signing_state
);
3439 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
3442 status
= cli_full_connection_recv(req
, output_cli
);
3448 /****************************************************************************
3449 Send an old style tcon.
3450 ****************************************************************************/
3451 struct cli_raw_tcon_state
{
3455 static void cli_raw_tcon_done(struct tevent_req
*subreq
);
3457 static struct tevent_req
*cli_raw_tcon_send(
3458 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
3459 const char *service
, const char *pass
, const char *dev
)
3461 struct tevent_req
*req
, *subreq
;
3462 struct cli_raw_tcon_state
*state
;
3465 req
= tevent_req_create(mem_ctx
, &state
, struct cli_raw_tcon_state
);
3470 if (!lp_client_plaintext_auth() && (*pass
)) {
3471 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
3472 " or 'client ntlmv2 auth = yes'\n"));
3473 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
3474 return tevent_req_post(req
, ev
);
3477 bytes
= talloc_array(state
, uint8_t, 0);
3478 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
3479 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
3480 service
, strlen(service
)+1, NULL
);
3481 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
3482 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
3483 pass
, strlen(pass
)+1, NULL
);
3484 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
3485 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
3486 dev
, strlen(dev
)+1, NULL
);
3488 if (tevent_req_nomem(bytes
, req
)) {
3489 return tevent_req_post(req
, ev
);
3492 subreq
= cli_smb_send(state
, ev
, cli
, SMBtcon
, 0, 0, NULL
,
3493 talloc_get_size(bytes
), bytes
);
3494 if (tevent_req_nomem(subreq
, req
)) {
3495 return tevent_req_post(req
, ev
);
3497 tevent_req_set_callback(subreq
, cli_raw_tcon_done
, req
);
3501 static void cli_raw_tcon_done(struct tevent_req
*subreq
)
3503 struct tevent_req
*req
= tevent_req_callback_data(
3504 subreq
, struct tevent_req
);
3505 struct cli_raw_tcon_state
*state
= tevent_req_data(
3506 req
, struct cli_raw_tcon_state
);
3509 status
= cli_smb_recv(subreq
, state
, NULL
, 2, NULL
, &state
->ret_vwv
,
3511 TALLOC_FREE(subreq
);
3512 if (tevent_req_nterror(req
, status
)) {
3515 tevent_req_done(req
);
3518 static NTSTATUS
cli_raw_tcon_recv(struct tevent_req
*req
,
3519 uint16
*max_xmit
, uint16
*tid
)
3521 struct cli_raw_tcon_state
*state
= tevent_req_data(
3522 req
, struct cli_raw_tcon_state
);
3525 if (tevent_req_is_nterror(req
, &status
)) {
3528 *max_xmit
= SVAL(state
->ret_vwv
+ 0, 0);
3529 *tid
= SVAL(state
->ret_vwv
+ 1, 0);
3530 return NT_STATUS_OK
;
3533 NTSTATUS
cli_raw_tcon(struct cli_state
*cli
,
3534 const char *service
, const char *pass
, const char *dev
,
3535 uint16
*max_xmit
, uint16
*tid
)
3537 struct tevent_context
*ev
;
3538 struct tevent_req
*req
;
3539 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
3541 ev
= samba_tevent_context_init(talloc_tos());
3545 req
= cli_raw_tcon_send(ev
, ev
, cli
, service
, pass
, dev
);
3549 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
3552 status
= cli_raw_tcon_recv(req
, max_xmit
, tid
);
3558 /* Return a cli_state pointing at the IPC$ share for the given server */
3560 struct cli_state
*get_ipc_connect(char *server
,
3561 struct sockaddr_storage
*server_ss
,
3562 const struct user_auth_info
*user_info
)
3564 struct cli_state
*cli
;
3566 uint32_t flags
= CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK
;
3568 if (user_info
->use_kerberos
) {
3569 flags
|= CLI_FULL_CONNECTION_USE_KERBEROS
;
3572 nt_status
= cli_full_connection(&cli
, NULL
, server
, server_ss
, 0, "IPC$", "IPC",
3573 user_info
->username
? user_info
->username
: "",
3575 user_info
->password
? user_info
->password
: "",
3577 SMB_SIGNING_DEFAULT
);
3579 if (NT_STATUS_IS_OK(nt_status
)) {
3581 } else if (is_ipaddress(server
)) {
3582 /* windows 9* needs a correct NMB name for connections */
3583 fstring remote_name
;
3585 if (name_status_find("*", 0, 0, server_ss
, remote_name
)) {
3586 cli
= get_ipc_connect(remote_name
, server_ss
, user_info
);
3595 * Given the IP address of a master browser on the network, return its
3596 * workgroup and connect to it.
3598 * This function is provided to allow additional processing beyond what
3599 * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
3600 * browsers and obtain each master browsers' list of domains (in case the
3601 * first master browser is recently on the network and has not yet
3602 * synchronized with other master browsers and therefore does not yet have the
3603 * entire network browse list)
3606 struct cli_state
*get_ipc_connect_master_ip(TALLOC_CTX
*ctx
,
3607 struct sockaddr_storage
*mb_ip
,
3608 const struct user_auth_info
*user_info
,
3609 char **pp_workgroup_out
)
3611 char addr
[INET6_ADDRSTRLEN
];
3613 struct cli_state
*cli
;
3614 struct sockaddr_storage server_ss
;
3616 *pp_workgroup_out
= NULL
;
3618 print_sockaddr(addr
, sizeof(addr
), mb_ip
);
3619 DEBUG(99, ("Looking up name of master browser %s\n",
3623 * Do a name status query to find out the name of the master browser.
3624 * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
3625 * master browser will not respond to a wildcard query (or, at least,
3626 * an NT4 server acting as the domain master browser will not).
3628 * We might be able to use ONLY the query on MSBROWSE, but that's not
3629 * yet been tested with all Windows versions, so until it is, leave
3630 * the original wildcard query as the first choice and fall back to
3631 * MSBROWSE if the wildcard query fails.
3633 if (!name_status_find("*", 0, 0x1d, mb_ip
, name
) &&
3634 !name_status_find(MSBROWSE
, 1, 0x1d, mb_ip
, name
)) {
3636 DEBUG(99, ("Could not retrieve name status for %s\n",
3641 if (!find_master_ip(name
, &server_ss
)) {
3642 DEBUG(99, ("Could not find master ip for %s\n", name
));
3646 *pp_workgroup_out
= talloc_strdup(ctx
, name
);
3648 DEBUG(4, ("found master browser %s, %s\n", name
, addr
));
3650 print_sockaddr(addr
, sizeof(addr
), &server_ss
);
3651 cli
= get_ipc_connect(addr
, &server_ss
, user_info
);
3657 * Return the IP address and workgroup of a master browser on the network, and
3661 struct cli_state
*get_ipc_connect_master_ip_bcast(TALLOC_CTX
*ctx
,
3662 const struct user_auth_info
*user_info
,
3663 char **pp_workgroup_out
)
3665 struct sockaddr_storage
*ip_list
;
3666 struct cli_state
*cli
;
3670 *pp_workgroup_out
= NULL
;
3672 DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
3674 /* Go looking for workgroups by broadcasting on the local network */
3676 status
= name_resolve_bcast(MSBROWSE
, 1, talloc_tos(),
3678 if (!NT_STATUS_IS_OK(status
)) {
3679 DEBUG(99, ("No master browsers responded: %s\n",
3680 nt_errstr(status
)));
3684 for (i
= 0; i
< count
; i
++) {
3685 char addr
[INET6_ADDRSTRLEN
];
3686 print_sockaddr(addr
, sizeof(addr
), &ip_list
[i
]);
3687 DEBUG(99, ("Found master browser %s\n", addr
));
3689 cli
= get_ipc_connect_master_ip(ctx
, &ip_list
[i
],
3690 user_info
, pp_workgroup_out
);