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 tevent_req_done(req
);
285 static NTSTATUS
cli_session_setup_lanman2_recv(struct tevent_req
*req
)
287 return tevent_req_simple_recv_ntstatus(req
);
290 /****************************************************************************
291 Work out suitable capabilities to offer the server.
292 ****************************************************************************/
294 static uint32_t cli_session_setup_capabilities(struct cli_state
*cli
,
295 uint32_t sesssetup_capabilities
)
297 uint32_t client_capabilities
= smb1cli_conn_capabilities(cli
->conn
);
300 * We only send capabilities based on the mask for:
301 * - client only flags
302 * - flags used in both directions
304 * We do not echo the server only flags, except some legacy flags.
306 * SMB_CAP_LEGACY_CLIENT_MASK contains CAP_LARGE_READX and
307 * CAP_LARGE_WRITEX in order to allow us to do large reads
308 * against old Samba releases (<= 3.6.x).
310 client_capabilities
&= (SMB_CAP_BOTH_MASK
| SMB_CAP_LEGACY_CLIENT_MASK
);
313 * Session Setup specific flags CAP_DYNAMIC_REAUTH
314 * and CAP_EXTENDED_SECURITY are passed by the caller.
315 * We need that in order to do guest logins even if
316 * CAP_EXTENDED_SECURITY is negotiated.
318 client_capabilities
&= ~(CAP_DYNAMIC_REAUTH
|CAP_EXTENDED_SECURITY
);
319 sesssetup_capabilities
&= (CAP_DYNAMIC_REAUTH
|CAP_EXTENDED_SECURITY
);
320 client_capabilities
|= sesssetup_capabilities
;
322 return client_capabilities
;
325 /****************************************************************************
326 Do a NT1 guest session setup.
327 ****************************************************************************/
329 struct cli_session_setup_guest_state
{
330 struct cli_state
*cli
;
335 static void cli_session_setup_guest_done(struct tevent_req
*subreq
);
337 struct tevent_req
*cli_session_setup_guest_create(TALLOC_CTX
*mem_ctx
,
338 struct tevent_context
*ev
,
339 struct cli_state
*cli
,
340 struct tevent_req
**psmbreq
)
342 struct tevent_req
*req
, *subreq
;
343 struct cli_session_setup_guest_state
*state
;
347 req
= tevent_req_create(mem_ctx
, &state
,
348 struct cli_session_setup_guest_state
);
355 SCVAL(vwv
+0, 0, 0xFF);
358 SSVAL(vwv
+2, 0, CLI_BUFFER_SIZE
);
360 SSVAL(vwv
+4, 0, cli_state_get_vc_num(cli
));
361 SIVAL(vwv
+5, 0, smb1cli_conn_server_session_key(cli
->conn
));
366 SIVAL(vwv
+11, 0, cli_session_setup_capabilities(cli
, 0));
368 bytes
= talloc_array(state
, uint8_t, 0);
370 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "", 1, /* username */
372 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "", 1, /* workgroup */
374 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "Unix", 5, NULL
);
375 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "Samba", 6, NULL
);
382 state
->bytes
.iov_base
= (void *)bytes
;
383 state
->bytes
.iov_len
= talloc_get_size(bytes
);
385 subreq
= cli_smb_req_create(state
, ev
, cli
, SMBsesssetupX
, 0, 13, vwv
,
387 if (subreq
== NULL
) {
391 tevent_req_set_callback(subreq
, cli_session_setup_guest_done
, req
);
396 struct tevent_req
*cli_session_setup_guest_send(TALLOC_CTX
*mem_ctx
,
397 struct tevent_context
*ev
,
398 struct cli_state
*cli
)
400 struct tevent_req
*req
, *subreq
;
403 req
= cli_session_setup_guest_create(mem_ctx
, ev
, cli
, &subreq
);
408 status
= smb1cli_req_chain_submit(&subreq
, 1);
409 if (!NT_STATUS_IS_OK(status
)) {
410 tevent_req_nterror(req
, status
);
411 return tevent_req_post(req
, ev
);
416 static void cli_session_setup_guest_done(struct tevent_req
*subreq
)
418 struct tevent_req
*req
= tevent_req_callback_data(
419 subreq
, struct tevent_req
);
420 struct cli_session_setup_guest_state
*state
= tevent_req_data(
421 req
, struct cli_session_setup_guest_state
);
422 struct cli_state
*cli
= state
->cli
;
433 status
= cli_smb_recv(subreq
, state
, &in
, 3, &wct
, &vwv
,
436 if (!NT_STATUS_IS_OK(status
)) {
437 tevent_req_nterror(req
, status
);
441 inhdr
= in
+ NBT_HDR_SIZE
;
444 cli_state_set_uid(state
->cli
, SVAL(inhdr
, HDR_UID
));
446 status
= smb_bytes_talloc_string(cli
,
453 if (!NT_STATUS_IS_OK(status
)) {
454 tevent_req_nterror(req
, status
);
459 status
= smb_bytes_talloc_string(cli
,
466 if (!NT_STATUS_IS_OK(status
)) {
467 tevent_req_nterror(req
, status
);
472 status
= smb_bytes_talloc_string(cli
,
479 if (!NT_STATUS_IS_OK(status
)) {
480 tevent_req_nterror(req
, status
);
485 tevent_req_done(req
);
488 NTSTATUS
cli_session_setup_guest_recv(struct tevent_req
*req
)
490 return tevent_req_simple_recv_ntstatus(req
);
493 /****************************************************************************
494 Do a NT1 plaintext session setup.
495 ****************************************************************************/
497 struct cli_session_setup_plain_state
{
498 struct cli_state
*cli
;
503 static void cli_session_setup_plain_done(struct tevent_req
*subreq
);
505 static struct tevent_req
*cli_session_setup_plain_send(
506 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
507 struct cli_state
*cli
,
508 const char *user
, const char *pass
, const char *workgroup
)
510 struct tevent_req
*req
, *subreq
;
511 struct cli_session_setup_plain_state
*state
;
517 req
= tevent_req_create(mem_ctx
, &state
,
518 struct cli_session_setup_plain_state
);
526 SCVAL(vwv
+0, 0, 0xff);
529 SSVAL(vwv
+2, 0, CLI_BUFFER_SIZE
);
531 SSVAL(vwv
+4, 0, cli_state_get_vc_num(cli
));
532 SIVAL(vwv
+5, 0, smb1cli_conn_server_session_key(cli
->conn
));
537 SIVAL(vwv
+11, 0, cli_session_setup_capabilities(cli
, 0));
539 bytes
= talloc_array(state
, uint8_t, 0);
540 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), pass
, strlen(pass
)+1,
542 if (tevent_req_nomem(bytes
, req
)) {
543 return tevent_req_post(req
, ev
);
545 SSVAL(vwv
+ (smbXcli_conn_use_unicode(cli
->conn
) ? 8 : 7), 0, passlen
);
547 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
548 user
, strlen(user
)+1, NULL
);
549 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
550 workgroup
, strlen(workgroup
)+1, NULL
);
551 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
554 version
= talloc_asprintf(talloc_tos(), "Samba %s",
555 samba_version_string());
556 if (tevent_req_nomem(version
, req
)){
557 return tevent_req_post(req
, ev
);
559 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
560 version
, strlen(version
)+1, NULL
);
561 TALLOC_FREE(version
);
563 if (tevent_req_nomem(bytes
, req
)) {
564 return tevent_req_post(req
, ev
);
567 subreq
= cli_smb_send(state
, ev
, cli
, SMBsesssetupX
, 0, 13, vwv
,
568 talloc_get_size(bytes
), bytes
);
569 if (tevent_req_nomem(subreq
, req
)) {
570 return tevent_req_post(req
, ev
);
572 tevent_req_set_callback(subreq
, cli_session_setup_plain_done
, req
);
576 static void cli_session_setup_plain_done(struct tevent_req
*subreq
)
578 struct tevent_req
*req
= tevent_req_callback_data(
579 subreq
, struct tevent_req
);
580 struct cli_session_setup_plain_state
*state
= tevent_req_data(
581 req
, struct cli_session_setup_plain_state
);
582 struct cli_state
*cli
= state
->cli
;
593 status
= cli_smb_recv(subreq
, state
, &in
, 3, &wct
, &vwv
,
596 if (tevent_req_nterror(req
, status
)) {
600 inhdr
= in
+ NBT_HDR_SIZE
;
603 cli_state_set_uid(state
->cli
, SVAL(inhdr
, HDR_UID
));
605 status
= smb_bytes_talloc_string(cli
,
612 if (!NT_STATUS_IS_OK(status
)) {
613 tevent_req_nterror(req
, status
);
618 status
= smb_bytes_talloc_string(cli
,
625 if (!NT_STATUS_IS_OK(status
)) {
626 tevent_req_nterror(req
, status
);
631 status
= smb_bytes_talloc_string(cli
,
638 if (!NT_STATUS_IS_OK(status
)) {
639 tevent_req_nterror(req
, status
);
644 tevent_req_done(req
);
647 static NTSTATUS
cli_session_setup_plain_recv(struct tevent_req
*req
)
649 return tevent_req_simple_recv_ntstatus(req
);
652 /****************************************************************************
653 do a NT1 NTLM/LM encrypted session setup - for when extended security
655 @param cli client state to create do session setup on
657 @param pass *either* cleartext password (passlen !=24) or LM response.
658 @param ntpass NT response, implies ntpasslen >=24, implies pass is not clear
659 @param workgroup The user's domain.
660 ****************************************************************************/
662 struct cli_session_setup_nt1_state
{
663 struct cli_state
*cli
;
666 DATA_BLOB session_key
;
670 static void cli_session_setup_nt1_done(struct tevent_req
*subreq
);
672 static struct tevent_req
*cli_session_setup_nt1_send(
673 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
674 struct cli_state
*cli
, const char *user
,
675 const char *pass
, size_t passlen
,
676 const char *ntpass
, size_t ntpasslen
,
677 const char *workgroup
)
679 struct tevent_req
*req
, *subreq
;
680 struct cli_session_setup_nt1_state
*state
;
681 DATA_BLOB lm_response
= data_blob_null
;
682 DATA_BLOB nt_response
= data_blob_null
;
683 DATA_BLOB session_key
= data_blob_null
;
686 char *workgroup_upper
;
688 req
= tevent_req_create(mem_ctx
, &state
,
689 struct cli_session_setup_nt1_state
);
698 /* do nothing - guest login */
699 } else if (passlen
!= 24) {
700 if (lp_client_ntlmv2_auth()) {
701 DATA_BLOB server_chal
;
702 DATA_BLOB names_blob
;
705 data_blob_const(smb1cli_conn_server_challenge(cli
->conn
),
709 * note that the 'workgroup' here is a best
710 * guess - we don't know the server's domain
711 * at this point. Windows clients also don't
714 names_blob
= NTLMv2_generate_names_blob(
715 NULL
, NULL
, workgroup
);
717 if (tevent_req_nomem(names_blob
.data
, req
)) {
718 return tevent_req_post(req
, ev
);
721 if (!SMBNTLMv2encrypt(NULL
, user
, workgroup
, pass
,
722 &server_chal
, &names_blob
,
723 &lm_response
, &nt_response
,
724 NULL
, &session_key
)) {
725 data_blob_free(&names_blob
);
727 req
, NT_STATUS_ACCESS_DENIED
);
728 return tevent_req_post(req
, ev
);
730 data_blob_free(&names_blob
);
734 E_md4hash(pass
, nt_hash
);
737 nt_response
= data_blob_null
;
739 nt_response
= data_blob(NULL
, 24);
740 if (tevent_req_nomem(nt_response
.data
, req
)) {
741 return tevent_req_post(req
, ev
);
744 SMBNTencrypt(pass
, smb1cli_conn_server_challenge(cli
->conn
),
747 /* non encrypted password supplied. Ignore ntpass. */
748 if (lp_client_lanman_auth()) {
750 lm_response
= data_blob(NULL
, 24);
751 if (tevent_req_nomem(lm_response
.data
, req
)) {
752 return tevent_req_post(req
, ev
);
755 if (!SMBencrypt(pass
,
756 smb1cli_conn_server_challenge(cli
->conn
),
759 * Oops, the LM response is
760 * invalid, just put the NT
761 * response there instead
763 data_blob_free(&lm_response
);
764 lm_response
= data_blob(
770 * LM disabled, place NT# in LM field
773 lm_response
= data_blob(
774 nt_response
.data
, nt_response
.length
);
777 if (tevent_req_nomem(lm_response
.data
, req
)) {
778 return tevent_req_post(req
, ev
);
781 session_key
= data_blob(NULL
, 16);
782 if (tevent_req_nomem(session_key
.data
, req
)) {
783 return tevent_req_post(req
, ev
);
786 E_deshash(pass
, session_key
.data
);
787 memset(&session_key
.data
[8], '\0', 8);
789 SMBsesskeygen_ntv1(nt_hash
, session_key
.data
);
793 /* pre-encrypted password supplied. Only used for
794 security=server, can't do
795 signing because we don't have original key */
797 lm_response
= data_blob(pass
, passlen
);
798 if (tevent_req_nomem(lm_response
.data
, req
)) {
799 return tevent_req_post(req
, ev
);
802 nt_response
= data_blob(ntpass
, ntpasslen
);
803 if (tevent_req_nomem(nt_response
.data
, req
)) {
804 return tevent_req_post(req
, ev
);
809 state
->response
= data_blob_talloc(
810 state
, lm_response
.data
, lm_response
.length
);
812 state
->response
= data_blob_talloc(
813 state
, nt_response
.data
, nt_response
.length
);
815 if (tevent_req_nomem(state
->response
.data
, req
)) {
816 return tevent_req_post(req
, ev
);
819 if (session_key
.data
) {
820 state
->session_key
= data_blob_talloc(
821 state
, session_key
.data
, session_key
.length
);
822 if (tevent_req_nomem(state
->session_key
.data
, req
)) {
823 return tevent_req_post(req
, ev
);
826 data_blob_free(&session_key
);
828 SCVAL(vwv
+0, 0, 0xff);
831 SSVAL(vwv
+2, 0, CLI_BUFFER_SIZE
);
833 SSVAL(vwv
+4, 0, cli_state_get_vc_num(cli
));
834 SIVAL(vwv
+5, 0, smb1cli_conn_server_session_key(cli
->conn
));
835 SSVAL(vwv
+7, 0, lm_response
.length
);
836 SSVAL(vwv
+8, 0, nt_response
.length
);
839 SIVAL(vwv
+11, 0, cli_session_setup_capabilities(cli
, 0));
841 bytes
= talloc_array(state
, uint8_t,
842 lm_response
.length
+ nt_response
.length
);
843 if (tevent_req_nomem(bytes
, req
)) {
844 return tevent_req_post(req
, ev
);
846 if (lm_response
.length
!= 0) {
847 memcpy(bytes
, lm_response
.data
, lm_response
.length
);
849 if (nt_response
.length
!= 0) {
850 memcpy(bytes
+ lm_response
.length
,
851 nt_response
.data
, nt_response
.length
);
853 data_blob_free(&lm_response
);
854 data_blob_free(&nt_response
);
856 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
857 user
, strlen(user
)+1, NULL
);
860 * Upper case here might help some NTLMv2 implementations
862 workgroup_upper
= talloc_strdup_upper(talloc_tos(), workgroup
);
863 if (tevent_req_nomem(workgroup_upper
, req
)) {
864 return tevent_req_post(req
, ev
);
866 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
867 workgroup_upper
, strlen(workgroup_upper
)+1,
869 TALLOC_FREE(workgroup_upper
);
871 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "Unix", 5, NULL
);
872 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "Samba", 6, NULL
);
873 if (tevent_req_nomem(bytes
, req
)) {
874 return tevent_req_post(req
, ev
);
877 subreq
= cli_smb_send(state
, ev
, cli
, SMBsesssetupX
, 0, 13, vwv
,
878 talloc_get_size(bytes
), bytes
);
879 if (tevent_req_nomem(subreq
, req
)) {
880 return tevent_req_post(req
, ev
);
882 tevent_req_set_callback(subreq
, cli_session_setup_nt1_done
, req
);
886 static void cli_session_setup_nt1_done(struct tevent_req
*subreq
)
888 struct tevent_req
*req
= tevent_req_callback_data(
889 subreq
, struct tevent_req
);
890 struct cli_session_setup_nt1_state
*state
= tevent_req_data(
891 req
, struct cli_session_setup_nt1_state
);
892 struct cli_state
*cli
= state
->cli
;
903 status
= cli_smb_recv(subreq
, state
, &in
, 3, &wct
, &vwv
,
906 if (!NT_STATUS_IS_OK(status
)) {
907 tevent_req_nterror(req
, status
);
911 inhdr
= in
+ NBT_HDR_SIZE
;
914 cli_state_set_uid(state
->cli
, SVAL(inhdr
, HDR_UID
));
916 status
= smb_bytes_talloc_string(cli
,
922 if (!NT_STATUS_IS_OK(status
)) {
923 tevent_req_nterror(req
, status
);
928 status
= smb_bytes_talloc_string(cli
,
934 if (!NT_STATUS_IS_OK(status
)) {
935 tevent_req_nterror(req
, status
);
940 status
= smb_bytes_talloc_string(cli
,
946 if (!NT_STATUS_IS_OK(status
)) {
947 tevent_req_nterror(req
, status
);
952 if (smb1cli_conn_activate_signing(cli
->conn
, state
->session_key
, state
->response
)
953 && !smb1cli_conn_check_signing(cli
->conn
, (uint8_t *)in
, 1)) {
954 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
957 if (state
->session_key
.data
) {
958 struct smbXcli_session
*session
= state
->cli
->smb1
.session
;
960 status
= smb1cli_session_set_session_key(session
,
962 if (tevent_req_nterror(req
, status
)) {
966 tevent_req_done(req
);
969 static NTSTATUS
cli_session_setup_nt1_recv(struct tevent_req
*req
)
971 return tevent_req_simple_recv_ntstatus(req
);
974 /* The following is calculated from :
976 * (smb_wcnt * 2) = 24 (smb_wcnt == 12 in cli_session_setup_blob_send() )
977 * (strlen("Unix") + 1 + strlen("Samba") + 1) * 2 = 22 (unicode strings at
981 #define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22)
983 struct cli_sesssetup_blob_state
{
984 struct tevent_context
*ev
;
985 struct cli_state
*cli
;
987 uint16_t max_blob_size
;
992 struct iovec
*recv_iov
;
999 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state
*state
,
1000 struct tevent_req
**psubreq
);
1001 static void cli_sesssetup_blob_done(struct tevent_req
*subreq
);
1003 static struct tevent_req
*cli_sesssetup_blob_send(TALLOC_CTX
*mem_ctx
,
1004 struct tevent_context
*ev
,
1005 struct cli_state
*cli
,
1008 struct tevent_req
*req
, *subreq
;
1009 struct cli_sesssetup_blob_state
*state
;
1010 uint32_t usable_space
;
1012 req
= tevent_req_create(mem_ctx
, &state
,
1013 struct cli_sesssetup_blob_state
);
1021 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
1022 usable_space
= UINT16_MAX
;
1024 usable_space
= cli_state_available_size(cli
,
1025 BASE_SESSSETUP_BLOB_PACKET_SIZE
);
1028 if (usable_space
== 0) {
1029 DEBUG(1, ("cli_session_setup_blob: cli->max_xmit too small "
1030 "(not possible to send %u bytes)\n",
1031 BASE_SESSSETUP_BLOB_PACKET_SIZE
+ 1));
1032 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1033 return tevent_req_post(req
, ev
);
1035 state
->max_blob_size
= MIN(usable_space
, 0xFFFF);
1037 if (!cli_sesssetup_blob_next(state
, &subreq
)) {
1038 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
1039 return tevent_req_post(req
, ev
);
1041 tevent_req_set_callback(subreq
, cli_sesssetup_blob_done
, req
);
1045 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state
*state
,
1046 struct tevent_req
**psubreq
)
1048 struct tevent_req
*subreq
;
1051 thistime
= MIN(state
->blob
.length
, state
->max_blob_size
);
1053 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
1055 state
->smb2_blob
.data
= state
->blob
.data
;
1056 state
->smb2_blob
.length
= thistime
;
1058 state
->blob
.data
+= thistime
;
1059 state
->blob
.length
-= thistime
;
1061 subreq
= smb2cli_session_setup_send(state
, state
->ev
,
1063 state
->cli
->timeout
,
1064 state
->cli
->smb2
.session
,
1066 SMB2_CAP_DFS
, /* in_capabilities */
1068 0, /* in_previous_session_id */
1070 if (subreq
== NULL
) {
1077 SCVAL(state
->vwv
+0, 0, 0xFF);
1078 SCVAL(state
->vwv
+0, 1, 0);
1079 SSVAL(state
->vwv
+1, 0, 0);
1080 SSVAL(state
->vwv
+2, 0, CLI_BUFFER_SIZE
);
1081 SSVAL(state
->vwv
+3, 0, 2);
1082 SSVAL(state
->vwv
+4, 0, 1);
1083 SIVAL(state
->vwv
+5, 0, 0);
1085 SSVAL(state
->vwv
+7, 0, thistime
);
1087 SSVAL(state
->vwv
+8, 0, 0);
1088 SSVAL(state
->vwv
+9, 0, 0);
1089 SIVAL(state
->vwv
+10, 0,
1090 cli_session_setup_capabilities(state
->cli
, CAP_EXTENDED_SECURITY
));
1092 state
->buf
= (uint8_t *)talloc_memdup(state
, state
->blob
.data
,
1094 if (state
->buf
== NULL
) {
1097 state
->blob
.data
+= thistime
;
1098 state
->blob
.length
-= thistime
;
1100 state
->buf
= smb_bytes_push_str(state
->buf
, smbXcli_conn_use_unicode(state
->cli
->conn
),
1102 state
->buf
= smb_bytes_push_str(state
->buf
, smbXcli_conn_use_unicode(state
->cli
->conn
),
1104 if (state
->buf
== NULL
) {
1107 subreq
= cli_smb_send(state
, state
->ev
, state
->cli
, SMBsesssetupX
, 0,
1109 talloc_get_size(state
->buf
), state
->buf
);
1110 if (subreq
== NULL
) {
1117 static void cli_sesssetup_blob_done(struct tevent_req
*subreq
)
1119 struct tevent_req
*req
= tevent_req_callback_data(
1120 subreq
, struct tevent_req
);
1121 struct cli_sesssetup_blob_state
*state
= tevent_req_data(
1122 req
, struct cli_sesssetup_blob_state
);
1123 struct cli_state
*cli
= state
->cli
;
1130 uint16_t blob_length
;
1135 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
1136 status
= smb2cli_session_setup_recv(subreq
, state
,
1140 status
= cli_smb_recv(subreq
, state
, &in
, 4, &wct
, &vwv
,
1141 &num_bytes
, &bytes
);
1142 TALLOC_FREE(state
->buf
);
1144 TALLOC_FREE(subreq
);
1145 if (!NT_STATUS_IS_OK(status
)
1146 && !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1147 tevent_req_nterror(req
, status
);
1151 state
->status
= status
;
1153 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
1158 inhdr
= in
+ NBT_HDR_SIZE
;
1159 cli_state_set_uid(state
->cli
, SVAL(inhdr
, HDR_UID
));
1161 blob_length
= SVAL(vwv
+3, 0);
1162 if (blob_length
> num_bytes
) {
1163 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
1166 state
->ret_blob
= data_blob_const(bytes
, blob_length
);
1168 p
= bytes
+ blob_length
;
1170 status
= smb_bytes_talloc_string(cli
,
1177 if (!NT_STATUS_IS_OK(status
)) {
1178 tevent_req_nterror(req
, status
);
1183 status
= smb_bytes_talloc_string(cli
,
1190 if (!NT_STATUS_IS_OK(status
)) {
1191 tevent_req_nterror(req
, status
);
1196 status
= smb_bytes_talloc_string(cli
,
1198 &cli
->server_domain
,
1203 if (!NT_STATUS_IS_OK(status
)) {
1204 tevent_req_nterror(req
, status
);
1210 if (state
->blob
.length
!= 0) {
1214 if (!cli_sesssetup_blob_next(state
, &subreq
)) {
1215 tevent_req_oom(req
);
1218 tevent_req_set_callback(subreq
, cli_sesssetup_blob_done
, req
);
1221 tevent_req_done(req
);
1224 static NTSTATUS
cli_sesssetup_blob_recv(struct tevent_req
*req
,
1225 TALLOC_CTX
*mem_ctx
,
1228 struct iovec
**precv_iov
)
1230 struct cli_sesssetup_blob_state
*state
= tevent_req_data(
1231 req
, struct cli_sesssetup_blob_state
);
1234 struct iovec
*recv_iov
;
1236 if (tevent_req_is_nterror(req
, &status
)) {
1237 TALLOC_FREE(state
->cli
->smb2
.session
);
1238 cli_state_set_uid(state
->cli
, UID_FIELD_INVALID
);
1242 inbuf
= talloc_move(mem_ctx
, &state
->inbuf
);
1243 recv_iov
= talloc_move(mem_ctx
, &state
->recv_iov
);
1244 if (pblob
!= NULL
) {
1245 *pblob
= state
->ret_blob
;
1247 if (pinbuf
!= NULL
) {
1250 if (precv_iov
!= NULL
) {
1251 *precv_iov
= recv_iov
;
1253 /* could be NT_STATUS_MORE_PROCESSING_REQUIRED */
1254 return state
->status
;
1259 /****************************************************************************
1260 Use in-memory credentials cache
1261 ****************************************************************************/
1263 static void use_in_memory_ccache(void) {
1264 setenv(KRB5_ENV_CCNAME
, "MEMORY:cliconnect", 1);
1267 /****************************************************************************
1268 Do a spnego/kerberos encrypted session setup.
1269 ****************************************************************************/
1271 struct cli_session_setup_kerberos_state
{
1272 struct cli_state
*cli
;
1273 DATA_BLOB negTokenTarg
;
1274 DATA_BLOB session_key_krb5
;
1275 ADS_STATUS ads_status
;
1278 static void cli_session_setup_kerberos_done(struct tevent_req
*subreq
);
1280 static struct tevent_req
*cli_session_setup_kerberos_send(
1281 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
1282 const char *principal
)
1284 struct tevent_req
*req
, *subreq
;
1285 struct cli_session_setup_kerberos_state
*state
;
1288 DEBUG(2,("Doing kerberos session setup\n"));
1290 req
= tevent_req_create(mem_ctx
, &state
,
1291 struct cli_session_setup_kerberos_state
);
1296 state
->ads_status
= ADS_SUCCESS
;
1299 * Ok, this is cheating: spnego_gen_krb5_negTokenInit can block if
1300 * we have to acquire a ticket. To be fixed later :-)
1302 rc
= spnego_gen_krb5_negTokenInit(state
, principal
, 0, &state
->negTokenTarg
,
1303 &state
->session_key_krb5
, 0, NULL
, NULL
);
1307 state
->ads_status
= ADS_ERROR_KRB5(rc
);
1308 status
= ads_ntstatus(state
->ads_status
);
1309 if (NT_STATUS_EQUAL(status
, NT_STATUS_UNSUCCESSFUL
)) {
1310 status
= NT_STATUS_LOGON_FAILURE
;
1311 state
->ads_status
= ADS_ERROR_NT(status
);
1313 DEBUG(1, ("cli_session_setup_kerberos: "
1314 "spnego_gen_krb5_negTokenInit failed: %s - %s\n",
1315 error_message(rc
), nt_errstr(status
)));
1316 tevent_req_nterror(req
, status
);
1317 return tevent_req_post(req
, ev
);
1321 file_save("negTokenTarg.dat", state
->negTokenTarg
.data
,
1322 state
->negTokenTarg
.length
);
1325 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
1326 state
->cli
->smb2
.session
= smbXcli_session_create(cli
,
1328 if (tevent_req_nomem(state
->cli
->smb2
.session
, req
)) {
1329 return tevent_req_post(req
, ev
);
1333 subreq
= cli_sesssetup_blob_send(state
, ev
, cli
, state
->negTokenTarg
);
1334 if (tevent_req_nomem(subreq
, req
)) {
1335 return tevent_req_post(req
, ev
);
1337 tevent_req_set_callback(subreq
, cli_session_setup_kerberos_done
, req
);
1341 static void cli_session_setup_kerberos_done(struct tevent_req
*subreq
)
1343 struct tevent_req
*req
= tevent_req_callback_data(
1344 subreq
, struct tevent_req
);
1345 struct cli_session_setup_kerberos_state
*state
= tevent_req_data(
1346 req
, struct cli_session_setup_kerberos_state
);
1347 uint8_t *inbuf
= NULL
;
1348 struct iovec
*recv_iov
= NULL
;
1351 status
= cli_sesssetup_blob_recv(subreq
, state
,
1352 NULL
, &inbuf
, &recv_iov
);
1353 TALLOC_FREE(subreq
);
1354 if (!NT_STATUS_IS_OK(status
)) {
1355 tevent_req_nterror(req
, status
);
1359 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
1360 struct smbXcli_session
*session
= state
->cli
->smb2
.session
;
1361 status
= smb2cli_session_set_session_key(session
,
1362 state
->session_key_krb5
,
1364 if (tevent_req_nterror(req
, status
)) {
1368 struct smbXcli_session
*session
= state
->cli
->smb1
.session
;
1370 status
= smb1cli_session_set_session_key(session
,
1371 state
->session_key_krb5
);
1372 if (tevent_req_nterror(req
, status
)) {
1376 if (smb1cli_conn_activate_signing(state
->cli
->conn
, state
->session_key_krb5
,
1378 && !smb1cli_conn_check_signing(state
->cli
->conn
, inbuf
, 1)) {
1379 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1384 tevent_req_done(req
);
1387 static ADS_STATUS
cli_session_setup_kerberos_recv(struct tevent_req
*req
)
1389 struct cli_session_setup_kerberos_state
*state
= tevent_req_data(
1390 req
, struct cli_session_setup_kerberos_state
);
1393 if (tevent_req_is_nterror(req
, &status
)) {
1394 ADS_STATUS ads
= state
->ads_status
;
1396 if (!ADS_ERR_OK(state
->ads_status
)) {
1397 ads
= state
->ads_status
;
1399 ads
= ADS_ERROR_NT(status
);
1401 tevent_req_received(req
);
1404 tevent_req_received(req
);
1408 #endif /* HAVE_KRB5 */
1410 /****************************************************************************
1411 Do a spnego/NTLMSSP encrypted session setup.
1412 ****************************************************************************/
1414 struct cli_session_setup_ntlmssp_state
{
1415 struct tevent_context
*ev
;
1416 struct cli_state
*cli
;
1417 struct ntlmssp_state
*ntlmssp_state
;
1422 static int cli_session_setup_ntlmssp_state_destructor(
1423 struct cli_session_setup_ntlmssp_state
*state
)
1425 if (state
->ntlmssp_state
!= NULL
) {
1426 TALLOC_FREE(state
->ntlmssp_state
);
1431 static void cli_session_setup_ntlmssp_done(struct tevent_req
*req
);
1433 static struct tevent_req
*cli_session_setup_ntlmssp_send(
1434 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
1435 const char *user
, const char *pass
, const char *domain
)
1437 struct tevent_req
*req
, *subreq
;
1438 struct cli_session_setup_ntlmssp_state
*state
;
1441 const char *OIDs_ntlm
[] = {OID_NTLMSSP
, NULL
};
1443 req
= tevent_req_create(mem_ctx
, &state
,
1444 struct cli_session_setup_ntlmssp_state
);
1452 state
->ntlmssp_state
= NULL
;
1453 talloc_set_destructor(
1454 state
, cli_session_setup_ntlmssp_state_destructor
);
1456 status
= ntlmssp_client_start(state
,
1459 lp_client_ntlmv2_auth(),
1460 &state
->ntlmssp_state
);
1461 if (!NT_STATUS_IS_OK(status
)) {
1464 ntlmssp_want_feature(state
->ntlmssp_state
,
1465 NTLMSSP_FEATURE_SESSION_KEY
);
1466 if (cli
->use_ccache
) {
1467 ntlmssp_want_feature(state
->ntlmssp_state
,
1468 NTLMSSP_FEATURE_CCACHE
);
1470 status
= ntlmssp_set_username(state
->ntlmssp_state
, user
);
1471 if (!NT_STATUS_IS_OK(status
)) {
1474 status
= ntlmssp_set_domain(state
->ntlmssp_state
, domain
);
1475 if (!NT_STATUS_IS_OK(status
)) {
1478 if (cli
->pw_nt_hash
) {
1479 status
= ntlmssp_set_password_hash(state
->ntlmssp_state
, pass
);
1481 status
= ntlmssp_set_password(state
->ntlmssp_state
, pass
);
1483 if (!NT_STATUS_IS_OK(status
)) {
1486 status
= ntlmssp_update(state
->ntlmssp_state
, data_blob_null
,
1488 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1492 state
->blob_out
= spnego_gen_negTokenInit(state
, OIDs_ntlm
, &blob_out
, NULL
);
1493 data_blob_free(&blob_out
);
1495 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
1496 state
->cli
->smb2
.session
= smbXcli_session_create(cli
,
1498 if (tevent_req_nomem(state
->cli
->smb2
.session
, req
)) {
1499 return tevent_req_post(req
, ev
);
1503 subreq
= cli_sesssetup_blob_send(state
, ev
, cli
, state
->blob_out
);
1504 if (tevent_req_nomem(subreq
, req
)) {
1505 return tevent_req_post(req
, ev
);
1507 tevent_req_set_callback(subreq
, cli_session_setup_ntlmssp_done
, req
);
1510 tevent_req_nterror(req
, status
);
1511 return tevent_req_post(req
, ev
);
1514 static void cli_session_setup_ntlmssp_done(struct tevent_req
*subreq
)
1516 struct tevent_req
*req
= tevent_req_callback_data(
1517 subreq
, struct tevent_req
);
1518 struct cli_session_setup_ntlmssp_state
*state
= tevent_req_data(
1519 req
, struct cli_session_setup_ntlmssp_state
);
1520 DATA_BLOB blob_in
, msg_in
, blob_out
;
1521 uint8_t *inbuf
= NULL
;
1522 struct iovec
*recv_iov
= NULL
;
1526 status
= cli_sesssetup_blob_recv(subreq
, talloc_tos(), &blob_in
,
1528 TALLOC_FREE(subreq
);
1529 data_blob_free(&state
->blob_out
);
1531 if (NT_STATUS_IS_OK(status
)) {
1532 if (state
->cli
->server_domain
[0] == '\0') {
1533 TALLOC_FREE(state
->cli
->server_domain
);
1534 state
->cli
->server_domain
= talloc_strdup(state
->cli
,
1535 state
->ntlmssp_state
->server
.netbios_domain
);
1536 if (state
->cli
->server_domain
== NULL
) {
1537 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
1542 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
1543 struct smbXcli_session
*session
= state
->cli
->smb2
.session
;
1545 if (ntlmssp_is_anonymous(state
->ntlmssp_state
)) {
1547 * Windows server does not set the
1548 * SMB2_SESSION_FLAG_IS_GUEST nor
1549 * SMB2_SESSION_FLAG_IS_NULL flag.
1551 * This fix makes sure we do not try
1552 * to verify a signature on the final
1553 * session setup response.
1555 TALLOC_FREE(state
->ntlmssp_state
);
1556 tevent_req_done(req
);
1560 status
= smb2cli_session_set_session_key(session
,
1561 state
->ntlmssp_state
->session_key
,
1563 if (tevent_req_nterror(req
, status
)) {
1567 struct smbXcli_session
*session
= state
->cli
->smb1
.session
;
1569 status
= smb1cli_session_set_session_key(session
,
1570 state
->ntlmssp_state
->session_key
);
1571 if (tevent_req_nterror(req
, status
)) {
1575 if (smb1cli_conn_activate_signing(
1576 state
->cli
->conn
, state
->ntlmssp_state
->session_key
,
1578 && !smb1cli_conn_check_signing(state
->cli
->conn
, inbuf
, 1)) {
1579 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1583 TALLOC_FREE(state
->ntlmssp_state
);
1584 tevent_req_done(req
);
1587 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1588 tevent_req_nterror(req
, status
);
1592 if (blob_in
.length
== 0) {
1593 tevent_req_nterror(req
, NT_STATUS_UNSUCCESSFUL
);
1597 if ((state
->turn
== 1)
1598 && NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1599 DATA_BLOB tmp_blob
= data_blob_null
;
1600 /* the server might give us back two challenges */
1601 parse_ret
= spnego_parse_challenge(state
, blob_in
, &msg_in
,
1603 data_blob_free(&tmp_blob
);
1605 parse_ret
= spnego_parse_auth_response(state
, blob_in
, status
,
1606 OID_NTLMSSP
, &msg_in
);
1611 DEBUG(3,("Failed to parse auth response\n"));
1612 if (NT_STATUS_IS_OK(status
)
1613 || NT_STATUS_EQUAL(status
,
1614 NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1616 req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
1621 status
= ntlmssp_update(state
->ntlmssp_state
, msg_in
, &blob_out
);
1623 if (!NT_STATUS_IS_OK(status
)
1624 && !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1625 TALLOC_FREE(state
->ntlmssp_state
);
1626 tevent_req_nterror(req
, status
);
1630 state
->blob_out
= spnego_gen_auth(state
, blob_out
);
1631 if (tevent_req_nomem(state
->blob_out
.data
, req
)) {
1635 subreq
= cli_sesssetup_blob_send(state
, state
->ev
, state
->cli
,
1637 if (tevent_req_nomem(subreq
, req
)) {
1640 tevent_req_set_callback(subreq
, cli_session_setup_ntlmssp_done
, req
);
1643 static NTSTATUS
cli_session_setup_ntlmssp_recv(struct tevent_req
*req
)
1645 struct cli_session_setup_ntlmssp_state
*state
= tevent_req_data(
1646 req
, struct cli_session_setup_ntlmssp_state
);
1649 if (tevent_req_is_nterror(req
, &status
)) {
1650 cli_state_set_uid(state
->cli
, UID_FIELD_INVALID
);
1653 return NT_STATUS_OK
;
1658 static char *cli_session_setup_get_principal(
1659 TALLOC_CTX
*mem_ctx
, const char *spnego_principal
,
1660 const char *remote_name
, const char *dest_realm
)
1662 char *principal
= NULL
;
1664 if (!lp_client_use_spnego_principal() ||
1665 strequal(spnego_principal
, ADS_IGNORE_PRINCIPAL
)) {
1666 spnego_principal
= NULL
;
1668 if (spnego_principal
!= NULL
) {
1669 DEBUG(3, ("cli_session_setup_spnego: using spnego provided "
1670 "principal %s\n", spnego_principal
));
1671 return talloc_strdup(mem_ctx
, spnego_principal
);
1673 if (is_ipaddress(remote_name
) ||
1674 strequal(remote_name
, STAR_SMBSERVER
)) {
1678 DEBUG(3, ("cli_session_setup_spnego: using target "
1679 "hostname not SPNEGO principal\n"));
1682 char *realm
= strupper_talloc(talloc_tos(), dest_realm
);
1683 if (realm
== NULL
) {
1686 principal
= talloc_asprintf(talloc_tos(), "cifs/%s@%s",
1687 remote_name
, realm
);
1690 principal
= kerberos_get_principal_from_service_hostname(
1691 talloc_tos(), "cifs", remote_name
, lp_realm());
1693 DEBUG(3, ("cli_session_setup_spnego: guessed server principal=%s\n",
1694 principal
? principal
: "<null>"));
1700 static char *cli_session_setup_get_account(TALLOC_CTX
*mem_ctx
,
1701 const char *principal
)
1705 account
= talloc_strdup(mem_ctx
, principal
);
1706 if (account
== NULL
) {
1709 p
= strchr_m(account
, '@');
1716 /****************************************************************************
1717 Do a spnego encrypted session setup.
1719 user_domain: The shortname of the domain the user/machine is a member of.
1720 dest_realm: The realm we're connecting to, if NULL we use our default realm.
1721 ****************************************************************************/
1723 struct cli_session_setup_spnego_state
{
1724 struct tevent_context
*ev
;
1725 struct cli_state
*cli
;
1727 const char *account
;
1729 const char *user_domain
;
1730 const char *dest_realm
;
1735 static void cli_session_setup_spnego_done_krb(struct tevent_req
*subreq
);
1738 static void cli_session_setup_spnego_done_ntlmssp(struct tevent_req
*subreq
);
1740 static struct tevent_req
*cli_session_setup_spnego_send(
1741 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
1742 const char *user
, const char *pass
, const char *user_domain
,
1743 const char *dest_realm
)
1745 struct tevent_req
*req
, *subreq
;
1746 struct cli_session_setup_spnego_state
*state
;
1747 char *principal
= NULL
;
1748 char *OIDs
[ASN1_MAX_OIDS
];
1750 const DATA_BLOB
*server_blob
;
1752 req
= tevent_req_create(mem_ctx
, &state
,
1753 struct cli_session_setup_spnego_state
);
1761 state
->user_domain
= user_domain
;
1762 state
->dest_realm
= dest_realm
;
1764 state
->account
= cli_session_setup_get_account(state
, user
);
1765 if (tevent_req_nomem(state
->account
, req
)) {
1766 return tevent_req_post(req
, ev
);
1769 server_blob
= smbXcli_conn_server_gss_blob(cli
->conn
);
1771 DEBUG(3,("Doing spnego session setup (blob length=%lu)\n",
1772 (unsigned long)server_blob
->length
));
1774 /* the server might not even do spnego */
1775 if (server_blob
->length
== 0) {
1776 DEBUG(3,("server didn't supply a full spnego negprot\n"));
1781 file_save("negprot.dat", cli
->secblob
.data
, cli
->secblob
.length
);
1784 /* The server sent us the first part of the SPNEGO exchange in the
1785 * negprot reply. It is WRONG to depend on the principal sent in the
1786 * negprot reply, but right now we do it. If we don't receive one,
1787 * we try to best guess, then fall back to NTLM. */
1788 if (!spnego_parse_negTokenInit(state
, *server_blob
, OIDs
,
1789 &principal
, NULL
) ||
1791 state
->result
= ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
1792 tevent_req_done(req
);
1793 return tevent_req_post(req
, ev
);
1796 /* make sure the server understands kerberos */
1797 for (i
=0;OIDs
[i
];i
++) {
1799 DEBUG(3,("got OID=%s\n", OIDs
[i
]));
1801 DEBUGADD(3,("got OID=%s\n", OIDs
[i
]));
1802 if (strcmp(OIDs
[i
], OID_KERBEROS5_OLD
) == 0 ||
1803 strcmp(OIDs
[i
], OID_KERBEROS5
) == 0) {
1804 cli
->got_kerberos_mechanism
= True
;
1806 talloc_free(OIDs
[i
]);
1809 DEBUG(3,("got principal=%s\n", principal
? principal
: "<null>"));
1812 /* If password is set we reauthenticate to kerberos server
1813 * and do not store results */
1815 if (user
&& *user
&& cli
->got_kerberos_mechanism
&& cli
->use_kerberos
) {
1816 const char *remote_name
= smbXcli_conn_remote_name(cli
->conn
);
1820 tmp
= cli_session_setup_get_principal(
1821 talloc_tos(), principal
, remote_name
, dest_realm
);
1822 TALLOC_FREE(principal
);
1825 if (pass
&& *pass
) {
1828 use_in_memory_ccache();
1829 ret
= kerberos_kinit_password(user
, pass
, 0 /* no time correction for now */, NULL
);
1832 DEBUG(0, ("Kinit for %s to access %s failed: %s\n", user
, principal
, error_message(ret
)));
1833 TALLOC_FREE(principal
);
1834 if (cli
->fallback_after_kerberos
)
1836 state
->result
= ADS_ERROR_KRB5(ret
);
1837 tevent_req_done(req
);
1838 return tevent_req_post(req
, ev
);
1843 subreq
= cli_session_setup_kerberos_send(
1844 state
, ev
, cli
, principal
);
1845 if (tevent_req_nomem(subreq
, req
)) {
1846 return tevent_req_post(req
, ev
);
1848 tevent_req_set_callback(
1849 subreq
, cli_session_setup_spnego_done_krb
,
1857 subreq
= cli_session_setup_ntlmssp_send(
1858 state
, ev
, cli
, state
->account
, pass
, user_domain
);
1859 if (tevent_req_nomem(subreq
, req
)) {
1860 return tevent_req_post(req
, ev
);
1862 tevent_req_set_callback(
1863 subreq
, cli_session_setup_spnego_done_ntlmssp
, req
);
1868 static void cli_session_setup_spnego_done_krb(struct tevent_req
*subreq
)
1870 struct tevent_req
*req
= tevent_req_callback_data(
1871 subreq
, struct tevent_req
);
1872 struct cli_session_setup_spnego_state
*state
= tevent_req_data(
1873 req
, struct cli_session_setup_spnego_state
);
1875 state
->result
= cli_session_setup_kerberos_recv(subreq
);
1876 TALLOC_FREE(subreq
);
1878 if (ADS_ERR_OK(state
->result
) ||
1879 !state
->cli
->fallback_after_kerberos
) {
1880 tevent_req_done(req
);
1884 subreq
= cli_session_setup_ntlmssp_send(
1885 state
, state
->ev
, state
->cli
, state
->account
, state
->pass
,
1886 state
->user_domain
);
1887 if (tevent_req_nomem(subreq
, req
)) {
1890 tevent_req_set_callback(subreq
, cli_session_setup_spnego_done_ntlmssp
,
1895 static void cli_session_setup_spnego_done_ntlmssp(struct tevent_req
*subreq
)
1897 struct tevent_req
*req
= tevent_req_callback_data(
1898 subreq
, struct tevent_req
);
1899 struct cli_session_setup_spnego_state
*state
= tevent_req_data(
1900 req
, struct cli_session_setup_spnego_state
);
1903 status
= cli_session_setup_ntlmssp_recv(subreq
);
1904 TALLOC_FREE(subreq
);
1905 state
->result
= ADS_ERROR_NT(status
);
1906 tevent_req_done(req
);
1909 static ADS_STATUS
cli_session_setup_spnego_recv(struct tevent_req
*req
)
1911 struct cli_session_setup_spnego_state
*state
= tevent_req_data(
1912 req
, struct cli_session_setup_spnego_state
);
1914 return state
->result
;
1917 struct cli_session_setup_state
{
1921 static void cli_session_setup_done_lanman2(struct tevent_req
*subreq
);
1922 static void cli_session_setup_done_spnego(struct tevent_req
*subreq
);
1923 static void cli_session_setup_done_guest(struct tevent_req
*subreq
);
1924 static void cli_session_setup_done_plain(struct tevent_req
*subreq
);
1925 static void cli_session_setup_done_nt1(struct tevent_req
*subreq
);
1927 /****************************************************************************
1928 Send a session setup. The username and workgroup is in UNIX character
1929 format and must be converted to DOS codepage format before sending. If the
1930 password is in plaintext, the same should be done.
1931 ****************************************************************************/
1933 struct tevent_req
*cli_session_setup_send(TALLOC_CTX
*mem_ctx
,
1934 struct tevent_context
*ev
,
1935 struct cli_state
*cli
,
1937 const char *pass
, int passlen
,
1938 const char *ntpass
, int ntpasslen
,
1939 const char *workgroup
)
1941 struct tevent_req
*req
, *subreq
;
1942 struct cli_session_setup_state
*state
;
1945 uint16_t sec_mode
= smb1cli_conn_server_security_mode(cli
->conn
);
1947 req
= tevent_req_create(mem_ctx
, &state
,
1948 struct cli_session_setup_state
);
1954 user2
= talloc_strdup(state
, user
);
1956 user2
= talloc_strdup(state
, "");
1958 if (user2
== NULL
) {
1959 tevent_req_oom(req
);
1960 return tevent_req_post(req
, ev
);
1967 /* allow for workgroups as part of the username */
1968 if ((p
=strchr_m(user2
,'\\')) || (p
=strchr_m(user2
,'/')) ||
1969 (p
=strchr_m(user2
,*lp_winbind_separator()))) {
1972 if (!strupper_m(user2
)) {
1973 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1974 return tevent_req_post(req
, ev
);
1979 if (smbXcli_conn_protocol(cli
->conn
) < PROTOCOL_LANMAN1
) {
1980 tevent_req_done(req
);
1981 return tevent_req_post(req
, ev
);
1984 /* now work out what sort of session setup we are going to
1985 do. I have split this into separate functions to make the
1986 flow a bit easier to understand (tridge) */
1988 /* if its an older server then we have to use the older request format */
1990 if (smbXcli_conn_protocol(cli
->conn
) < PROTOCOL_NT1
) {
1991 if (!lp_client_lanman_auth() && passlen
!= 24 && (*pass
)) {
1992 DEBUG(1, ("Server requested LM password but 'client lanman auth = no'"
1993 " or 'client ntlmv2 auth = yes'\n"));
1994 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1995 return tevent_req_post(req
, ev
);
1998 if ((sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
) == 0 &&
1999 !lp_client_plaintext_auth() && (*pass
)) {
2000 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
2001 " or 'client ntlmv2 auth = yes'\n"));
2002 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
2003 return tevent_req_post(req
, ev
);
2006 subreq
= cli_session_setup_lanman2_send(
2007 state
, ev
, cli
, user
, pass
, passlen
, workgroup
);
2008 if (tevent_req_nomem(subreq
, req
)) {
2009 return tevent_req_post(req
, ev
);
2011 tevent_req_set_callback(subreq
, cli_session_setup_done_lanman2
,
2016 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
2017 const char *remote_realm
= cli_state_remote_realm(cli
);
2019 subreq
= cli_session_setup_spnego_send(
2020 state
, ev
, cli
, user
, pass
, workgroup
, remote_realm
);
2021 if (tevent_req_nomem(subreq
, req
)) {
2022 return tevent_req_post(req
, ev
);
2024 tevent_req_set_callback(subreq
, cli_session_setup_done_spnego
,
2029 /* if no user is supplied then we have to do an anonymous connection.
2030 passwords are ignored */
2032 if (!user
|| !*user
) {
2033 subreq
= cli_session_setup_guest_send(state
, ev
, cli
);
2034 if (tevent_req_nomem(subreq
, req
)) {
2035 return tevent_req_post(req
, ev
);
2037 tevent_req_set_callback(subreq
, cli_session_setup_done_guest
,
2042 /* if the server is share level then send a plaintext null
2043 password at this point. The password is sent in the tree
2046 if ((sec_mode
& NEGOTIATE_SECURITY_USER_LEVEL
) == 0) {
2047 subreq
= cli_session_setup_plain_send(
2048 state
, ev
, cli
, user
, "", workgroup
);
2049 if (tevent_req_nomem(subreq
, req
)) {
2050 return tevent_req_post(req
, ev
);
2052 tevent_req_set_callback(subreq
, cli_session_setup_done_plain
,
2057 /* if the server doesn't support encryption then we have to use
2058 plaintext. The second password is ignored */
2060 if ((sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
) == 0) {
2061 if (!lp_client_plaintext_auth() && (*pass
)) {
2062 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
2063 " or 'client ntlmv2 auth = yes'\n"));
2064 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
2065 return tevent_req_post(req
, ev
);
2067 subreq
= cli_session_setup_plain_send(
2068 state
, ev
, cli
, user
, pass
, workgroup
);
2069 if (tevent_req_nomem(subreq
, req
)) {
2070 return tevent_req_post(req
, ev
);
2072 tevent_req_set_callback(subreq
, cli_session_setup_done_plain
,
2077 /* if the server supports extended security then use SPNEGO */
2079 if (smb1cli_conn_capabilities(cli
->conn
) & CAP_EXTENDED_SECURITY
) {
2080 const char *remote_realm
= cli_state_remote_realm(cli
);
2082 subreq
= cli_session_setup_spnego_send(
2083 state
, ev
, cli
, user
, pass
, workgroup
, remote_realm
);
2084 if (tevent_req_nomem(subreq
, req
)) {
2085 return tevent_req_post(req
, ev
);
2087 tevent_req_set_callback(subreq
, cli_session_setup_done_spnego
,
2091 /* otherwise do a NT1 style session setup */
2093 subreq
= cli_session_setup_nt1_send(
2094 state
, ev
, cli
, user
, pass
, passlen
, ntpass
, ntpasslen
,
2096 if (tevent_req_nomem(subreq
, req
)) {
2097 return tevent_req_post(req
, ev
);
2099 tevent_req_set_callback(subreq
, cli_session_setup_done_nt1
,
2104 tevent_req_done(req
);
2105 return tevent_req_post(req
, ev
);
2108 static void cli_session_setup_done_lanman2(struct tevent_req
*subreq
)
2110 struct tevent_req
*req
= tevent_req_callback_data(
2111 subreq
, struct tevent_req
);
2114 status
= cli_session_setup_lanman2_recv(subreq
);
2115 TALLOC_FREE(subreq
);
2116 if (!NT_STATUS_IS_OK(status
)) {
2117 tevent_req_nterror(req
, status
);
2120 tevent_req_done(req
);
2123 static void cli_session_setup_done_spnego(struct tevent_req
*subreq
)
2125 struct tevent_req
*req
= tevent_req_callback_data(
2126 subreq
, struct tevent_req
);
2129 status
= cli_session_setup_spnego_recv(subreq
);
2130 TALLOC_FREE(subreq
);
2131 if (!ADS_ERR_OK(status
)) {
2132 DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status
)));
2133 tevent_req_nterror(req
, ads_ntstatus(status
));
2136 tevent_req_done(req
);
2139 static void cli_session_setup_done_guest(struct tevent_req
*subreq
)
2141 struct tevent_req
*req
= tevent_req_callback_data(
2142 subreq
, struct tevent_req
);
2145 status
= cli_session_setup_guest_recv(subreq
);
2146 TALLOC_FREE(subreq
);
2147 if (!NT_STATUS_IS_OK(status
)) {
2148 tevent_req_nterror(req
, status
);
2151 tevent_req_done(req
);
2154 static void cli_session_setup_done_plain(struct tevent_req
*subreq
)
2156 struct tevent_req
*req
= tevent_req_callback_data(
2157 subreq
, struct tevent_req
);
2160 status
= cli_session_setup_plain_recv(subreq
);
2161 TALLOC_FREE(subreq
);
2162 if (!NT_STATUS_IS_OK(status
)) {
2163 tevent_req_nterror(req
, status
);
2166 tevent_req_done(req
);
2169 static void cli_session_setup_done_nt1(struct tevent_req
*subreq
)
2171 struct tevent_req
*req
= tevent_req_callback_data(
2172 subreq
, struct tevent_req
);
2175 status
= cli_session_setup_nt1_recv(subreq
);
2176 TALLOC_FREE(subreq
);
2177 if (!NT_STATUS_IS_OK(status
)) {
2178 DEBUG(3, ("cli_session_setup: NT1 session setup "
2179 "failed: %s\n", nt_errstr(status
)));
2180 tevent_req_nterror(req
, status
);
2183 tevent_req_done(req
);
2186 NTSTATUS
cli_session_setup_recv(struct tevent_req
*req
)
2188 return tevent_req_simple_recv_ntstatus(req
);
2191 NTSTATUS
cli_session_setup(struct cli_state
*cli
,
2193 const char *pass
, int passlen
,
2194 const char *ntpass
, int ntpasslen
,
2195 const char *workgroup
)
2197 struct tevent_context
*ev
;
2198 struct tevent_req
*req
;
2199 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2201 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
2202 return NT_STATUS_INVALID_PARAMETER
;
2204 ev
= samba_tevent_context_init(talloc_tos());
2208 req
= cli_session_setup_send(ev
, ev
, cli
, user
, pass
, passlen
,
2209 ntpass
, ntpasslen
, workgroup
);
2213 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2216 status
= cli_session_setup_recv(req
);
2222 /****************************************************************************
2224 *****************************************************************************/
2226 struct cli_ulogoff_state
{
2227 struct cli_state
*cli
;
2231 static void cli_ulogoff_done(struct tevent_req
*subreq
);
2233 static struct tevent_req
*cli_ulogoff_send(TALLOC_CTX
*mem_ctx
,
2234 struct tevent_context
*ev
,
2235 struct cli_state
*cli
)
2237 struct tevent_req
*req
, *subreq
;
2238 struct cli_ulogoff_state
*state
;
2240 req
= tevent_req_create(mem_ctx
, &state
, struct cli_ulogoff_state
);
2246 SCVAL(state
->vwv
+0, 0, 0xFF);
2247 SCVAL(state
->vwv
+1, 0, 0);
2248 SSVAL(state
->vwv
+2, 0, 0);
2250 subreq
= cli_smb_send(state
, ev
, cli
, SMBulogoffX
, 0, 2, state
->vwv
,
2252 if (tevent_req_nomem(subreq
, req
)) {
2253 return tevent_req_post(req
, ev
);
2255 tevent_req_set_callback(subreq
, cli_ulogoff_done
, req
);
2259 static void cli_ulogoff_done(struct tevent_req
*subreq
)
2261 struct tevent_req
*req
= tevent_req_callback_data(
2262 subreq
, struct tevent_req
);
2263 struct cli_ulogoff_state
*state
= tevent_req_data(
2264 req
, struct cli_ulogoff_state
);
2267 status
= cli_smb_recv(subreq
, NULL
, NULL
, 0, NULL
, NULL
, NULL
, NULL
);
2268 if (!NT_STATUS_IS_OK(status
)) {
2269 tevent_req_nterror(req
, status
);
2272 cli_state_set_uid(state
->cli
, UID_FIELD_INVALID
);
2273 tevent_req_done(req
);
2276 static NTSTATUS
cli_ulogoff_recv(struct tevent_req
*req
)
2278 return tevent_req_simple_recv_ntstatus(req
);
2281 NTSTATUS
cli_ulogoff(struct cli_state
*cli
)
2283 struct tevent_context
*ev
;
2284 struct tevent_req
*req
;
2285 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2287 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
2288 status
= smb2cli_logoff(cli
->conn
,
2291 if (!NT_STATUS_IS_OK(status
)) {
2294 smb2cli_session_set_id_and_flags(cli
->smb2
.session
,
2296 return NT_STATUS_OK
;
2299 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
2300 return NT_STATUS_INVALID_PARAMETER
;
2302 ev
= samba_tevent_context_init(talloc_tos());
2306 req
= cli_ulogoff_send(ev
, ev
, cli
);
2310 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2313 status
= cli_ulogoff_recv(req
);
2319 /****************************************************************************
2321 ****************************************************************************/
2323 struct cli_tcon_andx_state
{
2324 struct cli_state
*cli
;
2329 static void cli_tcon_andx_done(struct tevent_req
*subreq
);
2331 struct tevent_req
*cli_tcon_andx_create(TALLOC_CTX
*mem_ctx
,
2332 struct tevent_context
*ev
,
2333 struct cli_state
*cli
,
2334 const char *share
, const char *dev
,
2335 const char *pass
, int passlen
,
2336 struct tevent_req
**psmbreq
)
2338 struct tevent_req
*req
, *subreq
;
2339 struct cli_tcon_andx_state
*state
;
2344 uint16_t sec_mode
= smb1cli_conn_server_security_mode(cli
->conn
);
2345 uint16_t tcon_flags
= 0;
2349 req
= tevent_req_create(mem_ctx
, &state
, struct cli_tcon_andx_state
);
2356 cli
->share
= talloc_strdup(cli
, share
);
2361 /* in user level security don't send a password now */
2362 if (sec_mode
& NEGOTIATE_SECURITY_USER_LEVEL
) {
2365 } else if (pass
== NULL
) {
2366 DEBUG(1, ("Server not using user level security and no "
2367 "password supplied.\n"));
2371 if ((sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
) &&
2372 *pass
&& passlen
!= 24) {
2373 if (!lp_client_lanman_auth()) {
2374 DEBUG(1, ("Server requested LANMAN password "
2375 "(share-level security) but "
2376 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2381 * Non-encrypted passwords - convert to DOS codepage before
2384 SMBencrypt(pass
, smb1cli_conn_server_challenge(cli
->conn
), p24
);
2386 pass
= (const char *)p24
;
2388 if((sec_mode
& (NEGOTIATE_SECURITY_USER_LEVEL
2389 |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
))
2393 if (!lp_client_plaintext_auth() && (*pass
)) {
2394 DEBUG(1, ("Server requested PLAINTEXT "
2396 "'client plaintext auth = no' or 'client ntlmv2 auth = yes'\n"));
2401 * Non-encrypted passwords - convert to DOS codepage
2404 tmp_pass
= talloc_array(talloc_tos(), uint8_t, 0);
2405 if (tevent_req_nomem(tmp_pass
, req
)) {
2406 return tevent_req_post(req
, ev
);
2408 tmp_pass
= trans2_bytes_push_str(tmp_pass
,
2409 false, /* always DOS */
2413 if (tevent_req_nomem(tmp_pass
, req
)) {
2414 return tevent_req_post(req
, ev
);
2416 pass
= (const char *)tmp_pass
;
2417 passlen
= talloc_get_size(tmp_pass
);
2421 tcon_flags
|= TCONX_FLAG_EXTENDED_RESPONSE
;
2422 tcon_flags
|= TCONX_FLAG_EXTENDED_SIGNATURES
;
2424 SCVAL(vwv
+0, 0, 0xFF);
2427 SSVAL(vwv
+2, 0, tcon_flags
);
2428 SSVAL(vwv
+3, 0, passlen
);
2430 if (passlen
&& pass
) {
2431 bytes
= (uint8_t *)talloc_memdup(state
, pass
, passlen
);
2433 bytes
= talloc_array(state
, uint8_t, 0);
2439 tmp
= talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
2440 smbXcli_conn_remote_name(cli
->conn
), share
);
2445 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), tmp
, strlen(tmp
)+1,
2450 * Add the devicetype
2452 tmp
= talloc_strdup_upper(talloc_tos(), dev
);
2457 bytes
= smb_bytes_push_str(bytes
, false, tmp
, strlen(tmp
)+1, NULL
);
2460 if (bytes
== NULL
) {
2465 state
->bytes
.iov_base
= (void *)bytes
;
2466 state
->bytes
.iov_len
= talloc_get_size(bytes
);
2468 subreq
= cli_smb_req_create(state
, ev
, cli
, SMBtconX
, 0, 4, vwv
,
2470 if (subreq
== NULL
) {
2474 tevent_req_set_callback(subreq
, cli_tcon_andx_done
, req
);
2479 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
2480 return tevent_req_post(req
, ev
);
2483 struct tevent_req
*cli_tcon_andx_send(TALLOC_CTX
*mem_ctx
,
2484 struct tevent_context
*ev
,
2485 struct cli_state
*cli
,
2486 const char *share
, const char *dev
,
2487 const char *pass
, int passlen
)
2489 struct tevent_req
*req
, *subreq
;
2492 req
= cli_tcon_andx_create(mem_ctx
, ev
, cli
, share
, dev
, pass
, passlen
,
2497 if (subreq
== NULL
) {
2500 status
= smb1cli_req_chain_submit(&subreq
, 1);
2501 if (!NT_STATUS_IS_OK(status
)) {
2502 tevent_req_nterror(req
, status
);
2503 return tevent_req_post(req
, ev
);
2508 static void cli_tcon_andx_done(struct tevent_req
*subreq
)
2510 struct tevent_req
*req
= tevent_req_callback_data(
2511 subreq
, struct tevent_req
);
2512 struct cli_tcon_andx_state
*state
= tevent_req_data(
2513 req
, struct cli_tcon_andx_state
);
2514 struct cli_state
*cli
= state
->cli
;
2522 uint16_t optional_support
= 0;
2524 status
= cli_smb_recv(subreq
, state
, &in
, 0, &wct
, &vwv
,
2525 &num_bytes
, &bytes
);
2526 TALLOC_FREE(subreq
);
2527 if (!NT_STATUS_IS_OK(status
)) {
2528 tevent_req_nterror(req
, status
);
2532 inhdr
= in
+ NBT_HDR_SIZE
;
2535 if (clistr_pull_talloc(cli
,
2536 (const char *)inhdr
,
2537 SVAL(inhdr
, HDR_FLG2
),
2541 STR_TERMINATE
|STR_ASCII
) == -1) {
2542 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
2546 cli
->dev
= talloc_strdup(cli
, "");
2547 if (cli
->dev
== NULL
) {
2548 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
2553 if ((smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_NT1
) && (num_bytes
== 3)) {
2554 /* almost certainly win95 - enable bug fixes */
2559 * Make sure that we have the optional support 16-bit field. WCT > 2.
2560 * Avoids issues when connecting to Win9x boxes sharing files
2563 if ((wct
> 2) && (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_LANMAN2
)) {
2564 optional_support
= SVAL(vwv
+2, 0);
2567 if (optional_support
& SMB_EXTENDED_SIGNATURES
) {
2568 smb1cli_session_protect_session_key(cli
->smb1
.session
);
2571 smb1cli_tcon_set_values(state
->cli
->smb1
.tcon
,
2572 SVAL(inhdr
, HDR_TID
),
2574 0, /* maximal_access */
2575 0, /* guest_maximal_access */
2577 NULL
); /* fs_type */
2579 tevent_req_done(req
);
2582 NTSTATUS
cli_tcon_andx_recv(struct tevent_req
*req
)
2584 return tevent_req_simple_recv_ntstatus(req
);
2587 NTSTATUS
cli_tcon_andx(struct cli_state
*cli
, const char *share
,
2588 const char *dev
, const char *pass
, int passlen
)
2590 TALLOC_CTX
*frame
= talloc_stackframe();
2591 struct tevent_context
*ev
;
2592 struct tevent_req
*req
;
2593 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2595 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
2597 * Can't use sync call while an async call is in flight
2599 status
= NT_STATUS_INVALID_PARAMETER
;
2603 ev
= samba_tevent_context_init(frame
);
2608 req
= cli_tcon_andx_send(frame
, ev
, cli
, share
, dev
, pass
, passlen
);
2613 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2617 status
= cli_tcon_andx_recv(req
);
2623 struct cli_tree_connect_state
{
2624 struct cli_state
*cli
;
2627 static struct tevent_req
*cli_raw_tcon_send(
2628 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
2629 const char *service
, const char *pass
, const char *dev
);
2630 static NTSTATUS
cli_raw_tcon_recv(struct tevent_req
*req
,
2631 uint16_t *max_xmit
, uint16_t *tid
);
2633 static void cli_tree_connect_smb2_done(struct tevent_req
*subreq
);
2634 static void cli_tree_connect_andx_done(struct tevent_req
*subreq
);
2635 static void cli_tree_connect_raw_done(struct tevent_req
*subreq
);
2637 static struct tevent_req
*cli_tree_connect_send(
2638 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
2639 const char *share
, const char *dev
, const char *pass
, int passlen
)
2641 struct tevent_req
*req
, *subreq
;
2642 struct cli_tree_connect_state
*state
;
2644 req
= tevent_req_create(mem_ctx
, &state
,
2645 struct cli_tree_connect_state
);
2651 cli
->share
= talloc_strdup(cli
, share
);
2652 if (tevent_req_nomem(cli
->share
, req
)) {
2653 return tevent_req_post(req
, ev
);
2656 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
2659 cli
->smb2
.tcon
= smbXcli_tcon_create(cli
);
2660 if (tevent_req_nomem(cli
->smb2
.tcon
, req
)) {
2661 return tevent_req_post(req
, ev
);
2664 unc
= talloc_asprintf(state
, "\\\\%s\\%s",
2665 smbXcli_conn_remote_name(cli
->conn
),
2667 if (tevent_req_nomem(unc
, req
)) {
2668 return tevent_req_post(req
, ev
);
2671 subreq
= smb2cli_tcon_send(state
, ev
, cli
->conn
, cli
->timeout
,
2672 cli
->smb2
.session
, cli
->smb2
.tcon
,
2675 if (tevent_req_nomem(subreq
, req
)) {
2676 return tevent_req_post(req
, ev
);
2678 tevent_req_set_callback(subreq
, cli_tree_connect_smb2_done
,
2683 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_LANMAN1
) {
2684 subreq
= cli_tcon_andx_send(state
, ev
, cli
, share
, dev
,
2686 if (tevent_req_nomem(subreq
, req
)) {
2687 return tevent_req_post(req
, ev
);
2689 tevent_req_set_callback(subreq
, cli_tree_connect_andx_done
,
2694 subreq
= cli_raw_tcon_send(state
, ev
, cli
, share
, pass
, dev
);
2695 if (tevent_req_nomem(subreq
, req
)) {
2696 return tevent_req_post(req
, ev
);
2698 tevent_req_set_callback(subreq
, cli_tree_connect_raw_done
, req
);
2703 static void cli_tree_connect_smb2_done(struct tevent_req
*subreq
)
2705 tevent_req_simple_finish_ntstatus(
2706 subreq
, smb2cli_tcon_recv(subreq
));
2709 static void cli_tree_connect_andx_done(struct tevent_req
*subreq
)
2711 tevent_req_simple_finish_ntstatus(
2712 subreq
, cli_tcon_andx_recv(subreq
));
2715 static void cli_tree_connect_raw_done(struct tevent_req
*subreq
)
2717 struct tevent_req
*req
= tevent_req_callback_data(
2718 subreq
, struct tevent_req
);
2719 struct cli_tree_connect_state
*state
= tevent_req_data(
2720 req
, struct cli_tree_connect_state
);
2722 uint16_t max_xmit
= 0;
2725 status
= cli_raw_tcon_recv(subreq
, &max_xmit
, &tid
);
2726 if (tevent_req_nterror(req
, status
)) {
2730 smb1cli_tcon_set_values(state
->cli
->smb1
.tcon
,
2732 0, /* optional_support */
2733 0, /* maximal_access */
2734 0, /* guest_maximal_access */
2736 NULL
); /* fs_type */
2738 tevent_req_done(req
);
2741 static NTSTATUS
cli_tree_connect_recv(struct tevent_req
*req
)
2743 return tevent_req_simple_recv_ntstatus(req
);
2746 NTSTATUS
cli_tree_connect(struct cli_state
*cli
, const char *share
,
2747 const char *dev
, const char *pass
, int passlen
)
2749 struct tevent_context
*ev
;
2750 struct tevent_req
*req
;
2751 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2753 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
2754 return NT_STATUS_INVALID_PARAMETER
;
2756 ev
= samba_tevent_context_init(talloc_tos());
2760 req
= cli_tree_connect_send(ev
, ev
, cli
, share
, dev
, pass
, passlen
);
2764 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2767 status
= cli_tree_connect_recv(req
);
2773 /****************************************************************************
2774 Send a tree disconnect.
2775 ****************************************************************************/
2777 struct cli_tdis_state
{
2778 struct cli_state
*cli
;
2781 static void cli_tdis_done(struct tevent_req
*subreq
);
2783 static struct tevent_req
*cli_tdis_send(TALLOC_CTX
*mem_ctx
,
2784 struct tevent_context
*ev
,
2785 struct cli_state
*cli
)
2787 struct tevent_req
*req
, *subreq
;
2788 struct cli_tdis_state
*state
;
2790 req
= tevent_req_create(mem_ctx
, &state
, struct cli_tdis_state
);
2796 subreq
= cli_smb_send(state
, ev
, cli
, SMBtdis
, 0, 0, NULL
, 0, NULL
);
2797 if (tevent_req_nomem(subreq
, req
)) {
2798 return tevent_req_post(req
, ev
);
2800 tevent_req_set_callback(subreq
, cli_tdis_done
, req
);
2804 static void cli_tdis_done(struct tevent_req
*subreq
)
2806 struct tevent_req
*req
= tevent_req_callback_data(
2807 subreq
, struct tevent_req
);
2808 struct cli_tdis_state
*state
= tevent_req_data(
2809 req
, struct cli_tdis_state
);
2812 status
= cli_smb_recv(subreq
, NULL
, NULL
, 0, NULL
, NULL
, NULL
, NULL
);
2813 TALLOC_FREE(subreq
);
2814 if (!NT_STATUS_IS_OK(status
)) {
2815 tevent_req_nterror(req
, status
);
2818 cli_state_set_tid(state
->cli
, UINT16_MAX
);
2819 tevent_req_done(req
);
2822 static NTSTATUS
cli_tdis_recv(struct tevent_req
*req
)
2824 return tevent_req_simple_recv_ntstatus(req
);
2827 NTSTATUS
cli_tdis(struct cli_state
*cli
)
2829 struct tevent_context
*ev
;
2830 struct tevent_req
*req
;
2831 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2833 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
2834 return smb2cli_tdis(cli
->conn
,
2840 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
2841 return NT_STATUS_INVALID_PARAMETER
;
2843 ev
= samba_tevent_context_init(talloc_tos());
2847 req
= cli_tdis_send(ev
, ev
, cli
);
2851 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2854 status
= cli_tdis_recv(req
);
2860 struct cli_connect_sock_state
{
2861 const char **called_names
;
2862 const char **calling_names
;
2868 static void cli_connect_sock_done(struct tevent_req
*subreq
);
2871 * Async only if we don't have to look up the name, i.e. "pss" is set with a
2875 static struct tevent_req
*cli_connect_sock_send(
2876 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
2877 const char *host
, int name_type
, const struct sockaddr_storage
*pss
,
2878 const char *myname
, uint16_t port
)
2880 struct tevent_req
*req
, *subreq
;
2881 struct cli_connect_sock_state
*state
;
2883 struct sockaddr_storage
*addrs
;
2884 unsigned i
, num_addrs
;
2887 req
= tevent_req_create(mem_ctx
, &state
,
2888 struct cli_connect_sock_state
);
2893 prog
= getenv("LIBSMB_PROG");
2895 state
->fd
= sock_exec(prog
);
2896 if (state
->fd
== -1) {
2897 status
= map_nt_error_from_unix(errno
);
2898 tevent_req_nterror(req
, status
);
2901 tevent_req_done(req
);
2903 return tevent_req_post(req
, ev
);
2906 if ((pss
== NULL
) || is_zero_addr(pss
)) {
2909 * Here we cheat. resolve_name_list is not async at all. So
2910 * this call will only be really async if the name lookup has
2911 * been done externally.
2914 status
= resolve_name_list(state
, host
, name_type
,
2915 &addrs
, &num_addrs
);
2916 if (!NT_STATUS_IS_OK(status
)) {
2917 tevent_req_nterror(req
, status
);
2918 return tevent_req_post(req
, ev
);
2921 addrs
= talloc_array(state
, struct sockaddr_storage
, 1);
2922 if (tevent_req_nomem(addrs
, req
)) {
2923 return tevent_req_post(req
, ev
);
2929 state
->called_names
= talloc_array(state
, const char *, num_addrs
);
2930 if (tevent_req_nomem(state
->called_names
, req
)) {
2931 return tevent_req_post(req
, ev
);
2933 state
->called_types
= talloc_array(state
, int, num_addrs
);
2934 if (tevent_req_nomem(state
->called_types
, req
)) {
2935 return tevent_req_post(req
, ev
);
2937 state
->calling_names
= talloc_array(state
, const char *, num_addrs
);
2938 if (tevent_req_nomem(state
->calling_names
, req
)) {
2939 return tevent_req_post(req
, ev
);
2941 for (i
=0; i
<num_addrs
; i
++) {
2942 state
->called_names
[i
] = host
;
2943 state
->called_types
[i
] = name_type
;
2944 state
->calling_names
[i
] = myname
;
2947 subreq
= smbsock_any_connect_send(
2948 state
, ev
, addrs
, state
->called_names
, state
->called_types
,
2949 state
->calling_names
, NULL
, num_addrs
, port
);
2950 if (tevent_req_nomem(subreq
, req
)) {
2951 return tevent_req_post(req
, ev
);
2953 tevent_req_set_callback(subreq
, cli_connect_sock_done
, req
);
2957 static void cli_connect_sock_done(struct tevent_req
*subreq
)
2959 struct tevent_req
*req
= tevent_req_callback_data(
2960 subreq
, struct tevent_req
);
2961 struct cli_connect_sock_state
*state
= tevent_req_data(
2962 req
, struct cli_connect_sock_state
);
2965 status
= smbsock_any_connect_recv(subreq
, &state
->fd
, NULL
,
2967 TALLOC_FREE(subreq
);
2968 if (tevent_req_nterror(req
, status
)) {
2971 set_socket_options(state
->fd
, lp_socket_options());
2972 tevent_req_done(req
);
2975 static NTSTATUS
cli_connect_sock_recv(struct tevent_req
*req
,
2976 int *pfd
, uint16_t *pport
)
2978 struct cli_connect_sock_state
*state
= tevent_req_data(
2979 req
, struct cli_connect_sock_state
);
2982 if (tevent_req_is_nterror(req
, &status
)) {
2986 *pport
= state
->port
;
2987 return NT_STATUS_OK
;
2990 struct cli_connect_nb_state
{
2991 const char *desthost
;
2994 struct cli_state
*cli
;
2997 static void cli_connect_nb_done(struct tevent_req
*subreq
);
2999 static struct tevent_req
*cli_connect_nb_send(
3000 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
3001 const char *host
, const struct sockaddr_storage
*dest_ss
,
3002 uint16_t port
, int name_type
, const char *myname
,
3003 int signing_state
, int flags
)
3005 struct tevent_req
*req
, *subreq
;
3006 struct cli_connect_nb_state
*state
;
3008 req
= tevent_req_create(mem_ctx
, &state
, struct cli_connect_nb_state
);
3012 state
->signing_state
= signing_state
;
3013 state
->flags
= flags
;
3016 char *p
= strchr(host
, '#');
3019 name_type
= strtol(p
+1, NULL
, 16);
3020 host
= talloc_strndup(state
, host
, p
- host
);
3021 if (tevent_req_nomem(host
, req
)) {
3022 return tevent_req_post(req
, ev
);
3026 state
->desthost
= host
;
3028 state
->desthost
= print_canonical_sockaddr(state
, dest_ss
);
3029 if (tevent_req_nomem(state
->desthost
, req
)) {
3030 return tevent_req_post(req
, ev
);
3034 subreq
= cli_connect_sock_send(state
, ev
, host
, name_type
, dest_ss
,
3036 if (tevent_req_nomem(subreq
, req
)) {
3037 return tevent_req_post(req
, ev
);
3039 tevent_req_set_callback(subreq
, cli_connect_nb_done
, req
);
3043 static void cli_connect_nb_done(struct tevent_req
*subreq
)
3045 struct tevent_req
*req
= tevent_req_callback_data(
3046 subreq
, struct tevent_req
);
3047 struct cli_connect_nb_state
*state
= tevent_req_data(
3048 req
, struct cli_connect_nb_state
);
3053 status
= cli_connect_sock_recv(subreq
, &fd
, &port
);
3054 TALLOC_FREE(subreq
);
3055 if (tevent_req_nterror(req
, status
)) {
3059 state
->cli
= cli_state_create(state
, fd
, state
->desthost
, NULL
,
3060 state
->signing_state
, state
->flags
);
3061 if (tevent_req_nomem(state
->cli
, req
)) {
3065 tevent_req_done(req
);
3068 static NTSTATUS
cli_connect_nb_recv(struct tevent_req
*req
,
3069 struct cli_state
**pcli
)
3071 struct cli_connect_nb_state
*state
= tevent_req_data(
3072 req
, struct cli_connect_nb_state
);
3075 if (tevent_req_is_nterror(req
, &status
)) {
3078 *pcli
= talloc_move(NULL
, &state
->cli
);
3079 return NT_STATUS_OK
;
3082 NTSTATUS
cli_connect_nb(const char *host
, const struct sockaddr_storage
*dest_ss
,
3083 uint16_t port
, int name_type
, const char *myname
,
3084 int signing_state
, int flags
, struct cli_state
**pcli
)
3086 struct tevent_context
*ev
;
3087 struct tevent_req
*req
;
3088 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
3090 ev
= samba_tevent_context_init(talloc_tos());
3094 req
= cli_connect_nb_send(ev
, ev
, host
, dest_ss
, port
, name_type
,
3095 myname
, signing_state
, flags
);
3099 if (!tevent_req_set_endtime(req
, ev
, timeval_current_ofs(20, 0))) {
3102 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
3105 status
= cli_connect_nb_recv(req
, pcli
);
3111 struct cli_start_connection_state
{
3112 struct tevent_context
*ev
;
3113 struct cli_state
*cli
;
3116 static void cli_start_connection_connected(struct tevent_req
*subreq
);
3117 static void cli_start_connection_done(struct tevent_req
*subreq
);
3120 establishes a connection to after the negprot.
3121 @param output_cli A fully initialised cli structure, non-null only on success
3122 @param dest_host The netbios name of the remote host
3123 @param dest_ss (optional) The the destination IP, NULL for name based lookup
3124 @param port (optional) The destination port (0 for default)
3127 static struct tevent_req
*cli_start_connection_send(
3128 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
3129 const char *my_name
, const char *dest_host
,
3130 const struct sockaddr_storage
*dest_ss
, int port
,
3131 int signing_state
, int flags
)
3133 struct tevent_req
*req
, *subreq
;
3134 struct cli_start_connection_state
*state
;
3136 req
= tevent_req_create(mem_ctx
, &state
,
3137 struct cli_start_connection_state
);
3143 subreq
= cli_connect_nb_send(state
, ev
, dest_host
, dest_ss
, port
,
3144 0x20, my_name
, signing_state
, flags
);
3145 if (tevent_req_nomem(subreq
, req
)) {
3146 return tevent_req_post(req
, ev
);
3148 tevent_req_set_callback(subreq
, cli_start_connection_connected
, req
);
3152 static void cli_start_connection_connected(struct tevent_req
*subreq
)
3154 struct tevent_req
*req
= tevent_req_callback_data(
3155 subreq
, struct tevent_req
);
3156 struct cli_start_connection_state
*state
= tevent_req_data(
3157 req
, struct cli_start_connection_state
);
3160 status
= cli_connect_nb_recv(subreq
, &state
->cli
);
3161 TALLOC_FREE(subreq
);
3162 if (tevent_req_nterror(req
, status
)) {
3166 subreq
= smbXcli_negprot_send(state
, state
->ev
, state
->cli
->conn
,
3167 state
->cli
->timeout
,
3168 lp_client_min_protocol(),
3169 lp_client_max_protocol());
3170 if (tevent_req_nomem(subreq
, req
)) {
3173 tevent_req_set_callback(subreq
, cli_start_connection_done
, req
);
3176 static void cli_start_connection_done(struct tevent_req
*subreq
)
3178 struct tevent_req
*req
= tevent_req_callback_data(
3179 subreq
, struct tevent_req
);
3180 struct cli_start_connection_state
*state
= tevent_req_data(
3181 req
, struct cli_start_connection_state
);
3184 status
= smbXcli_negprot_recv(subreq
);
3185 TALLOC_FREE(subreq
);
3186 if (tevent_req_nterror(req
, status
)) {
3190 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
3191 /* Ensure we ask for some initial credits. */
3192 smb2cli_conn_set_max_credits(state
->cli
->conn
,
3193 DEFAULT_SMB2_MAX_CREDITS
);
3196 tevent_req_done(req
);
3199 static NTSTATUS
cli_start_connection_recv(struct tevent_req
*req
,
3200 struct cli_state
**output_cli
)
3202 struct cli_start_connection_state
*state
= tevent_req_data(
3203 req
, struct cli_start_connection_state
);
3206 if (tevent_req_is_nterror(req
, &status
)) {
3209 *output_cli
= state
->cli
;
3211 return NT_STATUS_OK
;
3214 NTSTATUS
cli_start_connection(struct cli_state
**output_cli
,
3215 const char *my_name
,
3216 const char *dest_host
,
3217 const struct sockaddr_storage
*dest_ss
, int port
,
3218 int signing_state
, int flags
)
3220 struct tevent_context
*ev
;
3221 struct tevent_req
*req
;
3222 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
3224 ev
= samba_tevent_context_init(talloc_tos());
3228 req
= cli_start_connection_send(ev
, ev
, my_name
, dest_host
, dest_ss
,
3229 port
, signing_state
, flags
);
3233 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
3236 status
= cli_start_connection_recv(req
, output_cli
);
3243 establishes a connection right up to doing tconX, password specified.
3244 @param output_cli A fully initialised cli structure, non-null only on success
3245 @param dest_host The netbios name of the remote host
3246 @param dest_ip (optional) The the destination IP, NULL for name based lookup
3247 @param port (optional) The destination port (0 for default)
3248 @param service (optional) The share to make the connection to. Should be 'unqualified' in any way.
3249 @param service_type The 'type' of serivice.
3250 @param user Username, unix string
3251 @param domain User's domain
3252 @param password User's password, unencrypted unix string.
3255 struct cli_full_connection_state
{
3256 struct tevent_context
*ev
;
3257 const char *service
;
3258 const char *service_type
;
3261 const char *password
;
3264 struct cli_state
*cli
;
3267 static int cli_full_connection_state_destructor(
3268 struct cli_full_connection_state
*s
);
3269 static void cli_full_connection_started(struct tevent_req
*subreq
);
3270 static void cli_full_connection_sess_set_up(struct tevent_req
*subreq
);
3271 static void cli_full_connection_done(struct tevent_req
*subreq
);
3273 struct tevent_req
*cli_full_connection_send(
3274 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
3275 const char *my_name
, const char *dest_host
,
3276 const struct sockaddr_storage
*dest_ss
, int port
,
3277 const char *service
, const char *service_type
,
3278 const char *user
, const char *domain
,
3279 const char *password
, int flags
, int signing_state
)
3281 struct tevent_req
*req
, *subreq
;
3282 struct cli_full_connection_state
*state
;
3284 req
= tevent_req_create(mem_ctx
, &state
,
3285 struct cli_full_connection_state
);
3289 talloc_set_destructor(state
, cli_full_connection_state_destructor
);
3292 state
->service
= service
;
3293 state
->service_type
= service_type
;
3295 state
->domain
= domain
;
3296 state
->password
= password
;
3297 state
->flags
= flags
;
3299 state
->pw_len
= state
->password
? strlen(state
->password
)+1 : 0;
3300 if (state
->password
== NULL
) {
3301 state
->password
= "";
3304 subreq
= cli_start_connection_send(
3305 state
, ev
, my_name
, dest_host
, dest_ss
, port
,
3306 signing_state
, flags
);
3307 if (tevent_req_nomem(subreq
, req
)) {
3308 return tevent_req_post(req
, ev
);
3310 tevent_req_set_callback(subreq
, cli_full_connection_started
, req
);
3314 static int cli_full_connection_state_destructor(
3315 struct cli_full_connection_state
*s
)
3317 if (s
->cli
!= NULL
) {
3318 cli_shutdown(s
->cli
);
3324 static void cli_full_connection_started(struct tevent_req
*subreq
)
3326 struct tevent_req
*req
= tevent_req_callback_data(
3327 subreq
, struct tevent_req
);
3328 struct cli_full_connection_state
*state
= tevent_req_data(
3329 req
, struct cli_full_connection_state
);
3332 status
= cli_start_connection_recv(subreq
, &state
->cli
);
3333 TALLOC_FREE(subreq
);
3334 if (tevent_req_nterror(req
, status
)) {
3337 subreq
= cli_session_setup_send(
3338 state
, state
->ev
, state
->cli
, state
->user
,
3339 state
->password
, state
->pw_len
, state
->password
, state
->pw_len
,
3341 if (tevent_req_nomem(subreq
, req
)) {
3344 tevent_req_set_callback(subreq
, cli_full_connection_sess_set_up
, req
);
3347 static void cli_full_connection_sess_set_up(struct tevent_req
*subreq
)
3349 struct tevent_req
*req
= tevent_req_callback_data(
3350 subreq
, struct tevent_req
);
3351 struct cli_full_connection_state
*state
= tevent_req_data(
3352 req
, struct cli_full_connection_state
);
3355 status
= cli_session_setup_recv(subreq
);
3356 TALLOC_FREE(subreq
);
3358 if (!NT_STATUS_IS_OK(status
) &&
3359 (state
->flags
& CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK
)) {
3361 state
->flags
&= ~CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK
;
3363 subreq
= cli_session_setup_send(
3364 state
, state
->ev
, state
->cli
, "", "", 0, "", 0,
3366 if (tevent_req_nomem(subreq
, req
)) {
3369 tevent_req_set_callback(
3370 subreq
, cli_full_connection_sess_set_up
, req
);
3374 if (tevent_req_nterror(req
, status
)) {
3378 if (state
->service
!= NULL
) {
3379 subreq
= cli_tree_connect_send(
3380 state
, state
->ev
, state
->cli
,
3381 state
->service
, state
->service_type
,
3382 state
->password
, state
->pw_len
);
3383 if (tevent_req_nomem(subreq
, req
)) {
3386 tevent_req_set_callback(subreq
, cli_full_connection_done
, req
);
3390 tevent_req_done(req
);
3393 static void cli_full_connection_done(struct tevent_req
*subreq
)
3395 struct tevent_req
*req
= tevent_req_callback_data(
3396 subreq
, struct tevent_req
);
3399 status
= cli_tree_connect_recv(subreq
);
3400 TALLOC_FREE(subreq
);
3401 if (tevent_req_nterror(req
, status
)) {
3405 tevent_req_done(req
);
3408 NTSTATUS
cli_full_connection_recv(struct tevent_req
*req
,
3409 struct cli_state
**output_cli
)
3411 struct cli_full_connection_state
*state
= tevent_req_data(
3412 req
, struct cli_full_connection_state
);
3415 if (tevent_req_is_nterror(req
, &status
)) {
3418 *output_cli
= state
->cli
;
3419 talloc_set_destructor(state
, NULL
);
3420 return NT_STATUS_OK
;
3423 NTSTATUS
cli_full_connection(struct cli_state
**output_cli
,
3424 const char *my_name
,
3425 const char *dest_host
,
3426 const struct sockaddr_storage
*dest_ss
, int port
,
3427 const char *service
, const char *service_type
,
3428 const char *user
, const char *domain
,
3429 const char *password
, int flags
,
3432 struct tevent_context
*ev
;
3433 struct tevent_req
*req
;
3434 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
3436 ev
= samba_tevent_context_init(talloc_tos());
3440 req
= cli_full_connection_send(
3441 ev
, ev
, my_name
, dest_host
, dest_ss
, port
, service
,
3442 service_type
, user
, domain
, password
, flags
, signing_state
);
3446 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
3449 status
= cli_full_connection_recv(req
, output_cli
);
3455 /****************************************************************************
3456 Send an old style tcon.
3457 ****************************************************************************/
3458 struct cli_raw_tcon_state
{
3462 static void cli_raw_tcon_done(struct tevent_req
*subreq
);
3464 static struct tevent_req
*cli_raw_tcon_send(
3465 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
3466 const char *service
, const char *pass
, const char *dev
)
3468 struct tevent_req
*req
, *subreq
;
3469 struct cli_raw_tcon_state
*state
;
3472 req
= tevent_req_create(mem_ctx
, &state
, struct cli_raw_tcon_state
);
3477 if (!lp_client_plaintext_auth() && (*pass
)) {
3478 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
3479 " or 'client ntlmv2 auth = yes'\n"));
3480 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
3481 return tevent_req_post(req
, ev
);
3484 bytes
= talloc_array(state
, uint8_t, 0);
3485 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
3486 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
3487 service
, strlen(service
)+1, NULL
);
3488 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
3489 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
3490 pass
, strlen(pass
)+1, NULL
);
3491 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
3492 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
3493 dev
, strlen(dev
)+1, NULL
);
3495 if (tevent_req_nomem(bytes
, req
)) {
3496 return tevent_req_post(req
, ev
);
3499 subreq
= cli_smb_send(state
, ev
, cli
, SMBtcon
, 0, 0, NULL
,
3500 talloc_get_size(bytes
), bytes
);
3501 if (tevent_req_nomem(subreq
, req
)) {
3502 return tevent_req_post(req
, ev
);
3504 tevent_req_set_callback(subreq
, cli_raw_tcon_done
, req
);
3508 static void cli_raw_tcon_done(struct tevent_req
*subreq
)
3510 struct tevent_req
*req
= tevent_req_callback_data(
3511 subreq
, struct tevent_req
);
3512 struct cli_raw_tcon_state
*state
= tevent_req_data(
3513 req
, struct cli_raw_tcon_state
);
3516 status
= cli_smb_recv(subreq
, state
, NULL
, 2, NULL
, &state
->ret_vwv
,
3518 TALLOC_FREE(subreq
);
3519 if (tevent_req_nterror(req
, status
)) {
3522 tevent_req_done(req
);
3525 static NTSTATUS
cli_raw_tcon_recv(struct tevent_req
*req
,
3526 uint16_t *max_xmit
, uint16_t *tid
)
3528 struct cli_raw_tcon_state
*state
= tevent_req_data(
3529 req
, struct cli_raw_tcon_state
);
3532 if (tevent_req_is_nterror(req
, &status
)) {
3535 *max_xmit
= SVAL(state
->ret_vwv
+ 0, 0);
3536 *tid
= SVAL(state
->ret_vwv
+ 1, 0);
3537 return NT_STATUS_OK
;
3540 NTSTATUS
cli_raw_tcon(struct cli_state
*cli
,
3541 const char *service
, const char *pass
, const char *dev
,
3542 uint16_t *max_xmit
, uint16_t *tid
)
3544 struct tevent_context
*ev
;
3545 struct tevent_req
*req
;
3546 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
3548 ev
= samba_tevent_context_init(talloc_tos());
3552 req
= cli_raw_tcon_send(ev
, ev
, cli
, service
, pass
, dev
);
3556 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
3559 status
= cli_raw_tcon_recv(req
, max_xmit
, tid
);
3565 /* Return a cli_state pointing at the IPC$ share for the given server */
3567 struct cli_state
*get_ipc_connect(char *server
,
3568 struct sockaddr_storage
*server_ss
,
3569 const struct user_auth_info
*user_info
)
3571 struct cli_state
*cli
;
3573 uint32_t flags
= CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK
;
3575 if (user_info
->use_kerberos
) {
3576 flags
|= CLI_FULL_CONNECTION_USE_KERBEROS
;
3579 nt_status
= cli_full_connection(&cli
, NULL
, server
, server_ss
, 0, "IPC$", "IPC",
3580 user_info
->username
? user_info
->username
: "",
3582 user_info
->password
? user_info
->password
: "",
3584 SMB_SIGNING_DEFAULT
);
3586 if (NT_STATUS_IS_OK(nt_status
)) {
3588 } else if (is_ipaddress(server
)) {
3589 /* windows 9* needs a correct NMB name for connections */
3590 fstring remote_name
;
3592 if (name_status_find("*", 0, 0, server_ss
, remote_name
)) {
3593 cli
= get_ipc_connect(remote_name
, server_ss
, user_info
);
3602 * Given the IP address of a master browser on the network, return its
3603 * workgroup and connect to it.
3605 * This function is provided to allow additional processing beyond what
3606 * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
3607 * browsers and obtain each master browsers' list of domains (in case the
3608 * first master browser is recently on the network and has not yet
3609 * synchronized with other master browsers and therefore does not yet have the
3610 * entire network browse list)
3613 struct cli_state
*get_ipc_connect_master_ip(TALLOC_CTX
*ctx
,
3614 struct sockaddr_storage
*mb_ip
,
3615 const struct user_auth_info
*user_info
,
3616 char **pp_workgroup_out
)
3618 char addr
[INET6_ADDRSTRLEN
];
3620 struct cli_state
*cli
;
3621 struct sockaddr_storage server_ss
;
3623 *pp_workgroup_out
= NULL
;
3625 print_sockaddr(addr
, sizeof(addr
), mb_ip
);
3626 DEBUG(99, ("Looking up name of master browser %s\n",
3630 * Do a name status query to find out the name of the master browser.
3631 * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
3632 * master browser will not respond to a wildcard query (or, at least,
3633 * an NT4 server acting as the domain master browser will not).
3635 * We might be able to use ONLY the query on MSBROWSE, but that's not
3636 * yet been tested with all Windows versions, so until it is, leave
3637 * the original wildcard query as the first choice and fall back to
3638 * MSBROWSE if the wildcard query fails.
3640 if (!name_status_find("*", 0, 0x1d, mb_ip
, name
) &&
3641 !name_status_find(MSBROWSE
, 1, 0x1d, mb_ip
, name
)) {
3643 DEBUG(99, ("Could not retrieve name status for %s\n",
3648 if (!find_master_ip(name
, &server_ss
)) {
3649 DEBUG(99, ("Could not find master ip for %s\n", name
));
3653 *pp_workgroup_out
= talloc_strdup(ctx
, name
);
3655 DEBUG(4, ("found master browser %s, %s\n", name
, addr
));
3657 print_sockaddr(addr
, sizeof(addr
), &server_ss
);
3658 cli
= get_ipc_connect(addr
, &server_ss
, user_info
);
3664 * Return the IP address and workgroup of a master browser on the network, and
3668 struct cli_state
*get_ipc_connect_master_ip_bcast(TALLOC_CTX
*ctx
,
3669 const struct user_auth_info
*user_info
,
3670 char **pp_workgroup_out
)
3672 struct sockaddr_storage
*ip_list
;
3673 struct cli_state
*cli
;
3677 *pp_workgroup_out
= NULL
;
3679 DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
3681 /* Go looking for workgroups by broadcasting on the local network */
3683 status
= name_resolve_bcast(MSBROWSE
, 1, talloc_tos(),
3685 if (!NT_STATUS_IS_OK(status
)) {
3686 DEBUG(99, ("No master browsers responded: %s\n",
3687 nt_errstr(status
)));
3691 for (i
= 0; i
< count
; i
++) {
3692 char addr
[INET6_ADDRSTRLEN
];
3693 print_sockaddr(addr
, sizeof(addr
), &ip_list
[i
]);
3694 DEBUG(99, ("Found master browser %s\n", addr
));
3696 cli
= get_ipc_connect_master_ip(ctx
, &ip_list
[i
],
3697 user_info
, pp_workgroup_out
);