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"
38 #define STAR_SMBSERVER "*SMBSERVER"
40 /********************************************************
41 Utility function to ensure we always return at least
42 a valid char * pointer to an empty string for the
43 cli->server_os, cli->server_type and cli->server_domain
45 *******************************************************/
47 static NTSTATUS
smb_bytes_talloc_string(TALLOC_CTX
*mem_ctx
,
54 *destlen
= clistr_pull_talloc(mem_ctx
,
62 return NT_STATUS_NO_MEMORY
;
66 *dest
= talloc_strdup(mem_ctx
, "");
68 return NT_STATUS_NO_MEMORY
;
74 /****************************************************************************
75 Do an old lanman2 style session setup.
76 ****************************************************************************/
78 struct cli_session_setup_lanman2_state
{
79 struct cli_state
*cli
;
84 static void cli_session_setup_lanman2_done(struct tevent_req
*subreq
);
86 static struct tevent_req
*cli_session_setup_lanman2_send(
87 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
88 struct cli_state
*cli
, const char *user
,
89 const char *pass
, size_t passlen
,
90 const char *workgroup
)
92 struct tevent_req
*req
, *subreq
;
93 struct cli_session_setup_lanman2_state
*state
;
94 DATA_BLOB lm_response
= data_blob_null
;
98 uint16_t sec_mode
= smb1cli_conn_server_security_mode(cli
->conn
);
100 req
= tevent_req_create(mem_ctx
, &state
,
101 struct cli_session_setup_lanman2_state
);
110 * if in share level security then don't send a password now
112 if (!(sec_mode
& NEGOTIATE_SECURITY_USER_LEVEL
)) {
117 && (sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
)
120 * Encrypted mode needed, and non encrypted password
123 lm_response
= data_blob(NULL
, 24);
124 if (tevent_req_nomem(lm_response
.data
, req
)) {
125 return tevent_req_post(req
, ev
);
128 if (!SMBencrypt(pass
, smb1cli_conn_server_challenge(cli
->conn
),
129 (uint8_t *)lm_response
.data
)) {
130 DEBUG(1, ("Password is > 14 chars in length, and is "
131 "therefore incompatible with Lanman "
132 "authentication\n"));
133 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
134 return tevent_req_post(req
, ev
);
136 } else if ((sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
)
139 * Encrypted mode needed, and encrypted password
142 lm_response
= data_blob(pass
, passlen
);
143 if (tevent_req_nomem(lm_response
.data
, req
)) {
144 return tevent_req_post(req
, ev
);
146 } else if (passlen
> 0) {
148 size_t converted_size
;
150 * Plaintext mode needed, assume plaintext supplied.
152 buf
= talloc_array(talloc_tos(), uint8_t, 0);
153 buf
= smb_bytes_push_str(buf
, smbXcli_conn_use_unicode(cli
->conn
), pass
, passlen
+1,
155 if (tevent_req_nomem(buf
, req
)) {
156 return tevent_req_post(req
, ev
);
158 lm_response
= data_blob(pass
, passlen
);
160 if (tevent_req_nomem(lm_response
.data
, req
)) {
161 return tevent_req_post(req
, ev
);
165 SCVAL(vwv
+0, 0, 0xff);
168 SSVAL(vwv
+2, 0, CLI_BUFFER_SIZE
);
171 SIVAL(vwv
+5, 0, smb1cli_conn_server_session_key(cli
->conn
));
172 SSVAL(vwv
+7, 0, lm_response
.length
);
174 bytes
= talloc_array(state
, uint8_t, lm_response
.length
);
175 if (tevent_req_nomem(bytes
, req
)) {
176 return tevent_req_post(req
, ev
);
178 if (lm_response
.length
!= 0) {
179 memcpy(bytes
, lm_response
.data
, lm_response
.length
);
181 data_blob_free(&lm_response
);
183 tmp
= talloc_strdup_upper(talloc_tos(), user
);
184 if (tevent_req_nomem(tmp
, req
)) {
185 return tevent_req_post(req
, ev
);
187 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), tmp
, strlen(tmp
)+1,
191 tmp
= talloc_strdup_upper(talloc_tos(), workgroup
);
192 if (tevent_req_nomem(tmp
, req
)) {
193 return tevent_req_post(req
, ev
);
195 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), tmp
, strlen(tmp
)+1,
197 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "Unix", 5, NULL
);
198 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "Samba", 6, NULL
);
200 if (tevent_req_nomem(bytes
, req
)) {
201 return tevent_req_post(req
, ev
);
204 subreq
= cli_smb_send(state
, ev
, cli
, SMBsesssetupX
, 0, 10, vwv
,
205 talloc_get_size(bytes
), bytes
);
206 if (tevent_req_nomem(subreq
, req
)) {
207 return tevent_req_post(req
, ev
);
209 tevent_req_set_callback(subreq
, cli_session_setup_lanman2_done
, req
);
213 static void cli_session_setup_lanman2_done(struct tevent_req
*subreq
)
215 struct tevent_req
*req
= tevent_req_callback_data(
216 subreq
, struct tevent_req
);
217 struct cli_session_setup_lanman2_state
*state
= tevent_req_data(
218 req
, struct cli_session_setup_lanman2_state
);
219 struct cli_state
*cli
= state
->cli
;
230 status
= cli_smb_recv(subreq
, state
, &in
, 3, &wct
, &vwv
,
233 if (!NT_STATUS_IS_OK(status
)) {
234 tevent_req_nterror(req
, status
);
238 inhdr
= in
+ NBT_HDR_SIZE
;
241 cli_state_set_uid(state
->cli
, SVAL(inhdr
, HDR_UID
));
243 status
= smb_bytes_talloc_string(cli
,
250 if (!NT_STATUS_IS_OK(status
)) {
251 tevent_req_nterror(req
, status
);
256 status
= smb_bytes_talloc_string(cli
,
263 if (!NT_STATUS_IS_OK(status
)) {
264 tevent_req_nterror(req
, status
);
269 status
= smb_bytes_talloc_string(cli
,
276 if (!NT_STATUS_IS_OK(status
)) {
277 tevent_req_nterror(req
, status
);
282 status
= cli_set_username(cli
, state
->user
);
283 if (tevent_req_nterror(req
, status
)) {
286 tevent_req_done(req
);
289 static NTSTATUS
cli_session_setup_lanman2_recv(struct tevent_req
*req
)
291 return tevent_req_simple_recv_ntstatus(req
);
294 /****************************************************************************
295 Work out suitable capabilities to offer the server.
296 ****************************************************************************/
298 static uint32_t cli_session_setup_capabilities(struct cli_state
*cli
,
299 uint32_t sesssetup_capabilities
)
301 uint32_t client_capabilities
= smb1cli_conn_capabilities(cli
->conn
);
304 * We only send capabilities based on the mask for:
305 * - client only flags
306 * - flags used in both directions
308 * We do not echo the server only flags, except some legacy flags.
310 * SMB_CAP_LEGACY_CLIENT_MASK contains CAP_LARGE_READX and
311 * CAP_LARGE_WRITEX in order to allow us to do large reads
312 * against old Samba releases (<= 3.6.x).
314 client_capabilities
&= (SMB_CAP_BOTH_MASK
| SMB_CAP_LEGACY_CLIENT_MASK
);
317 * Session Setup specific flags CAP_DYNAMIC_REAUTH
318 * and CAP_EXTENDED_SECURITY are passed by the caller.
319 * We need that in order to do guest logins even if
320 * CAP_EXTENDED_SECURITY is negotiated.
322 client_capabilities
&= ~(CAP_DYNAMIC_REAUTH
|CAP_EXTENDED_SECURITY
);
323 sesssetup_capabilities
&= (CAP_DYNAMIC_REAUTH
|CAP_EXTENDED_SECURITY
);
324 client_capabilities
|= sesssetup_capabilities
;
326 return client_capabilities
;
329 /****************************************************************************
330 Do a NT1 guest session setup.
331 ****************************************************************************/
333 struct cli_session_setup_guest_state
{
334 struct cli_state
*cli
;
339 static void cli_session_setup_guest_done(struct tevent_req
*subreq
);
341 struct tevent_req
*cli_session_setup_guest_create(TALLOC_CTX
*mem_ctx
,
342 struct tevent_context
*ev
,
343 struct cli_state
*cli
,
344 struct tevent_req
**psmbreq
)
346 struct tevent_req
*req
, *subreq
;
347 struct cli_session_setup_guest_state
*state
;
351 req
= tevent_req_create(mem_ctx
, &state
,
352 struct cli_session_setup_guest_state
);
359 SCVAL(vwv
+0, 0, 0xFF);
362 SSVAL(vwv
+2, 0, CLI_BUFFER_SIZE
);
364 SSVAL(vwv
+4, 0, cli_state_get_vc_num(cli
));
365 SIVAL(vwv
+5, 0, smb1cli_conn_server_session_key(cli
->conn
));
370 SIVAL(vwv
+11, 0, cli_session_setup_capabilities(cli
, 0));
372 bytes
= talloc_array(state
, uint8_t, 0);
374 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "", 1, /* username */
376 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "", 1, /* workgroup */
378 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "Unix", 5, NULL
);
379 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "Samba", 6, NULL
);
386 state
->bytes
.iov_base
= (void *)bytes
;
387 state
->bytes
.iov_len
= talloc_get_size(bytes
);
389 subreq
= cli_smb_req_create(state
, ev
, cli
, SMBsesssetupX
, 0, 13, vwv
,
391 if (subreq
== NULL
) {
395 tevent_req_set_callback(subreq
, cli_session_setup_guest_done
, req
);
400 struct tevent_req
*cli_session_setup_guest_send(TALLOC_CTX
*mem_ctx
,
401 struct tevent_context
*ev
,
402 struct cli_state
*cli
)
404 struct tevent_req
*req
, *subreq
;
407 req
= cli_session_setup_guest_create(mem_ctx
, ev
, cli
, &subreq
);
412 status
= smb1cli_req_chain_submit(&subreq
, 1);
413 if (!NT_STATUS_IS_OK(status
)) {
414 tevent_req_nterror(req
, status
);
415 return tevent_req_post(req
, ev
);
420 static void cli_session_setup_guest_done(struct tevent_req
*subreq
)
422 struct tevent_req
*req
= tevent_req_callback_data(
423 subreq
, struct tevent_req
);
424 struct cli_session_setup_guest_state
*state
= tevent_req_data(
425 req
, struct cli_session_setup_guest_state
);
426 struct cli_state
*cli
= state
->cli
;
437 status
= cli_smb_recv(subreq
, state
, &in
, 3, &wct
, &vwv
,
440 if (!NT_STATUS_IS_OK(status
)) {
441 tevent_req_nterror(req
, status
);
445 inhdr
= in
+ NBT_HDR_SIZE
;
448 cli_state_set_uid(state
->cli
, SVAL(inhdr
, HDR_UID
));
450 status
= smb_bytes_talloc_string(cli
,
457 if (!NT_STATUS_IS_OK(status
)) {
458 tevent_req_nterror(req
, status
);
463 status
= smb_bytes_talloc_string(cli
,
470 if (!NT_STATUS_IS_OK(status
)) {
471 tevent_req_nterror(req
, status
);
476 status
= smb_bytes_talloc_string(cli
,
483 if (!NT_STATUS_IS_OK(status
)) {
484 tevent_req_nterror(req
, status
);
489 status
= cli_set_username(cli
, "");
490 if (!NT_STATUS_IS_OK(status
)) {
491 tevent_req_nterror(req
, status
);
494 tevent_req_done(req
);
497 NTSTATUS
cli_session_setup_guest_recv(struct tevent_req
*req
)
499 return tevent_req_simple_recv_ntstatus(req
);
502 /****************************************************************************
503 Do a NT1 plaintext session setup.
504 ****************************************************************************/
506 struct cli_session_setup_plain_state
{
507 struct cli_state
*cli
;
512 static void cli_session_setup_plain_done(struct tevent_req
*subreq
);
514 static struct tevent_req
*cli_session_setup_plain_send(
515 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
516 struct cli_state
*cli
,
517 const char *user
, const char *pass
, const char *workgroup
)
519 struct tevent_req
*req
, *subreq
;
520 struct cli_session_setup_plain_state
*state
;
526 req
= tevent_req_create(mem_ctx
, &state
,
527 struct cli_session_setup_plain_state
);
535 SCVAL(vwv
+0, 0, 0xff);
538 SSVAL(vwv
+2, 0, CLI_BUFFER_SIZE
);
540 SSVAL(vwv
+4, 0, cli_state_get_vc_num(cli
));
541 SIVAL(vwv
+5, 0, smb1cli_conn_server_session_key(cli
->conn
));
546 SIVAL(vwv
+11, 0, cli_session_setup_capabilities(cli
, 0));
548 bytes
= talloc_array(state
, uint8_t, 0);
549 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), pass
, strlen(pass
)+1,
551 if (tevent_req_nomem(bytes
, req
)) {
552 return tevent_req_post(req
, ev
);
554 SSVAL(vwv
+ (smbXcli_conn_use_unicode(cli
->conn
) ? 8 : 7), 0, passlen
);
556 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
557 user
, strlen(user
)+1, NULL
);
558 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
559 workgroup
, strlen(workgroup
)+1, NULL
);
560 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
563 version
= talloc_asprintf(talloc_tos(), "Samba %s",
564 samba_version_string());
565 if (tevent_req_nomem(version
, req
)){
566 return tevent_req_post(req
, ev
);
568 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
569 version
, strlen(version
)+1, NULL
);
570 TALLOC_FREE(version
);
572 if (tevent_req_nomem(bytes
, req
)) {
573 return tevent_req_post(req
, ev
);
576 subreq
= cli_smb_send(state
, ev
, cli
, SMBsesssetupX
, 0, 13, vwv
,
577 talloc_get_size(bytes
), bytes
);
578 if (tevent_req_nomem(subreq
, req
)) {
579 return tevent_req_post(req
, ev
);
581 tevent_req_set_callback(subreq
, cli_session_setup_plain_done
, req
);
585 static void cli_session_setup_plain_done(struct tevent_req
*subreq
)
587 struct tevent_req
*req
= tevent_req_callback_data(
588 subreq
, struct tevent_req
);
589 struct cli_session_setup_plain_state
*state
= tevent_req_data(
590 req
, struct cli_session_setup_plain_state
);
591 struct cli_state
*cli
= state
->cli
;
602 status
= cli_smb_recv(subreq
, state
, &in
, 3, &wct
, &vwv
,
605 if (tevent_req_nterror(req
, status
)) {
609 inhdr
= in
+ NBT_HDR_SIZE
;
612 cli_state_set_uid(state
->cli
, SVAL(inhdr
, HDR_UID
));
614 status
= smb_bytes_talloc_string(cli
,
621 if (!NT_STATUS_IS_OK(status
)) {
622 tevent_req_nterror(req
, status
);
627 status
= smb_bytes_talloc_string(cli
,
634 if (!NT_STATUS_IS_OK(status
)) {
635 tevent_req_nterror(req
, status
);
640 status
= smb_bytes_talloc_string(cli
,
647 if (!NT_STATUS_IS_OK(status
)) {
648 tevent_req_nterror(req
, status
);
653 status
= cli_set_username(cli
, state
->user
);
654 if (tevent_req_nterror(req
, status
)) {
658 tevent_req_done(req
);
661 static NTSTATUS
cli_session_setup_plain_recv(struct tevent_req
*req
)
663 return tevent_req_simple_recv_ntstatus(req
);
666 /****************************************************************************
667 do a NT1 NTLM/LM encrypted session setup - for when extended security
669 @param cli client state to create do session setup on
671 @param pass *either* cleartext password (passlen !=24) or LM response.
672 @param ntpass NT response, implies ntpasslen >=24, implies pass is not clear
673 @param workgroup The user's domain.
674 ****************************************************************************/
676 struct cli_session_setup_nt1_state
{
677 struct cli_state
*cli
;
680 DATA_BLOB session_key
;
684 static void cli_session_setup_nt1_done(struct tevent_req
*subreq
);
686 static struct tevent_req
*cli_session_setup_nt1_send(
687 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
688 struct cli_state
*cli
, const char *user
,
689 const char *pass
, size_t passlen
,
690 const char *ntpass
, size_t ntpasslen
,
691 const char *workgroup
)
693 struct tevent_req
*req
, *subreq
;
694 struct cli_session_setup_nt1_state
*state
;
695 DATA_BLOB lm_response
= data_blob_null
;
696 DATA_BLOB nt_response
= data_blob_null
;
697 DATA_BLOB session_key
= data_blob_null
;
700 char *workgroup_upper
;
702 req
= tevent_req_create(mem_ctx
, &state
,
703 struct cli_session_setup_nt1_state
);
712 /* do nothing - guest login */
713 } else if (passlen
!= 24) {
714 if (lp_client_ntlmv2_auth()) {
715 DATA_BLOB server_chal
;
716 DATA_BLOB names_blob
;
719 data_blob_const(smb1cli_conn_server_challenge(cli
->conn
),
723 * note that the 'workgroup' here is a best
724 * guess - we don't know the server's domain
725 * at this point. Windows clients also don't
728 names_blob
= NTLMv2_generate_names_blob(
729 NULL
, NULL
, workgroup
);
731 if (tevent_req_nomem(names_blob
.data
, req
)) {
732 return tevent_req_post(req
, ev
);
735 if (!SMBNTLMv2encrypt(NULL
, user
, workgroup
, pass
,
736 &server_chal
, &names_blob
,
737 &lm_response
, &nt_response
,
738 NULL
, &session_key
)) {
739 data_blob_free(&names_blob
);
741 req
, NT_STATUS_ACCESS_DENIED
);
742 return tevent_req_post(req
, ev
);
744 data_blob_free(&names_blob
);
748 E_md4hash(pass
, nt_hash
);
751 nt_response
= data_blob_null
;
753 nt_response
= data_blob(NULL
, 24);
754 if (tevent_req_nomem(nt_response
.data
, req
)) {
755 return tevent_req_post(req
, ev
);
758 SMBNTencrypt(pass
, smb1cli_conn_server_challenge(cli
->conn
),
761 /* non encrypted password supplied. Ignore ntpass. */
762 if (lp_client_lanman_auth()) {
764 lm_response
= data_blob(NULL
, 24);
765 if (tevent_req_nomem(lm_response
.data
, req
)) {
766 return tevent_req_post(req
, ev
);
769 if (!SMBencrypt(pass
,
770 smb1cli_conn_server_challenge(cli
->conn
),
773 * Oops, the LM response is
774 * invalid, just put the NT
775 * response there instead
777 data_blob_free(&lm_response
);
778 lm_response
= data_blob(
784 * LM disabled, place NT# in LM field
787 lm_response
= data_blob(
788 nt_response
.data
, nt_response
.length
);
791 if (tevent_req_nomem(lm_response
.data
, req
)) {
792 return tevent_req_post(req
, ev
);
795 session_key
= data_blob(NULL
, 16);
796 if (tevent_req_nomem(session_key
.data
, req
)) {
797 return tevent_req_post(req
, ev
);
800 E_deshash(pass
, session_key
.data
);
801 memset(&session_key
.data
[8], '\0', 8);
803 SMBsesskeygen_ntv1(nt_hash
, session_key
.data
);
807 /* pre-encrypted password supplied. Only used for
808 security=server, can't do
809 signing because we don't have original key */
811 lm_response
= data_blob(pass
, passlen
);
812 if (tevent_req_nomem(lm_response
.data
, req
)) {
813 return tevent_req_post(req
, ev
);
816 nt_response
= data_blob(ntpass
, ntpasslen
);
817 if (tevent_req_nomem(nt_response
.data
, req
)) {
818 return tevent_req_post(req
, ev
);
823 state
->response
= data_blob_talloc(
824 state
, lm_response
.data
, lm_response
.length
);
826 state
->response
= data_blob_talloc(
827 state
, nt_response
.data
, nt_response
.length
);
829 if (tevent_req_nomem(state
->response
.data
, req
)) {
830 return tevent_req_post(req
, ev
);
833 if (session_key
.data
) {
834 state
->session_key
= data_blob_talloc(
835 state
, session_key
.data
, session_key
.length
);
836 if (tevent_req_nomem(state
->session_key
.data
, req
)) {
837 return tevent_req_post(req
, ev
);
840 data_blob_free(&session_key
);
842 SCVAL(vwv
+0, 0, 0xff);
845 SSVAL(vwv
+2, 0, CLI_BUFFER_SIZE
);
847 SSVAL(vwv
+4, 0, cli_state_get_vc_num(cli
));
848 SIVAL(vwv
+5, 0, smb1cli_conn_server_session_key(cli
->conn
));
849 SSVAL(vwv
+7, 0, lm_response
.length
);
850 SSVAL(vwv
+8, 0, nt_response
.length
);
853 SIVAL(vwv
+11, 0, cli_session_setup_capabilities(cli
, 0));
855 bytes
= talloc_array(state
, uint8_t,
856 lm_response
.length
+ nt_response
.length
);
857 if (tevent_req_nomem(bytes
, req
)) {
858 return tevent_req_post(req
, ev
);
860 if (lm_response
.length
!= 0) {
861 memcpy(bytes
, lm_response
.data
, lm_response
.length
);
863 if (nt_response
.length
!= 0) {
864 memcpy(bytes
+ lm_response
.length
,
865 nt_response
.data
, nt_response
.length
);
867 data_blob_free(&lm_response
);
868 data_blob_free(&nt_response
);
870 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
871 user
, strlen(user
)+1, NULL
);
874 * Upper case here might help some NTLMv2 implementations
876 workgroup_upper
= talloc_strdup_upper(talloc_tos(), workgroup
);
877 if (tevent_req_nomem(workgroup_upper
, req
)) {
878 return tevent_req_post(req
, ev
);
880 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
881 workgroup_upper
, strlen(workgroup_upper
)+1,
883 TALLOC_FREE(workgroup_upper
);
885 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "Unix", 5, NULL
);
886 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "Samba", 6, NULL
);
887 if (tevent_req_nomem(bytes
, req
)) {
888 return tevent_req_post(req
, ev
);
891 subreq
= cli_smb_send(state
, ev
, cli
, SMBsesssetupX
, 0, 13, vwv
,
892 talloc_get_size(bytes
), bytes
);
893 if (tevent_req_nomem(subreq
, req
)) {
894 return tevent_req_post(req
, ev
);
896 tevent_req_set_callback(subreq
, cli_session_setup_nt1_done
, req
);
900 static void cli_session_setup_nt1_done(struct tevent_req
*subreq
)
902 struct tevent_req
*req
= tevent_req_callback_data(
903 subreq
, struct tevent_req
);
904 struct cli_session_setup_nt1_state
*state
= tevent_req_data(
905 req
, struct cli_session_setup_nt1_state
);
906 struct cli_state
*cli
= state
->cli
;
917 status
= cli_smb_recv(subreq
, state
, &in
, 3, &wct
, &vwv
,
920 if (!NT_STATUS_IS_OK(status
)) {
921 tevent_req_nterror(req
, status
);
925 inhdr
= in
+ NBT_HDR_SIZE
;
928 cli_state_set_uid(state
->cli
, SVAL(inhdr
, HDR_UID
));
930 status
= smb_bytes_talloc_string(cli
,
936 if (!NT_STATUS_IS_OK(status
)) {
937 tevent_req_nterror(req
, status
);
942 status
= smb_bytes_talloc_string(cli
,
948 if (!NT_STATUS_IS_OK(status
)) {
949 tevent_req_nterror(req
, status
);
954 status
= smb_bytes_talloc_string(cli
,
960 if (!NT_STATUS_IS_OK(status
)) {
961 tevent_req_nterror(req
, status
);
966 status
= cli_set_username(cli
, state
->user
);
967 if (tevent_req_nterror(req
, status
)) {
970 if (smb1cli_conn_activate_signing(cli
->conn
, state
->session_key
, state
->response
)
971 && !smb1cli_conn_check_signing(cli
->conn
, (uint8_t *)in
, 1)) {
972 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
975 if (state
->session_key
.data
) {
976 struct smbXcli_session
*session
= state
->cli
->smb1
.session
;
978 status
= smb1cli_session_set_session_key(session
,
980 if (tevent_req_nterror(req
, status
)) {
984 tevent_req_done(req
);
987 static NTSTATUS
cli_session_setup_nt1_recv(struct tevent_req
*req
)
989 return tevent_req_simple_recv_ntstatus(req
);
992 /* The following is calculated from :
994 * (smb_wcnt * 2) = 24 (smb_wcnt == 12 in cli_session_setup_blob_send() )
995 * (strlen("Unix") + 1 + strlen("Samba") + 1) * 2 = 22 (unicode strings at
999 #define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22)
1001 struct cli_sesssetup_blob_state
{
1002 struct tevent_context
*ev
;
1003 struct cli_state
*cli
;
1005 uint16_t max_blob_size
;
1009 DATA_BLOB smb2_blob
;
1010 struct iovec
*recv_iov
;
1017 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state
*state
,
1018 struct tevent_req
**psubreq
);
1019 static void cli_sesssetup_blob_done(struct tevent_req
*subreq
);
1021 static struct tevent_req
*cli_sesssetup_blob_send(TALLOC_CTX
*mem_ctx
,
1022 struct tevent_context
*ev
,
1023 struct cli_state
*cli
,
1026 struct tevent_req
*req
, *subreq
;
1027 struct cli_sesssetup_blob_state
*state
;
1028 uint32_t usable_space
;
1030 req
= tevent_req_create(mem_ctx
, &state
,
1031 struct cli_sesssetup_blob_state
);
1039 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
1040 usable_space
= UINT16_MAX
;
1042 usable_space
= cli_state_available_size(cli
,
1043 BASE_SESSSETUP_BLOB_PACKET_SIZE
);
1046 if (usable_space
== 0) {
1047 DEBUG(1, ("cli_session_setup_blob: cli->max_xmit too small "
1048 "(not possible to send %u bytes)\n",
1049 BASE_SESSSETUP_BLOB_PACKET_SIZE
+ 1));
1050 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1051 return tevent_req_post(req
, ev
);
1053 state
->max_blob_size
= MIN(usable_space
, 0xFFFF);
1055 if (!cli_sesssetup_blob_next(state
, &subreq
)) {
1056 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
1057 return tevent_req_post(req
, ev
);
1059 tevent_req_set_callback(subreq
, cli_sesssetup_blob_done
, req
);
1063 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state
*state
,
1064 struct tevent_req
**psubreq
)
1066 struct tevent_req
*subreq
;
1069 thistime
= MIN(state
->blob
.length
, state
->max_blob_size
);
1071 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
1073 state
->smb2_blob
.data
= state
->blob
.data
;
1074 state
->smb2_blob
.length
= thistime
;
1076 state
->blob
.data
+= thistime
;
1077 state
->blob
.length
-= thistime
;
1079 subreq
= smb2cli_session_setup_send(state
, state
->ev
,
1081 state
->cli
->timeout
,
1082 state
->cli
->smb2
.session
,
1084 SMB2_CAP_DFS
, /* in_capabilities */
1086 0, /* in_previous_session_id */
1088 if (subreq
== NULL
) {
1095 SCVAL(state
->vwv
+0, 0, 0xFF);
1096 SCVAL(state
->vwv
+0, 1, 0);
1097 SSVAL(state
->vwv
+1, 0, 0);
1098 SSVAL(state
->vwv
+2, 0, CLI_BUFFER_SIZE
);
1099 SSVAL(state
->vwv
+3, 0, 2);
1100 SSVAL(state
->vwv
+4, 0, 1);
1101 SIVAL(state
->vwv
+5, 0, 0);
1103 SSVAL(state
->vwv
+7, 0, thistime
);
1105 SSVAL(state
->vwv
+8, 0, 0);
1106 SSVAL(state
->vwv
+9, 0, 0);
1107 SIVAL(state
->vwv
+10, 0,
1108 cli_session_setup_capabilities(state
->cli
, CAP_EXTENDED_SECURITY
));
1110 state
->buf
= (uint8_t *)talloc_memdup(state
, state
->blob
.data
,
1112 if (state
->buf
== NULL
) {
1115 state
->blob
.data
+= thistime
;
1116 state
->blob
.length
-= thistime
;
1118 state
->buf
= smb_bytes_push_str(state
->buf
, smbXcli_conn_use_unicode(state
->cli
->conn
),
1120 state
->buf
= smb_bytes_push_str(state
->buf
, smbXcli_conn_use_unicode(state
->cli
->conn
),
1122 if (state
->buf
== NULL
) {
1125 subreq
= cli_smb_send(state
, state
->ev
, state
->cli
, SMBsesssetupX
, 0,
1127 talloc_get_size(state
->buf
), state
->buf
);
1128 if (subreq
== NULL
) {
1135 static void cli_sesssetup_blob_done(struct tevent_req
*subreq
)
1137 struct tevent_req
*req
= tevent_req_callback_data(
1138 subreq
, struct tevent_req
);
1139 struct cli_sesssetup_blob_state
*state
= tevent_req_data(
1140 req
, struct cli_sesssetup_blob_state
);
1141 struct cli_state
*cli
= state
->cli
;
1148 uint16_t blob_length
;
1153 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
1154 status
= smb2cli_session_setup_recv(subreq
, state
,
1158 status
= cli_smb_recv(subreq
, state
, &in
, 4, &wct
, &vwv
,
1159 &num_bytes
, &bytes
);
1160 TALLOC_FREE(state
->buf
);
1162 TALLOC_FREE(subreq
);
1163 if (!NT_STATUS_IS_OK(status
)
1164 && !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1165 tevent_req_nterror(req
, status
);
1169 state
->status
= status
;
1171 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
1176 inhdr
= in
+ NBT_HDR_SIZE
;
1177 cli_state_set_uid(state
->cli
, SVAL(inhdr
, HDR_UID
));
1179 blob_length
= SVAL(vwv
+3, 0);
1180 if (blob_length
> num_bytes
) {
1181 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
1184 state
->ret_blob
= data_blob_const(bytes
, blob_length
);
1186 p
= bytes
+ blob_length
;
1188 status
= smb_bytes_talloc_string(cli
,
1195 if (!NT_STATUS_IS_OK(status
)) {
1196 tevent_req_nterror(req
, status
);
1201 status
= smb_bytes_talloc_string(cli
,
1208 if (!NT_STATUS_IS_OK(status
)) {
1209 tevent_req_nterror(req
, status
);
1214 status
= smb_bytes_talloc_string(cli
,
1216 &cli
->server_domain
,
1221 if (!NT_STATUS_IS_OK(status
)) {
1222 tevent_req_nterror(req
, status
);
1228 if (state
->blob
.length
!= 0) {
1232 if (!cli_sesssetup_blob_next(state
, &subreq
)) {
1233 tevent_req_oom(req
);
1236 tevent_req_set_callback(subreq
, cli_sesssetup_blob_done
, req
);
1239 tevent_req_done(req
);
1242 static NTSTATUS
cli_sesssetup_blob_recv(struct tevent_req
*req
,
1243 TALLOC_CTX
*mem_ctx
,
1246 struct iovec
**precv_iov
)
1248 struct cli_sesssetup_blob_state
*state
= tevent_req_data(
1249 req
, struct cli_sesssetup_blob_state
);
1252 struct iovec
*recv_iov
;
1254 if (tevent_req_is_nterror(req
, &status
)) {
1255 TALLOC_FREE(state
->cli
->smb2
.session
);
1256 cli_state_set_uid(state
->cli
, UID_FIELD_INVALID
);
1260 inbuf
= talloc_move(mem_ctx
, &state
->inbuf
);
1261 recv_iov
= talloc_move(mem_ctx
, &state
->recv_iov
);
1262 if (pblob
!= NULL
) {
1263 *pblob
= state
->ret_blob
;
1265 if (pinbuf
!= NULL
) {
1268 if (precv_iov
!= NULL
) {
1269 *precv_iov
= recv_iov
;
1271 /* could be NT_STATUS_MORE_PROCESSING_REQUIRED */
1272 return state
->status
;
1277 /****************************************************************************
1278 Use in-memory credentials cache
1279 ****************************************************************************/
1281 static void use_in_memory_ccache(void) {
1282 setenv(KRB5_ENV_CCNAME
, "MEMORY:cliconnect", 1);
1285 /****************************************************************************
1286 Do a spnego/kerberos encrypted session setup.
1287 ****************************************************************************/
1289 struct cli_session_setup_kerberos_state
{
1290 struct cli_state
*cli
;
1291 DATA_BLOB negTokenTarg
;
1292 DATA_BLOB session_key_krb5
;
1293 ADS_STATUS ads_status
;
1296 static void cli_session_setup_kerberos_done(struct tevent_req
*subreq
);
1298 static struct tevent_req
*cli_session_setup_kerberos_send(
1299 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
1300 const char *principal
)
1302 struct tevent_req
*req
, *subreq
;
1303 struct cli_session_setup_kerberos_state
*state
;
1306 DEBUG(2,("Doing kerberos session setup\n"));
1308 req
= tevent_req_create(mem_ctx
, &state
,
1309 struct cli_session_setup_kerberos_state
);
1314 state
->ads_status
= ADS_SUCCESS
;
1317 * Ok, this is cheating: spnego_gen_krb5_negTokenInit can block if
1318 * we have to acquire a ticket. To be fixed later :-)
1320 rc
= spnego_gen_krb5_negTokenInit(state
, principal
, 0, &state
->negTokenTarg
,
1321 &state
->session_key_krb5
, 0, NULL
, NULL
);
1323 DEBUG(1, ("cli_session_setup_kerberos: "
1324 "spnego_gen_krb5_negTokenInit failed: %s\n",
1325 error_message(rc
)));
1326 state
->ads_status
= ADS_ERROR_KRB5(rc
);
1327 tevent_req_nterror(req
, NT_STATUS_UNSUCCESSFUL
);
1328 return tevent_req_post(req
, ev
);
1332 file_save("negTokenTarg.dat", state
->negTokenTarg
.data
,
1333 state
->negTokenTarg
.length
);
1336 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
1337 state
->cli
->smb2
.session
= smbXcli_session_create(cli
,
1339 if (tevent_req_nomem(state
->cli
->smb2
.session
, req
)) {
1340 return tevent_req_post(req
, ev
);
1344 subreq
= cli_sesssetup_blob_send(state
, ev
, cli
, state
->negTokenTarg
);
1345 if (tevent_req_nomem(subreq
, req
)) {
1346 return tevent_req_post(req
, ev
);
1348 tevent_req_set_callback(subreq
, cli_session_setup_kerberos_done
, req
);
1352 static void cli_session_setup_kerberos_done(struct tevent_req
*subreq
)
1354 struct tevent_req
*req
= tevent_req_callback_data(
1355 subreq
, struct tevent_req
);
1356 struct cli_session_setup_kerberos_state
*state
= tevent_req_data(
1357 req
, struct cli_session_setup_kerberos_state
);
1358 uint8_t *inbuf
= NULL
;
1359 struct iovec
*recv_iov
= NULL
;
1362 status
= cli_sesssetup_blob_recv(subreq
, state
,
1363 NULL
, &inbuf
, &recv_iov
);
1364 TALLOC_FREE(subreq
);
1365 if (!NT_STATUS_IS_OK(status
)) {
1366 tevent_req_nterror(req
, status
);
1370 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
1371 struct smbXcli_session
*session
= state
->cli
->smb2
.session
;
1372 status
= smb2cli_session_set_session_key(session
,
1373 state
->session_key_krb5
,
1375 if (tevent_req_nterror(req
, status
)) {
1379 struct smbXcli_session
*session
= state
->cli
->smb1
.session
;
1381 status
= smb1cli_session_set_session_key(session
,
1382 state
->session_key_krb5
);
1383 if (tevent_req_nterror(req
, status
)) {
1387 if (smb1cli_conn_activate_signing(state
->cli
->conn
, state
->session_key_krb5
,
1389 && !smb1cli_conn_check_signing(state
->cli
->conn
, inbuf
, 1)) {
1390 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1395 tevent_req_done(req
);
1398 static ADS_STATUS
cli_session_setup_kerberos_recv(struct tevent_req
*req
)
1400 struct cli_session_setup_kerberos_state
*state
= tevent_req_data(
1401 req
, struct cli_session_setup_kerberos_state
);
1404 if (tevent_req_is_nterror(req
, &status
)) {
1405 return ADS_ERROR_NT(status
);
1407 return state
->ads_status
;
1410 #endif /* HAVE_KRB5 */
1412 /****************************************************************************
1413 Do a spnego/NTLMSSP encrypted session setup.
1414 ****************************************************************************/
1416 struct cli_session_setup_ntlmssp_state
{
1417 struct tevent_context
*ev
;
1418 struct cli_state
*cli
;
1419 struct ntlmssp_state
*ntlmssp_state
;
1424 static int cli_session_setup_ntlmssp_state_destructor(
1425 struct cli_session_setup_ntlmssp_state
*state
)
1427 if (state
->ntlmssp_state
!= NULL
) {
1428 TALLOC_FREE(state
->ntlmssp_state
);
1433 static void cli_session_setup_ntlmssp_done(struct tevent_req
*req
);
1435 static struct tevent_req
*cli_session_setup_ntlmssp_send(
1436 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
1437 const char *user
, const char *pass
, const char *domain
)
1439 struct tevent_req
*req
, *subreq
;
1440 struct cli_session_setup_ntlmssp_state
*state
;
1443 const char *OIDs_ntlm
[] = {OID_NTLMSSP
, NULL
};
1445 req
= tevent_req_create(mem_ctx
, &state
,
1446 struct cli_session_setup_ntlmssp_state
);
1454 state
->ntlmssp_state
= NULL
;
1455 talloc_set_destructor(
1456 state
, cli_session_setup_ntlmssp_state_destructor
);
1458 status
= ntlmssp_client_start(state
,
1461 lp_client_ntlmv2_auth(),
1462 &state
->ntlmssp_state
);
1463 if (!NT_STATUS_IS_OK(status
)) {
1466 ntlmssp_want_feature(state
->ntlmssp_state
,
1467 NTLMSSP_FEATURE_SESSION_KEY
);
1468 if (cli
->use_ccache
) {
1469 ntlmssp_want_feature(state
->ntlmssp_state
,
1470 NTLMSSP_FEATURE_CCACHE
);
1472 status
= ntlmssp_set_username(state
->ntlmssp_state
, user
);
1473 if (!NT_STATUS_IS_OK(status
)) {
1476 status
= ntlmssp_set_domain(state
->ntlmssp_state
, domain
);
1477 if (!NT_STATUS_IS_OK(status
)) {
1480 if (cli
->pw_nt_hash
) {
1481 status
= ntlmssp_set_password_hash(state
->ntlmssp_state
, pass
);
1483 status
= ntlmssp_set_password(state
->ntlmssp_state
, pass
);
1485 if (!NT_STATUS_IS_OK(status
)) {
1488 status
= ntlmssp_update(state
->ntlmssp_state
, data_blob_null
,
1490 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1494 state
->blob_out
= spnego_gen_negTokenInit(state
, OIDs_ntlm
, &blob_out
, NULL
);
1495 data_blob_free(&blob_out
);
1497 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
1498 state
->cli
->smb2
.session
= smbXcli_session_create(cli
,
1500 if (tevent_req_nomem(state
->cli
->smb2
.session
, req
)) {
1501 return tevent_req_post(req
, ev
);
1505 subreq
= cli_sesssetup_blob_send(state
, ev
, cli
, state
->blob_out
);
1506 if (tevent_req_nomem(subreq
, req
)) {
1507 return tevent_req_post(req
, ev
);
1509 tevent_req_set_callback(subreq
, cli_session_setup_ntlmssp_done
, req
);
1512 tevent_req_nterror(req
, status
);
1513 return tevent_req_post(req
, ev
);
1516 static void cli_session_setup_ntlmssp_done(struct tevent_req
*subreq
)
1518 struct tevent_req
*req
= tevent_req_callback_data(
1519 subreq
, struct tevent_req
);
1520 struct cli_session_setup_ntlmssp_state
*state
= tevent_req_data(
1521 req
, struct cli_session_setup_ntlmssp_state
);
1522 DATA_BLOB blob_in
, msg_in
, blob_out
;
1523 uint8_t *inbuf
= NULL
;
1524 struct iovec
*recv_iov
= NULL
;
1528 status
= cli_sesssetup_blob_recv(subreq
, talloc_tos(), &blob_in
,
1530 TALLOC_FREE(subreq
);
1531 data_blob_free(&state
->blob_out
);
1533 if (NT_STATUS_IS_OK(status
)) {
1534 if (state
->cli
->server_domain
[0] == '\0') {
1535 TALLOC_FREE(state
->cli
->server_domain
);
1536 state
->cli
->server_domain
= talloc_strdup(state
->cli
,
1537 state
->ntlmssp_state
->server
.netbios_domain
);
1538 if (state
->cli
->server_domain
== NULL
) {
1539 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
1544 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
1545 struct smbXcli_session
*session
= state
->cli
->smb2
.session
;
1547 if (ntlmssp_is_anonymous(state
->ntlmssp_state
)) {
1549 * Windows server does not set the
1550 * SMB2_SESSION_FLAG_IS_GUEST nor
1551 * SMB2_SESSION_FLAG_IS_NULL flag.
1553 * This fix makes sure we do not try
1554 * to verify a signature on the final
1555 * session setup response.
1557 TALLOC_FREE(state
->ntlmssp_state
);
1558 tevent_req_done(req
);
1562 status
= smb2cli_session_set_session_key(session
,
1563 state
->ntlmssp_state
->session_key
,
1565 if (tevent_req_nterror(req
, status
)) {
1569 struct smbXcli_session
*session
= state
->cli
->smb1
.session
;
1571 status
= smb1cli_session_set_session_key(session
,
1572 state
->ntlmssp_state
->session_key
);
1573 if (tevent_req_nterror(req
, status
)) {
1577 if (smb1cli_conn_activate_signing(
1578 state
->cli
->conn
, state
->ntlmssp_state
->session_key
,
1580 && !smb1cli_conn_check_signing(state
->cli
->conn
, inbuf
, 1)) {
1581 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1585 TALLOC_FREE(state
->ntlmssp_state
);
1586 tevent_req_done(req
);
1589 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1590 tevent_req_nterror(req
, status
);
1594 if (blob_in
.length
== 0) {
1595 tevent_req_nterror(req
, NT_STATUS_UNSUCCESSFUL
);
1599 if ((state
->turn
== 1)
1600 && NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1601 DATA_BLOB tmp_blob
= data_blob_null
;
1602 /* the server might give us back two challenges */
1603 parse_ret
= spnego_parse_challenge(state
, blob_in
, &msg_in
,
1605 data_blob_free(&tmp_blob
);
1607 parse_ret
= spnego_parse_auth_response(state
, blob_in
, status
,
1608 OID_NTLMSSP
, &msg_in
);
1613 DEBUG(3,("Failed to parse auth response\n"));
1614 if (NT_STATUS_IS_OK(status
)
1615 || NT_STATUS_EQUAL(status
,
1616 NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1618 req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
1623 status
= ntlmssp_update(state
->ntlmssp_state
, msg_in
, &blob_out
);
1625 if (!NT_STATUS_IS_OK(status
)
1626 && !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1627 TALLOC_FREE(state
->ntlmssp_state
);
1628 tevent_req_nterror(req
, status
);
1632 state
->blob_out
= spnego_gen_auth(state
, blob_out
);
1633 if (tevent_req_nomem(state
->blob_out
.data
, req
)) {
1637 subreq
= cli_sesssetup_blob_send(state
, state
->ev
, state
->cli
,
1639 if (tevent_req_nomem(subreq
, req
)) {
1642 tevent_req_set_callback(subreq
, cli_session_setup_ntlmssp_done
, req
);
1645 static NTSTATUS
cli_session_setup_ntlmssp_recv(struct tevent_req
*req
)
1647 struct cli_session_setup_ntlmssp_state
*state
= tevent_req_data(
1648 req
, struct cli_session_setup_ntlmssp_state
);
1651 if (tevent_req_is_nterror(req
, &status
)) {
1652 cli_state_set_uid(state
->cli
, UID_FIELD_INVALID
);
1655 return NT_STATUS_OK
;
1660 static char *cli_session_setup_get_principal(
1661 TALLOC_CTX
*mem_ctx
, const char *spnego_principal
,
1662 const char *remote_name
, const char *dest_realm
)
1664 char *principal
= NULL
;
1666 if (!lp_client_use_spnego_principal() ||
1667 strequal(principal
, ADS_IGNORE_PRINCIPAL
)) {
1668 spnego_principal
= NULL
;
1670 if (spnego_principal
!= NULL
) {
1671 DEBUG(3, ("cli_session_setup_spnego: using spnego provided "
1672 "principal %s\n", spnego_principal
));
1673 return talloc_strdup(mem_ctx
, spnego_principal
);
1675 if (is_ipaddress(remote_name
) ||
1676 strequal(remote_name
, STAR_SMBSERVER
)) {
1680 DEBUG(3, ("cli_session_setup_spnego: using target "
1681 "hostname not SPNEGO principal\n"));
1684 char *realm
= strupper_talloc(talloc_tos(), dest_realm
);
1685 if (realm
== NULL
) {
1688 principal
= talloc_asprintf(talloc_tos(), "cifs/%s@%s",
1689 remote_name
, realm
);
1692 principal
= kerberos_get_principal_from_service_hostname(
1693 talloc_tos(), "cifs", remote_name
, lp_realm());
1695 DEBUG(3, ("cli_session_setup_spnego: guessed server principal=%s\n",
1696 principal
? principal
: "<null>"));
1702 static char *cli_session_setup_get_account(TALLOC_CTX
*mem_ctx
,
1703 const char *principal
)
1707 account
= talloc_strdup(mem_ctx
, principal
);
1708 if (account
== NULL
) {
1711 p
= strchr_m(account
, '@');
1718 /****************************************************************************
1719 Do a spnego encrypted session setup.
1721 user_domain: The shortname of the domain the user/machine is a member of.
1722 dest_realm: The realm we're connecting to, if NULL we use our default realm.
1723 ****************************************************************************/
1725 struct cli_session_setup_spnego_state
{
1726 struct tevent_context
*ev
;
1727 struct cli_state
*cli
;
1729 const char *account
;
1731 const char *user_domain
;
1732 const char *dest_realm
;
1737 static void cli_session_setup_spnego_done_krb(struct tevent_req
*subreq
);
1740 static void cli_session_setup_spnego_done_ntlmssp(struct tevent_req
*subreq
);
1742 static struct tevent_req
*cli_session_setup_spnego_send(
1743 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
1744 const char *user
, const char *pass
, const char *user_domain
,
1745 const char *dest_realm
)
1747 struct tevent_req
*req
, *subreq
;
1748 struct cli_session_setup_spnego_state
*state
;
1749 char *principal
= NULL
;
1750 char *OIDs
[ASN1_MAX_OIDS
];
1752 const DATA_BLOB
*server_blob
;
1755 req
= tevent_req_create(mem_ctx
, &state
,
1756 struct cli_session_setup_spnego_state
);
1764 state
->user_domain
= user_domain
;
1765 state
->dest_realm
= dest_realm
;
1767 state
->account
= cli_session_setup_get_account(state
, user
);
1768 if (tevent_req_nomem(state
->account
, req
)) {
1769 return tevent_req_post(req
, ev
);
1772 server_blob
= smbXcli_conn_server_gss_blob(cli
->conn
);
1774 DEBUG(3,("Doing spnego session setup (blob length=%lu)\n",
1775 (unsigned long)server_blob
->length
));
1777 /* the server might not even do spnego */
1778 if (server_blob
->length
== 0) {
1779 DEBUG(3,("server didn't supply a full spnego negprot\n"));
1784 file_save("negprot.dat", cli
->secblob
.data
, cli
->secblob
.length
);
1787 /* The server sent us the first part of the SPNEGO exchange in the
1788 * negprot reply. It is WRONG to depend on the principal sent in the
1789 * negprot reply, but right now we do it. If we don't receive one,
1790 * we try to best guess, then fall back to NTLM. */
1791 if (!spnego_parse_negTokenInit(state
, *server_blob
, OIDs
,
1792 &principal
, NULL
) ||
1794 state
->result
= ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
1795 tevent_req_done(req
);
1796 return tevent_req_post(req
, ev
);
1799 /* make sure the server understands kerberos */
1800 for (i
=0;OIDs
[i
];i
++) {
1802 DEBUG(3,("got OID=%s\n", OIDs
[i
]));
1804 DEBUGADD(3,("got OID=%s\n", OIDs
[i
]));
1805 if (strcmp(OIDs
[i
], OID_KERBEROS5_OLD
) == 0 ||
1806 strcmp(OIDs
[i
], OID_KERBEROS5
) == 0) {
1807 cli
->got_kerberos_mechanism
= True
;
1809 talloc_free(OIDs
[i
]);
1812 DEBUG(3,("got principal=%s\n", principal
? principal
: "<null>"));
1814 status
= cli_set_username(cli
, user
);
1815 if (!NT_STATUS_IS_OK(status
)) {
1816 state
->result
= ADS_ERROR_NT(status
);
1817 tevent_req_done(req
);
1818 return tevent_req_post(req
, ev
);
1822 /* If password is set we reauthenticate to kerberos server
1823 * and do not store results */
1825 if (user
&& *user
&& cli
->got_kerberos_mechanism
&& cli
->use_kerberos
) {
1826 const char *remote_name
= smbXcli_conn_remote_name(cli
->conn
);
1829 if (pass
&& *pass
) {
1832 use_in_memory_ccache();
1833 ret
= kerberos_kinit_password(user
, pass
, 0 /* no time correction for now */, NULL
);
1836 TALLOC_FREE(principal
);
1837 DEBUG(0, ("Kinit failed: %s\n", error_message(ret
)));
1838 if (cli
->fallback_after_kerberos
)
1840 state
->result
= ADS_ERROR_KRB5(ret
);
1841 tevent_req_done(req
);
1842 return tevent_req_post(req
, ev
);
1846 tmp
= cli_session_setup_get_principal(
1847 talloc_tos(), principal
, remote_name
, dest_realm
);
1848 TALLOC_FREE(principal
);
1852 subreq
= cli_session_setup_kerberos_send(
1853 state
, ev
, cli
, principal
);
1854 if (tevent_req_nomem(subreq
, req
)) {
1855 return tevent_req_post(req
, ev
);
1857 tevent_req_set_callback(
1858 subreq
, cli_session_setup_spnego_done_krb
,
1866 subreq
= cli_session_setup_ntlmssp_send(
1867 state
, ev
, cli
, state
->account
, pass
, user_domain
);
1868 if (tevent_req_nomem(subreq
, req
)) {
1869 return tevent_req_post(req
, ev
);
1871 tevent_req_set_callback(
1872 subreq
, cli_session_setup_spnego_done_ntlmssp
, req
);
1877 static void cli_session_setup_spnego_done_krb(struct tevent_req
*subreq
)
1879 struct tevent_req
*req
= tevent_req_callback_data(
1880 subreq
, struct tevent_req
);
1881 struct cli_session_setup_spnego_state
*state
= tevent_req_data(
1882 req
, struct cli_session_setup_spnego_state
);
1884 state
->result
= cli_session_setup_kerberos_recv(subreq
);
1885 TALLOC_FREE(subreq
);
1887 if (ADS_ERR_OK(state
->result
) ||
1888 !state
->cli
->fallback_after_kerberos
) {
1889 tevent_req_done(req
);
1893 subreq
= cli_session_setup_ntlmssp_send(
1894 state
, state
->ev
, state
->cli
, state
->account
, state
->pass
,
1895 state
->user_domain
);
1896 if (tevent_req_nomem(subreq
, req
)) {
1899 tevent_req_set_callback(subreq
, cli_session_setup_spnego_done_ntlmssp
,
1904 static void cli_session_setup_spnego_done_ntlmssp(struct tevent_req
*subreq
)
1906 struct tevent_req
*req
= tevent_req_callback_data(
1907 subreq
, struct tevent_req
);
1908 struct cli_session_setup_spnego_state
*state
= tevent_req_data(
1909 req
, struct cli_session_setup_spnego_state
);
1912 status
= cli_session_setup_ntlmssp_recv(subreq
);
1913 TALLOC_FREE(subreq
);
1914 state
->result
= ADS_ERROR_NT(status
);
1915 tevent_req_done(req
);
1918 static ADS_STATUS
cli_session_setup_spnego_recv(struct tevent_req
*req
)
1920 struct cli_session_setup_spnego_state
*state
= tevent_req_data(
1921 req
, struct cli_session_setup_spnego_state
);
1923 return state
->result
;
1926 struct cli_session_setup_state
{
1930 static void cli_session_setup_done_lanman2(struct tevent_req
*subreq
);
1931 static void cli_session_setup_done_spnego(struct tevent_req
*subreq
);
1932 static void cli_session_setup_done_guest(struct tevent_req
*subreq
);
1933 static void cli_session_setup_done_plain(struct tevent_req
*subreq
);
1934 static void cli_session_setup_done_nt1(struct tevent_req
*subreq
);
1936 /****************************************************************************
1937 Send a session setup. The username and workgroup is in UNIX character
1938 format and must be converted to DOS codepage format before sending. If the
1939 password is in plaintext, the same should be done.
1940 ****************************************************************************/
1942 struct tevent_req
*cli_session_setup_send(TALLOC_CTX
*mem_ctx
,
1943 struct tevent_context
*ev
,
1944 struct cli_state
*cli
,
1946 const char *pass
, int passlen
,
1947 const char *ntpass
, int ntpasslen
,
1948 const char *workgroup
)
1950 struct tevent_req
*req
, *subreq
;
1951 struct cli_session_setup_state
*state
;
1954 uint16_t sec_mode
= smb1cli_conn_server_security_mode(cli
->conn
);
1956 req
= tevent_req_create(mem_ctx
, &state
,
1957 struct cli_session_setup_state
);
1963 user2
= talloc_strdup(state
, user
);
1965 user2
= talloc_strdup(state
, "");
1967 if (user2
== NULL
) {
1968 tevent_req_oom(req
);
1969 return tevent_req_post(req
, ev
);
1976 /* allow for workgroups as part of the username */
1977 if ((p
=strchr_m(user2
,'\\')) || (p
=strchr_m(user2
,'/')) ||
1978 (p
=strchr_m(user2
,*lp_winbind_separator()))) {
1981 if (!strupper_m(user2
)) {
1982 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1983 return tevent_req_post(req
, ev
);
1988 if (smbXcli_conn_protocol(cli
->conn
) < PROTOCOL_LANMAN1
) {
1989 tevent_req_done(req
);
1990 return tevent_req_post(req
, ev
);
1993 /* now work out what sort of session setup we are going to
1994 do. I have split this into separate functions to make the
1995 flow a bit easier to understand (tridge) */
1997 /* if its an older server then we have to use the older request format */
1999 if (smbXcli_conn_protocol(cli
->conn
) < PROTOCOL_NT1
) {
2000 if (!lp_client_lanman_auth() && passlen
!= 24 && (*pass
)) {
2001 DEBUG(1, ("Server requested LM password but 'client lanman auth = no'"
2002 " or 'client ntlmv2 auth = yes'\n"));
2003 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
2004 return tevent_req_post(req
, ev
);
2007 if ((sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
) == 0 &&
2008 !lp_client_plaintext_auth() && (*pass
)) {
2009 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
2010 " or 'client ntlmv2 auth = yes'\n"));
2011 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
2012 return tevent_req_post(req
, ev
);
2015 subreq
= cli_session_setup_lanman2_send(
2016 state
, ev
, cli
, user
, pass
, passlen
, workgroup
);
2017 if (tevent_req_nomem(subreq
, req
)) {
2018 return tevent_req_post(req
, ev
);
2020 tevent_req_set_callback(subreq
, cli_session_setup_done_lanman2
,
2025 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
2026 const char *remote_realm
= cli_state_remote_realm(cli
);
2028 subreq
= cli_session_setup_spnego_send(
2029 state
, ev
, cli
, user
, pass
, workgroup
, remote_realm
);
2030 if (tevent_req_nomem(subreq
, req
)) {
2031 return tevent_req_post(req
, ev
);
2033 tevent_req_set_callback(subreq
, cli_session_setup_done_spnego
,
2038 /* if no user is supplied then we have to do an anonymous connection.
2039 passwords are ignored */
2041 if (!user
|| !*user
) {
2042 subreq
= cli_session_setup_guest_send(state
, ev
, cli
);
2043 if (tevent_req_nomem(subreq
, req
)) {
2044 return tevent_req_post(req
, ev
);
2046 tevent_req_set_callback(subreq
, cli_session_setup_done_guest
,
2051 /* if the server is share level then send a plaintext null
2052 password at this point. The password is sent in the tree
2055 if ((sec_mode
& NEGOTIATE_SECURITY_USER_LEVEL
) == 0) {
2056 subreq
= cli_session_setup_plain_send(
2057 state
, ev
, cli
, user
, "", workgroup
);
2058 if (tevent_req_nomem(subreq
, req
)) {
2059 return tevent_req_post(req
, ev
);
2061 tevent_req_set_callback(subreq
, cli_session_setup_done_plain
,
2066 /* if the server doesn't support encryption then we have to use
2067 plaintext. The second password is ignored */
2069 if ((sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
) == 0) {
2070 if (!lp_client_plaintext_auth() && (*pass
)) {
2071 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
2072 " or 'client ntlmv2 auth = yes'\n"));
2073 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
2074 return tevent_req_post(req
, ev
);
2076 subreq
= cli_session_setup_plain_send(
2077 state
, ev
, cli
, user
, pass
, workgroup
);
2078 if (tevent_req_nomem(subreq
, req
)) {
2079 return tevent_req_post(req
, ev
);
2081 tevent_req_set_callback(subreq
, cli_session_setup_done_plain
,
2086 /* if the server supports extended security then use SPNEGO */
2088 if (smb1cli_conn_capabilities(cli
->conn
) & CAP_EXTENDED_SECURITY
) {
2089 const char *remote_realm
= cli_state_remote_realm(cli
);
2091 subreq
= cli_session_setup_spnego_send(
2092 state
, ev
, cli
, user
, pass
, workgroup
, remote_realm
);
2093 if (tevent_req_nomem(subreq
, req
)) {
2094 return tevent_req_post(req
, ev
);
2096 tevent_req_set_callback(subreq
, cli_session_setup_done_spnego
,
2100 /* otherwise do a NT1 style session setup */
2102 subreq
= cli_session_setup_nt1_send(
2103 state
, ev
, cli
, user
, pass
, passlen
, ntpass
, ntpasslen
,
2105 if (tevent_req_nomem(subreq
, req
)) {
2106 return tevent_req_post(req
, ev
);
2108 tevent_req_set_callback(subreq
, cli_session_setup_done_nt1
,
2113 tevent_req_done(req
);
2114 return tevent_req_post(req
, ev
);
2117 static void cli_session_setup_done_lanman2(struct tevent_req
*subreq
)
2119 struct tevent_req
*req
= tevent_req_callback_data(
2120 subreq
, struct tevent_req
);
2123 status
= cli_session_setup_lanman2_recv(subreq
);
2124 TALLOC_FREE(subreq
);
2125 if (!NT_STATUS_IS_OK(status
)) {
2126 tevent_req_nterror(req
, status
);
2129 tevent_req_done(req
);
2132 static void cli_session_setup_done_spnego(struct tevent_req
*subreq
)
2134 struct tevent_req
*req
= tevent_req_callback_data(
2135 subreq
, struct tevent_req
);
2138 status
= cli_session_setup_spnego_recv(subreq
);
2139 TALLOC_FREE(subreq
);
2140 if (!ADS_ERR_OK(status
)) {
2141 DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status
)));
2142 tevent_req_nterror(req
, ads_ntstatus(status
));
2145 tevent_req_done(req
);
2148 static void cli_session_setup_done_guest(struct tevent_req
*subreq
)
2150 struct tevent_req
*req
= tevent_req_callback_data(
2151 subreq
, struct tevent_req
);
2154 status
= cli_session_setup_guest_recv(subreq
);
2155 TALLOC_FREE(subreq
);
2156 if (!NT_STATUS_IS_OK(status
)) {
2157 tevent_req_nterror(req
, status
);
2160 tevent_req_done(req
);
2163 static void cli_session_setup_done_plain(struct tevent_req
*subreq
)
2165 struct tevent_req
*req
= tevent_req_callback_data(
2166 subreq
, struct tevent_req
);
2169 status
= cli_session_setup_plain_recv(subreq
);
2170 TALLOC_FREE(subreq
);
2171 if (!NT_STATUS_IS_OK(status
)) {
2172 tevent_req_nterror(req
, status
);
2175 tevent_req_done(req
);
2178 static void cli_session_setup_done_nt1(struct tevent_req
*subreq
)
2180 struct tevent_req
*req
= tevent_req_callback_data(
2181 subreq
, struct tevent_req
);
2184 status
= cli_session_setup_nt1_recv(subreq
);
2185 TALLOC_FREE(subreq
);
2186 if (!NT_STATUS_IS_OK(status
)) {
2187 DEBUG(3, ("cli_session_setup: NT1 session setup "
2188 "failed: %s\n", nt_errstr(status
)));
2189 tevent_req_nterror(req
, status
);
2192 tevent_req_done(req
);
2195 NTSTATUS
cli_session_setup_recv(struct tevent_req
*req
)
2197 return tevent_req_simple_recv_ntstatus(req
);
2200 NTSTATUS
cli_session_setup(struct cli_state
*cli
,
2202 const char *pass
, int passlen
,
2203 const char *ntpass
, int ntpasslen
,
2204 const char *workgroup
)
2206 struct tevent_context
*ev
;
2207 struct tevent_req
*req
;
2208 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2210 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
2211 return NT_STATUS_INVALID_PARAMETER
;
2213 ev
= samba_tevent_context_init(talloc_tos());
2217 req
= cli_session_setup_send(ev
, ev
, cli
, user
, pass
, passlen
,
2218 ntpass
, ntpasslen
, workgroup
);
2222 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2225 status
= cli_session_setup_recv(req
);
2231 /****************************************************************************
2233 *****************************************************************************/
2235 struct cli_ulogoff_state
{
2236 struct cli_state
*cli
;
2240 static void cli_ulogoff_done(struct tevent_req
*subreq
);
2242 static struct tevent_req
*cli_ulogoff_send(TALLOC_CTX
*mem_ctx
,
2243 struct tevent_context
*ev
,
2244 struct cli_state
*cli
)
2246 struct tevent_req
*req
, *subreq
;
2247 struct cli_ulogoff_state
*state
;
2249 req
= tevent_req_create(mem_ctx
, &state
, struct cli_ulogoff_state
);
2255 SCVAL(state
->vwv
+0, 0, 0xFF);
2256 SCVAL(state
->vwv
+1, 0, 0);
2257 SSVAL(state
->vwv
+2, 0, 0);
2259 subreq
= cli_smb_send(state
, ev
, cli
, SMBulogoffX
, 0, 2, state
->vwv
,
2261 if (tevent_req_nomem(subreq
, req
)) {
2262 return tevent_req_post(req
, ev
);
2264 tevent_req_set_callback(subreq
, cli_ulogoff_done
, req
);
2268 static void cli_ulogoff_done(struct tevent_req
*subreq
)
2270 struct tevent_req
*req
= tevent_req_callback_data(
2271 subreq
, struct tevent_req
);
2272 struct cli_ulogoff_state
*state
= tevent_req_data(
2273 req
, struct cli_ulogoff_state
);
2276 status
= cli_smb_recv(subreq
, NULL
, NULL
, 0, NULL
, NULL
, NULL
, NULL
);
2277 if (!NT_STATUS_IS_OK(status
)) {
2278 tevent_req_nterror(req
, status
);
2281 cli_state_set_uid(state
->cli
, UID_FIELD_INVALID
);
2282 tevent_req_done(req
);
2285 static NTSTATUS
cli_ulogoff_recv(struct tevent_req
*req
)
2287 return tevent_req_simple_recv_ntstatus(req
);
2290 NTSTATUS
cli_ulogoff(struct cli_state
*cli
)
2292 struct tevent_context
*ev
;
2293 struct tevent_req
*req
;
2294 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2296 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
2297 status
= smb2cli_logoff(cli
->conn
,
2300 if (!NT_STATUS_IS_OK(status
)) {
2303 smb2cli_session_set_id_and_flags(cli
->smb2
.session
,
2305 return NT_STATUS_OK
;
2308 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
2309 return NT_STATUS_INVALID_PARAMETER
;
2311 ev
= samba_tevent_context_init(talloc_tos());
2315 req
= cli_ulogoff_send(ev
, ev
, cli
);
2319 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2322 status
= cli_ulogoff_recv(req
);
2328 /****************************************************************************
2330 ****************************************************************************/
2332 struct cli_tcon_andx_state
{
2333 struct cli_state
*cli
;
2338 static void cli_tcon_andx_done(struct tevent_req
*subreq
);
2340 struct tevent_req
*cli_tcon_andx_create(TALLOC_CTX
*mem_ctx
,
2341 struct tevent_context
*ev
,
2342 struct cli_state
*cli
,
2343 const char *share
, const char *dev
,
2344 const char *pass
, int passlen
,
2345 struct tevent_req
**psmbreq
)
2347 struct tevent_req
*req
, *subreq
;
2348 struct cli_tcon_andx_state
*state
;
2353 uint16_t sec_mode
= smb1cli_conn_server_security_mode(cli
->conn
);
2354 uint16_t tcon_flags
= 0;
2358 req
= tevent_req_create(mem_ctx
, &state
, struct cli_tcon_andx_state
);
2365 cli
->share
= talloc_strdup(cli
, share
);
2370 /* in user level security don't send a password now */
2371 if (sec_mode
& NEGOTIATE_SECURITY_USER_LEVEL
) {
2374 } else if (pass
== NULL
) {
2375 DEBUG(1, ("Server not using user level security and no "
2376 "password supplied.\n"));
2380 if ((sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
) &&
2381 *pass
&& passlen
!= 24) {
2382 if (!lp_client_lanman_auth()) {
2383 DEBUG(1, ("Server requested LANMAN password "
2384 "(share-level security) but "
2385 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2390 * Non-encrypted passwords - convert to DOS codepage before
2393 SMBencrypt(pass
, smb1cli_conn_server_challenge(cli
->conn
), p24
);
2395 pass
= (const char *)p24
;
2397 if((sec_mode
& (NEGOTIATE_SECURITY_USER_LEVEL
2398 |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
))
2402 if (!lp_client_plaintext_auth() && (*pass
)) {
2403 DEBUG(1, ("Server requested PLAINTEXT "
2405 "'client plaintext auth = no' or 'client ntlmv2 auth = yes'\n"));
2410 * Non-encrypted passwords - convert to DOS codepage
2413 tmp_pass
= talloc_array(talloc_tos(), uint8
, 0);
2414 if (tevent_req_nomem(tmp_pass
, req
)) {
2415 return tevent_req_post(req
, ev
);
2417 tmp_pass
= trans2_bytes_push_str(tmp_pass
,
2418 false, /* always DOS */
2422 if (tevent_req_nomem(tmp_pass
, req
)) {
2423 return tevent_req_post(req
, ev
);
2425 pass
= (const char *)tmp_pass
;
2426 passlen
= talloc_get_size(tmp_pass
);
2430 tcon_flags
|= TCONX_FLAG_EXTENDED_RESPONSE
;
2431 tcon_flags
|= TCONX_FLAG_EXTENDED_SIGNATURES
;
2433 SCVAL(vwv
+0, 0, 0xFF);
2436 SSVAL(vwv
+2, 0, tcon_flags
);
2437 SSVAL(vwv
+3, 0, passlen
);
2439 if (passlen
&& pass
) {
2440 bytes
= (uint8_t *)talloc_memdup(state
, pass
, passlen
);
2442 bytes
= talloc_array(state
, uint8_t, 0);
2448 tmp
= talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
2449 smbXcli_conn_remote_name(cli
->conn
), share
);
2454 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), tmp
, strlen(tmp
)+1,
2459 * Add the devicetype
2461 tmp
= talloc_strdup_upper(talloc_tos(), dev
);
2466 bytes
= smb_bytes_push_str(bytes
, false, tmp
, strlen(tmp
)+1, NULL
);
2469 if (bytes
== NULL
) {
2474 state
->bytes
.iov_base
= (void *)bytes
;
2475 state
->bytes
.iov_len
= talloc_get_size(bytes
);
2477 subreq
= cli_smb_req_create(state
, ev
, cli
, SMBtconX
, 0, 4, vwv
,
2479 if (subreq
== NULL
) {
2483 tevent_req_set_callback(subreq
, cli_tcon_andx_done
, req
);
2488 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
2489 return tevent_req_post(req
, ev
);
2492 struct tevent_req
*cli_tcon_andx_send(TALLOC_CTX
*mem_ctx
,
2493 struct tevent_context
*ev
,
2494 struct cli_state
*cli
,
2495 const char *share
, const char *dev
,
2496 const char *pass
, int passlen
)
2498 struct tevent_req
*req
, *subreq
;
2501 req
= cli_tcon_andx_create(mem_ctx
, ev
, cli
, share
, dev
, pass
, passlen
,
2506 if (subreq
== NULL
) {
2509 status
= smb1cli_req_chain_submit(&subreq
, 1);
2510 if (!NT_STATUS_IS_OK(status
)) {
2511 tevent_req_nterror(req
, status
);
2512 return tevent_req_post(req
, ev
);
2517 static void cli_tcon_andx_done(struct tevent_req
*subreq
)
2519 struct tevent_req
*req
= tevent_req_callback_data(
2520 subreq
, struct tevent_req
);
2521 struct cli_tcon_andx_state
*state
= tevent_req_data(
2522 req
, struct cli_tcon_andx_state
);
2523 struct cli_state
*cli
= state
->cli
;
2531 uint16_t optional_support
= 0;
2533 status
= cli_smb_recv(subreq
, state
, &in
, 0, &wct
, &vwv
,
2534 &num_bytes
, &bytes
);
2535 TALLOC_FREE(subreq
);
2536 if (!NT_STATUS_IS_OK(status
)) {
2537 tevent_req_nterror(req
, status
);
2541 inhdr
= in
+ NBT_HDR_SIZE
;
2544 if (clistr_pull_talloc(cli
,
2545 (const char *)inhdr
,
2546 SVAL(inhdr
, HDR_FLG2
),
2550 STR_TERMINATE
|STR_ASCII
) == -1) {
2551 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
2555 cli
->dev
= talloc_strdup(cli
, "");
2556 if (cli
->dev
== NULL
) {
2557 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
2562 if ((smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_NT1
) && (num_bytes
== 3)) {
2563 /* almost certainly win95 - enable bug fixes */
2568 * Make sure that we have the optional support 16-bit field. WCT > 2.
2569 * Avoids issues when connecting to Win9x boxes sharing files
2572 if ((wct
> 2) && (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_LANMAN2
)) {
2573 optional_support
= SVAL(vwv
+2, 0);
2576 if (optional_support
& SMB_EXTENDED_SIGNATURES
) {
2577 smb1cli_session_protect_session_key(cli
->smb1
.session
);
2580 smb1cli_tcon_set_values(state
->cli
->smb1
.tcon
,
2581 SVAL(inhdr
, HDR_TID
),
2583 0, /* maximal_access */
2584 0, /* guest_maximal_access */
2586 NULL
); /* fs_type */
2588 tevent_req_done(req
);
2591 NTSTATUS
cli_tcon_andx_recv(struct tevent_req
*req
)
2593 return tevent_req_simple_recv_ntstatus(req
);
2596 NTSTATUS
cli_tcon_andx(struct cli_state
*cli
, const char *share
,
2597 const char *dev
, const char *pass
, int passlen
)
2599 TALLOC_CTX
*frame
= talloc_stackframe();
2600 struct tevent_context
*ev
;
2601 struct tevent_req
*req
;
2602 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2604 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
2606 * Can't use sync call while an async call is in flight
2608 status
= NT_STATUS_INVALID_PARAMETER
;
2612 ev
= samba_tevent_context_init(frame
);
2617 req
= cli_tcon_andx_send(frame
, ev
, cli
, share
, dev
, pass
, passlen
);
2622 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2626 status
= cli_tcon_andx_recv(req
);
2632 struct cli_tree_connect_state
{
2633 struct cli_state
*cli
;
2636 static struct tevent_req
*cli_raw_tcon_send(
2637 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
2638 const char *service
, const char *pass
, const char *dev
);
2639 static NTSTATUS
cli_raw_tcon_recv(struct tevent_req
*req
,
2640 uint16
*max_xmit
, uint16
*tid
);
2642 static void cli_tree_connect_smb2_done(struct tevent_req
*subreq
);
2643 static void cli_tree_connect_andx_done(struct tevent_req
*subreq
);
2644 static void cli_tree_connect_raw_done(struct tevent_req
*subreq
);
2646 static struct tevent_req
*cli_tree_connect_send(
2647 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
2648 const char *share
, const char *dev
, const char *pass
, int passlen
)
2650 struct tevent_req
*req
, *subreq
;
2651 struct cli_tree_connect_state
*state
;
2653 req
= tevent_req_create(mem_ctx
, &state
,
2654 struct cli_tree_connect_state
);
2660 cli
->share
= talloc_strdup(cli
, share
);
2661 if (tevent_req_nomem(cli
->share
, req
)) {
2662 return tevent_req_post(req
, ev
);
2665 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
2668 cli
->smb2
.tcon
= smbXcli_tcon_create(cli
);
2669 if (tevent_req_nomem(cli
->smb2
.tcon
, req
)) {
2670 return tevent_req_post(req
, ev
);
2673 unc
= talloc_asprintf(state
, "\\\\%s\\%s",
2674 smbXcli_conn_remote_name(cli
->conn
),
2676 if (tevent_req_nomem(unc
, req
)) {
2677 return tevent_req_post(req
, ev
);
2680 subreq
= smb2cli_tcon_send(state
, ev
, cli
->conn
, cli
->timeout
,
2681 cli
->smb2
.session
, cli
->smb2
.tcon
,
2684 if (tevent_req_nomem(subreq
, req
)) {
2685 return tevent_req_post(req
, ev
);
2687 tevent_req_set_callback(subreq
, cli_tree_connect_smb2_done
,
2692 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_LANMAN1
) {
2693 subreq
= cli_tcon_andx_send(state
, ev
, cli
, share
, dev
,
2695 if (tevent_req_nomem(subreq
, req
)) {
2696 return tevent_req_post(req
, ev
);
2698 tevent_req_set_callback(subreq
, cli_tree_connect_andx_done
,
2703 subreq
= cli_raw_tcon_send(state
, ev
, cli
, share
, pass
, dev
);
2704 if (tevent_req_nomem(subreq
, req
)) {
2705 return tevent_req_post(req
, ev
);
2707 tevent_req_set_callback(subreq
, cli_tree_connect_raw_done
, req
);
2712 static void cli_tree_connect_smb2_done(struct tevent_req
*subreq
)
2714 tevent_req_simple_finish_ntstatus(
2715 subreq
, smb2cli_tcon_recv(subreq
));
2718 static void cli_tree_connect_andx_done(struct tevent_req
*subreq
)
2720 tevent_req_simple_finish_ntstatus(
2721 subreq
, cli_tcon_andx_recv(subreq
));
2724 static void cli_tree_connect_raw_done(struct tevent_req
*subreq
)
2726 struct tevent_req
*req
= tevent_req_callback_data(
2727 subreq
, struct tevent_req
);
2728 struct cli_tree_connect_state
*state
= tevent_req_data(
2729 req
, struct cli_tree_connect_state
);
2731 uint16_t max_xmit
= 0;
2734 status
= cli_raw_tcon_recv(subreq
, &max_xmit
, &tid
);
2735 if (tevent_req_nterror(req
, status
)) {
2739 smb1cli_tcon_set_values(state
->cli
->smb1
.tcon
,
2741 0, /* optional_support */
2742 0, /* maximal_access */
2743 0, /* guest_maximal_access */
2745 NULL
); /* fs_type */
2747 tevent_req_done(req
);
2750 static NTSTATUS
cli_tree_connect_recv(struct tevent_req
*req
)
2752 return tevent_req_simple_recv_ntstatus(req
);
2755 NTSTATUS
cli_tree_connect(struct cli_state
*cli
, const char *share
,
2756 const char *dev
, const char *pass
, int passlen
)
2758 struct tevent_context
*ev
;
2759 struct tevent_req
*req
;
2760 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2762 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
2763 return NT_STATUS_INVALID_PARAMETER
;
2765 ev
= samba_tevent_context_init(talloc_tos());
2769 req
= cli_tree_connect_send(ev
, ev
, cli
, share
, dev
, pass
, passlen
);
2773 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2776 status
= cli_tree_connect_recv(req
);
2782 /****************************************************************************
2783 Send a tree disconnect.
2784 ****************************************************************************/
2786 struct cli_tdis_state
{
2787 struct cli_state
*cli
;
2790 static void cli_tdis_done(struct tevent_req
*subreq
);
2792 static struct tevent_req
*cli_tdis_send(TALLOC_CTX
*mem_ctx
,
2793 struct tevent_context
*ev
,
2794 struct cli_state
*cli
)
2796 struct tevent_req
*req
, *subreq
;
2797 struct cli_tdis_state
*state
;
2799 req
= tevent_req_create(mem_ctx
, &state
, struct cli_tdis_state
);
2805 subreq
= cli_smb_send(state
, ev
, cli
, SMBtdis
, 0, 0, NULL
, 0, NULL
);
2806 if (tevent_req_nomem(subreq
, req
)) {
2807 return tevent_req_post(req
, ev
);
2809 tevent_req_set_callback(subreq
, cli_tdis_done
, req
);
2813 static void cli_tdis_done(struct tevent_req
*subreq
)
2815 struct tevent_req
*req
= tevent_req_callback_data(
2816 subreq
, struct tevent_req
);
2817 struct cli_tdis_state
*state
= tevent_req_data(
2818 req
, struct cli_tdis_state
);
2821 status
= cli_smb_recv(subreq
, NULL
, NULL
, 0, NULL
, NULL
, NULL
, NULL
);
2822 TALLOC_FREE(subreq
);
2823 if (!NT_STATUS_IS_OK(status
)) {
2824 tevent_req_nterror(req
, status
);
2827 cli_state_set_tid(state
->cli
, UINT16_MAX
);
2828 tevent_req_done(req
);
2831 static NTSTATUS
cli_tdis_recv(struct tevent_req
*req
)
2833 return tevent_req_simple_recv_ntstatus(req
);
2836 NTSTATUS
cli_tdis(struct cli_state
*cli
)
2838 struct tevent_context
*ev
;
2839 struct tevent_req
*req
;
2840 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2842 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
2843 return smb2cli_tdis(cli
->conn
,
2849 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
2850 return NT_STATUS_INVALID_PARAMETER
;
2852 ev
= samba_tevent_context_init(talloc_tos());
2856 req
= cli_tdis_send(ev
, ev
, cli
);
2860 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2863 status
= cli_tdis_recv(req
);
2869 struct cli_connect_sock_state
{
2870 const char **called_names
;
2871 const char **calling_names
;
2877 static void cli_connect_sock_done(struct tevent_req
*subreq
);
2880 * Async only if we don't have to look up the name, i.e. "pss" is set with a
2884 static struct tevent_req
*cli_connect_sock_send(
2885 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
2886 const char *host
, int name_type
, const struct sockaddr_storage
*pss
,
2887 const char *myname
, uint16_t port
)
2889 struct tevent_req
*req
, *subreq
;
2890 struct cli_connect_sock_state
*state
;
2892 struct sockaddr_storage
*addrs
;
2893 unsigned i
, num_addrs
;
2896 req
= tevent_req_create(mem_ctx
, &state
,
2897 struct cli_connect_sock_state
);
2902 prog
= getenv("LIBSMB_PROG");
2904 state
->fd
= sock_exec(prog
);
2905 if (state
->fd
== -1) {
2906 status
= map_nt_error_from_unix(errno
);
2907 tevent_req_nterror(req
, status
);
2910 tevent_req_done(req
);
2912 return tevent_req_post(req
, ev
);
2915 if ((pss
== NULL
) || is_zero_addr(pss
)) {
2918 * Here we cheat. resolve_name_list is not async at all. So
2919 * this call will only be really async if the name lookup has
2920 * been done externally.
2923 status
= resolve_name_list(state
, host
, name_type
,
2924 &addrs
, &num_addrs
);
2925 if (!NT_STATUS_IS_OK(status
)) {
2926 tevent_req_nterror(req
, status
);
2927 return tevent_req_post(req
, ev
);
2930 addrs
= talloc_array(state
, struct sockaddr_storage
, 1);
2931 if (tevent_req_nomem(addrs
, req
)) {
2932 return tevent_req_post(req
, ev
);
2938 state
->called_names
= talloc_array(state
, const char *, num_addrs
);
2939 if (tevent_req_nomem(state
->called_names
, req
)) {
2940 return tevent_req_post(req
, ev
);
2942 state
->called_types
= talloc_array(state
, int, num_addrs
);
2943 if (tevent_req_nomem(state
->called_types
, req
)) {
2944 return tevent_req_post(req
, ev
);
2946 state
->calling_names
= talloc_array(state
, const char *, num_addrs
);
2947 if (tevent_req_nomem(state
->calling_names
, req
)) {
2948 return tevent_req_post(req
, ev
);
2950 for (i
=0; i
<num_addrs
; i
++) {
2951 state
->called_names
[i
] = host
;
2952 state
->called_types
[i
] = name_type
;
2953 state
->calling_names
[i
] = myname
;
2956 subreq
= smbsock_any_connect_send(
2957 state
, ev
, addrs
, state
->called_names
, state
->called_types
,
2958 state
->calling_names
, NULL
, num_addrs
, port
);
2959 if (tevent_req_nomem(subreq
, req
)) {
2960 return tevent_req_post(req
, ev
);
2962 tevent_req_set_callback(subreq
, cli_connect_sock_done
, req
);
2966 static void cli_connect_sock_done(struct tevent_req
*subreq
)
2968 struct tevent_req
*req
= tevent_req_callback_data(
2969 subreq
, struct tevent_req
);
2970 struct cli_connect_sock_state
*state
= tevent_req_data(
2971 req
, struct cli_connect_sock_state
);
2974 status
= smbsock_any_connect_recv(subreq
, &state
->fd
, NULL
,
2976 TALLOC_FREE(subreq
);
2977 if (tevent_req_nterror(req
, status
)) {
2980 set_socket_options(state
->fd
, lp_socket_options());
2981 tevent_req_done(req
);
2984 static NTSTATUS
cli_connect_sock_recv(struct tevent_req
*req
,
2985 int *pfd
, uint16_t *pport
)
2987 struct cli_connect_sock_state
*state
= tevent_req_data(
2988 req
, struct cli_connect_sock_state
);
2991 if (tevent_req_is_nterror(req
, &status
)) {
2995 *pport
= state
->port
;
2996 return NT_STATUS_OK
;
2999 struct cli_connect_nb_state
{
3000 const char *desthost
;
3003 struct cli_state
*cli
;
3006 static void cli_connect_nb_done(struct tevent_req
*subreq
);
3008 static struct tevent_req
*cli_connect_nb_send(
3009 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
3010 const char *host
, const struct sockaddr_storage
*dest_ss
,
3011 uint16_t port
, int name_type
, const char *myname
,
3012 int signing_state
, int flags
)
3014 struct tevent_req
*req
, *subreq
;
3015 struct cli_connect_nb_state
*state
;
3018 req
= tevent_req_create(mem_ctx
, &state
, struct cli_connect_nb_state
);
3022 state
->desthost
= host
;
3023 state
->signing_state
= signing_state
;
3024 state
->flags
= flags
;
3026 p
= strchr(host
, '#');
3028 name_type
= strtol(p
+1, NULL
, 16);
3029 host
= talloc_strndup(state
, host
, p
- host
);
3030 if (tevent_req_nomem(host
, req
)) {
3031 return tevent_req_post(req
, ev
);
3035 subreq
= cli_connect_sock_send(state
, ev
, host
, name_type
, dest_ss
,
3037 if (tevent_req_nomem(subreq
, req
)) {
3038 return tevent_req_post(req
, ev
);
3040 tevent_req_set_callback(subreq
, cli_connect_nb_done
, req
);
3044 static void cli_connect_nb_done(struct tevent_req
*subreq
)
3046 struct tevent_req
*req
= tevent_req_callback_data(
3047 subreq
, struct tevent_req
);
3048 struct cli_connect_nb_state
*state
= tevent_req_data(
3049 req
, struct cli_connect_nb_state
);
3054 status
= cli_connect_sock_recv(subreq
, &fd
, &port
);
3055 TALLOC_FREE(subreq
);
3056 if (tevent_req_nterror(req
, status
)) {
3060 state
->cli
= cli_state_create(state
, fd
, state
->desthost
, NULL
,
3061 state
->signing_state
, state
->flags
);
3062 if (tevent_req_nomem(state
->cli
, req
)) {
3066 tevent_req_done(req
);
3069 static NTSTATUS
cli_connect_nb_recv(struct tevent_req
*req
,
3070 struct cli_state
**pcli
)
3072 struct cli_connect_nb_state
*state
= tevent_req_data(
3073 req
, struct cli_connect_nb_state
);
3076 if (tevent_req_is_nterror(req
, &status
)) {
3079 *pcli
= talloc_move(NULL
, &state
->cli
);
3080 return NT_STATUS_OK
;
3083 NTSTATUS
cli_connect_nb(const char *host
, const struct sockaddr_storage
*dest_ss
,
3084 uint16_t port
, int name_type
, const char *myname
,
3085 int signing_state
, int flags
, struct cli_state
**pcli
)
3087 struct tevent_context
*ev
;
3088 struct tevent_req
*req
;
3089 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
3091 ev
= samba_tevent_context_init(talloc_tos());
3095 req
= cli_connect_nb_send(ev
, ev
, host
, dest_ss
, port
, name_type
,
3096 myname
, signing_state
, flags
);
3100 if (!tevent_req_set_endtime(req
, ev
, timeval_current_ofs(20, 0))) {
3103 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
3106 status
= cli_connect_nb_recv(req
, pcli
);
3112 struct cli_start_connection_state
{
3113 struct tevent_context
*ev
;
3114 struct cli_state
*cli
;
3117 static void cli_start_connection_connected(struct tevent_req
*subreq
);
3118 static void cli_start_connection_done(struct tevent_req
*subreq
);
3121 establishes a connection to after the negprot.
3122 @param output_cli A fully initialised cli structure, non-null only on success
3123 @param dest_host The netbios name of the remote host
3124 @param dest_ss (optional) The the destination IP, NULL for name based lookup
3125 @param port (optional) The destination port (0 for default)
3128 static struct tevent_req
*cli_start_connection_send(
3129 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
3130 const char *my_name
, const char *dest_host
,
3131 const struct sockaddr_storage
*dest_ss
, int port
,
3132 int signing_state
, int flags
)
3134 struct tevent_req
*req
, *subreq
;
3135 struct cli_start_connection_state
*state
;
3137 req
= tevent_req_create(mem_ctx
, &state
,
3138 struct cli_start_connection_state
);
3144 subreq
= cli_connect_nb_send(state
, ev
, dest_host
, dest_ss
, port
,
3145 0x20, my_name
, signing_state
, flags
);
3146 if (tevent_req_nomem(subreq
, req
)) {
3147 return tevent_req_post(req
, ev
);
3149 tevent_req_set_callback(subreq
, cli_start_connection_connected
, req
);
3153 static void cli_start_connection_connected(struct tevent_req
*subreq
)
3155 struct tevent_req
*req
= tevent_req_callback_data(
3156 subreq
, struct tevent_req
);
3157 struct cli_start_connection_state
*state
= tevent_req_data(
3158 req
, struct cli_start_connection_state
);
3161 status
= cli_connect_nb_recv(subreq
, &state
->cli
);
3162 TALLOC_FREE(subreq
);
3163 if (tevent_req_nterror(req
, status
)) {
3167 subreq
= smbXcli_negprot_send(state
, state
->ev
, state
->cli
->conn
,
3168 state
->cli
->timeout
,
3169 lp_client_min_protocol(),
3170 lp_client_max_protocol());
3171 if (tevent_req_nomem(subreq
, req
)) {
3174 tevent_req_set_callback(subreq
, cli_start_connection_done
, req
);
3177 static void cli_start_connection_done(struct tevent_req
*subreq
)
3179 struct tevent_req
*req
= tevent_req_callback_data(
3180 subreq
, struct tevent_req
);
3181 struct cli_start_connection_state
*state
= tevent_req_data(
3182 req
, struct cli_start_connection_state
);
3185 status
= smbXcli_negprot_recv(subreq
);
3186 TALLOC_FREE(subreq
);
3187 if (tevent_req_nterror(req
, status
)) {
3191 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
3192 /* Ensure we ask for some initial credits. */
3193 smb2cli_conn_set_max_credits(state
->cli
->conn
,
3194 DEFAULT_SMB2_MAX_CREDITS
);
3197 tevent_req_done(req
);
3200 static NTSTATUS
cli_start_connection_recv(struct tevent_req
*req
,
3201 struct cli_state
**output_cli
)
3203 struct cli_start_connection_state
*state
= tevent_req_data(
3204 req
, struct cli_start_connection_state
);
3207 if (tevent_req_is_nterror(req
, &status
)) {
3210 *output_cli
= state
->cli
;
3212 return NT_STATUS_OK
;
3215 NTSTATUS
cli_start_connection(struct cli_state
**output_cli
,
3216 const char *my_name
,
3217 const char *dest_host
,
3218 const struct sockaddr_storage
*dest_ss
, int port
,
3219 int signing_state
, int flags
)
3221 struct tevent_context
*ev
;
3222 struct tevent_req
*req
;
3223 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
3225 ev
= samba_tevent_context_init(talloc_tos());
3229 req
= cli_start_connection_send(ev
, ev
, my_name
, dest_host
, dest_ss
,
3230 port
, signing_state
, flags
);
3234 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
3237 status
= cli_start_connection_recv(req
, output_cli
);
3244 establishes a connection right up to doing tconX, password specified.
3245 @param output_cli A fully initialised cli structure, non-null only on success
3246 @param dest_host The netbios name of the remote host
3247 @param dest_ip (optional) The the destination IP, NULL for name based lookup
3248 @param port (optional) The destination port (0 for default)
3249 @param service (optional) The share to make the connection to. Should be 'unqualified' in any way.
3250 @param service_type The 'type' of serivice.
3251 @param user Username, unix string
3252 @param domain User's domain
3253 @param password User's password, unencrypted unix string.
3256 struct cli_full_connection_state
{
3257 struct tevent_context
*ev
;
3258 const char *service
;
3259 const char *service_type
;
3262 const char *password
;
3265 struct cli_state
*cli
;
3268 static int cli_full_connection_state_destructor(
3269 struct cli_full_connection_state
*s
);
3270 static void cli_full_connection_started(struct tevent_req
*subreq
);
3271 static void cli_full_connection_sess_set_up(struct tevent_req
*subreq
);
3272 static void cli_full_connection_done(struct tevent_req
*subreq
);
3274 struct tevent_req
*cli_full_connection_send(
3275 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
3276 const char *my_name
, const char *dest_host
,
3277 const struct sockaddr_storage
*dest_ss
, int port
,
3278 const char *service
, const char *service_type
,
3279 const char *user
, const char *domain
,
3280 const char *password
, int flags
, int signing_state
)
3282 struct tevent_req
*req
, *subreq
;
3283 struct cli_full_connection_state
*state
;
3285 req
= tevent_req_create(mem_ctx
, &state
,
3286 struct cli_full_connection_state
);
3290 talloc_set_destructor(state
, cli_full_connection_state_destructor
);
3293 state
->service
= service
;
3294 state
->service_type
= service_type
;
3296 state
->domain
= domain
;
3297 state
->password
= password
;
3298 state
->flags
= flags
;
3300 state
->pw_len
= state
->password
? strlen(state
->password
)+1 : 0;
3301 if (state
->password
== NULL
) {
3302 state
->password
= "";
3305 subreq
= cli_start_connection_send(
3306 state
, ev
, my_name
, dest_host
, dest_ss
, port
,
3307 signing_state
, flags
);
3308 if (tevent_req_nomem(subreq
, req
)) {
3309 return tevent_req_post(req
, ev
);
3311 tevent_req_set_callback(subreq
, cli_full_connection_started
, req
);
3315 static int cli_full_connection_state_destructor(
3316 struct cli_full_connection_state
*s
)
3318 if (s
->cli
!= NULL
) {
3319 cli_shutdown(s
->cli
);
3325 static void cli_full_connection_started(struct tevent_req
*subreq
)
3327 struct tevent_req
*req
= tevent_req_callback_data(
3328 subreq
, struct tevent_req
);
3329 struct cli_full_connection_state
*state
= tevent_req_data(
3330 req
, struct cli_full_connection_state
);
3333 status
= cli_start_connection_recv(subreq
, &state
->cli
);
3334 TALLOC_FREE(subreq
);
3335 if (tevent_req_nterror(req
, status
)) {
3338 subreq
= cli_session_setup_send(
3339 state
, state
->ev
, state
->cli
, state
->user
,
3340 state
->password
, state
->pw_len
, state
->password
, state
->pw_len
,
3342 if (tevent_req_nomem(subreq
, req
)) {
3345 tevent_req_set_callback(subreq
, cli_full_connection_sess_set_up
, req
);
3348 static void cli_full_connection_sess_set_up(struct tevent_req
*subreq
)
3350 struct tevent_req
*req
= tevent_req_callback_data(
3351 subreq
, struct tevent_req
);
3352 struct cli_full_connection_state
*state
= tevent_req_data(
3353 req
, struct cli_full_connection_state
);
3356 status
= cli_session_setup_recv(subreq
);
3357 TALLOC_FREE(subreq
);
3359 if (!NT_STATUS_IS_OK(status
) &&
3360 (state
->flags
& CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK
)) {
3362 state
->flags
&= ~CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK
;
3364 subreq
= cli_session_setup_send(
3365 state
, state
->ev
, state
->cli
, "", "", 0, "", 0,
3367 if (tevent_req_nomem(subreq
, req
)) {
3370 tevent_req_set_callback(
3371 subreq
, cli_full_connection_sess_set_up
, req
);
3375 if (tevent_req_nterror(req
, status
)) {
3379 if (state
->service
!= NULL
) {
3380 subreq
= cli_tree_connect_send(
3381 state
, state
->ev
, state
->cli
,
3382 state
->service
, state
->service_type
,
3383 state
->password
, state
->pw_len
);
3384 if (tevent_req_nomem(subreq
, req
)) {
3387 tevent_req_set_callback(subreq
, cli_full_connection_done
, req
);
3391 status
= cli_init_creds(state
->cli
, state
->user
, state
->domain
,
3393 if (tevent_req_nterror(req
, status
)) {
3396 tevent_req_done(req
);
3399 static void cli_full_connection_done(struct tevent_req
*subreq
)
3401 struct tevent_req
*req
= tevent_req_callback_data(
3402 subreq
, struct tevent_req
);
3403 struct cli_full_connection_state
*state
= tevent_req_data(
3404 req
, struct cli_full_connection_state
);
3407 status
= cli_tree_connect_recv(subreq
);
3408 TALLOC_FREE(subreq
);
3409 if (tevent_req_nterror(req
, status
)) {
3412 status
= cli_init_creds(state
->cli
, state
->user
, state
->domain
,
3414 if (tevent_req_nterror(req
, status
)) {
3417 tevent_req_done(req
);
3420 NTSTATUS
cli_full_connection_recv(struct tevent_req
*req
,
3421 struct cli_state
**output_cli
)
3423 struct cli_full_connection_state
*state
= tevent_req_data(
3424 req
, struct cli_full_connection_state
);
3427 if (tevent_req_is_nterror(req
, &status
)) {
3430 *output_cli
= state
->cli
;
3431 talloc_set_destructor(state
, NULL
);
3432 return NT_STATUS_OK
;
3435 NTSTATUS
cli_full_connection(struct cli_state
**output_cli
,
3436 const char *my_name
,
3437 const char *dest_host
,
3438 const struct sockaddr_storage
*dest_ss
, int port
,
3439 const char *service
, const char *service_type
,
3440 const char *user
, const char *domain
,
3441 const char *password
, int flags
,
3444 struct tevent_context
*ev
;
3445 struct tevent_req
*req
;
3446 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
3448 ev
= samba_tevent_context_init(talloc_tos());
3452 req
= cli_full_connection_send(
3453 ev
, ev
, my_name
, dest_host
, dest_ss
, port
, service
,
3454 service_type
, user
, domain
, password
, flags
, signing_state
);
3458 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
3461 status
= cli_full_connection_recv(req
, output_cli
);
3467 /****************************************************************************
3468 Send an old style tcon.
3469 ****************************************************************************/
3470 struct cli_raw_tcon_state
{
3474 static void cli_raw_tcon_done(struct tevent_req
*subreq
);
3476 static struct tevent_req
*cli_raw_tcon_send(
3477 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
3478 const char *service
, const char *pass
, const char *dev
)
3480 struct tevent_req
*req
, *subreq
;
3481 struct cli_raw_tcon_state
*state
;
3484 req
= tevent_req_create(mem_ctx
, &state
, struct cli_raw_tcon_state
);
3489 if (!lp_client_plaintext_auth() && (*pass
)) {
3490 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
3491 " or 'client ntlmv2 auth = yes'\n"));
3492 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
3493 return tevent_req_post(req
, ev
);
3496 bytes
= talloc_array(state
, uint8_t, 0);
3497 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
3498 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
3499 service
, strlen(service
)+1, NULL
);
3500 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
3501 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
3502 pass
, strlen(pass
)+1, NULL
);
3503 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
3504 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
3505 dev
, strlen(dev
)+1, NULL
);
3507 if (tevent_req_nomem(bytes
, req
)) {
3508 return tevent_req_post(req
, ev
);
3511 subreq
= cli_smb_send(state
, ev
, cli
, SMBtcon
, 0, 0, NULL
,
3512 talloc_get_size(bytes
), bytes
);
3513 if (tevent_req_nomem(subreq
, req
)) {
3514 return tevent_req_post(req
, ev
);
3516 tevent_req_set_callback(subreq
, cli_raw_tcon_done
, req
);
3520 static void cli_raw_tcon_done(struct tevent_req
*subreq
)
3522 struct tevent_req
*req
= tevent_req_callback_data(
3523 subreq
, struct tevent_req
);
3524 struct cli_raw_tcon_state
*state
= tevent_req_data(
3525 req
, struct cli_raw_tcon_state
);
3528 status
= cli_smb_recv(subreq
, state
, NULL
, 2, NULL
, &state
->ret_vwv
,
3530 TALLOC_FREE(subreq
);
3531 if (tevent_req_nterror(req
, status
)) {
3534 tevent_req_done(req
);
3537 static NTSTATUS
cli_raw_tcon_recv(struct tevent_req
*req
,
3538 uint16
*max_xmit
, uint16
*tid
)
3540 struct cli_raw_tcon_state
*state
= tevent_req_data(
3541 req
, struct cli_raw_tcon_state
);
3544 if (tevent_req_is_nterror(req
, &status
)) {
3547 *max_xmit
= SVAL(state
->ret_vwv
+ 0, 0);
3548 *tid
= SVAL(state
->ret_vwv
+ 1, 0);
3549 return NT_STATUS_OK
;
3552 NTSTATUS
cli_raw_tcon(struct cli_state
*cli
,
3553 const char *service
, const char *pass
, const char *dev
,
3554 uint16
*max_xmit
, uint16
*tid
)
3556 struct tevent_context
*ev
;
3557 struct tevent_req
*req
;
3558 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
3560 ev
= samba_tevent_context_init(talloc_tos());
3564 req
= cli_raw_tcon_send(ev
, ev
, cli
, service
, pass
, dev
);
3568 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
3571 status
= cli_raw_tcon_recv(req
, max_xmit
, tid
);
3577 /* Return a cli_state pointing at the IPC$ share for the given server */
3579 struct cli_state
*get_ipc_connect(char *server
,
3580 struct sockaddr_storage
*server_ss
,
3581 const struct user_auth_info
*user_info
)
3583 struct cli_state
*cli
;
3585 uint32_t flags
= CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK
;
3587 if (user_info
->use_kerberos
) {
3588 flags
|= CLI_FULL_CONNECTION_USE_KERBEROS
;
3591 nt_status
= cli_full_connection(&cli
, NULL
, server
, server_ss
, 0, "IPC$", "IPC",
3592 user_info
->username
? user_info
->username
: "",
3594 user_info
->password
? user_info
->password
: "",
3596 SMB_SIGNING_DEFAULT
);
3598 if (NT_STATUS_IS_OK(nt_status
)) {
3600 } else if (is_ipaddress(server
)) {
3601 /* windows 9* needs a correct NMB name for connections */
3602 fstring remote_name
;
3604 if (name_status_find("*", 0, 0, server_ss
, remote_name
)) {
3605 cli
= get_ipc_connect(remote_name
, server_ss
, user_info
);
3614 * Given the IP address of a master browser on the network, return its
3615 * workgroup and connect to it.
3617 * This function is provided to allow additional processing beyond what
3618 * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
3619 * browsers and obtain each master browsers' list of domains (in case the
3620 * first master browser is recently on the network and has not yet
3621 * synchronized with other master browsers and therefore does not yet have the
3622 * entire network browse list)
3625 struct cli_state
*get_ipc_connect_master_ip(TALLOC_CTX
*ctx
,
3626 struct sockaddr_storage
*mb_ip
,
3627 const struct user_auth_info
*user_info
,
3628 char **pp_workgroup_out
)
3630 char addr
[INET6_ADDRSTRLEN
];
3632 struct cli_state
*cli
;
3633 struct sockaddr_storage server_ss
;
3635 *pp_workgroup_out
= NULL
;
3637 print_sockaddr(addr
, sizeof(addr
), mb_ip
);
3638 DEBUG(99, ("Looking up name of master browser %s\n",
3642 * Do a name status query to find out the name of the master browser.
3643 * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
3644 * master browser will not respond to a wildcard query (or, at least,
3645 * an NT4 server acting as the domain master browser will not).
3647 * We might be able to use ONLY the query on MSBROWSE, but that's not
3648 * yet been tested with all Windows versions, so until it is, leave
3649 * the original wildcard query as the first choice and fall back to
3650 * MSBROWSE if the wildcard query fails.
3652 if (!name_status_find("*", 0, 0x1d, mb_ip
, name
) &&
3653 !name_status_find(MSBROWSE
, 1, 0x1d, mb_ip
, name
)) {
3655 DEBUG(99, ("Could not retrieve name status for %s\n",
3660 if (!find_master_ip(name
, &server_ss
)) {
3661 DEBUG(99, ("Could not find master ip for %s\n", name
));
3665 *pp_workgroup_out
= talloc_strdup(ctx
, name
);
3667 DEBUG(4, ("found master browser %s, %s\n", name
, addr
));
3669 print_sockaddr(addr
, sizeof(addr
), &server_ss
);
3670 cli
= get_ipc_connect(addr
, &server_ss
, user_info
);
3676 * Return the IP address and workgroup of a master browser on the network, and
3680 struct cli_state
*get_ipc_connect_master_ip_bcast(TALLOC_CTX
*ctx
,
3681 const struct user_auth_info
*user_info
,
3682 char **pp_workgroup_out
)
3684 struct sockaddr_storage
*ip_list
;
3685 struct cli_state
*cli
;
3689 *pp_workgroup_out
= NULL
;
3691 DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
3693 /* Go looking for workgroups by broadcasting on the local network */
3695 status
= name_resolve_bcast(MSBROWSE
, 1, talloc_tos(),
3697 if (!NT_STATUS_IS_OK(status
)) {
3698 DEBUG(99, ("No master browsers responded: %s\n",
3699 nt_errstr(status
)));
3703 for (i
= 0; i
< count
; i
++) {
3704 char addr
[INET6_ADDRSTRLEN
];
3705 print_sockaddr(addr
, sizeof(addr
), &ip_list
[i
]);
3706 DEBUG(99, ("Found master browser %s\n", addr
));
3708 cli
= get_ipc_connect_master_ip(ctx
, &ip_list
[i
],
3709 user_info
, pp_workgroup_out
);