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/credentials/credentials.h"
30 #include "auth/gensec/gensec.h"
31 #include "auth/ntlmssp/ntlmssp.h"
32 #include "auth_generic.h"
33 #include "libads/kerberos_proto.h"
35 #include "../lib/util/tevent_ntstatus.h"
36 #include "async_smb.h"
37 #include "libsmb/nmblib.h"
38 #include "librpc/ndr/libndr.h"
39 #include "../libcli/smb/smbXcli_base.h"
41 #define STAR_SMBSERVER "*SMBSERVER"
43 /********************************************************
44 Utility function to ensure we always return at least
45 a valid char * pointer to an empty string for the
46 cli->server_os, cli->server_type and cli->server_domain
48 *******************************************************/
50 static NTSTATUS
smb_bytes_talloc_string(TALLOC_CTX
*mem_ctx
,
57 *destlen
= clistr_pull_talloc(mem_ctx
,
65 return NT_STATUS_NO_MEMORY
;
69 *dest
= talloc_strdup(mem_ctx
, "");
71 return NT_STATUS_NO_MEMORY
;
78 /****************************************************************************
79 Do an old lanman2 style session setup.
80 ****************************************************************************/
82 struct cli_session_setup_lanman2_state
{
83 struct cli_state
*cli
;
88 static void cli_session_setup_lanman2_done(struct tevent_req
*subreq
);
90 static struct tevent_req
*cli_session_setup_lanman2_send(
91 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
92 struct cli_state
*cli
, const char *user
,
93 const char *pass
, size_t passlen
,
94 const char *workgroup
)
96 struct tevent_req
*req
, *subreq
;
97 struct cli_session_setup_lanman2_state
*state
;
98 DATA_BLOB lm_response
= data_blob_null
;
102 uint16_t sec_mode
= smb1cli_conn_server_security_mode(cli
->conn
);
104 req
= tevent_req_create(mem_ctx
, &state
,
105 struct cli_session_setup_lanman2_state
);
114 * if in share level security then don't send a password now
116 if (!(sec_mode
& NEGOTIATE_SECURITY_USER_LEVEL
)) {
121 && (sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
)
124 * Encrypted mode needed, and non encrypted password
127 lm_response
= data_blob(NULL
, 24);
128 if (tevent_req_nomem(lm_response
.data
, req
)) {
129 return tevent_req_post(req
, ev
);
132 if (!SMBencrypt(pass
, smb1cli_conn_server_challenge(cli
->conn
),
133 (uint8_t *)lm_response
.data
)) {
134 DEBUG(1, ("Password is > 14 chars in length, and is "
135 "therefore incompatible with Lanman "
136 "authentication\n"));
137 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
138 return tevent_req_post(req
, ev
);
140 } else if ((sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
)
143 * Encrypted mode needed, and encrypted password
146 lm_response
= data_blob(pass
, passlen
);
147 if (tevent_req_nomem(lm_response
.data
, req
)) {
148 return tevent_req_post(req
, ev
);
150 } else if (passlen
> 0) {
152 size_t converted_size
;
154 * Plaintext mode needed, assume plaintext supplied.
156 buf
= talloc_array(talloc_tos(), uint8_t, 0);
157 buf
= smb_bytes_push_str(buf
, smbXcli_conn_use_unicode(cli
->conn
), pass
, passlen
+1,
159 if (tevent_req_nomem(buf
, req
)) {
160 return tevent_req_post(req
, ev
);
162 lm_response
= data_blob(pass
, passlen
);
164 if (tevent_req_nomem(lm_response
.data
, req
)) {
165 return tevent_req_post(req
, ev
);
169 SCVAL(vwv
+0, 0, 0xff);
172 SSVAL(vwv
+2, 0, CLI_BUFFER_SIZE
);
175 SIVAL(vwv
+5, 0, smb1cli_conn_server_session_key(cli
->conn
));
176 SSVAL(vwv
+7, 0, lm_response
.length
);
178 bytes
= talloc_array(state
, uint8_t, lm_response
.length
);
179 if (tevent_req_nomem(bytes
, req
)) {
180 return tevent_req_post(req
, ev
);
182 if (lm_response
.length
!= 0) {
183 memcpy(bytes
, lm_response
.data
, lm_response
.length
);
185 data_blob_free(&lm_response
);
187 tmp
= talloc_strdup_upper(talloc_tos(), user
);
188 if (tevent_req_nomem(tmp
, req
)) {
189 return tevent_req_post(req
, ev
);
191 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), tmp
, strlen(tmp
)+1,
195 tmp
= talloc_strdup_upper(talloc_tos(), workgroup
);
196 if (tevent_req_nomem(tmp
, req
)) {
197 return tevent_req_post(req
, ev
);
199 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), tmp
, strlen(tmp
)+1,
201 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "Unix", 5, NULL
);
202 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "Samba", 6, NULL
);
204 if (tevent_req_nomem(bytes
, req
)) {
205 return tevent_req_post(req
, ev
);
208 subreq
= cli_smb_send(state
, ev
, cli
, SMBsesssetupX
, 0, 0, 10, vwv
,
209 talloc_get_size(bytes
), bytes
);
210 if (tevent_req_nomem(subreq
, req
)) {
211 return tevent_req_post(req
, ev
);
213 tevent_req_set_callback(subreq
, cli_session_setup_lanman2_done
, req
);
217 static void cli_session_setup_lanman2_done(struct tevent_req
*subreq
)
219 struct tevent_req
*req
= tevent_req_callback_data(
220 subreq
, struct tevent_req
);
221 struct cli_session_setup_lanman2_state
*state
= tevent_req_data(
222 req
, struct cli_session_setup_lanman2_state
);
223 struct cli_state
*cli
= state
->cli
;
234 status
= cli_smb_recv(subreq
, state
, &in
, 3, &wct
, &vwv
,
237 if (!NT_STATUS_IS_OK(status
)) {
238 tevent_req_nterror(req
, status
);
242 inhdr
= in
+ NBT_HDR_SIZE
;
245 cli_state_set_uid(state
->cli
, SVAL(inhdr
, HDR_UID
));
246 smb1cli_session_set_action(cli
->smb1
.session
, SVAL(vwv
+2, 0));
248 status
= smb_bytes_talloc_string(cli
,
255 if (!NT_STATUS_IS_OK(status
)) {
256 tevent_req_nterror(req
, status
);
261 status
= smb_bytes_talloc_string(cli
,
268 if (!NT_STATUS_IS_OK(status
)) {
269 tevent_req_nterror(req
, status
);
274 status
= smb_bytes_talloc_string(cli
,
281 if (!NT_STATUS_IS_OK(status
)) {
282 tevent_req_nterror(req
, status
);
287 tevent_req_done(req
);
290 static NTSTATUS
cli_session_setup_lanman2_recv(struct tevent_req
*req
)
292 return tevent_req_simple_recv_ntstatus(req
);
296 /****************************************************************************
297 Work out suitable capabilities to offer the server.
298 ****************************************************************************/
300 static uint32_t cli_session_setup_capabilities(struct cli_state
*cli
,
301 uint32_t sesssetup_capabilities
)
303 uint32_t client_capabilities
= smb1cli_conn_capabilities(cli
->conn
);
306 * We only send capabilities based on the mask for:
307 * - client only flags
308 * - flags used in both directions
310 * We do not echo the server only flags, except some legacy flags.
312 * SMB_CAP_LEGACY_CLIENT_MASK contains CAP_LARGE_READX and
313 * CAP_LARGE_WRITEX in order to allow us to do large reads
314 * against old Samba releases (<= 3.6.x).
316 client_capabilities
&= (SMB_CAP_BOTH_MASK
| SMB_CAP_LEGACY_CLIENT_MASK
);
319 * Session Setup specific flags CAP_DYNAMIC_REAUTH
320 * and CAP_EXTENDED_SECURITY are passed by the caller.
321 * We need that in order to do guest logins even if
322 * CAP_EXTENDED_SECURITY is negotiated.
324 client_capabilities
&= ~(CAP_DYNAMIC_REAUTH
|CAP_EXTENDED_SECURITY
);
325 sesssetup_capabilities
&= (CAP_DYNAMIC_REAUTH
|CAP_EXTENDED_SECURITY
);
326 client_capabilities
|= sesssetup_capabilities
;
328 return client_capabilities
;
331 /****************************************************************************
332 Do a NT1 guest session setup.
333 ****************************************************************************/
335 struct cli_session_setup_guest_state
{
336 struct cli_state
*cli
;
341 static void cli_session_setup_guest_done(struct tevent_req
*subreq
);
343 struct tevent_req
*cli_session_setup_guest_create(TALLOC_CTX
*mem_ctx
,
344 struct tevent_context
*ev
,
345 struct cli_state
*cli
,
346 struct tevent_req
**psmbreq
)
348 struct tevent_req
*req
, *subreq
;
349 struct cli_session_setup_guest_state
*state
;
353 req
= tevent_req_create(mem_ctx
, &state
,
354 struct cli_session_setup_guest_state
);
361 SCVAL(vwv
+0, 0, 0xFF);
364 SSVAL(vwv
+2, 0, CLI_BUFFER_SIZE
);
366 SSVAL(vwv
+4, 0, cli_state_get_vc_num(cli
));
367 SIVAL(vwv
+5, 0, smb1cli_conn_server_session_key(cli
->conn
));
372 SIVAL(vwv
+11, 0, cli_session_setup_capabilities(cli
, 0));
374 bytes
= talloc_array(state
, uint8_t, 0);
376 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "", 1, /* username */
378 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "", 1, /* workgroup */
380 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "Unix", 5, NULL
);
381 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "Samba", 6, NULL
);
388 state
->bytes
.iov_base
= (void *)bytes
;
389 state
->bytes
.iov_len
= talloc_get_size(bytes
);
391 subreq
= cli_smb_req_create(state
, ev
, cli
, SMBsesssetupX
, 0, 0, 13,
392 vwv
, 1, &state
->bytes
);
393 if (subreq
== NULL
) {
397 tevent_req_set_callback(subreq
, cli_session_setup_guest_done
, req
);
402 struct tevent_req
*cli_session_setup_guest_send(TALLOC_CTX
*mem_ctx
,
403 struct tevent_context
*ev
,
404 struct cli_state
*cli
)
406 struct tevent_req
*req
, *subreq
;
409 req
= cli_session_setup_guest_create(mem_ctx
, ev
, cli
, &subreq
);
414 status
= smb1cli_req_chain_submit(&subreq
, 1);
415 if (!NT_STATUS_IS_OK(status
)) {
416 tevent_req_nterror(req
, status
);
417 return tevent_req_post(req
, ev
);
422 static void cli_session_setup_guest_done(struct tevent_req
*subreq
)
424 struct tevent_req
*req
= tevent_req_callback_data(
425 subreq
, struct tevent_req
);
426 struct cli_session_setup_guest_state
*state
= tevent_req_data(
427 req
, struct cli_session_setup_guest_state
);
428 struct cli_state
*cli
= state
->cli
;
439 status
= cli_smb_recv(subreq
, state
, &in
, 3, &wct
, &vwv
,
442 if (!NT_STATUS_IS_OK(status
)) {
443 tevent_req_nterror(req
, status
);
447 inhdr
= in
+ NBT_HDR_SIZE
;
450 cli_state_set_uid(state
->cli
, SVAL(inhdr
, HDR_UID
));
451 smb1cli_session_set_action(cli
->smb1
.session
, SVAL(vwv
+2, 0));
453 status
= smb_bytes_talloc_string(cli
,
460 if (!NT_STATUS_IS_OK(status
)) {
461 tevent_req_nterror(req
, status
);
466 status
= smb_bytes_talloc_string(cli
,
473 if (!NT_STATUS_IS_OK(status
)) {
474 tevent_req_nterror(req
, status
);
479 status
= smb_bytes_talloc_string(cli
,
486 if (!NT_STATUS_IS_OK(status
)) {
487 tevent_req_nterror(req
, status
);
492 tevent_req_done(req
);
495 NTSTATUS
cli_session_setup_guest_recv(struct tevent_req
*req
)
497 return tevent_req_simple_recv_ntstatus(req
);
501 /****************************************************************************
502 Do a NT1 plaintext session setup.
503 ****************************************************************************/
505 struct cli_session_setup_plain_state
{
506 struct cli_state
*cli
;
511 static void cli_session_setup_plain_done(struct tevent_req
*subreq
);
513 static struct tevent_req
*cli_session_setup_plain_send(
514 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
515 struct cli_state
*cli
,
516 const char *user
, const char *pass
, const char *workgroup
)
518 struct tevent_req
*req
, *subreq
;
519 struct cli_session_setup_plain_state
*state
;
525 req
= tevent_req_create(mem_ctx
, &state
,
526 struct cli_session_setup_plain_state
);
534 SCVAL(vwv
+0, 0, 0xff);
537 SSVAL(vwv
+2, 0, CLI_BUFFER_SIZE
);
539 SSVAL(vwv
+4, 0, cli_state_get_vc_num(cli
));
540 SIVAL(vwv
+5, 0, smb1cli_conn_server_session_key(cli
->conn
));
545 SIVAL(vwv
+11, 0, cli_session_setup_capabilities(cli
, 0));
547 bytes
= talloc_array(state
, uint8_t, 0);
548 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), pass
, strlen(pass
)+1,
550 if (tevent_req_nomem(bytes
, req
)) {
551 return tevent_req_post(req
, ev
);
553 SSVAL(vwv
+ (smbXcli_conn_use_unicode(cli
->conn
) ? 8 : 7), 0, passlen
);
555 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
556 user
, strlen(user
)+1, NULL
);
557 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
558 workgroup
, strlen(workgroup
)+1, NULL
);
559 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
562 version
= talloc_asprintf(talloc_tos(), "Samba %s",
563 samba_version_string());
564 if (tevent_req_nomem(version
, req
)){
565 return tevent_req_post(req
, ev
);
567 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
568 version
, strlen(version
)+1, NULL
);
569 TALLOC_FREE(version
);
571 if (tevent_req_nomem(bytes
, req
)) {
572 return tevent_req_post(req
, ev
);
575 subreq
= cli_smb_send(state
, ev
, cli
, SMBsesssetupX
, 0, 0, 13, vwv
,
576 talloc_get_size(bytes
), bytes
);
577 if (tevent_req_nomem(subreq
, req
)) {
578 return tevent_req_post(req
, ev
);
580 tevent_req_set_callback(subreq
, cli_session_setup_plain_done
, req
);
584 static void cli_session_setup_plain_done(struct tevent_req
*subreq
)
586 struct tevent_req
*req
= tevent_req_callback_data(
587 subreq
, struct tevent_req
);
588 struct cli_session_setup_plain_state
*state
= tevent_req_data(
589 req
, struct cli_session_setup_plain_state
);
590 struct cli_state
*cli
= state
->cli
;
601 status
= cli_smb_recv(subreq
, state
, &in
, 3, &wct
, &vwv
,
604 if (tevent_req_nterror(req
, status
)) {
608 inhdr
= in
+ NBT_HDR_SIZE
;
611 cli_state_set_uid(state
->cli
, SVAL(inhdr
, HDR_UID
));
612 smb1cli_session_set_action(cli
->smb1
.session
, SVAL(vwv
+2, 0));
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 tevent_req_done(req
);
656 static NTSTATUS
cli_session_setup_plain_recv(struct tevent_req
*req
)
658 return tevent_req_simple_recv_ntstatus(req
);
661 /****************************************************************************
662 do a NT1 NTLM/LM encrypted session setup - for when extended security
664 @param cli client state to create do session setup on
666 @param pass *either* cleartext password (passlen !=24) or LM response.
667 @param ntpass NT response, implies ntpasslen >=24, implies pass is not clear
668 @param workgroup The user's domain.
669 ****************************************************************************/
671 struct cli_session_setup_nt1_state
{
672 struct cli_state
*cli
;
675 DATA_BLOB session_key
;
679 static void cli_session_setup_nt1_done(struct tevent_req
*subreq
);
681 static struct tevent_req
*cli_session_setup_nt1_send(
682 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
683 struct cli_state
*cli
, const char *user
,
684 const char *pass
, size_t passlen
,
685 const char *ntpass
, size_t ntpasslen
,
686 const char *workgroup
)
688 struct tevent_req
*req
, *subreq
;
689 struct cli_session_setup_nt1_state
*state
;
690 DATA_BLOB lm_response
= data_blob_null
;
691 DATA_BLOB nt_response
= data_blob_null
;
692 DATA_BLOB session_key
= data_blob_null
;
695 char *workgroup_upper
;
697 req
= tevent_req_create(mem_ctx
, &state
,
698 struct cli_session_setup_nt1_state
);
707 /* do nothing - guest login */
708 } else if (passlen
!= 24) {
709 if (lp_client_ntlmv2_auth()) {
710 DATA_BLOB server_chal
;
711 DATA_BLOB names_blob
;
714 data_blob_const(smb1cli_conn_server_challenge(cli
->conn
),
718 * note that the 'workgroup' here is a best
719 * guess - we don't know the server's domain
720 * at this point. Windows clients also don't
723 names_blob
= NTLMv2_generate_names_blob(
724 NULL
, NULL
, workgroup
);
726 if (tevent_req_nomem(names_blob
.data
, req
)) {
727 return tevent_req_post(req
, ev
);
730 if (!SMBNTLMv2encrypt(NULL
, user
, workgroup
, pass
,
731 &server_chal
, &names_blob
,
732 &lm_response
, &nt_response
,
733 NULL
, &session_key
)) {
734 data_blob_free(&names_blob
);
736 req
, NT_STATUS_ACCESS_DENIED
);
737 return tevent_req_post(req
, ev
);
739 data_blob_free(&names_blob
);
743 E_md4hash(pass
, nt_hash
);
746 nt_response
= data_blob_null
;
748 nt_response
= data_blob(NULL
, 24);
749 if (tevent_req_nomem(nt_response
.data
, req
)) {
750 return tevent_req_post(req
, ev
);
753 SMBNTencrypt(pass
, smb1cli_conn_server_challenge(cli
->conn
),
756 /* non encrypted password supplied. Ignore ntpass. */
757 if (lp_client_lanman_auth()) {
759 lm_response
= data_blob(NULL
, 24);
760 if (tevent_req_nomem(lm_response
.data
, req
)) {
761 return tevent_req_post(req
, ev
);
764 if (!SMBencrypt(pass
,
765 smb1cli_conn_server_challenge(cli
->conn
),
768 * Oops, the LM response is
769 * invalid, just put the NT
770 * response there instead
772 data_blob_free(&lm_response
);
773 lm_response
= data_blob(
779 * LM disabled, place NT# in LM field
782 lm_response
= data_blob(
783 nt_response
.data
, nt_response
.length
);
786 if (tevent_req_nomem(lm_response
.data
, req
)) {
787 return tevent_req_post(req
, ev
);
790 session_key
= data_blob(NULL
, 16);
791 if (tevent_req_nomem(session_key
.data
, req
)) {
792 return tevent_req_post(req
, ev
);
795 E_deshash(pass
, session_key
.data
);
796 memset(&session_key
.data
[8], '\0', 8);
798 SMBsesskeygen_ntv1(nt_hash
, session_key
.data
);
802 /* pre-encrypted password supplied. Only used for
803 security=server, can't do
804 signing because we don't have original key */
806 lm_response
= data_blob(pass
, passlen
);
807 if (tevent_req_nomem(lm_response
.data
, req
)) {
808 return tevent_req_post(req
, ev
);
811 nt_response
= data_blob(ntpass
, ntpasslen
);
812 if (tevent_req_nomem(nt_response
.data
, req
)) {
813 return tevent_req_post(req
, ev
);
818 state
->response
= data_blob_talloc(
819 state
, lm_response
.data
, lm_response
.length
);
821 state
->response
= data_blob_talloc(
822 state
, nt_response
.data
, nt_response
.length
);
824 if (tevent_req_nomem(state
->response
.data
, req
)) {
825 return tevent_req_post(req
, ev
);
828 if (session_key
.data
) {
829 state
->session_key
= data_blob_talloc(
830 state
, session_key
.data
, session_key
.length
);
831 if (tevent_req_nomem(state
->session_key
.data
, req
)) {
832 return tevent_req_post(req
, ev
);
835 data_blob_free(&session_key
);
837 SCVAL(vwv
+0, 0, 0xff);
840 SSVAL(vwv
+2, 0, CLI_BUFFER_SIZE
);
842 SSVAL(vwv
+4, 0, cli_state_get_vc_num(cli
));
843 SIVAL(vwv
+5, 0, smb1cli_conn_server_session_key(cli
->conn
));
844 SSVAL(vwv
+7, 0, lm_response
.length
);
845 SSVAL(vwv
+8, 0, nt_response
.length
);
848 SIVAL(vwv
+11, 0, cli_session_setup_capabilities(cli
, 0));
850 bytes
= talloc_array(state
, uint8_t,
851 lm_response
.length
+ nt_response
.length
);
852 if (tevent_req_nomem(bytes
, req
)) {
853 return tevent_req_post(req
, ev
);
855 if (lm_response
.length
!= 0) {
856 memcpy(bytes
, lm_response
.data
, lm_response
.length
);
858 if (nt_response
.length
!= 0) {
859 memcpy(bytes
+ lm_response
.length
,
860 nt_response
.data
, nt_response
.length
);
862 data_blob_free(&lm_response
);
863 data_blob_free(&nt_response
);
865 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
866 user
, strlen(user
)+1, NULL
);
869 * Upper case here might help some NTLMv2 implementations
871 workgroup_upper
= talloc_strdup_upper(talloc_tos(), workgroup
);
872 if (tevent_req_nomem(workgroup_upper
, req
)) {
873 return tevent_req_post(req
, ev
);
875 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
876 workgroup_upper
, strlen(workgroup_upper
)+1,
878 TALLOC_FREE(workgroup_upper
);
880 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "Unix", 5, NULL
);
881 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "Samba", 6, NULL
);
882 if (tevent_req_nomem(bytes
, req
)) {
883 return tevent_req_post(req
, ev
);
886 subreq
= cli_smb_send(state
, ev
, cli
, SMBsesssetupX
, 0, 0, 13, vwv
,
887 talloc_get_size(bytes
), bytes
);
888 if (tevent_req_nomem(subreq
, req
)) {
889 return tevent_req_post(req
, ev
);
891 tevent_req_set_callback(subreq
, cli_session_setup_nt1_done
, req
);
895 static void cli_session_setup_nt1_done(struct tevent_req
*subreq
)
897 struct tevent_req
*req
= tevent_req_callback_data(
898 subreq
, struct tevent_req
);
899 struct cli_session_setup_nt1_state
*state
= tevent_req_data(
900 req
, struct cli_session_setup_nt1_state
);
901 struct cli_state
*cli
= state
->cli
;
912 status
= cli_smb_recv(subreq
, state
, &in
, 3, &wct
, &vwv
,
915 if (!NT_STATUS_IS_OK(status
)) {
916 tevent_req_nterror(req
, status
);
920 inhdr
= in
+ NBT_HDR_SIZE
;
923 cli_state_set_uid(state
->cli
, SVAL(inhdr
, HDR_UID
));
924 smb1cli_session_set_action(cli
->smb1
.session
, SVAL(vwv
+2, 0));
926 status
= smb_bytes_talloc_string(cli
,
932 if (!NT_STATUS_IS_OK(status
)) {
933 tevent_req_nterror(req
, status
);
938 status
= smb_bytes_talloc_string(cli
,
944 if (!NT_STATUS_IS_OK(status
)) {
945 tevent_req_nterror(req
, status
);
950 status
= smb_bytes_talloc_string(cli
,
956 if (!NT_STATUS_IS_OK(status
)) {
957 tevent_req_nterror(req
, status
);
962 if (smb1cli_conn_activate_signing(cli
->conn
, state
->session_key
, state
->response
)
963 && !smb1cli_conn_check_signing(cli
->conn
, (uint8_t *)in
, 1)) {
964 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
967 if (state
->session_key
.data
) {
968 struct smbXcli_session
*session
= state
->cli
->smb1
.session
;
970 status
= smb1cli_session_set_session_key(session
,
972 if (tevent_req_nterror(req
, status
)) {
976 tevent_req_done(req
);
979 static NTSTATUS
cli_session_setup_nt1_recv(struct tevent_req
*req
)
981 return tevent_req_simple_recv_ntstatus(req
);
985 /* The following is calculated from :
987 * (smb_wcnt * 2) = 24 (smb_wcnt == 12 in cli_session_setup_blob_send() )
988 * (strlen("Unix") + 1 + strlen("Samba") + 1) * 2 = 22 (unicode strings at
992 #define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22)
994 struct cli_sesssetup_blob_state
{
995 struct tevent_context
*ev
;
996 struct cli_state
*cli
;
998 uint16_t max_blob_size
;
1000 DATA_BLOB this_blob
;
1001 struct iovec
*recv_iov
;
1004 const uint8_t *inbuf
;
1007 char *out_native_os
;
1008 char *out_native_lm
;
1011 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state
*state
,
1012 struct tevent_req
**psubreq
);
1013 static void cli_sesssetup_blob_done(struct tevent_req
*subreq
);
1015 static struct tevent_req
*cli_sesssetup_blob_send(TALLOC_CTX
*mem_ctx
,
1016 struct tevent_context
*ev
,
1017 struct cli_state
*cli
,
1020 struct tevent_req
*req
, *subreq
;
1021 struct cli_sesssetup_blob_state
*state
;
1022 uint32_t usable_space
;
1024 req
= tevent_req_create(mem_ctx
, &state
,
1025 struct cli_sesssetup_blob_state
);
1033 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
1034 usable_space
= UINT16_MAX
;
1036 usable_space
= cli_state_available_size(cli
,
1037 BASE_SESSSETUP_BLOB_PACKET_SIZE
);
1040 if (usable_space
== 0) {
1041 DEBUG(1, ("cli_session_setup_blob: cli->max_xmit too small "
1042 "(not possible to send %u bytes)\n",
1043 BASE_SESSSETUP_BLOB_PACKET_SIZE
+ 1));
1044 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1045 return tevent_req_post(req
, ev
);
1047 state
->max_blob_size
= MIN(usable_space
, 0xFFFF);
1049 if (!cli_sesssetup_blob_next(state
, &subreq
)) {
1050 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
1051 return tevent_req_post(req
, ev
);
1053 tevent_req_set_callback(subreq
, cli_sesssetup_blob_done
, req
);
1057 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state
*state
,
1058 struct tevent_req
**psubreq
)
1060 struct tevent_req
*subreq
;
1063 thistime
= MIN(state
->blob
.length
, state
->max_blob_size
);
1065 state
->this_blob
.data
= state
->blob
.data
;
1066 state
->this_blob
.length
= thistime
;
1068 state
->blob
.data
+= thistime
;
1069 state
->blob
.length
-= thistime
;
1071 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
1072 subreq
= smb2cli_session_setup_send(state
, state
->ev
,
1074 state
->cli
->timeout
,
1075 state
->cli
->smb2
.session
,
1077 SMB2_CAP_DFS
, /* in_capabilities */
1079 0, /* in_previous_session_id */
1081 if (subreq
== NULL
) {
1085 uint16_t in_buf_size
= 0;
1086 uint16_t in_mpx_max
= 0;
1087 uint16_t in_vc_num
= 0;
1088 uint32_t in_sess_key
= 0;
1089 uint32_t in_capabilities
= 0;
1090 const char *in_native_os
= NULL
;
1091 const char *in_native_lm
= NULL
;
1093 in_buf_size
= CLI_BUFFER_SIZE
;
1094 in_mpx_max
= smbXcli_conn_max_requests(state
->cli
->conn
);
1095 in_vc_num
= cli_state_get_vc_num(state
->cli
);
1096 in_sess_key
= smb1cli_conn_server_session_key(state
->cli
->conn
);
1097 in_capabilities
= cli_session_setup_capabilities(state
->cli
,
1098 CAP_EXTENDED_SECURITY
);
1099 in_native_os
= "Unix";
1100 in_native_lm
= "Samba";
1103 * For now we keep the same values as before,
1104 * we may remove these in a separate commit later.
1110 subreq
= smb1cli_session_setup_ext_send(state
, state
->ev
,
1112 state
->cli
->timeout
,
1113 state
->cli
->smb1
.pid
,
1114 state
->cli
->smb1
.session
,
1123 if (subreq
== NULL
) {
1131 static void cli_sesssetup_blob_done(struct tevent_req
*subreq
)
1133 struct tevent_req
*req
= tevent_req_callback_data(
1134 subreq
, struct tevent_req
);
1135 struct cli_sesssetup_blob_state
*state
= tevent_req_data(
1136 req
, struct cli_sesssetup_blob_state
);
1137 struct cli_state
*cli
= state
->cli
;
1140 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
1141 status
= smb2cli_session_setup_recv(subreq
, state
,
1145 status
= smb1cli_session_setup_ext_recv(subreq
, state
,
1149 &state
->out_native_os
,
1150 &state
->out_native_lm
);
1152 TALLOC_FREE(subreq
);
1153 if (!NT_STATUS_IS_OK(status
)
1154 && !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1155 tevent_req_nterror(req
, status
);
1159 if (cli
->server_os
== NULL
) {
1160 cli
->server_os
= talloc_move(cli
, &state
->out_native_os
);
1162 if (cli
->server_type
== NULL
) {
1163 cli
->server_type
= talloc_move(cli
, &state
->out_native_lm
);
1166 state
->status
= status
;
1168 if (state
->blob
.length
!= 0) {
1172 if (!cli_sesssetup_blob_next(state
, &subreq
)) {
1173 tevent_req_oom(req
);
1176 tevent_req_set_callback(subreq
, cli_sesssetup_blob_done
, req
);
1179 tevent_req_done(req
);
1182 static NTSTATUS
cli_sesssetup_blob_recv(struct tevent_req
*req
,
1183 TALLOC_CTX
*mem_ctx
,
1185 const uint8_t **pinbuf
,
1186 struct iovec
**precv_iov
)
1188 struct cli_sesssetup_blob_state
*state
= tevent_req_data(
1189 req
, struct cli_sesssetup_blob_state
);
1191 struct iovec
*recv_iov
;
1193 if (tevent_req_is_nterror(req
, &status
)) {
1194 TALLOC_FREE(state
->cli
->smb2
.session
);
1195 cli_state_set_uid(state
->cli
, UID_FIELD_INVALID
);
1196 tevent_req_received(req
);
1200 recv_iov
= talloc_move(mem_ctx
, &state
->recv_iov
);
1201 if (pblob
!= NULL
) {
1202 *pblob
= state
->ret_blob
;
1204 if (pinbuf
!= NULL
) {
1205 *pinbuf
= state
->inbuf
;
1207 if (precv_iov
!= NULL
) {
1208 *precv_iov
= recv_iov
;
1210 /* could be NT_STATUS_MORE_PROCESSING_REQUIRED */
1211 status
= state
->status
;
1212 tevent_req_received(req
);
1218 /****************************************************************************
1219 Use in-memory credentials cache
1220 ****************************************************************************/
1222 static void use_in_memory_ccache(void) {
1223 setenv(KRB5_ENV_CCNAME
, "MEMORY:cliconnect", 1);
1226 #endif /* HAVE_KRB5 */
1228 /****************************************************************************
1229 Do a spnego/NTLMSSP encrypted session setup.
1230 ****************************************************************************/
1232 struct cli_session_setup_gensec_state
{
1233 struct tevent_context
*ev
;
1234 struct cli_state
*cli
;
1235 struct auth_generic_state
*auth_generic
;
1238 const uint8_t *inbuf
;
1239 struct iovec
*recv_iov
;
1243 DATA_BLOB session_key
;
1246 static int cli_session_setup_gensec_state_destructor(
1247 struct cli_session_setup_gensec_state
*state
)
1249 TALLOC_FREE(state
->auth_generic
);
1250 data_blob_clear_free(&state
->session_key
);
1254 static void cli_session_setup_gensec_local_next(struct tevent_req
*req
);
1255 static void cli_session_setup_gensec_local_done(struct tevent_req
*subreq
);
1256 static void cli_session_setup_gensec_remote_next(struct tevent_req
*req
);
1257 static void cli_session_setup_gensec_remote_done(struct tevent_req
*subreq
);
1258 static void cli_session_setup_gensec_ready(struct tevent_req
*req
);
1260 static struct tevent_req
*cli_session_setup_gensec_send(
1261 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
1262 const char *user
, const char *pass
, const char *domain
,
1263 enum credentials_use_kerberos krb5_state
,
1264 const char *target_service
,
1265 const char *target_hostname
,
1266 const char *target_principal
)
1268 struct tevent_req
*req
;
1269 struct cli_session_setup_gensec_state
*state
;
1271 bool use_spnego_principal
= lp_client_use_spnego_principal();
1273 req
= tevent_req_create(mem_ctx
, &state
,
1274 struct cli_session_setup_gensec_state
);
1281 talloc_set_destructor(
1282 state
, cli_session_setup_gensec_state_destructor
);
1284 if (user
== NULL
|| strlen(user
) == 0) {
1285 if (pass
!= NULL
&& strlen(pass
) == 0) {
1287 * some callers pass "" as no password
1289 * gensec only handles NULL as no password.
1295 status
= auth_generic_client_prepare(state
, &state
->auth_generic
);
1296 if (tevent_req_nterror(req
, status
)) {
1297 return tevent_req_post(req
, ev
);
1300 gensec_want_feature(state
->auth_generic
->gensec_security
,
1301 GENSEC_FEATURE_SESSION_KEY
);
1302 if (cli
->use_ccache
) {
1303 gensec_want_feature(state
->auth_generic
->gensec_security
,
1304 GENSEC_FEATURE_NTLM_CCACHE
);
1305 if (pass
!= NULL
&& strlen(pass
) == 0) {
1307 * some callers pass "" as no password
1309 * GENSEC_FEATURE_NTLM_CCACHE only handles
1310 * NULL as no password.
1316 status
= auth_generic_set_username(state
->auth_generic
, user
);
1317 if (tevent_req_nterror(req
, status
)) {
1318 return tevent_req_post(req
, ev
);
1321 status
= auth_generic_set_domain(state
->auth_generic
, domain
);
1322 if (tevent_req_nterror(req
, status
)) {
1323 return tevent_req_post(req
, ev
);
1326 if (cli
->pw_nt_hash
) {
1327 struct samr_Password nt_hash
;
1332 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER_MIX
);
1333 return tevent_req_post(req
, ev
);
1336 converted
= strhex_to_str((char *)nt_hash
.hash
,
1337 sizeof(nt_hash
.hash
),
1338 pass
, strlen(pass
));
1339 if (converted
!= sizeof(nt_hash
.hash
)) {
1340 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER_MIX
);
1341 return tevent_req_post(req
, ev
);
1344 ok
= cli_credentials_set_nt_hash(state
->auth_generic
->credentials
,
1345 &nt_hash
, CRED_SPECIFIED
);
1347 tevent_req_oom(req
);
1348 return tevent_req_post(req
, ev
);
1351 status
= auth_generic_set_password(state
->auth_generic
, pass
);
1352 if (tevent_req_nterror(req
, status
)) {
1353 return tevent_req_post(req
, ev
);
1357 cli_credentials_set_kerberos_state(state
->auth_generic
->credentials
,
1360 if (krb5_state
== CRED_DONT_USE_KERBEROS
) {
1361 use_spnego_principal
= false;
1364 if (target_service
!= NULL
) {
1365 status
= gensec_set_target_service(
1366 state
->auth_generic
->gensec_security
,
1368 if (tevent_req_nterror(req
, status
)) {
1369 return tevent_req_post(req
, ev
);
1373 if (target_hostname
!= NULL
) {
1374 status
= gensec_set_target_hostname(
1375 state
->auth_generic
->gensec_security
,
1377 if (tevent_req_nterror(req
, status
)) {
1378 return tevent_req_post(req
, ev
);
1382 if (target_principal
!= NULL
) {
1383 status
= gensec_set_target_principal(
1384 state
->auth_generic
->gensec_security
,
1386 if (tevent_req_nterror(req
, status
)) {
1387 return tevent_req_post(req
, ev
);
1389 use_spnego_principal
= false;
1390 } else if (target_service
!= NULL
&& target_hostname
!= NULL
) {
1391 use_spnego_principal
= false;
1394 if (use_spnego_principal
) {
1396 b
= smbXcli_conn_server_gss_blob(cli
->conn
);
1398 state
->blob_in
= *b
;
1402 state
->is_anonymous
= cli_credentials_is_anonymous(state
->auth_generic
->credentials
);
1404 status
= auth_generic_client_start(state
->auth_generic
,
1406 if (tevent_req_nterror(req
, status
)) {
1407 return tevent_req_post(req
, ev
);
1410 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
1411 state
->cli
->smb2
.session
= smbXcli_session_create(cli
,
1413 if (tevent_req_nomem(state
->cli
->smb2
.session
, req
)) {
1414 return tevent_req_post(req
, ev
);
1418 cli_session_setup_gensec_local_next(req
);
1419 if (!tevent_req_is_in_progress(req
)) {
1420 return tevent_req_post(req
, ev
);
1426 static void cli_session_setup_gensec_local_next(struct tevent_req
*req
)
1428 struct cli_session_setup_gensec_state
*state
=
1429 tevent_req_data(req
,
1430 struct cli_session_setup_gensec_state
);
1431 struct tevent_req
*subreq
= NULL
;
1433 if (state
->local_ready
) {
1434 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
1438 subreq
= gensec_update_send(state
, state
->ev
,
1439 state
->auth_generic
->gensec_security
,
1441 if (tevent_req_nomem(subreq
, req
)) {
1444 tevent_req_set_callback(subreq
, cli_session_setup_gensec_local_done
, req
);
1447 static void cli_session_setup_gensec_local_done(struct tevent_req
*subreq
)
1449 struct tevent_req
*req
=
1450 tevent_req_callback_data(subreq
,
1452 struct cli_session_setup_gensec_state
*state
=
1453 tevent_req_data(req
,
1454 struct cli_session_setup_gensec_state
);
1457 status
= gensec_update_recv(subreq
, state
, &state
->blob_out
);
1458 TALLOC_FREE(subreq
);
1459 state
->blob_in
= data_blob_null
;
1460 if (!NT_STATUS_IS_OK(status
) &&
1461 !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
))
1463 tevent_req_nterror(req
, status
);
1467 if (NT_STATUS_IS_OK(status
)) {
1468 state
->local_ready
= true;
1471 if (state
->local_ready
&& state
->remote_ready
) {
1472 cli_session_setup_gensec_ready(req
);
1476 cli_session_setup_gensec_remote_next(req
);
1479 static void cli_session_setup_gensec_remote_next(struct tevent_req
*req
)
1481 struct cli_session_setup_gensec_state
*state
=
1482 tevent_req_data(req
,
1483 struct cli_session_setup_gensec_state
);
1484 struct tevent_req
*subreq
= NULL
;
1486 if (state
->remote_ready
) {
1487 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
1491 subreq
= cli_sesssetup_blob_send(state
, state
->ev
,
1492 state
->cli
, state
->blob_out
);
1493 if (tevent_req_nomem(subreq
, req
)) {
1496 tevent_req_set_callback(subreq
,
1497 cli_session_setup_gensec_remote_done
,
1501 static void cli_session_setup_gensec_remote_done(struct tevent_req
*subreq
)
1503 struct tevent_req
*req
=
1504 tevent_req_callback_data(subreq
,
1506 struct cli_session_setup_gensec_state
*state
=
1507 tevent_req_data(req
,
1508 struct cli_session_setup_gensec_state
);
1511 state
->inbuf
= NULL
;
1512 TALLOC_FREE(state
->recv_iov
);
1514 status
= cli_sesssetup_blob_recv(subreq
, state
, &state
->blob_in
,
1515 &state
->inbuf
, &state
->recv_iov
);
1516 TALLOC_FREE(subreq
);
1517 data_blob_free(&state
->blob_out
);
1518 if (!NT_STATUS_IS_OK(status
) &&
1519 !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
))
1521 tevent_req_nterror(req
, status
);
1525 if (NT_STATUS_IS_OK(status
)) {
1526 struct smbXcli_session
*session
= NULL
;
1527 bool is_guest
= false;
1529 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
1530 session
= state
->cli
->smb2
.session
;
1532 session
= state
->cli
->smb1
.session
;
1535 is_guest
= smbXcli_session_is_guest(session
);
1538 * We can't finish the gensec handshake, we don't
1539 * have a negotiated session key.
1541 * So just pretend we are completely done.
1543 * Note that smbXcli_session_is_guest()
1544 * always returns false if we require signing.
1546 state
->blob_in
= data_blob_null
;
1547 state
->local_ready
= true;
1550 state
->remote_ready
= true;
1553 if (state
->local_ready
&& state
->remote_ready
) {
1554 cli_session_setup_gensec_ready(req
);
1558 cli_session_setup_gensec_local_next(req
);
1561 static void cli_session_setup_gensec_ready(struct tevent_req
*req
)
1563 struct cli_session_setup_gensec_state
*state
=
1564 tevent_req_data(req
,
1565 struct cli_session_setup_gensec_state
);
1566 const char *server_domain
= NULL
;
1569 if (state
->blob_in
.length
!= 0) {
1570 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
1574 if (state
->blob_out
.length
!= 0) {
1575 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
1580 * gensec_ntlmssp_server_domain() returns NULL
1581 * if NTLMSSP is not used.
1583 * We can remove this later
1584 * and leave the server domain empty for SMB2 and above
1585 * in future releases.
1587 server_domain
= gensec_ntlmssp_server_domain(
1588 state
->auth_generic
->gensec_security
);
1590 if (state
->cli
->server_domain
[0] == '\0' && server_domain
!= NULL
) {
1591 TALLOC_FREE(state
->cli
->server_domain
);
1592 state
->cli
->server_domain
= talloc_strdup(state
->cli
,
1594 if (state
->cli
->server_domain
== NULL
) {
1595 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
1600 if (state
->is_anonymous
) {
1602 * Windows server does not set the
1603 * SMB2_SESSION_FLAG_IS_NULL flag.
1605 * This fix makes sure we do not try
1606 * to verify a signature on the final
1607 * session setup response.
1609 tevent_req_done(req
);
1613 status
= gensec_session_key(state
->auth_generic
->gensec_security
,
1614 state
, &state
->session_key
);
1615 if (tevent_req_nterror(req
, status
)) {
1619 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
1620 struct smbXcli_session
*session
= state
->cli
->smb2
.session
;
1622 status
= smb2cli_session_set_session_key(session
,
1625 if (tevent_req_nterror(req
, status
)) {
1629 struct smbXcli_session
*session
= state
->cli
->smb1
.session
;
1632 status
= smb1cli_session_set_session_key(session
,
1633 state
->session_key
);
1634 if (tevent_req_nterror(req
, status
)) {
1638 active
= smb1cli_conn_activate_signing(state
->cli
->conn
,
1644 ok
= smb1cli_conn_check_signing(state
->cli
->conn
,
1647 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1653 tevent_req_done(req
);
1656 static NTSTATUS
cli_session_setup_gensec_recv(struct tevent_req
*req
)
1658 struct cli_session_setup_gensec_state
*state
=
1659 tevent_req_data(req
,
1660 struct cli_session_setup_gensec_state
);
1663 if (tevent_req_is_nterror(req
, &status
)) {
1664 cli_state_set_uid(state
->cli
, UID_FIELD_INVALID
);
1667 return NT_STATUS_OK
;
1672 static char *cli_session_setup_get_principal(
1673 TALLOC_CTX
*mem_ctx
, const char *spnego_principal
,
1674 const char *remote_name
, const char *dest_realm
)
1676 char *principal
= NULL
;
1678 if (!lp_client_use_spnego_principal() ||
1679 strequal(spnego_principal
, ADS_IGNORE_PRINCIPAL
)) {
1680 spnego_principal
= NULL
;
1682 if (spnego_principal
!= NULL
) {
1683 DEBUG(3, ("cli_session_setup_spnego: using spnego provided "
1684 "principal %s\n", spnego_principal
));
1685 return talloc_strdup(mem_ctx
, spnego_principal
);
1687 if (is_ipaddress(remote_name
) ||
1688 strequal(remote_name
, STAR_SMBSERVER
)) {
1692 DEBUG(3, ("cli_session_setup_spnego: using target "
1693 "hostname not SPNEGO principal\n"));
1696 char *realm
= strupper_talloc(talloc_tos(), dest_realm
);
1697 if (realm
== NULL
) {
1700 principal
= talloc_asprintf(talloc_tos(), "cifs/%s@%s",
1701 remote_name
, realm
);
1705 smb_krb5_get_principal_from_service_hostname(talloc_tos(),
1710 DEBUG(3, ("cli_session_setup_spnego: guessed server principal=%s\n",
1711 principal
? principal
: "<null>"));
1717 static char *cli_session_setup_get_account(TALLOC_CTX
*mem_ctx
,
1718 const char *principal
)
1722 account
= talloc_strdup(mem_ctx
, principal
);
1723 if (account
== NULL
) {
1726 p
= strchr_m(account
, '@');
1733 /****************************************************************************
1734 Do a spnego encrypted session setup.
1736 user_domain: The shortname of the domain the user/machine is a member of.
1737 dest_realm: The realm we're connecting to, if NULL we use our default realm.
1738 ****************************************************************************/
1740 struct cli_session_setup_spnego_state
{
1741 struct tevent_context
*ev
;
1742 struct cli_state
*cli
;
1743 const char *target_hostname
;
1745 const char *account
;
1747 const char *user_domain
;
1748 const char *dest_realm
;
1753 static void cli_session_setup_spnego_done_krb(struct tevent_req
*subreq
);
1756 static void cli_session_setup_spnego_done_ntlmssp(struct tevent_req
*subreq
);
1758 static struct tevent_req
*cli_session_setup_spnego_send(
1759 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
1760 const char *user
, const char *pass
, const char *user_domain
)
1762 struct tevent_req
*req
, *subreq
;
1763 struct cli_session_setup_spnego_state
*state
;
1764 char *principal
= NULL
;
1765 char *OIDs
[ASN1_MAX_OIDS
];
1767 const char *dest_realm
= cli_state_remote_realm(cli
);
1768 const DATA_BLOB
*server_blob
;
1770 req
= tevent_req_create(mem_ctx
, &state
,
1771 struct cli_session_setup_spnego_state
);
1779 state
->user_domain
= user_domain
;
1780 state
->dest_realm
= dest_realm
;
1782 state
->account
= cli_session_setup_get_account(state
, user
);
1783 if (tevent_req_nomem(state
->account
, req
)) {
1784 return tevent_req_post(req
, ev
);
1787 state
->target_hostname
= smbXcli_conn_remote_name(cli
->conn
);
1788 server_blob
= smbXcli_conn_server_gss_blob(cli
->conn
);
1790 DEBUG(3,("Doing spnego session setup (blob length=%lu)\n",
1791 (unsigned long)server_blob
->length
));
1793 /* the server might not even do spnego */
1794 if (server_blob
->length
== 0) {
1795 DEBUG(3,("server didn't supply a full spnego negprot\n"));
1800 file_save("negprot.dat", cli
->secblob
.data
, cli
->secblob
.length
);
1803 /* The server sent us the first part of the SPNEGO exchange in the
1804 * negprot reply. It is WRONG to depend on the principal sent in the
1805 * negprot reply, but right now we do it. If we don't receive one,
1806 * we try to best guess, then fall back to NTLM. */
1807 if (!spnego_parse_negTokenInit(state
, *server_blob
, OIDs
,
1808 &principal
, NULL
) ||
1810 state
->result
= ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
1811 tevent_req_done(req
);
1812 return tevent_req_post(req
, ev
);
1815 /* make sure the server understands kerberos */
1816 for (i
=0;OIDs
[i
];i
++) {
1818 DEBUG(3,("got OID=%s\n", OIDs
[i
]));
1820 DEBUGADD(3,("got OID=%s\n", OIDs
[i
]));
1821 if (strcmp(OIDs
[i
], OID_KERBEROS5_OLD
) == 0 ||
1822 strcmp(OIDs
[i
], OID_KERBEROS5
) == 0) {
1823 cli
->got_kerberos_mechanism
= True
;
1825 talloc_free(OIDs
[i
]);
1828 DEBUG(3,("got principal=%s\n", principal
? principal
: "<null>"));
1831 /* If password is set we reauthenticate to kerberos server
1832 * and do not store results */
1834 if (user
&& *user
&& cli
->got_kerberos_mechanism
&& cli
->use_kerberos
) {
1837 tmp
= cli_session_setup_get_principal(
1838 talloc_tos(), principal
, state
->target_hostname
, dest_realm
);
1839 TALLOC_FREE(principal
);
1842 if (pass
&& *pass
) {
1845 use_in_memory_ccache();
1846 ret
= kerberos_kinit_password(user
, pass
, 0 /* no time correction for now */, NULL
);
1849 DEBUG(0, ("Kinit for %s to access %s failed: %s\n", user
, principal
, error_message(ret
)));
1850 TALLOC_FREE(principal
);
1851 if (cli
->fallback_after_kerberos
)
1853 state
->result
= ADS_ERROR_KRB5(ret
);
1854 tevent_req_done(req
);
1855 return tevent_req_post(req
, ev
);
1860 subreq
= cli_session_setup_gensec_send(
1862 state
->account
, pass
, user_domain
,
1863 CRED_MUST_USE_KERBEROS
,
1864 "cifs", state
->target_hostname
, principal
);
1865 if (tevent_req_nomem(subreq
, req
)) {
1866 return tevent_req_post(req
, ev
);
1868 tevent_req_set_callback(
1869 subreq
, cli_session_setup_spnego_done_krb
,
1877 subreq
= cli_session_setup_gensec_send(
1878 state
, state
->ev
, state
->cli
,
1879 state
->account
, state
->pass
, state
->user_domain
,
1880 CRED_DONT_USE_KERBEROS
,
1881 "cifs", state
->target_hostname
, NULL
);
1882 if (tevent_req_nomem(subreq
, req
)) {
1883 return tevent_req_post(req
, ev
);
1885 tevent_req_set_callback(
1886 subreq
, cli_session_setup_spnego_done_ntlmssp
, req
);
1891 static void cli_session_setup_spnego_done_krb(struct tevent_req
*subreq
)
1893 struct tevent_req
*req
= tevent_req_callback_data(
1894 subreq
, struct tevent_req
);
1895 struct cli_session_setup_spnego_state
*state
= tevent_req_data(
1896 req
, struct cli_session_setup_spnego_state
);
1899 status
= cli_session_setup_gensec_recv(subreq
);
1900 TALLOC_FREE(subreq
);
1901 state
->result
= ADS_ERROR_NT(status
);
1903 if (ADS_ERR_OK(state
->result
) ||
1904 !state
->cli
->fallback_after_kerberos
) {
1905 tevent_req_done(req
);
1909 subreq
= cli_session_setup_gensec_send(
1910 state
, state
->ev
, state
->cli
,
1911 state
->account
, state
->pass
, state
->user_domain
,
1912 CRED_DONT_USE_KERBEROS
,
1913 "cifs", state
->target_hostname
, NULL
);
1914 if (tevent_req_nomem(subreq
, req
)) {
1917 tevent_req_set_callback(subreq
, cli_session_setup_spnego_done_ntlmssp
,
1922 static void cli_session_setup_spnego_done_ntlmssp(struct tevent_req
*subreq
)
1924 struct tevent_req
*req
= tevent_req_callback_data(
1925 subreq
, struct tevent_req
);
1926 struct cli_session_setup_spnego_state
*state
= tevent_req_data(
1927 req
, struct cli_session_setup_spnego_state
);
1930 status
= cli_session_setup_gensec_recv(subreq
);
1931 TALLOC_FREE(subreq
);
1932 state
->result
= ADS_ERROR_NT(status
);
1933 tevent_req_done(req
);
1936 static ADS_STATUS
cli_session_setup_spnego_recv(struct tevent_req
*req
)
1938 struct cli_session_setup_spnego_state
*state
= tevent_req_data(
1939 req
, struct cli_session_setup_spnego_state
);
1941 return state
->result
;
1944 struct cli_session_setup_state
{
1945 struct cli_state
*cli
;
1946 uint8_t nt_hash
[16];
1947 uint8_t lm_hash
[16];
1948 DATA_BLOB apassword_blob
;
1949 DATA_BLOB upassword_blob
;
1950 DATA_BLOB lm_session_key
;
1951 DATA_BLOB session_key
;
1952 char *out_native_os
;
1953 char *out_native_lm
;
1954 char *out_primary_domain
;
1957 static void cli_session_setup_cleanup(struct tevent_req
*req
,
1958 enum tevent_req_state req_state
)
1960 struct cli_session_setup_state
*state
= tevent_req_data(
1961 req
, struct cli_session_setup_state
);
1963 if (req_state
!= TEVENT_REQ_RECEIVED
) {
1968 * We only call data_blob_clear() as
1969 * some of the blobs point to the same memory.
1971 * We let the talloc hierachy free the memory.
1973 data_blob_clear(&state
->apassword_blob
);
1974 data_blob_clear(&state
->upassword_blob
);
1975 data_blob_clear(&state
->lm_session_key
);
1976 data_blob_clear(&state
->session_key
);
1977 ZERO_STRUCTP(state
);
1980 static void cli_session_setup_done_spnego(struct tevent_req
*subreq
);
1981 static void cli_session_setup_done_nt1(struct tevent_req
*subreq
);
1982 static void cli_session_setup_done_lm21(struct tevent_req
*subreq
);
1984 /****************************************************************************
1985 Send a session setup. The username and workgroup is in UNIX character
1986 format and must be converted to DOS codepage format before sending. If the
1987 password is in plaintext, the same should be done.
1988 ****************************************************************************/
1990 struct tevent_req
*cli_session_setup_send(TALLOC_CTX
*mem_ctx
,
1991 struct tevent_context
*ev
,
1992 struct cli_state
*cli
,
1995 const char *workgroup
)
1997 struct tevent_req
*req
, *subreq
;
1998 struct cli_session_setup_state
*state
;
2001 uint16_t sec_mode
= smb1cli_conn_server_security_mode(cli
->conn
);
2002 bool use_spnego
= false;
2003 bool do_lmresponse
= false;
2004 const char *username
= "";
2005 const char *domain
= "";
2006 const char *password
= "";
2007 DATA_BLOB target_info
= data_blob_null
;
2008 DATA_BLOB challenge
= data_blob_null
;
2009 uint16_t in_buf_size
= 0;
2010 uint16_t in_mpx_max
= 0;
2011 uint16_t in_vc_num
= 0;
2012 uint32_t in_sess_key
= 0;
2013 const char *in_native_os
= NULL
;
2014 const char *in_native_lm
= NULL
;
2016 req
= tevent_req_create(mem_ctx
, &state
,
2017 struct cli_session_setup_state
);
2023 tevent_req_set_cleanup_fn(req
, cli_session_setup_cleanup
);
2026 user2
= talloc_strdup(state
, user
);
2028 user2
= talloc_strdup(state
, "");
2030 if (user2
== NULL
) {
2031 tevent_req_oom(req
);
2032 return tevent_req_post(req
, ev
);
2039 /* allow for workgroups as part of the username */
2040 if ((p
=strchr_m(user2
,'\\')) || (p
=strchr_m(user2
,'/')) ||
2041 (p
=strchr_m(user2
,*lp_winbind_separator()))) {
2044 if (!strupper_m(user2
)) {
2045 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2046 return tevent_req_post(req
, ev
);
2052 * Now work out what sort of session setup we are going to
2053 * do. I have split this into separate functions to make the flow a bit
2054 * easier to understand (tridge).
2056 if (smbXcli_conn_protocol(cli
->conn
) < PROTOCOL_NT1
) {
2058 } else if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
2060 } else if (smb1cli_conn_capabilities(cli
->conn
) & CAP_EXTENDED_SECURITY
) {
2062 * if the server supports extended security then use SPNEGO
2063 * even for anonymous connections.
2071 subreq
= cli_session_setup_spnego_send(
2072 state
, ev
, cli
, user
, pass
, workgroup
);
2073 if (tevent_req_nomem(subreq
, req
)) {
2074 return tevent_req_post(req
, ev
);
2076 tevent_req_set_callback(subreq
, cli_session_setup_done_spnego
,
2081 if (smbXcli_conn_protocol(cli
->conn
) < PROTOCOL_LANMAN1
) {
2083 * SessionSetupAndX was introduced by LANMAN 1.0. So we skip
2084 * this step against older servers.
2086 tevent_req_done(req
);
2087 return tevent_req_post(req
, ev
);
2090 if (user
== NULL
|| strlen(user
) == 0) {
2092 * Do an anonymous session setup
2094 goto non_spnego_creds_done
;
2097 if ((sec_mode
& NEGOTIATE_SECURITY_USER_LEVEL
) == 0) {
2099 * Do an anonymous session setup,
2100 * the password is passed via the tree connect.
2102 goto non_spnego_creds_done
;
2111 if ((sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
) == 0) {
2112 bool use_unicode
= smbXcli_conn_use_unicode(cli
->conn
);
2113 uint8_t *bytes
= NULL
;
2114 size_t bytes_len
= 0;
2115 const char *pw
= password
;
2121 pw_len
= strlen(pw
) + 1;
2123 if (!lp_client_plaintext_auth()) {
2124 DEBUG(1, ("Server requested PLAINTEXT password but "
2125 "'client plaintext auth = no'\n"));
2126 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
2127 return tevent_req_post(req
, ev
);
2130 bytes
= talloc_array(state
, uint8_t, 0);
2131 bytes
= trans2_bytes_push_str(bytes
, use_unicode
,
2132 pw
, pw_len
, &bytes_len
);
2133 if (tevent_req_nomem(bytes
, req
)) {
2134 return tevent_req_post(req
, ev
);
2139 * CAP_UNICODE, can only be negotiated by NT1.
2141 state
->upassword_blob
= data_blob_const(bytes
,
2144 state
->apassword_blob
= data_blob_const(bytes
,
2148 goto non_spnego_creds_done
;
2151 challenge
= data_blob_const(smb1cli_conn_server_challenge(cli
->conn
), 8);
2152 E_md4hash(password
, state
->nt_hash
);
2154 if (smbXcli_conn_protocol(cli
->conn
) == PROTOCOL_NT1
) {
2155 if (lp_client_ntlmv2_auth() && lp_client_use_spnego()) {
2157 * Don't send an NTLMv2 response without NTLMSSP if we
2158 * want to use spnego support.
2160 DEBUG(1, ("Server does not support EXTENDED_SECURITY "
2161 " but 'client use spnego = yes'"
2162 " and 'client ntlmv2 auth = yes' is set\n"));
2163 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
2164 return tevent_req_post(req
, ev
);
2167 if (lp_client_ntlmv2_auth()) {
2171 * note that the 'domain' here is a best
2172 * guess - we don't know the server's domain
2173 * at this point. Windows clients also don't
2176 target_info
= NTLMv2_generate_names_blob(state
,
2179 if (tevent_req_nomem(target_info
.data
, req
)) {
2180 return tevent_req_post(req
, ev
);
2183 ok
= SMBNTLMv2encrypt_hash(state
,
2188 NULL
, /* server_timestamp */
2190 &state
->apassword_blob
,
2191 &state
->upassword_blob
,
2192 &state
->lm_session_key
,
2193 &state
->session_key
);
2195 tevent_req_nterror(req
,
2196 NT_STATUS_ACCESS_DENIED
);
2197 return tevent_req_post(req
, ev
);
2200 state
->upassword_blob
= data_blob_talloc_zero(state
, 24);
2201 if (tevent_req_nomem(state
->upassword_blob
.data
, req
)) {
2202 return tevent_req_post(req
, ev
);
2204 state
->session_key
= data_blob_talloc_zero(state
, 16);
2205 if (tevent_req_nomem(state
->session_key
.data
, req
)) {
2206 return tevent_req_post(req
, ev
);
2209 SMBNTencrypt_hash(state
->nt_hash
, challenge
.data
,
2210 state
->upassword_blob
.data
);
2211 SMBsesskeygen_ntv1(state
->nt_hash
,
2212 state
->session_key
.data
);
2214 if (lp_client_lanman_auth()) {
2215 do_lmresponse
= E_deshash(password
,
2220 if (!lp_client_lanman_auth()) {
2221 DEBUG(1, ("Server requested LM password but "
2222 "'client lanman auth = no' "
2223 "or 'client ntlmv2 auth = yes' is set\n"));
2224 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
2225 return tevent_req_post(req
, ev
);
2228 do_lmresponse
= E_deshash(password
, state
->lm_hash
);
2231 if (do_lmresponse
) {
2232 state
->apassword_blob
= data_blob_talloc_zero(state
, 24);
2233 if (tevent_req_nomem(state
->apassword_blob
.data
, req
)) {
2234 return tevent_req_post(req
, ev
);
2237 SMBencrypt_hash(state
->lm_hash
,
2239 state
->apassword_blob
.data
);
2242 if (state
->apassword_blob
.length
== 0) {
2243 if (state
->upassword_blob
.length
== 0) {
2244 DEBUG(1, ("Password is > 14 chars in length, and is "
2245 "therefore incompatible with Lanman "
2246 "authentication\n"));
2247 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
2248 return tevent_req_post(req
, ev
);
2252 * LM disabled, place NT# in LM field
2255 state
->apassword_blob
= state
->upassword_blob
;
2258 non_spnego_creds_done
:
2260 in_buf_size
= CLI_BUFFER_SIZE
;
2261 in_mpx_max
= smbXcli_conn_max_requests(cli
->conn
);
2262 in_vc_num
= cli_state_get_vc_num(cli
);
2263 in_sess_key
= smb1cli_conn_server_session_key(cli
->conn
);
2264 in_native_os
= "Unix";
2265 in_native_lm
= "Samba";
2267 if (smbXcli_conn_protocol(cli
->conn
) == PROTOCOL_NT1
) {
2268 uint32_t in_capabilities
= 0;
2270 in_capabilities
= cli_session_setup_capabilities(cli
, 0);
2273 * For now we keep the same values as before,
2274 * we may remove these in a separate commit later.
2278 subreq
= smb1cli_session_setup_nt1_send(state
, ev
,
2289 state
->apassword_blob
,
2290 state
->upassword_blob
,
2294 if (tevent_req_nomem(subreq
, req
)) {
2295 return tevent_req_post(req
, ev
);
2297 tevent_req_set_callback(subreq
, cli_session_setup_done_nt1
,
2303 * For now we keep the same values as before,
2304 * we may remove these in a separate commit later.
2309 subreq
= smb1cli_session_setup_lm21_send(state
, ev
,
2320 state
->apassword_blob
,
2323 if (tevent_req_nomem(subreq
, req
)) {
2324 return tevent_req_post(req
, ev
);
2326 tevent_req_set_callback(subreq
, cli_session_setup_done_lm21
,
2331 static void cli_session_setup_done_spnego(struct tevent_req
*subreq
)
2333 struct tevent_req
*req
= tevent_req_callback_data(
2334 subreq
, struct tevent_req
);
2337 status
= cli_session_setup_spnego_recv(subreq
);
2338 TALLOC_FREE(subreq
);
2339 if (!ADS_ERR_OK(status
)) {
2340 DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status
)));
2341 tevent_req_nterror(req
, ads_ntstatus(status
));
2344 tevent_req_done(req
);
2347 static void cli_session_setup_done_nt1(struct tevent_req
*subreq
)
2349 struct tevent_req
*req
= tevent_req_callback_data(
2350 subreq
, struct tevent_req
);
2351 struct cli_session_setup_state
*state
= tevent_req_data(
2352 req
, struct cli_session_setup_state
);
2353 struct cli_state
*cli
= state
->cli
;
2355 struct iovec
*recv_iov
= NULL
;
2356 const uint8_t *inbuf
= NULL
;
2359 status
= smb1cli_session_setup_nt1_recv(subreq
, state
,
2362 &state
->out_native_os
,
2363 &state
->out_native_lm
,
2364 &state
->out_primary_domain
);
2365 TALLOC_FREE(subreq
);
2366 if (!NT_STATUS_IS_OK(status
)) {
2367 DEBUG(3, ("NT1 login failed: %s\n", nt_errstr(status
)));
2368 tevent_req_nterror(req
, status
);
2372 if (cli
->server_os
== NULL
) {
2373 cli
->server_os
= talloc_move(cli
, &state
->out_native_os
);
2375 if (cli
->server_type
== NULL
) {
2376 cli
->server_type
= talloc_move(cli
, &state
->out_native_lm
);
2378 if (cli
->server_domain
== NULL
) {
2379 cli
->server_domain
= talloc_move(cli
, &state
->out_primary_domain
);
2382 ok
= smb1cli_conn_activate_signing(cli
->conn
,
2384 state
->upassword_blob
);
2386 ok
= smb1cli_conn_check_signing(cli
->conn
, inbuf
, 1);
2388 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
2393 if (state
->session_key
.data
) {
2394 struct smbXcli_session
*session
= cli
->smb1
.session
;
2396 status
= smb1cli_session_set_session_key(session
,
2397 state
->session_key
);
2398 if (tevent_req_nterror(req
, status
)) {
2403 tevent_req_done(req
);
2406 static void cli_session_setup_done_lm21(struct tevent_req
*subreq
)
2408 struct tevent_req
*req
= tevent_req_callback_data(
2409 subreq
, struct tevent_req
);
2410 struct cli_session_setup_state
*state
= tevent_req_data(
2411 req
, struct cli_session_setup_state
);
2412 struct cli_state
*cli
= state
->cli
;
2415 status
= smb1cli_session_setup_lm21_recv(subreq
, state
,
2416 &state
->out_native_os
,
2417 &state
->out_native_lm
);
2418 TALLOC_FREE(subreq
);
2419 if (!NT_STATUS_IS_OK(status
)) {
2420 DEBUG(3, ("LM21 login failed: %s\n", nt_errstr(status
)));
2421 tevent_req_nterror(req
, status
);
2425 if (cli
->server_os
== NULL
) {
2426 cli
->server_os
= talloc_move(cli
, &state
->out_native_os
);
2428 if (cli
->server_type
== NULL
) {
2429 cli
->server_type
= talloc_move(cli
, &state
->out_native_lm
);
2432 tevent_req_done(req
);
2435 NTSTATUS
cli_session_setup_recv(struct tevent_req
*req
)
2437 return tevent_req_simple_recv_ntstatus(req
);
2440 NTSTATUS
cli_session_setup(struct cli_state
*cli
,
2443 const char *workgroup
)
2445 struct tevent_context
*ev
;
2446 struct tevent_req
*req
;
2447 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2449 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
2450 return NT_STATUS_INVALID_PARAMETER
;
2452 ev
= samba_tevent_context_init(talloc_tos());
2456 req
= cli_session_setup_send(ev
, ev
, cli
, user
, pass
, workgroup
);
2460 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2463 status
= cli_session_setup_recv(req
);
2469 /****************************************************************************
2471 *****************************************************************************/
2473 struct cli_ulogoff_state
{
2474 struct cli_state
*cli
;
2478 static void cli_ulogoff_done(struct tevent_req
*subreq
);
2480 static struct tevent_req
*cli_ulogoff_send(TALLOC_CTX
*mem_ctx
,
2481 struct tevent_context
*ev
,
2482 struct cli_state
*cli
)
2484 struct tevent_req
*req
, *subreq
;
2485 struct cli_ulogoff_state
*state
;
2487 req
= tevent_req_create(mem_ctx
, &state
, struct cli_ulogoff_state
);
2493 SCVAL(state
->vwv
+0, 0, 0xFF);
2494 SCVAL(state
->vwv
+1, 0, 0);
2495 SSVAL(state
->vwv
+2, 0, 0);
2497 subreq
= cli_smb_send(state
, ev
, cli
, SMBulogoffX
, 0, 0, 2, state
->vwv
,
2499 if (tevent_req_nomem(subreq
, req
)) {
2500 return tevent_req_post(req
, ev
);
2502 tevent_req_set_callback(subreq
, cli_ulogoff_done
, req
);
2506 static void cli_ulogoff_done(struct tevent_req
*subreq
)
2508 struct tevent_req
*req
= tevent_req_callback_data(
2509 subreq
, struct tevent_req
);
2510 struct cli_ulogoff_state
*state
= tevent_req_data(
2511 req
, struct cli_ulogoff_state
);
2514 status
= cli_smb_recv(subreq
, NULL
, NULL
, 0, NULL
, NULL
, NULL
, NULL
);
2515 if (!NT_STATUS_IS_OK(status
)) {
2516 tevent_req_nterror(req
, status
);
2519 cli_state_set_uid(state
->cli
, UID_FIELD_INVALID
);
2520 tevent_req_done(req
);
2523 static NTSTATUS
cli_ulogoff_recv(struct tevent_req
*req
)
2525 return tevent_req_simple_recv_ntstatus(req
);
2528 NTSTATUS
cli_ulogoff(struct cli_state
*cli
)
2530 struct tevent_context
*ev
;
2531 struct tevent_req
*req
;
2532 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2534 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
2535 status
= smb2cli_logoff(cli
->conn
,
2538 if (!NT_STATUS_IS_OK(status
)) {
2541 smb2cli_session_set_id_and_flags(cli
->smb2
.session
,
2543 return NT_STATUS_OK
;
2546 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
2547 return NT_STATUS_INVALID_PARAMETER
;
2549 ev
= samba_tevent_context_init(talloc_tos());
2553 req
= cli_ulogoff_send(ev
, ev
, cli
);
2557 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2560 status
= cli_ulogoff_recv(req
);
2566 /****************************************************************************
2568 ****************************************************************************/
2570 struct cli_tcon_andx_state
{
2571 struct cli_state
*cli
;
2576 static void cli_tcon_andx_done(struct tevent_req
*subreq
);
2578 struct tevent_req
*cli_tcon_andx_create(TALLOC_CTX
*mem_ctx
,
2579 struct tevent_context
*ev
,
2580 struct cli_state
*cli
,
2581 const char *share
, const char *dev
,
2582 const char *pass
, int passlen
,
2583 struct tevent_req
**psmbreq
)
2585 struct tevent_req
*req
, *subreq
;
2586 struct cli_tcon_andx_state
*state
;
2591 uint16_t sec_mode
= smb1cli_conn_server_security_mode(cli
->conn
);
2592 uint16_t tcon_flags
= 0;
2596 req
= tevent_req_create(mem_ctx
, &state
, struct cli_tcon_andx_state
);
2603 cli
->share
= talloc_strdup(cli
, share
);
2608 /* in user level security don't send a password now */
2609 if (sec_mode
& NEGOTIATE_SECURITY_USER_LEVEL
) {
2612 } else if (pass
== NULL
) {
2613 DEBUG(1, ("Server not using user level security and no "
2614 "password supplied.\n"));
2618 if ((sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
) &&
2619 *pass
&& passlen
!= 24) {
2620 if (!lp_client_lanman_auth()) {
2621 DEBUG(1, ("Server requested LANMAN password "
2622 "(share-level security) but "
2623 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2628 * Non-encrypted passwords - convert to DOS codepage before
2631 SMBencrypt(pass
, smb1cli_conn_server_challenge(cli
->conn
), p24
);
2633 pass
= (const char *)p24
;
2635 if((sec_mode
& (NEGOTIATE_SECURITY_USER_LEVEL
2636 |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
))
2640 if (!lp_client_plaintext_auth() && (*pass
)) {
2641 DEBUG(1, ("Server requested PLAINTEXT "
2643 "'client plaintext auth = no' or 'client ntlmv2 auth = yes'\n"));
2648 * Non-encrypted passwords - convert to DOS codepage
2651 tmp_pass
= talloc_array(talloc_tos(), uint8_t, 0);
2652 if (tevent_req_nomem(tmp_pass
, req
)) {
2653 return tevent_req_post(req
, ev
);
2655 tmp_pass
= trans2_bytes_push_str(tmp_pass
,
2656 false, /* always DOS */
2660 if (tevent_req_nomem(tmp_pass
, req
)) {
2661 return tevent_req_post(req
, ev
);
2663 pass
= (const char *)tmp_pass
;
2664 passlen
= talloc_get_size(tmp_pass
);
2668 tcon_flags
|= TCONX_FLAG_EXTENDED_RESPONSE
;
2669 tcon_flags
|= TCONX_FLAG_EXTENDED_SIGNATURES
;
2671 SCVAL(vwv
+0, 0, 0xFF);
2674 SSVAL(vwv
+2, 0, tcon_flags
);
2675 SSVAL(vwv
+3, 0, passlen
);
2677 if (passlen
&& pass
) {
2678 bytes
= (uint8_t *)talloc_memdup(state
, pass
, passlen
);
2680 bytes
= talloc_array(state
, uint8_t, 0);
2686 tmp
= talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
2687 smbXcli_conn_remote_name(cli
->conn
), share
);
2692 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), tmp
, strlen(tmp
)+1,
2697 * Add the devicetype
2699 tmp
= talloc_strdup_upper(talloc_tos(), dev
);
2704 bytes
= smb_bytes_push_str(bytes
, false, tmp
, strlen(tmp
)+1, NULL
);
2707 if (bytes
== NULL
) {
2712 state
->bytes
.iov_base
= (void *)bytes
;
2713 state
->bytes
.iov_len
= talloc_get_size(bytes
);
2715 subreq
= cli_smb_req_create(state
, ev
, cli
, SMBtconX
, 0, 0, 4, vwv
,
2717 if (subreq
== NULL
) {
2721 tevent_req_set_callback(subreq
, cli_tcon_andx_done
, req
);
2726 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
2727 return tevent_req_post(req
, ev
);
2730 struct tevent_req
*cli_tcon_andx_send(TALLOC_CTX
*mem_ctx
,
2731 struct tevent_context
*ev
,
2732 struct cli_state
*cli
,
2733 const char *share
, const char *dev
,
2734 const char *pass
, int passlen
)
2736 struct tevent_req
*req
, *subreq
;
2739 req
= cli_tcon_andx_create(mem_ctx
, ev
, cli
, share
, dev
, pass
, passlen
,
2744 if (subreq
== NULL
) {
2747 status
= smb1cli_req_chain_submit(&subreq
, 1);
2748 if (!NT_STATUS_IS_OK(status
)) {
2749 tevent_req_nterror(req
, status
);
2750 return tevent_req_post(req
, ev
);
2755 static void cli_tcon_andx_done(struct tevent_req
*subreq
)
2757 struct tevent_req
*req
= tevent_req_callback_data(
2758 subreq
, struct tevent_req
);
2759 struct cli_tcon_andx_state
*state
= tevent_req_data(
2760 req
, struct cli_tcon_andx_state
);
2761 struct cli_state
*cli
= state
->cli
;
2769 uint16_t optional_support
= 0;
2771 status
= cli_smb_recv(subreq
, state
, &in
, 0, &wct
, &vwv
,
2772 &num_bytes
, &bytes
);
2773 TALLOC_FREE(subreq
);
2774 if (!NT_STATUS_IS_OK(status
)) {
2775 tevent_req_nterror(req
, status
);
2779 inhdr
= in
+ NBT_HDR_SIZE
;
2782 if (clistr_pull_talloc(cli
,
2783 (const char *)inhdr
,
2784 SVAL(inhdr
, HDR_FLG2
),
2788 STR_TERMINATE
|STR_ASCII
) == -1) {
2789 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
2793 cli
->dev
= talloc_strdup(cli
, "");
2794 if (cli
->dev
== NULL
) {
2795 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
2800 if ((smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_NT1
) && (num_bytes
== 3)) {
2801 /* almost certainly win95 - enable bug fixes */
2806 * Make sure that we have the optional support 16-bit field. WCT > 2.
2807 * Avoids issues when connecting to Win9x boxes sharing files
2810 if ((wct
> 2) && (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_LANMAN2
)) {
2811 optional_support
= SVAL(vwv
+2, 0);
2814 if (optional_support
& SMB_EXTENDED_SIGNATURES
) {
2815 smb1cli_session_protect_session_key(cli
->smb1
.session
);
2818 smb1cli_tcon_set_values(state
->cli
->smb1
.tcon
,
2819 SVAL(inhdr
, HDR_TID
),
2821 0, /* maximal_access */
2822 0, /* guest_maximal_access */
2824 NULL
); /* fs_type */
2826 tevent_req_done(req
);
2829 NTSTATUS
cli_tcon_andx_recv(struct tevent_req
*req
)
2831 return tevent_req_simple_recv_ntstatus(req
);
2834 NTSTATUS
cli_tcon_andx(struct cli_state
*cli
, const char *share
,
2835 const char *dev
, const char *pass
, int passlen
)
2837 TALLOC_CTX
*frame
= talloc_stackframe();
2838 struct tevent_context
*ev
;
2839 struct tevent_req
*req
;
2840 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2842 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
2844 * Can't use sync call while an async call is in flight
2846 status
= NT_STATUS_INVALID_PARAMETER
;
2850 ev
= samba_tevent_context_init(frame
);
2855 req
= cli_tcon_andx_send(frame
, ev
, cli
, share
, dev
, pass
, passlen
);
2860 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2864 status
= cli_tcon_andx_recv(req
);
2870 struct cli_tree_connect_state
{
2871 struct cli_state
*cli
;
2874 static struct tevent_req
*cli_raw_tcon_send(
2875 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
2876 const char *service
, const char *pass
, const char *dev
);
2877 static NTSTATUS
cli_raw_tcon_recv(struct tevent_req
*req
,
2878 uint16_t *max_xmit
, uint16_t *tid
);
2880 static void cli_tree_connect_smb2_done(struct tevent_req
*subreq
);
2881 static void cli_tree_connect_andx_done(struct tevent_req
*subreq
);
2882 static void cli_tree_connect_raw_done(struct tevent_req
*subreq
);
2884 static struct tevent_req
*cli_tree_connect_send(
2885 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
2886 const char *share
, const char *dev
, const char *pass
, int passlen
)
2888 struct tevent_req
*req
, *subreq
;
2889 struct cli_tree_connect_state
*state
;
2891 req
= tevent_req_create(mem_ctx
, &state
,
2892 struct cli_tree_connect_state
);
2898 cli
->share
= talloc_strdup(cli
, share
);
2899 if (tevent_req_nomem(cli
->share
, req
)) {
2900 return tevent_req_post(req
, ev
);
2903 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
2906 cli
->smb2
.tcon
= smbXcli_tcon_create(cli
);
2907 if (tevent_req_nomem(cli
->smb2
.tcon
, req
)) {
2908 return tevent_req_post(req
, ev
);
2911 unc
= talloc_asprintf(state
, "\\\\%s\\%s",
2912 smbXcli_conn_remote_name(cli
->conn
),
2914 if (tevent_req_nomem(unc
, req
)) {
2915 return tevent_req_post(req
, ev
);
2918 subreq
= smb2cli_tcon_send(state
, ev
, cli
->conn
, cli
->timeout
,
2919 cli
->smb2
.session
, cli
->smb2
.tcon
,
2922 if (tevent_req_nomem(subreq
, req
)) {
2923 return tevent_req_post(req
, ev
);
2925 tevent_req_set_callback(subreq
, cli_tree_connect_smb2_done
,
2930 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_LANMAN1
) {
2931 subreq
= cli_tcon_andx_send(state
, ev
, cli
, share
, dev
,
2933 if (tevent_req_nomem(subreq
, req
)) {
2934 return tevent_req_post(req
, ev
);
2936 tevent_req_set_callback(subreq
, cli_tree_connect_andx_done
,
2941 subreq
= cli_raw_tcon_send(state
, ev
, cli
, share
, pass
, dev
);
2942 if (tevent_req_nomem(subreq
, req
)) {
2943 return tevent_req_post(req
, ev
);
2945 tevent_req_set_callback(subreq
, cli_tree_connect_raw_done
, req
);
2950 static void cli_tree_connect_smb2_done(struct tevent_req
*subreq
)
2952 tevent_req_simple_finish_ntstatus(
2953 subreq
, smb2cli_tcon_recv(subreq
));
2956 static void cli_tree_connect_andx_done(struct tevent_req
*subreq
)
2958 tevent_req_simple_finish_ntstatus(
2959 subreq
, cli_tcon_andx_recv(subreq
));
2962 static void cli_tree_connect_raw_done(struct tevent_req
*subreq
)
2964 struct tevent_req
*req
= tevent_req_callback_data(
2965 subreq
, struct tevent_req
);
2966 struct cli_tree_connect_state
*state
= tevent_req_data(
2967 req
, struct cli_tree_connect_state
);
2969 uint16_t max_xmit
= 0;
2972 status
= cli_raw_tcon_recv(subreq
, &max_xmit
, &tid
);
2973 if (tevent_req_nterror(req
, status
)) {
2977 smb1cli_tcon_set_values(state
->cli
->smb1
.tcon
,
2979 0, /* optional_support */
2980 0, /* maximal_access */
2981 0, /* guest_maximal_access */
2983 NULL
); /* fs_type */
2985 tevent_req_done(req
);
2988 static NTSTATUS
cli_tree_connect_recv(struct tevent_req
*req
)
2990 return tevent_req_simple_recv_ntstatus(req
);
2993 NTSTATUS
cli_tree_connect(struct cli_state
*cli
, const char *share
,
2994 const char *dev
, const char *pass
, int passlen
)
2996 struct tevent_context
*ev
;
2997 struct tevent_req
*req
;
2998 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
3000 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
3001 return NT_STATUS_INVALID_PARAMETER
;
3003 ev
= samba_tevent_context_init(talloc_tos());
3007 req
= cli_tree_connect_send(ev
, ev
, cli
, share
, dev
, pass
, passlen
);
3011 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
3014 status
= cli_tree_connect_recv(req
);
3020 /****************************************************************************
3021 Send a tree disconnect.
3022 ****************************************************************************/
3024 struct cli_tdis_state
{
3025 struct cli_state
*cli
;
3028 static void cli_tdis_done(struct tevent_req
*subreq
);
3030 static struct tevent_req
*cli_tdis_send(TALLOC_CTX
*mem_ctx
,
3031 struct tevent_context
*ev
,
3032 struct cli_state
*cli
)
3034 struct tevent_req
*req
, *subreq
;
3035 struct cli_tdis_state
*state
;
3037 req
= tevent_req_create(mem_ctx
, &state
, struct cli_tdis_state
);
3043 subreq
= cli_smb_send(state
, ev
, cli
, SMBtdis
, 0, 0, 0, NULL
, 0, NULL
);
3044 if (tevent_req_nomem(subreq
, req
)) {
3045 return tevent_req_post(req
, ev
);
3047 tevent_req_set_callback(subreq
, cli_tdis_done
, req
);
3051 static void cli_tdis_done(struct tevent_req
*subreq
)
3053 struct tevent_req
*req
= tevent_req_callback_data(
3054 subreq
, struct tevent_req
);
3055 struct cli_tdis_state
*state
= tevent_req_data(
3056 req
, struct cli_tdis_state
);
3059 status
= cli_smb_recv(subreq
, NULL
, NULL
, 0, NULL
, NULL
, NULL
, NULL
);
3060 TALLOC_FREE(subreq
);
3061 if (!NT_STATUS_IS_OK(status
)) {
3062 tevent_req_nterror(req
, status
);
3065 cli_state_set_tid(state
->cli
, UINT16_MAX
);
3066 tevent_req_done(req
);
3069 static NTSTATUS
cli_tdis_recv(struct tevent_req
*req
)
3071 return tevent_req_simple_recv_ntstatus(req
);
3074 NTSTATUS
cli_tdis(struct cli_state
*cli
)
3076 struct tevent_context
*ev
;
3077 struct tevent_req
*req
;
3078 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
3080 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
3081 return smb2cli_tdis(cli
->conn
,
3087 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
3088 return NT_STATUS_INVALID_PARAMETER
;
3090 ev
= samba_tevent_context_init(talloc_tos());
3094 req
= cli_tdis_send(ev
, ev
, cli
);
3098 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
3101 status
= cli_tdis_recv(req
);
3107 struct cli_connect_sock_state
{
3108 const char **called_names
;
3109 const char **calling_names
;
3115 static void cli_connect_sock_done(struct tevent_req
*subreq
);
3118 * Async only if we don't have to look up the name, i.e. "pss" is set with a
3122 static struct tevent_req
*cli_connect_sock_send(
3123 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
3124 const char *host
, int name_type
, const struct sockaddr_storage
*pss
,
3125 const char *myname
, uint16_t port
)
3127 struct tevent_req
*req
, *subreq
;
3128 struct cli_connect_sock_state
*state
;
3130 struct sockaddr_storage
*addrs
;
3131 unsigned i
, num_addrs
;
3134 req
= tevent_req_create(mem_ctx
, &state
,
3135 struct cli_connect_sock_state
);
3140 prog
= getenv("LIBSMB_PROG");
3142 state
->fd
= sock_exec(prog
);
3143 if (state
->fd
== -1) {
3144 status
= map_nt_error_from_unix(errno
);
3145 tevent_req_nterror(req
, status
);
3148 tevent_req_done(req
);
3150 return tevent_req_post(req
, ev
);
3153 if ((pss
== NULL
) || is_zero_addr(pss
)) {
3156 * Here we cheat. resolve_name_list is not async at all. So
3157 * this call will only be really async if the name lookup has
3158 * been done externally.
3161 status
= resolve_name_list(state
, host
, name_type
,
3162 &addrs
, &num_addrs
);
3163 if (!NT_STATUS_IS_OK(status
)) {
3164 tevent_req_nterror(req
, status
);
3165 return tevent_req_post(req
, ev
);
3168 addrs
= talloc_array(state
, struct sockaddr_storage
, 1);
3169 if (tevent_req_nomem(addrs
, req
)) {
3170 return tevent_req_post(req
, ev
);
3176 state
->called_names
= talloc_array(state
, const char *, num_addrs
);
3177 if (tevent_req_nomem(state
->called_names
, req
)) {
3178 return tevent_req_post(req
, ev
);
3180 state
->called_types
= talloc_array(state
, int, num_addrs
);
3181 if (tevent_req_nomem(state
->called_types
, req
)) {
3182 return tevent_req_post(req
, ev
);
3184 state
->calling_names
= talloc_array(state
, const char *, num_addrs
);
3185 if (tevent_req_nomem(state
->calling_names
, req
)) {
3186 return tevent_req_post(req
, ev
);
3188 for (i
=0; i
<num_addrs
; i
++) {
3189 state
->called_names
[i
] = host
;
3190 state
->called_types
[i
] = name_type
;
3191 state
->calling_names
[i
] = myname
;
3194 subreq
= smbsock_any_connect_send(
3195 state
, ev
, addrs
, state
->called_names
, state
->called_types
,
3196 state
->calling_names
, NULL
, num_addrs
, port
);
3197 if (tevent_req_nomem(subreq
, req
)) {
3198 return tevent_req_post(req
, ev
);
3200 tevent_req_set_callback(subreq
, cli_connect_sock_done
, req
);
3204 static void cli_connect_sock_done(struct tevent_req
*subreq
)
3206 struct tevent_req
*req
= tevent_req_callback_data(
3207 subreq
, struct tevent_req
);
3208 struct cli_connect_sock_state
*state
= tevent_req_data(
3209 req
, struct cli_connect_sock_state
);
3212 status
= smbsock_any_connect_recv(subreq
, &state
->fd
, NULL
,
3214 TALLOC_FREE(subreq
);
3215 if (tevent_req_nterror(req
, status
)) {
3218 set_socket_options(state
->fd
, lp_socket_options());
3219 tevent_req_done(req
);
3222 static NTSTATUS
cli_connect_sock_recv(struct tevent_req
*req
,
3223 int *pfd
, uint16_t *pport
)
3225 struct cli_connect_sock_state
*state
= tevent_req_data(
3226 req
, struct cli_connect_sock_state
);
3229 if (tevent_req_is_nterror(req
, &status
)) {
3233 *pport
= state
->port
;
3234 return NT_STATUS_OK
;
3237 struct cli_connect_nb_state
{
3238 const char *desthost
;
3241 struct cli_state
*cli
;
3244 static void cli_connect_nb_done(struct tevent_req
*subreq
);
3246 static struct tevent_req
*cli_connect_nb_send(
3247 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
3248 const char *host
, const struct sockaddr_storage
*dest_ss
,
3249 uint16_t port
, int name_type
, const char *myname
,
3250 int signing_state
, int flags
)
3252 struct tevent_req
*req
, *subreq
;
3253 struct cli_connect_nb_state
*state
;
3255 req
= tevent_req_create(mem_ctx
, &state
, struct cli_connect_nb_state
);
3259 state
->signing_state
= signing_state
;
3260 state
->flags
= flags
;
3263 char *p
= strchr(host
, '#');
3266 name_type
= strtol(p
+1, NULL
, 16);
3267 host
= talloc_strndup(state
, host
, p
- host
);
3268 if (tevent_req_nomem(host
, req
)) {
3269 return tevent_req_post(req
, ev
);
3273 state
->desthost
= host
;
3274 } else if (dest_ss
!= NULL
) {
3275 state
->desthost
= print_canonical_sockaddr(state
, dest_ss
);
3276 if (tevent_req_nomem(state
->desthost
, req
)) {
3277 return tevent_req_post(req
, ev
);
3280 /* No host or dest_ss given. Error out. */
3281 tevent_req_error(req
, EINVAL
);
3282 return tevent_req_post(req
, ev
);
3285 subreq
= cli_connect_sock_send(state
, ev
, host
, name_type
, dest_ss
,
3287 if (tevent_req_nomem(subreq
, req
)) {
3288 return tevent_req_post(req
, ev
);
3290 tevent_req_set_callback(subreq
, cli_connect_nb_done
, req
);
3294 static void cli_connect_nb_done(struct tevent_req
*subreq
)
3296 struct tevent_req
*req
= tevent_req_callback_data(
3297 subreq
, struct tevent_req
);
3298 struct cli_connect_nb_state
*state
= tevent_req_data(
3299 req
, struct cli_connect_nb_state
);
3304 status
= cli_connect_sock_recv(subreq
, &fd
, &port
);
3305 TALLOC_FREE(subreq
);
3306 if (tevent_req_nterror(req
, status
)) {
3310 state
->cli
= cli_state_create(state
, fd
, state
->desthost
, NULL
,
3311 state
->signing_state
, state
->flags
);
3312 if (tevent_req_nomem(state
->cli
, req
)) {
3316 tevent_req_done(req
);
3319 static NTSTATUS
cli_connect_nb_recv(struct tevent_req
*req
,
3320 struct cli_state
**pcli
)
3322 struct cli_connect_nb_state
*state
= tevent_req_data(
3323 req
, struct cli_connect_nb_state
);
3326 if (tevent_req_is_nterror(req
, &status
)) {
3329 *pcli
= talloc_move(NULL
, &state
->cli
);
3330 return NT_STATUS_OK
;
3333 NTSTATUS
cli_connect_nb(const char *host
, const struct sockaddr_storage
*dest_ss
,
3334 uint16_t port
, int name_type
, const char *myname
,
3335 int signing_state
, int flags
, struct cli_state
**pcli
)
3337 struct tevent_context
*ev
;
3338 struct tevent_req
*req
;
3339 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
3341 ev
= samba_tevent_context_init(talloc_tos());
3345 req
= cli_connect_nb_send(ev
, ev
, host
, dest_ss
, port
, name_type
,
3346 myname
, signing_state
, flags
);
3350 if (!tevent_req_set_endtime(req
, ev
, timeval_current_ofs(20, 0))) {
3353 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
3356 status
= cli_connect_nb_recv(req
, pcli
);
3362 struct cli_start_connection_state
{
3363 struct tevent_context
*ev
;
3364 struct cli_state
*cli
;
3369 static void cli_start_connection_connected(struct tevent_req
*subreq
);
3370 static void cli_start_connection_done(struct tevent_req
*subreq
);
3373 establishes a connection to after the negprot.
3374 @param output_cli A fully initialised cli structure, non-null only on success
3375 @param dest_host The netbios name of the remote host
3376 @param dest_ss (optional) The the destination IP, NULL for name based lookup
3377 @param port (optional) The destination port (0 for default)
3380 static struct tevent_req
*cli_start_connection_send(
3381 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
3382 const char *my_name
, const char *dest_host
,
3383 const struct sockaddr_storage
*dest_ss
, int port
,
3384 int signing_state
, int flags
)
3386 struct tevent_req
*req
, *subreq
;
3387 struct cli_start_connection_state
*state
;
3389 req
= tevent_req_create(mem_ctx
, &state
,
3390 struct cli_start_connection_state
);
3396 if (signing_state
== SMB_SIGNING_IPC_DEFAULT
) {
3397 state
->min_protocol
= lp_client_ipc_min_protocol();
3398 state
->max_protocol
= lp_client_ipc_max_protocol();
3400 state
->min_protocol
= lp_client_min_protocol();
3401 state
->max_protocol
= lp_client_max_protocol();
3404 subreq
= cli_connect_nb_send(state
, ev
, dest_host
, dest_ss
, port
,
3405 0x20, my_name
, signing_state
, flags
);
3406 if (tevent_req_nomem(subreq
, req
)) {
3407 return tevent_req_post(req
, ev
);
3409 tevent_req_set_callback(subreq
, cli_start_connection_connected
, req
);
3413 static void cli_start_connection_connected(struct tevent_req
*subreq
)
3415 struct tevent_req
*req
= tevent_req_callback_data(
3416 subreq
, struct tevent_req
);
3417 struct cli_start_connection_state
*state
= tevent_req_data(
3418 req
, struct cli_start_connection_state
);
3421 status
= cli_connect_nb_recv(subreq
, &state
->cli
);
3422 TALLOC_FREE(subreq
);
3423 if (tevent_req_nterror(req
, status
)) {
3427 subreq
= smbXcli_negprot_send(state
, state
->ev
, state
->cli
->conn
,
3428 state
->cli
->timeout
,
3429 state
->min_protocol
,
3430 state
->max_protocol
);
3431 if (tevent_req_nomem(subreq
, req
)) {
3434 tevent_req_set_callback(subreq
, cli_start_connection_done
, req
);
3437 static void cli_start_connection_done(struct tevent_req
*subreq
)
3439 struct tevent_req
*req
= tevent_req_callback_data(
3440 subreq
, struct tevent_req
);
3441 struct cli_start_connection_state
*state
= tevent_req_data(
3442 req
, struct cli_start_connection_state
);
3445 status
= smbXcli_negprot_recv(subreq
);
3446 TALLOC_FREE(subreq
);
3447 if (tevent_req_nterror(req
, status
)) {
3451 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
3452 /* Ensure we ask for some initial credits. */
3453 smb2cli_conn_set_max_credits(state
->cli
->conn
,
3454 DEFAULT_SMB2_MAX_CREDITS
);
3457 tevent_req_done(req
);
3460 static NTSTATUS
cli_start_connection_recv(struct tevent_req
*req
,
3461 struct cli_state
**output_cli
)
3463 struct cli_start_connection_state
*state
= tevent_req_data(
3464 req
, struct cli_start_connection_state
);
3467 if (tevent_req_is_nterror(req
, &status
)) {
3470 *output_cli
= state
->cli
;
3472 return NT_STATUS_OK
;
3475 NTSTATUS
cli_start_connection(struct cli_state
**output_cli
,
3476 const char *my_name
,
3477 const char *dest_host
,
3478 const struct sockaddr_storage
*dest_ss
, int port
,
3479 int signing_state
, int flags
)
3481 struct tevent_context
*ev
;
3482 struct tevent_req
*req
;
3483 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
3485 ev
= samba_tevent_context_init(talloc_tos());
3489 req
= cli_start_connection_send(ev
, ev
, my_name
, dest_host
, dest_ss
,
3490 port
, signing_state
, flags
);
3494 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
3497 status
= cli_start_connection_recv(req
, output_cli
);
3504 establishes a connection right up to doing tconX, password specified.
3505 @param output_cli A fully initialised cli structure, non-null only on success
3506 @param dest_host The netbios name of the remote host
3507 @param dest_ip (optional) The the destination IP, NULL for name based lookup
3508 @param port (optional) The destination port (0 for default)
3509 @param service (optional) The share to make the connection to. Should be 'unqualified' in any way.
3510 @param service_type The 'type' of serivice.
3511 @param user Username, unix string
3512 @param domain User's domain
3513 @param password User's password, unencrypted unix string.
3516 struct cli_full_connection_state
{
3517 struct tevent_context
*ev
;
3518 const char *service
;
3519 const char *service_type
;
3522 const char *password
;
3525 struct cli_state
*cli
;
3528 static int cli_full_connection_state_destructor(
3529 struct cli_full_connection_state
*s
);
3530 static void cli_full_connection_started(struct tevent_req
*subreq
);
3531 static void cli_full_connection_sess_set_up(struct tevent_req
*subreq
);
3532 static void cli_full_connection_done(struct tevent_req
*subreq
);
3534 struct tevent_req
*cli_full_connection_send(
3535 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
3536 const char *my_name
, const char *dest_host
,
3537 const struct sockaddr_storage
*dest_ss
, int port
,
3538 const char *service
, const char *service_type
,
3539 const char *user
, const char *domain
,
3540 const char *password
, int flags
, int signing_state
)
3542 struct tevent_req
*req
, *subreq
;
3543 struct cli_full_connection_state
*state
;
3545 req
= tevent_req_create(mem_ctx
, &state
,
3546 struct cli_full_connection_state
);
3550 talloc_set_destructor(state
, cli_full_connection_state_destructor
);
3553 state
->service
= service
;
3554 state
->service_type
= service_type
;
3556 state
->domain
= domain
;
3557 state
->password
= password
;
3558 state
->flags
= flags
;
3560 state
->pw_len
= state
->password
? strlen(state
->password
)+1 : 0;
3561 if (state
->password
== NULL
) {
3562 state
->password
= "";
3565 subreq
= cli_start_connection_send(
3566 state
, ev
, my_name
, dest_host
, dest_ss
, port
,
3567 signing_state
, flags
);
3568 if (tevent_req_nomem(subreq
, req
)) {
3569 return tevent_req_post(req
, ev
);
3571 tevent_req_set_callback(subreq
, cli_full_connection_started
, req
);
3575 static int cli_full_connection_state_destructor(
3576 struct cli_full_connection_state
*s
)
3578 if (s
->cli
!= NULL
) {
3579 cli_shutdown(s
->cli
);
3585 static void cli_full_connection_started(struct tevent_req
*subreq
)
3587 struct tevent_req
*req
= tevent_req_callback_data(
3588 subreq
, struct tevent_req
);
3589 struct cli_full_connection_state
*state
= tevent_req_data(
3590 req
, struct cli_full_connection_state
);
3593 status
= cli_start_connection_recv(subreq
, &state
->cli
);
3594 TALLOC_FREE(subreq
);
3595 if (tevent_req_nterror(req
, status
)) {
3598 subreq
= cli_session_setup_send(
3599 state
, state
->ev
, state
->cli
, state
->user
,
3600 state
->password
, state
->domain
);
3601 if (tevent_req_nomem(subreq
, req
)) {
3604 tevent_req_set_callback(subreq
, cli_full_connection_sess_set_up
, req
);
3607 static void cli_full_connection_sess_set_up(struct tevent_req
*subreq
)
3609 struct tevent_req
*req
= tevent_req_callback_data(
3610 subreq
, struct tevent_req
);
3611 struct cli_full_connection_state
*state
= tevent_req_data(
3612 req
, struct cli_full_connection_state
);
3615 status
= cli_session_setup_recv(subreq
);
3616 TALLOC_FREE(subreq
);
3618 if (!NT_STATUS_IS_OK(status
) &&
3619 (state
->flags
& CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK
)) {
3621 state
->flags
&= ~CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK
;
3623 subreq
= cli_session_setup_send(
3624 state
, state
->ev
, state
->cli
, "", "",
3626 if (tevent_req_nomem(subreq
, req
)) {
3629 tevent_req_set_callback(
3630 subreq
, cli_full_connection_sess_set_up
, req
);
3634 if (tevent_req_nterror(req
, status
)) {
3638 if (state
->service
!= NULL
) {
3639 subreq
= cli_tree_connect_send(
3640 state
, state
->ev
, state
->cli
,
3641 state
->service
, state
->service_type
,
3642 state
->password
, state
->pw_len
);
3643 if (tevent_req_nomem(subreq
, req
)) {
3646 tevent_req_set_callback(subreq
, cli_full_connection_done
, req
);
3650 tevent_req_done(req
);
3653 static void cli_full_connection_done(struct tevent_req
*subreq
)
3655 struct tevent_req
*req
= tevent_req_callback_data(
3656 subreq
, struct tevent_req
);
3659 status
= cli_tree_connect_recv(subreq
);
3660 TALLOC_FREE(subreq
);
3661 if (tevent_req_nterror(req
, status
)) {
3665 tevent_req_done(req
);
3668 NTSTATUS
cli_full_connection_recv(struct tevent_req
*req
,
3669 struct cli_state
**output_cli
)
3671 struct cli_full_connection_state
*state
= tevent_req_data(
3672 req
, struct cli_full_connection_state
);
3675 if (tevent_req_is_nterror(req
, &status
)) {
3678 *output_cli
= state
->cli
;
3679 talloc_set_destructor(state
, NULL
);
3680 return NT_STATUS_OK
;
3683 NTSTATUS
cli_full_connection(struct cli_state
**output_cli
,
3684 const char *my_name
,
3685 const char *dest_host
,
3686 const struct sockaddr_storage
*dest_ss
, int port
,
3687 const char *service
, const char *service_type
,
3688 const char *user
, const char *domain
,
3689 const char *password
, int flags
,
3692 struct tevent_context
*ev
;
3693 struct tevent_req
*req
;
3694 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
3696 ev
= samba_tevent_context_init(talloc_tos());
3700 req
= cli_full_connection_send(
3701 ev
, ev
, my_name
, dest_host
, dest_ss
, port
, service
,
3702 service_type
, user
, domain
, password
, flags
, signing_state
);
3706 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
3709 status
= cli_full_connection_recv(req
, output_cli
);
3715 /****************************************************************************
3716 Send an old style tcon.
3717 ****************************************************************************/
3718 struct cli_raw_tcon_state
{
3722 static void cli_raw_tcon_done(struct tevent_req
*subreq
);
3724 static struct tevent_req
*cli_raw_tcon_send(
3725 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
3726 const char *service
, const char *pass
, const char *dev
)
3728 struct tevent_req
*req
, *subreq
;
3729 struct cli_raw_tcon_state
*state
;
3732 req
= tevent_req_create(mem_ctx
, &state
, struct cli_raw_tcon_state
);
3737 if (!lp_client_plaintext_auth() && (*pass
)) {
3738 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
3739 " or 'client ntlmv2 auth = yes'\n"));
3740 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
3741 return tevent_req_post(req
, ev
);
3744 bytes
= talloc_array(state
, uint8_t, 0);
3745 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
3746 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
3747 service
, strlen(service
)+1, NULL
);
3748 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
3749 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
3750 pass
, strlen(pass
)+1, NULL
);
3751 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
3752 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
3753 dev
, strlen(dev
)+1, NULL
);
3755 if (tevent_req_nomem(bytes
, req
)) {
3756 return tevent_req_post(req
, ev
);
3759 subreq
= cli_smb_send(state
, ev
, cli
, SMBtcon
, 0, 0, 0, NULL
,
3760 talloc_get_size(bytes
), bytes
);
3761 if (tevent_req_nomem(subreq
, req
)) {
3762 return tevent_req_post(req
, ev
);
3764 tevent_req_set_callback(subreq
, cli_raw_tcon_done
, req
);
3768 static void cli_raw_tcon_done(struct tevent_req
*subreq
)
3770 struct tevent_req
*req
= tevent_req_callback_data(
3771 subreq
, struct tevent_req
);
3772 struct cli_raw_tcon_state
*state
= tevent_req_data(
3773 req
, struct cli_raw_tcon_state
);
3776 status
= cli_smb_recv(subreq
, state
, NULL
, 2, NULL
, &state
->ret_vwv
,
3778 TALLOC_FREE(subreq
);
3779 if (tevent_req_nterror(req
, status
)) {
3782 tevent_req_done(req
);
3785 static NTSTATUS
cli_raw_tcon_recv(struct tevent_req
*req
,
3786 uint16_t *max_xmit
, uint16_t *tid
)
3788 struct cli_raw_tcon_state
*state
= tevent_req_data(
3789 req
, struct cli_raw_tcon_state
);
3792 if (tevent_req_is_nterror(req
, &status
)) {
3795 *max_xmit
= SVAL(state
->ret_vwv
+ 0, 0);
3796 *tid
= SVAL(state
->ret_vwv
+ 1, 0);
3797 return NT_STATUS_OK
;
3800 NTSTATUS
cli_raw_tcon(struct cli_state
*cli
,
3801 const char *service
, const char *pass
, const char *dev
,
3802 uint16_t *max_xmit
, uint16_t *tid
)
3804 struct tevent_context
*ev
;
3805 struct tevent_req
*req
;
3806 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
3808 ev
= samba_tevent_context_init(talloc_tos());
3812 req
= cli_raw_tcon_send(ev
, ev
, cli
, service
, pass
, dev
);
3816 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
3819 status
= cli_raw_tcon_recv(req
, max_xmit
, tid
);
3825 /* Return a cli_state pointing at the IPC$ share for the given server */
3827 struct cli_state
*get_ipc_connect(char *server
,
3828 struct sockaddr_storage
*server_ss
,
3829 const struct user_auth_info
*user_info
)
3831 struct cli_state
*cli
;
3833 uint32_t flags
= CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK
;
3835 if (get_cmdline_auth_info_use_kerberos(user_info
)) {
3836 flags
|= CLI_FULL_CONNECTION_USE_KERBEROS
;
3839 nt_status
= cli_full_connection(&cli
, NULL
, server
, server_ss
, 0, "IPC$", "IPC",
3840 get_cmdline_auth_info_username(user_info
),
3842 get_cmdline_auth_info_password(user_info
),
3844 SMB_SIGNING_DEFAULT
);
3846 if (NT_STATUS_IS_OK(nt_status
)) {
3848 } else if (is_ipaddress(server
)) {
3849 /* windows 9* needs a correct NMB name for connections */
3850 fstring remote_name
;
3852 if (name_status_find("*", 0, 0, server_ss
, remote_name
)) {
3853 cli
= get_ipc_connect(remote_name
, server_ss
, user_info
);
3862 * Given the IP address of a master browser on the network, return its
3863 * workgroup and connect to it.
3865 * This function is provided to allow additional processing beyond what
3866 * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
3867 * browsers and obtain each master browsers' list of domains (in case the
3868 * first master browser is recently on the network and has not yet
3869 * synchronized with other master browsers and therefore does not yet have the
3870 * entire network browse list)
3873 struct cli_state
*get_ipc_connect_master_ip(TALLOC_CTX
*ctx
,
3874 struct sockaddr_storage
*mb_ip
,
3875 const struct user_auth_info
*user_info
,
3876 char **pp_workgroup_out
)
3878 char addr
[INET6_ADDRSTRLEN
];
3880 struct cli_state
*cli
;
3881 struct sockaddr_storage server_ss
;
3883 *pp_workgroup_out
= NULL
;
3885 print_sockaddr(addr
, sizeof(addr
), mb_ip
);
3886 DEBUG(99, ("Looking up name of master browser %s\n",
3890 * Do a name status query to find out the name of the master browser.
3891 * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
3892 * master browser will not respond to a wildcard query (or, at least,
3893 * an NT4 server acting as the domain master browser will not).
3895 * We might be able to use ONLY the query on MSBROWSE, but that's not
3896 * yet been tested with all Windows versions, so until it is, leave
3897 * the original wildcard query as the first choice and fall back to
3898 * MSBROWSE if the wildcard query fails.
3900 if (!name_status_find("*", 0, 0x1d, mb_ip
, name
) &&
3901 !name_status_find(MSBROWSE
, 1, 0x1d, mb_ip
, name
)) {
3903 DEBUG(99, ("Could not retrieve name status for %s\n",
3908 if (!find_master_ip(name
, &server_ss
)) {
3909 DEBUG(99, ("Could not find master ip for %s\n", name
));
3913 *pp_workgroup_out
= talloc_strdup(ctx
, name
);
3915 DEBUG(4, ("found master browser %s, %s\n", name
, addr
));
3917 print_sockaddr(addr
, sizeof(addr
), &server_ss
);
3918 cli
= get_ipc_connect(addr
, &server_ss
, user_info
);
3924 * Return the IP address and workgroup of a master browser on the network, and
3928 struct cli_state
*get_ipc_connect_master_ip_bcast(TALLOC_CTX
*ctx
,
3929 const struct user_auth_info
*user_info
,
3930 char **pp_workgroup_out
)
3932 struct sockaddr_storage
*ip_list
;
3933 struct cli_state
*cli
;
3937 *pp_workgroup_out
= NULL
;
3939 DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
3941 /* Go looking for workgroups by broadcasting on the local network */
3943 status
= name_resolve_bcast(MSBROWSE
, 1, talloc_tos(),
3945 if (!NT_STATUS_IS_OK(status
)) {
3946 DEBUG(99, ("No master browsers responded: %s\n",
3947 nt_errstr(status
)));
3951 for (i
= 0; i
< count
; i
++) {
3952 char addr
[INET6_ADDRSTRLEN
];
3953 print_sockaddr(addr
, sizeof(addr
), &ip_list
[i
]);
3954 DEBUG(99, ("Found master browser %s\n", addr
));
3956 cli
= get_ipc_connect_master_ip(ctx
, &ip_list
[i
],
3957 user_info
, pp_workgroup_out
);