2 Unix SMB/CIFS implementation.
3 client connect/disconnect routines
4 Copyright (C) Andrew Tridgell 1994-1998
5 Copyright (C) Andrew Bartlett 2001-2003
6 Copyright (C) Volker Lendecke 2011
7 Copyright (C) Jeremy Allison 2011
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "libsmb/libsmb.h"
25 #include "auth_info.h"
26 #include "../libcli/auth/libcli_auth.h"
27 #include "../libcli/auth/spnego.h"
29 #include "../auth/ntlmssp/ntlmssp.h"
30 #include "libads/kerberos_proto.h"
32 #include "../lib/util/tevent_ntstatus.h"
33 #include "async_smb.h"
34 #include "libsmb/nmblib.h"
35 #include "librpc/ndr/libndr.h"
36 #include "../libcli/smb/smbXcli_base.h"
39 #define STAR_SMBSERVER "*SMBSERVER"
41 /********************************************************
42 Utility function to ensure we always return at least
43 a valid char * pointer to an empty string for the
44 cli->server_os, cli->server_type and cli->server_domain
46 *******************************************************/
48 static NTSTATUS
smb_bytes_talloc_string(TALLOC_CTX
*mem_ctx
,
55 *destlen
= clistr_pull_talloc(mem_ctx
,
63 return NT_STATUS_NO_MEMORY
;
67 *dest
= talloc_strdup(mem_ctx
, "");
69 return NT_STATUS_NO_MEMORY
;
75 /****************************************************************************
76 Do an old lanman2 style session setup.
77 ****************************************************************************/
79 struct cli_session_setup_lanman2_state
{
80 struct cli_state
*cli
;
85 static void cli_session_setup_lanman2_done(struct tevent_req
*subreq
);
87 static struct tevent_req
*cli_session_setup_lanman2_send(
88 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
89 struct cli_state
*cli
, const char *user
,
90 const char *pass
, size_t passlen
,
91 const char *workgroup
)
93 struct tevent_req
*req
, *subreq
;
94 struct cli_session_setup_lanman2_state
*state
;
95 DATA_BLOB lm_response
= data_blob_null
;
99 uint16_t sec_mode
= smb1cli_conn_server_security_mode(cli
->conn
);
101 req
= tevent_req_create(mem_ctx
, &state
,
102 struct cli_session_setup_lanman2_state
);
111 * if in share level security then don't send a password now
113 if (!(sec_mode
& NEGOTIATE_SECURITY_USER_LEVEL
)) {
118 && (sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
)
121 * Encrypted mode needed, and non encrypted password
124 lm_response
= data_blob(NULL
, 24);
125 if (tevent_req_nomem(lm_response
.data
, req
)) {
126 return tevent_req_post(req
, ev
);
129 if (!SMBencrypt(pass
, smb1cli_conn_server_challenge(cli
->conn
),
130 (uint8_t *)lm_response
.data
)) {
131 DEBUG(1, ("Password is > 14 chars in length, and is "
132 "therefore incompatible with Lanman "
133 "authentication\n"));
134 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
135 return tevent_req_post(req
, ev
);
137 } else if ((sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
)
140 * Encrypted mode needed, and encrypted password
143 lm_response
= data_blob(pass
, passlen
);
144 if (tevent_req_nomem(lm_response
.data
, req
)) {
145 return tevent_req_post(req
, ev
);
147 } else if (passlen
> 0) {
149 size_t converted_size
;
151 * Plaintext mode needed, assume plaintext supplied.
153 buf
= talloc_array(talloc_tos(), uint8_t, 0);
154 buf
= smb_bytes_push_str(buf
, smbXcli_conn_use_unicode(cli
->conn
), pass
, passlen
+1,
156 if (tevent_req_nomem(buf
, req
)) {
157 return tevent_req_post(req
, ev
);
159 lm_response
= data_blob(pass
, passlen
);
161 if (tevent_req_nomem(lm_response
.data
, req
)) {
162 return tevent_req_post(req
, ev
);
166 SCVAL(vwv
+0, 0, 0xff);
169 SSVAL(vwv
+2, 0, CLI_BUFFER_SIZE
);
172 SIVAL(vwv
+5, 0, smb1cli_conn_server_session_key(cli
->conn
));
173 SSVAL(vwv
+7, 0, lm_response
.length
);
175 bytes
= talloc_array(state
, uint8_t, lm_response
.length
);
176 if (tevent_req_nomem(bytes
, req
)) {
177 return tevent_req_post(req
, ev
);
179 if (lm_response
.length
!= 0) {
180 memcpy(bytes
, lm_response
.data
, lm_response
.length
);
182 data_blob_free(&lm_response
);
184 tmp
= talloc_strdup_upper(talloc_tos(), user
);
185 if (tevent_req_nomem(tmp
, req
)) {
186 return tevent_req_post(req
, ev
);
188 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), tmp
, strlen(tmp
)+1,
192 tmp
= talloc_strdup_upper(talloc_tos(), workgroup
);
193 if (tevent_req_nomem(tmp
, req
)) {
194 return tevent_req_post(req
, ev
);
196 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), tmp
, strlen(tmp
)+1,
198 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "Unix", 5, NULL
);
199 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "Samba", 6, NULL
);
201 if (tevent_req_nomem(bytes
, req
)) {
202 return tevent_req_post(req
, ev
);
205 subreq
= cli_smb_send(state
, ev
, cli
, SMBsesssetupX
, 0, 10, vwv
,
206 talloc_get_size(bytes
), bytes
);
207 if (tevent_req_nomem(subreq
, req
)) {
208 return tevent_req_post(req
, ev
);
210 tevent_req_set_callback(subreq
, cli_session_setup_lanman2_done
, req
);
214 static void cli_session_setup_lanman2_done(struct tevent_req
*subreq
)
216 struct tevent_req
*req
= tevent_req_callback_data(
217 subreq
, struct tevent_req
);
218 struct cli_session_setup_lanman2_state
*state
= tevent_req_data(
219 req
, struct cli_session_setup_lanman2_state
);
220 struct cli_state
*cli
= state
->cli
;
231 status
= cli_smb_recv(subreq
, state
, &in
, 3, &wct
, &vwv
,
234 if (!NT_STATUS_IS_OK(status
)) {
235 tevent_req_nterror(req
, status
);
239 inhdr
= in
+ NBT_HDR_SIZE
;
242 cli_state_set_uid(state
->cli
, SVAL(inhdr
, HDR_UID
));
243 cli
->is_guestlogin
= ((SVAL(vwv
+2, 0) & 1) != 0);
245 status
= smb_bytes_talloc_string(cli
,
252 if (!NT_STATUS_IS_OK(status
)) {
253 tevent_req_nterror(req
, status
);
258 status
= smb_bytes_talloc_string(cli
,
265 if (!NT_STATUS_IS_OK(status
)) {
266 tevent_req_nterror(req
, status
);
271 status
= smb_bytes_talloc_string(cli
,
278 if (!NT_STATUS_IS_OK(status
)) {
279 tevent_req_nterror(req
, status
);
284 status
= cli_set_username(cli
, state
->user
);
285 if (tevent_req_nterror(req
, status
)) {
288 tevent_req_done(req
);
291 static NTSTATUS
cli_session_setup_lanman2_recv(struct tevent_req
*req
)
293 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, 13, vwv
,
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 cli
->is_guestlogin
= ((SVAL(vwv
+2, 0) & 1) != 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 status
= cli_set_username(cli
, "");
493 if (!NT_STATUS_IS_OK(status
)) {
494 tevent_req_nterror(req
, status
);
497 tevent_req_done(req
);
500 NTSTATUS
cli_session_setup_guest_recv(struct tevent_req
*req
)
502 return tevent_req_simple_recv_ntstatus(req
);
505 /****************************************************************************
506 Do a NT1 plaintext session setup.
507 ****************************************************************************/
509 struct cli_session_setup_plain_state
{
510 struct cli_state
*cli
;
515 static void cli_session_setup_plain_done(struct tevent_req
*subreq
);
517 static struct tevent_req
*cli_session_setup_plain_send(
518 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
519 struct cli_state
*cli
,
520 const char *user
, const char *pass
, const char *workgroup
)
522 struct tevent_req
*req
, *subreq
;
523 struct cli_session_setup_plain_state
*state
;
529 req
= tevent_req_create(mem_ctx
, &state
,
530 struct cli_session_setup_plain_state
);
538 SCVAL(vwv
+0, 0, 0xff);
541 SSVAL(vwv
+2, 0, CLI_BUFFER_SIZE
);
543 SSVAL(vwv
+4, 0, cli_state_get_vc_num(cli
));
544 SIVAL(vwv
+5, 0, smb1cli_conn_server_session_key(cli
->conn
));
549 SIVAL(vwv
+11, 0, cli_session_setup_capabilities(cli
, 0));
551 bytes
= talloc_array(state
, uint8_t, 0);
552 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), pass
, strlen(pass
)+1,
554 if (tevent_req_nomem(bytes
, req
)) {
555 return tevent_req_post(req
, ev
);
557 SSVAL(vwv
+ (smbXcli_conn_use_unicode(cli
->conn
) ? 8 : 7), 0, passlen
);
559 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
560 user
, strlen(user
)+1, NULL
);
561 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
562 workgroup
, strlen(workgroup
)+1, NULL
);
563 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
566 version
= talloc_asprintf(talloc_tos(), "Samba %s",
567 samba_version_string());
568 if (tevent_req_nomem(version
, req
)){
569 return tevent_req_post(req
, ev
);
571 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
572 version
, strlen(version
)+1, NULL
);
573 TALLOC_FREE(version
);
575 if (tevent_req_nomem(bytes
, req
)) {
576 return tevent_req_post(req
, ev
);
579 subreq
= cli_smb_send(state
, ev
, cli
, SMBsesssetupX
, 0, 13, vwv
,
580 talloc_get_size(bytes
), bytes
);
581 if (tevent_req_nomem(subreq
, req
)) {
582 return tevent_req_post(req
, ev
);
584 tevent_req_set_callback(subreq
, cli_session_setup_plain_done
, req
);
588 static void cli_session_setup_plain_done(struct tevent_req
*subreq
)
590 struct tevent_req
*req
= tevent_req_callback_data(
591 subreq
, struct tevent_req
);
592 struct cli_session_setup_plain_state
*state
= tevent_req_data(
593 req
, struct cli_session_setup_plain_state
);
594 struct cli_state
*cli
= state
->cli
;
605 status
= cli_smb_recv(subreq
, state
, &in
, 3, &wct
, &vwv
,
608 if (tevent_req_nterror(req
, status
)) {
612 inhdr
= in
+ NBT_HDR_SIZE
;
615 cli_state_set_uid(state
->cli
, SVAL(inhdr
, HDR_UID
));
616 cli
->is_guestlogin
= ((SVAL(vwv
+2, 0) & 1) != 0);
618 status
= smb_bytes_talloc_string(cli
,
625 if (!NT_STATUS_IS_OK(status
)) {
626 tevent_req_nterror(req
, status
);
631 status
= smb_bytes_talloc_string(cli
,
638 if (!NT_STATUS_IS_OK(status
)) {
639 tevent_req_nterror(req
, status
);
644 status
= smb_bytes_talloc_string(cli
,
651 if (!NT_STATUS_IS_OK(status
)) {
652 tevent_req_nterror(req
, status
);
657 status
= cli_set_username(cli
, state
->user
);
658 if (tevent_req_nterror(req
, status
)) {
662 tevent_req_done(req
);
665 static NTSTATUS
cli_session_setup_plain_recv(struct tevent_req
*req
)
667 return tevent_req_simple_recv_ntstatus(req
);
670 /****************************************************************************
671 do a NT1 NTLM/LM encrypted session setup - for when extended security
673 @param cli client state to create do session setup on
675 @param pass *either* cleartext password (passlen !=24) or LM response.
676 @param ntpass NT response, implies ntpasslen >=24, implies pass is not clear
677 @param workgroup The user's domain.
678 ****************************************************************************/
680 struct cli_session_setup_nt1_state
{
681 struct cli_state
*cli
;
684 DATA_BLOB session_key
;
688 static void cli_session_setup_nt1_done(struct tevent_req
*subreq
);
690 static struct tevent_req
*cli_session_setup_nt1_send(
691 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
692 struct cli_state
*cli
, const char *user
,
693 const char *pass
, size_t passlen
,
694 const char *ntpass
, size_t ntpasslen
,
695 const char *workgroup
)
697 struct tevent_req
*req
, *subreq
;
698 struct cli_session_setup_nt1_state
*state
;
699 DATA_BLOB lm_response
= data_blob_null
;
700 DATA_BLOB nt_response
= data_blob_null
;
701 DATA_BLOB session_key
= data_blob_null
;
704 char *workgroup_upper
;
706 req
= tevent_req_create(mem_ctx
, &state
,
707 struct cli_session_setup_nt1_state
);
716 /* do nothing - guest login */
717 } else if (passlen
!= 24) {
718 if (lp_client_ntlmv2_auth()) {
719 DATA_BLOB server_chal
;
720 DATA_BLOB names_blob
;
723 data_blob_const(smb1cli_conn_server_challenge(cli
->conn
),
727 * note that the 'workgroup' here is a best
728 * guess - we don't know the server's domain
729 * at this point. Windows clients also don't
732 names_blob
= NTLMv2_generate_names_blob(
733 NULL
, NULL
, workgroup
);
735 if (tevent_req_nomem(names_blob
.data
, req
)) {
736 return tevent_req_post(req
, ev
);
739 if (!SMBNTLMv2encrypt(NULL
, user
, workgroup
, pass
,
740 &server_chal
, &names_blob
,
741 &lm_response
, &nt_response
,
742 NULL
, &session_key
)) {
743 data_blob_free(&names_blob
);
745 req
, NT_STATUS_ACCESS_DENIED
);
746 return tevent_req_post(req
, ev
);
748 data_blob_free(&names_blob
);
752 E_md4hash(pass
, nt_hash
);
755 nt_response
= data_blob_null
;
757 nt_response
= data_blob(NULL
, 24);
758 if (tevent_req_nomem(nt_response
.data
, req
)) {
759 return tevent_req_post(req
, ev
);
762 SMBNTencrypt(pass
, smb1cli_conn_server_challenge(cli
->conn
),
765 /* non encrypted password supplied. Ignore ntpass. */
766 if (lp_client_lanman_auth()) {
768 lm_response
= data_blob(NULL
, 24);
769 if (tevent_req_nomem(lm_response
.data
, req
)) {
770 return tevent_req_post(req
, ev
);
773 if (!SMBencrypt(pass
,
774 smb1cli_conn_server_challenge(cli
->conn
),
777 * Oops, the LM response is
778 * invalid, just put the NT
779 * response there instead
781 data_blob_free(&lm_response
);
782 lm_response
= data_blob(
788 * LM disabled, place NT# in LM field
791 lm_response
= data_blob(
792 nt_response
.data
, nt_response
.length
);
795 if (tevent_req_nomem(lm_response
.data
, req
)) {
796 return tevent_req_post(req
, ev
);
799 session_key
= data_blob(NULL
, 16);
800 if (tevent_req_nomem(session_key
.data
, req
)) {
801 return tevent_req_post(req
, ev
);
804 E_deshash(pass
, session_key
.data
);
805 memset(&session_key
.data
[8], '\0', 8);
807 SMBsesskeygen_ntv1(nt_hash
, session_key
.data
);
811 /* pre-encrypted password supplied. Only used for
812 security=server, can't do
813 signing because we don't have original key */
815 lm_response
= data_blob(pass
, passlen
);
816 if (tevent_req_nomem(lm_response
.data
, req
)) {
817 return tevent_req_post(req
, ev
);
820 nt_response
= data_blob(ntpass
, ntpasslen
);
821 if (tevent_req_nomem(nt_response
.data
, req
)) {
822 return tevent_req_post(req
, ev
);
827 state
->response
= data_blob_talloc(
828 state
, lm_response
.data
, lm_response
.length
);
830 state
->response
= data_blob_talloc(
831 state
, nt_response
.data
, nt_response
.length
);
833 if (tevent_req_nomem(state
->response
.data
, req
)) {
834 return tevent_req_post(req
, ev
);
837 if (session_key
.data
) {
838 state
->session_key
= data_blob_talloc(
839 state
, session_key
.data
, session_key
.length
);
840 if (tevent_req_nomem(state
->session_key
.data
, req
)) {
841 return tevent_req_post(req
, ev
);
844 data_blob_free(&session_key
);
846 SCVAL(vwv
+0, 0, 0xff);
849 SSVAL(vwv
+2, 0, CLI_BUFFER_SIZE
);
851 SSVAL(vwv
+4, 0, cli_state_get_vc_num(cli
));
852 SIVAL(vwv
+5, 0, smb1cli_conn_server_session_key(cli
->conn
));
853 SSVAL(vwv
+7, 0, lm_response
.length
);
854 SSVAL(vwv
+8, 0, nt_response
.length
);
857 SIVAL(vwv
+11, 0, cli_session_setup_capabilities(cli
, 0));
859 bytes
= talloc_array(state
, uint8_t,
860 lm_response
.length
+ nt_response
.length
);
861 if (tevent_req_nomem(bytes
, req
)) {
862 return tevent_req_post(req
, ev
);
864 if (lm_response
.length
!= 0) {
865 memcpy(bytes
, lm_response
.data
, lm_response
.length
);
867 if (nt_response
.length
!= 0) {
868 memcpy(bytes
+ lm_response
.length
,
869 nt_response
.data
, nt_response
.length
);
871 data_blob_free(&lm_response
);
872 data_blob_free(&nt_response
);
874 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
875 user
, strlen(user
)+1, NULL
);
878 * Upper case here might help some NTLMv2 implementations
880 workgroup_upper
= talloc_strdup_upper(talloc_tos(), workgroup
);
881 if (tevent_req_nomem(workgroup_upper
, req
)) {
882 return tevent_req_post(req
, ev
);
884 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
885 workgroup_upper
, strlen(workgroup_upper
)+1,
887 TALLOC_FREE(workgroup_upper
);
889 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "Unix", 5, NULL
);
890 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "Samba", 6, NULL
);
891 if (tevent_req_nomem(bytes
, req
)) {
892 return tevent_req_post(req
, ev
);
895 subreq
= cli_smb_send(state
, ev
, cli
, SMBsesssetupX
, 0, 13, vwv
,
896 talloc_get_size(bytes
), bytes
);
897 if (tevent_req_nomem(subreq
, req
)) {
898 return tevent_req_post(req
, ev
);
900 tevent_req_set_callback(subreq
, cli_session_setup_nt1_done
, req
);
904 static void cli_session_setup_nt1_done(struct tevent_req
*subreq
)
906 struct tevent_req
*req
= tevent_req_callback_data(
907 subreq
, struct tevent_req
);
908 struct cli_session_setup_nt1_state
*state
= tevent_req_data(
909 req
, struct cli_session_setup_nt1_state
);
910 struct cli_state
*cli
= state
->cli
;
921 status
= cli_smb_recv(subreq
, state
, &in
, 3, &wct
, &vwv
,
924 if (!NT_STATUS_IS_OK(status
)) {
925 tevent_req_nterror(req
, status
);
929 inhdr
= in
+ NBT_HDR_SIZE
;
932 cli_state_set_uid(state
->cli
, SVAL(inhdr
, HDR_UID
));
933 cli
->is_guestlogin
= ((SVAL(vwv
+2, 0) & 1) != 0);
935 status
= smb_bytes_talloc_string(cli
,
941 if (!NT_STATUS_IS_OK(status
)) {
942 tevent_req_nterror(req
, status
);
947 status
= smb_bytes_talloc_string(cli
,
953 if (!NT_STATUS_IS_OK(status
)) {
954 tevent_req_nterror(req
, status
);
959 status
= smb_bytes_talloc_string(cli
,
965 if (!NT_STATUS_IS_OK(status
)) {
966 tevent_req_nterror(req
, status
);
971 status
= cli_set_username(cli
, state
->user
);
972 if (tevent_req_nterror(req
, status
)) {
975 if (smb1cli_conn_activate_signing(cli
->conn
, state
->session_key
, state
->response
)
976 && !smb1cli_conn_check_signing(cli
->conn
, (uint8_t *)in
, 1)) {
977 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
980 if (state
->session_key
.data
) {
981 struct smbXcli_session
*session
= state
->cli
->smb1
.session
;
983 status
= smb1cli_session_set_session_key(session
,
985 if (tevent_req_nterror(req
, status
)) {
989 tevent_req_done(req
);
992 static NTSTATUS
cli_session_setup_nt1_recv(struct tevent_req
*req
)
994 return tevent_req_simple_recv_ntstatus(req
);
997 /* The following is calculated from :
999 * (smb_wcnt * 2) = 24 (smb_wcnt == 12 in cli_session_setup_blob_send() )
1000 * (strlen("Unix") + 1 + strlen("Samba") + 1) * 2 = 22 (unicode strings at
1004 #define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22)
1006 struct cli_sesssetup_blob_state
{
1007 struct tevent_context
*ev
;
1008 struct cli_state
*cli
;
1010 uint16_t max_blob_size
;
1014 DATA_BLOB smb2_blob
;
1015 struct iovec
*recv_iov
;
1022 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state
*state
,
1023 struct tevent_req
**psubreq
);
1024 static void cli_sesssetup_blob_done(struct tevent_req
*subreq
);
1026 static struct tevent_req
*cli_sesssetup_blob_send(TALLOC_CTX
*mem_ctx
,
1027 struct tevent_context
*ev
,
1028 struct cli_state
*cli
,
1031 struct tevent_req
*req
, *subreq
;
1032 struct cli_sesssetup_blob_state
*state
;
1033 uint32_t usable_space
;
1035 req
= tevent_req_create(mem_ctx
, &state
,
1036 struct cli_sesssetup_blob_state
);
1044 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
1045 usable_space
= UINT16_MAX
;
1047 usable_space
= cli_state_available_size(cli
,
1048 BASE_SESSSETUP_BLOB_PACKET_SIZE
);
1051 if (usable_space
== 0) {
1052 DEBUG(1, ("cli_session_setup_blob: cli->max_xmit too small "
1053 "(not possible to send %u bytes)\n",
1054 BASE_SESSSETUP_BLOB_PACKET_SIZE
+ 1));
1055 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1056 return tevent_req_post(req
, ev
);
1058 state
->max_blob_size
= MIN(usable_space
, 0xFFFF);
1060 if (!cli_sesssetup_blob_next(state
, &subreq
)) {
1061 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
1062 return tevent_req_post(req
, ev
);
1064 tevent_req_set_callback(subreq
, cli_sesssetup_blob_done
, req
);
1068 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state
*state
,
1069 struct tevent_req
**psubreq
)
1071 struct tevent_req
*subreq
;
1074 thistime
= MIN(state
->blob
.length
, state
->max_blob_size
);
1076 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
1078 state
->smb2_blob
.data
= state
->blob
.data
;
1079 state
->smb2_blob
.length
= thistime
;
1081 state
->blob
.data
+= thistime
;
1082 state
->blob
.length
-= thistime
;
1084 subreq
= smb2cli_session_setup_send(state
, state
->ev
,
1086 state
->cli
->timeout
,
1087 state
->cli
->smb2
.session
,
1089 SMB2_CAP_DFS
, /* in_capabilities */
1091 0, /* in_previous_session_id */
1093 if (subreq
== NULL
) {
1100 SCVAL(state
->vwv
+0, 0, 0xFF);
1101 SCVAL(state
->vwv
+0, 1, 0);
1102 SSVAL(state
->vwv
+1, 0, 0);
1103 SSVAL(state
->vwv
+2, 0, CLI_BUFFER_SIZE
);
1104 SSVAL(state
->vwv
+3, 0, 2);
1105 SSVAL(state
->vwv
+4, 0, 1);
1106 SIVAL(state
->vwv
+5, 0, 0);
1108 SSVAL(state
->vwv
+7, 0, thistime
);
1110 SSVAL(state
->vwv
+8, 0, 0);
1111 SSVAL(state
->vwv
+9, 0, 0);
1112 SIVAL(state
->vwv
+10, 0,
1113 cli_session_setup_capabilities(state
->cli
, CAP_EXTENDED_SECURITY
));
1115 state
->buf
= (uint8_t *)talloc_memdup(state
, state
->blob
.data
,
1117 if (state
->buf
== NULL
) {
1120 state
->blob
.data
+= thistime
;
1121 state
->blob
.length
-= thistime
;
1123 state
->buf
= smb_bytes_push_str(state
->buf
, smbXcli_conn_use_unicode(state
->cli
->conn
),
1125 state
->buf
= smb_bytes_push_str(state
->buf
, smbXcli_conn_use_unicode(state
->cli
->conn
),
1127 if (state
->buf
== NULL
) {
1130 subreq
= cli_smb_send(state
, state
->ev
, state
->cli
, SMBsesssetupX
, 0,
1132 talloc_get_size(state
->buf
), state
->buf
);
1133 if (subreq
== NULL
) {
1140 static void cli_sesssetup_blob_done(struct tevent_req
*subreq
)
1142 struct tevent_req
*req
= tevent_req_callback_data(
1143 subreq
, struct tevent_req
);
1144 struct cli_sesssetup_blob_state
*state
= tevent_req_data(
1145 req
, struct cli_sesssetup_blob_state
);
1146 struct cli_state
*cli
= state
->cli
;
1153 uint16_t blob_length
;
1158 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
1159 status
= smb2cli_session_setup_recv(subreq
, state
,
1163 status
= cli_smb_recv(subreq
, state
, &in
, 4, &wct
, &vwv
,
1164 &num_bytes
, &bytes
);
1165 TALLOC_FREE(state
->buf
);
1167 TALLOC_FREE(subreq
);
1168 if (!NT_STATUS_IS_OK(status
)
1169 && !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1170 tevent_req_nterror(req
, status
);
1174 state
->status
= status
;
1176 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
1181 inhdr
= in
+ NBT_HDR_SIZE
;
1182 cli_state_set_uid(state
->cli
, SVAL(inhdr
, HDR_UID
));
1183 cli
->is_guestlogin
= ((SVAL(vwv
+2, 0) & 1) != 0);
1185 blob_length
= SVAL(vwv
+3, 0);
1186 if (blob_length
> num_bytes
) {
1187 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
1190 state
->ret_blob
= data_blob_const(bytes
, blob_length
);
1192 p
= bytes
+ blob_length
;
1194 status
= smb_bytes_talloc_string(cli
,
1201 if (!NT_STATUS_IS_OK(status
)) {
1202 tevent_req_nterror(req
, status
);
1207 status
= smb_bytes_talloc_string(cli
,
1214 if (!NT_STATUS_IS_OK(status
)) {
1215 tevent_req_nterror(req
, status
);
1220 status
= smb_bytes_talloc_string(cli
,
1222 &cli
->server_domain
,
1227 if (!NT_STATUS_IS_OK(status
)) {
1228 tevent_req_nterror(req
, status
);
1234 if (state
->blob
.length
!= 0) {
1238 if (!cli_sesssetup_blob_next(state
, &subreq
)) {
1239 tevent_req_oom(req
);
1242 tevent_req_set_callback(subreq
, cli_sesssetup_blob_done
, req
);
1245 tevent_req_done(req
);
1248 static NTSTATUS
cli_sesssetup_blob_recv(struct tevent_req
*req
,
1249 TALLOC_CTX
*mem_ctx
,
1252 struct iovec
**precv_iov
)
1254 struct cli_sesssetup_blob_state
*state
= tevent_req_data(
1255 req
, struct cli_sesssetup_blob_state
);
1258 struct iovec
*recv_iov
;
1260 if (tevent_req_is_nterror(req
, &status
)) {
1261 TALLOC_FREE(state
->cli
->smb2
.session
);
1262 cli_state_set_uid(state
->cli
, UID_FIELD_INVALID
);
1266 inbuf
= talloc_move(mem_ctx
, &state
->inbuf
);
1267 recv_iov
= talloc_move(mem_ctx
, &state
->recv_iov
);
1268 if (pblob
!= NULL
) {
1269 *pblob
= state
->ret_blob
;
1271 if (pinbuf
!= NULL
) {
1274 if (precv_iov
!= NULL
) {
1275 *precv_iov
= recv_iov
;
1277 /* could be NT_STATUS_MORE_PROCESSING_REQUIRED */
1278 return state
->status
;
1283 /****************************************************************************
1284 Use in-memory credentials cache
1285 ****************************************************************************/
1287 static void use_in_memory_ccache(void) {
1288 setenv(KRB5_ENV_CCNAME
, "MEMORY:cliconnect", 1);
1291 /****************************************************************************
1292 Do a spnego/kerberos encrypted session setup.
1293 ****************************************************************************/
1295 struct cli_session_setup_kerberos_state
{
1296 struct cli_state
*cli
;
1297 DATA_BLOB negTokenTarg
;
1298 DATA_BLOB session_key_krb5
;
1299 ADS_STATUS ads_status
;
1302 static void cli_session_setup_kerberos_done(struct tevent_req
*subreq
);
1304 static struct tevent_req
*cli_session_setup_kerberos_send(
1305 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
1306 const char *principal
)
1308 struct tevent_req
*req
, *subreq
;
1309 struct cli_session_setup_kerberos_state
*state
;
1312 DEBUG(2,("Doing kerberos session setup\n"));
1314 req
= tevent_req_create(mem_ctx
, &state
,
1315 struct cli_session_setup_kerberos_state
);
1320 state
->ads_status
= ADS_SUCCESS
;
1323 * Ok, this is cheating: spnego_gen_krb5_negTokenInit can block if
1324 * we have to acquire a ticket. To be fixed later :-)
1326 rc
= spnego_gen_krb5_negTokenInit(state
, principal
, 0, &state
->negTokenTarg
,
1327 &state
->session_key_krb5
, 0, NULL
, NULL
);
1329 DEBUG(1, ("cli_session_setup_kerberos: "
1330 "spnego_gen_krb5_negTokenInit failed: %s\n",
1331 error_message(rc
)));
1332 state
->ads_status
= ADS_ERROR_KRB5(rc
);
1333 tevent_req_nterror(req
, NT_STATUS_UNSUCCESSFUL
);
1334 return tevent_req_post(req
, ev
);
1338 file_save("negTokenTarg.dat", state
->negTokenTarg
.data
,
1339 state
->negTokenTarg
.length
);
1342 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
1343 state
->cli
->smb2
.session
= smbXcli_session_create(cli
,
1345 if (tevent_req_nomem(state
->cli
->smb2
.session
, req
)) {
1346 return tevent_req_post(req
, ev
);
1350 subreq
= cli_sesssetup_blob_send(state
, ev
, cli
, state
->negTokenTarg
);
1351 if (tevent_req_nomem(subreq
, req
)) {
1352 return tevent_req_post(req
, ev
);
1354 tevent_req_set_callback(subreq
, cli_session_setup_kerberos_done
, req
);
1358 static void cli_session_setup_kerberos_done(struct tevent_req
*subreq
)
1360 struct tevent_req
*req
= tevent_req_callback_data(
1361 subreq
, struct tevent_req
);
1362 struct cli_session_setup_kerberos_state
*state
= tevent_req_data(
1363 req
, struct cli_session_setup_kerberos_state
);
1364 uint8_t *inbuf
= NULL
;
1365 struct iovec
*recv_iov
= NULL
;
1368 status
= cli_sesssetup_blob_recv(subreq
, state
,
1369 NULL
, &inbuf
, &recv_iov
);
1370 TALLOC_FREE(subreq
);
1371 if (!NT_STATUS_IS_OK(status
)) {
1372 tevent_req_nterror(req
, status
);
1376 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
1377 struct smbXcli_session
*session
= state
->cli
->smb2
.session
;
1378 status
= smb2cli_session_set_session_key(session
,
1379 state
->session_key_krb5
,
1381 if (tevent_req_nterror(req
, status
)) {
1385 struct smbXcli_session
*session
= state
->cli
->smb1
.session
;
1387 status
= smb1cli_session_set_session_key(session
,
1388 state
->session_key_krb5
);
1389 if (tevent_req_nterror(req
, status
)) {
1393 if (smb1cli_conn_activate_signing(state
->cli
->conn
, state
->session_key_krb5
,
1395 && !smb1cli_conn_check_signing(state
->cli
->conn
, inbuf
, 1)) {
1396 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1401 tevent_req_done(req
);
1404 static ADS_STATUS
cli_session_setup_kerberos_recv(struct tevent_req
*req
)
1406 struct cli_session_setup_kerberos_state
*state
= tevent_req_data(
1407 req
, struct cli_session_setup_kerberos_state
);
1410 if (tevent_req_is_nterror(req
, &status
)) {
1411 return ADS_ERROR_NT(status
);
1413 return state
->ads_status
;
1416 #endif /* HAVE_KRB5 */
1418 /****************************************************************************
1419 Do a spnego/NTLMSSP encrypted session setup.
1420 ****************************************************************************/
1422 struct cli_session_setup_ntlmssp_state
{
1423 struct tevent_context
*ev
;
1424 struct cli_state
*cli
;
1425 struct ntlmssp_state
*ntlmssp_state
;
1430 static int cli_session_setup_ntlmssp_state_destructor(
1431 struct cli_session_setup_ntlmssp_state
*state
)
1433 if (state
->ntlmssp_state
!= NULL
) {
1434 TALLOC_FREE(state
->ntlmssp_state
);
1439 static void cli_session_setup_ntlmssp_done(struct tevent_req
*req
);
1441 static struct tevent_req
*cli_session_setup_ntlmssp_send(
1442 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
1443 const char *user
, const char *pass
, const char *domain
)
1445 struct tevent_req
*req
, *subreq
;
1446 struct cli_session_setup_ntlmssp_state
*state
;
1449 const char *OIDs_ntlm
[] = {OID_NTLMSSP
, NULL
};
1451 req
= tevent_req_create(mem_ctx
, &state
,
1452 struct cli_session_setup_ntlmssp_state
);
1460 state
->ntlmssp_state
= NULL
;
1461 talloc_set_destructor(
1462 state
, cli_session_setup_ntlmssp_state_destructor
);
1464 status
= ntlmssp_client_start(state
,
1467 lp_client_ntlmv2_auth(),
1468 &state
->ntlmssp_state
);
1469 if (!NT_STATUS_IS_OK(status
)) {
1472 ntlmssp_want_feature(state
->ntlmssp_state
,
1473 NTLMSSP_FEATURE_SESSION_KEY
);
1474 if (cli
->use_ccache
) {
1475 ntlmssp_want_feature(state
->ntlmssp_state
,
1476 NTLMSSP_FEATURE_CCACHE
);
1478 status
= ntlmssp_set_username(state
->ntlmssp_state
, user
);
1479 if (!NT_STATUS_IS_OK(status
)) {
1482 status
= ntlmssp_set_domain(state
->ntlmssp_state
, domain
);
1483 if (!NT_STATUS_IS_OK(status
)) {
1486 if (cli
->pw_nt_hash
) {
1487 status
= ntlmssp_set_password_hash(state
->ntlmssp_state
, pass
);
1489 status
= ntlmssp_set_password(state
->ntlmssp_state
, pass
);
1491 if (!NT_STATUS_IS_OK(status
)) {
1494 status
= ntlmssp_update(state
->ntlmssp_state
, data_blob_null
,
1496 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1500 state
->blob_out
= spnego_gen_negTokenInit(state
, OIDs_ntlm
, &blob_out
, NULL
);
1501 data_blob_free(&blob_out
);
1503 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
1504 state
->cli
->smb2
.session
= smbXcli_session_create(cli
,
1506 if (tevent_req_nomem(state
->cli
->smb2
.session
, req
)) {
1507 return tevent_req_post(req
, ev
);
1511 subreq
= cli_sesssetup_blob_send(state
, ev
, cli
, state
->blob_out
);
1512 if (tevent_req_nomem(subreq
, req
)) {
1513 return tevent_req_post(req
, ev
);
1515 tevent_req_set_callback(subreq
, cli_session_setup_ntlmssp_done
, req
);
1518 tevent_req_nterror(req
, status
);
1519 return tevent_req_post(req
, ev
);
1522 static void cli_session_setup_ntlmssp_done(struct tevent_req
*subreq
)
1524 struct tevent_req
*req
= tevent_req_callback_data(
1525 subreq
, struct tevent_req
);
1526 struct cli_session_setup_ntlmssp_state
*state
= tevent_req_data(
1527 req
, struct cli_session_setup_ntlmssp_state
);
1528 DATA_BLOB blob_in
, msg_in
, blob_out
;
1529 uint8_t *inbuf
= NULL
;
1530 struct iovec
*recv_iov
= NULL
;
1534 status
= cli_sesssetup_blob_recv(subreq
, talloc_tos(), &blob_in
,
1536 TALLOC_FREE(subreq
);
1537 data_blob_free(&state
->blob_out
);
1539 if (NT_STATUS_IS_OK(status
)) {
1540 if (state
->cli
->server_domain
[0] == '\0') {
1541 TALLOC_FREE(state
->cli
->server_domain
);
1542 state
->cli
->server_domain
= talloc_strdup(state
->cli
,
1543 state
->ntlmssp_state
->server
.netbios_domain
);
1544 if (state
->cli
->server_domain
== NULL
) {
1545 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
1550 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
1551 struct smbXcli_session
*session
= state
->cli
->smb2
.session
;
1553 if (ntlmssp_is_anonymous(state
->ntlmssp_state
)) {
1555 * Windows server does not set the
1556 * SMB2_SESSION_FLAG_IS_GUEST nor
1557 * SMB2_SESSION_FLAG_IS_NULL flag.
1559 * This fix makes sure we do not try
1560 * to verify a signature on the final
1561 * session setup response.
1563 TALLOC_FREE(state
->ntlmssp_state
);
1564 tevent_req_done(req
);
1568 status
= smb2cli_session_set_session_key(session
,
1569 state
->ntlmssp_state
->session_key
,
1571 if (tevent_req_nterror(req
, status
)) {
1575 struct smbXcli_session
*session
= state
->cli
->smb1
.session
;
1577 status
= smb1cli_session_set_session_key(session
,
1578 state
->ntlmssp_state
->session_key
);
1579 if (tevent_req_nterror(req
, status
)) {
1583 if (smb1cli_conn_activate_signing(
1584 state
->cli
->conn
, state
->ntlmssp_state
->session_key
,
1586 && !smb1cli_conn_check_signing(state
->cli
->conn
, inbuf
, 1)) {
1587 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1591 TALLOC_FREE(state
->ntlmssp_state
);
1592 tevent_req_done(req
);
1595 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1596 tevent_req_nterror(req
, status
);
1600 if (blob_in
.length
== 0) {
1601 tevent_req_nterror(req
, NT_STATUS_UNSUCCESSFUL
);
1605 if ((state
->turn
== 1)
1606 && NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1607 DATA_BLOB tmp_blob
= data_blob_null
;
1608 /* the server might give us back two challenges */
1609 parse_ret
= spnego_parse_challenge(state
, blob_in
, &msg_in
,
1611 data_blob_free(&tmp_blob
);
1613 parse_ret
= spnego_parse_auth_response(state
, blob_in
, status
,
1614 OID_NTLMSSP
, &msg_in
);
1619 DEBUG(3,("Failed to parse auth response\n"));
1620 if (NT_STATUS_IS_OK(status
)
1621 || NT_STATUS_EQUAL(status
,
1622 NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1624 req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
1629 status
= ntlmssp_update(state
->ntlmssp_state
, msg_in
, &blob_out
);
1631 if (!NT_STATUS_IS_OK(status
)
1632 && !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1633 TALLOC_FREE(state
->ntlmssp_state
);
1634 tevent_req_nterror(req
, status
);
1638 state
->blob_out
= spnego_gen_auth(state
, blob_out
);
1639 if (tevent_req_nomem(state
->blob_out
.data
, req
)) {
1643 subreq
= cli_sesssetup_blob_send(state
, state
->ev
, state
->cli
,
1645 if (tevent_req_nomem(subreq
, req
)) {
1648 tevent_req_set_callback(subreq
, cli_session_setup_ntlmssp_done
, req
);
1651 static NTSTATUS
cli_session_setup_ntlmssp_recv(struct tevent_req
*req
)
1653 struct cli_session_setup_ntlmssp_state
*state
= tevent_req_data(
1654 req
, struct cli_session_setup_ntlmssp_state
);
1657 if (tevent_req_is_nterror(req
, &status
)) {
1658 cli_state_set_uid(state
->cli
, UID_FIELD_INVALID
);
1661 return NT_STATUS_OK
;
1666 static char *cli_session_setup_get_principal(
1667 TALLOC_CTX
*mem_ctx
, const char *spnego_principal
,
1668 const char *remote_name
, const char *dest_realm
)
1670 char *principal
= NULL
;
1672 if (!lp_client_use_spnego_principal() ||
1673 strequal(principal
, ADS_IGNORE_PRINCIPAL
)) {
1674 spnego_principal
= NULL
;
1676 if (spnego_principal
!= NULL
) {
1677 DEBUG(3, ("cli_session_setup_spnego: using spnego provided "
1678 "principal %s\n", spnego_principal
));
1679 return talloc_strdup(mem_ctx
, spnego_principal
);
1681 if (is_ipaddress(remote_name
) ||
1682 strequal(remote_name
, STAR_SMBSERVER
)) {
1686 DEBUG(3, ("cli_session_setup_spnego: using target "
1687 "hostname not SPNEGO principal\n"));
1690 char *realm
= strupper_talloc(talloc_tos(), dest_realm
);
1691 if (realm
== NULL
) {
1694 principal
= talloc_asprintf(talloc_tos(), "cifs/%s@%s",
1695 remote_name
, realm
);
1698 principal
= kerberos_get_principal_from_service_hostname(
1699 talloc_tos(), "cifs", remote_name
, lp_realm());
1701 DEBUG(3, ("cli_session_setup_spnego: guessed server principal=%s\n",
1702 principal
? principal
: "<null>"));
1708 static char *cli_session_setup_get_account(TALLOC_CTX
*mem_ctx
,
1709 const char *principal
)
1713 account
= talloc_strdup(mem_ctx
, principal
);
1714 if (account
== NULL
) {
1717 p
= strchr_m(account
, '@');
1724 /****************************************************************************
1725 Do a spnego encrypted session setup.
1727 user_domain: The shortname of the domain the user/machine is a member of.
1728 dest_realm: The realm we're connecting to, if NULL we use our default realm.
1729 ****************************************************************************/
1731 struct cli_session_setup_spnego_state
{
1732 struct tevent_context
*ev
;
1733 struct cli_state
*cli
;
1735 const char *account
;
1737 const char *user_domain
;
1738 const char *dest_realm
;
1743 static void cli_session_setup_spnego_done_krb(struct tevent_req
*subreq
);
1746 static void cli_session_setup_spnego_done_ntlmssp(struct tevent_req
*subreq
);
1748 static struct tevent_req
*cli_session_setup_spnego_send(
1749 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
1750 const char *user
, const char *pass
, const char *user_domain
,
1751 const char *dest_realm
)
1753 struct tevent_req
*req
, *subreq
;
1754 struct cli_session_setup_spnego_state
*state
;
1755 char *principal
= NULL
;
1756 char *OIDs
[ASN1_MAX_OIDS
];
1758 const DATA_BLOB
*server_blob
;
1761 req
= tevent_req_create(mem_ctx
, &state
,
1762 struct cli_session_setup_spnego_state
);
1770 state
->user_domain
= user_domain
;
1771 state
->dest_realm
= dest_realm
;
1773 state
->account
= cli_session_setup_get_account(state
, user
);
1774 if (tevent_req_nomem(state
->account
, req
)) {
1775 return tevent_req_post(req
, ev
);
1778 server_blob
= smbXcli_conn_server_gss_blob(cli
->conn
);
1780 DEBUG(3,("Doing spnego session setup (blob length=%lu)\n",
1781 (unsigned long)server_blob
->length
));
1783 /* the server might not even do spnego */
1784 if (server_blob
->length
== 0) {
1785 DEBUG(3,("server didn't supply a full spnego negprot\n"));
1790 file_save("negprot.dat", cli
->secblob
.data
, cli
->secblob
.length
);
1793 /* The server sent us the first part of the SPNEGO exchange in the
1794 * negprot reply. It is WRONG to depend on the principal sent in the
1795 * negprot reply, but right now we do it. If we don't receive one,
1796 * we try to best guess, then fall back to NTLM. */
1797 if (!spnego_parse_negTokenInit(state
, *server_blob
, OIDs
,
1798 &principal
, NULL
) ||
1800 state
->result
= ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
1801 tevent_req_done(req
);
1802 return tevent_req_post(req
, ev
);
1805 /* make sure the server understands kerberos */
1806 for (i
=0;OIDs
[i
];i
++) {
1808 DEBUG(3,("got OID=%s\n", OIDs
[i
]));
1810 DEBUGADD(3,("got OID=%s\n", OIDs
[i
]));
1811 if (strcmp(OIDs
[i
], OID_KERBEROS5_OLD
) == 0 ||
1812 strcmp(OIDs
[i
], OID_KERBEROS5
) == 0) {
1813 cli
->got_kerberos_mechanism
= True
;
1815 talloc_free(OIDs
[i
]);
1818 DEBUG(3,("got principal=%s\n", principal
? principal
: "<null>"));
1820 status
= cli_set_username(cli
, user
);
1821 if (!NT_STATUS_IS_OK(status
)) {
1822 state
->result
= ADS_ERROR_NT(status
);
1823 tevent_req_done(req
);
1824 return tevent_req_post(req
, ev
);
1828 /* If password is set we reauthenticate to kerberos server
1829 * and do not store results */
1831 if (user
&& *user
&& cli
->got_kerberos_mechanism
&& cli
->use_kerberos
) {
1832 const char *remote_name
= smbXcli_conn_remote_name(cli
->conn
);
1835 if (pass
&& *pass
) {
1838 use_in_memory_ccache();
1839 ret
= kerberos_kinit_password(user
, pass
, 0 /* no time correction for now */, NULL
);
1842 TALLOC_FREE(principal
);
1843 DEBUG(0, ("Kinit failed: %s\n", error_message(ret
)));
1844 if (cli
->fallback_after_kerberos
)
1846 state
->result
= ADS_ERROR_KRB5(ret
);
1847 tevent_req_done(req
);
1848 return tevent_req_post(req
, ev
);
1852 tmp
= cli_session_setup_get_principal(
1853 talloc_tos(), principal
, remote_name
, dest_realm
);
1854 TALLOC_FREE(principal
);
1858 subreq
= cli_session_setup_kerberos_send(
1859 state
, ev
, cli
, principal
);
1860 if (tevent_req_nomem(subreq
, req
)) {
1861 return tevent_req_post(req
, ev
);
1863 tevent_req_set_callback(
1864 subreq
, cli_session_setup_spnego_done_krb
,
1872 subreq
= cli_session_setup_ntlmssp_send(
1873 state
, ev
, cli
, state
->account
, pass
, user_domain
);
1874 if (tevent_req_nomem(subreq
, req
)) {
1875 return tevent_req_post(req
, ev
);
1877 tevent_req_set_callback(
1878 subreq
, cli_session_setup_spnego_done_ntlmssp
, req
);
1883 static void cli_session_setup_spnego_done_krb(struct tevent_req
*subreq
)
1885 struct tevent_req
*req
= tevent_req_callback_data(
1886 subreq
, struct tevent_req
);
1887 struct cli_session_setup_spnego_state
*state
= tevent_req_data(
1888 req
, struct cli_session_setup_spnego_state
);
1890 state
->result
= cli_session_setup_kerberos_recv(subreq
);
1891 TALLOC_FREE(subreq
);
1893 if (ADS_ERR_OK(state
->result
) ||
1894 !state
->cli
->fallback_after_kerberos
) {
1895 tevent_req_done(req
);
1899 subreq
= cli_session_setup_ntlmssp_send(
1900 state
, state
->ev
, state
->cli
, state
->account
, state
->pass
,
1901 state
->user_domain
);
1902 if (tevent_req_nomem(subreq
, req
)) {
1905 tevent_req_set_callback(subreq
, cli_session_setup_spnego_done_ntlmssp
,
1910 static void cli_session_setup_spnego_done_ntlmssp(struct tevent_req
*subreq
)
1912 struct tevent_req
*req
= tevent_req_callback_data(
1913 subreq
, struct tevent_req
);
1914 struct cli_session_setup_spnego_state
*state
= tevent_req_data(
1915 req
, struct cli_session_setup_spnego_state
);
1918 status
= cli_session_setup_ntlmssp_recv(subreq
);
1919 TALLOC_FREE(subreq
);
1920 state
->result
= ADS_ERROR_NT(status
);
1921 tevent_req_done(req
);
1924 static ADS_STATUS
cli_session_setup_spnego_recv(struct tevent_req
*req
)
1926 struct cli_session_setup_spnego_state
*state
= tevent_req_data(
1927 req
, struct cli_session_setup_spnego_state
);
1929 return state
->result
;
1932 struct cli_session_setup_state
{
1936 static void cli_session_setup_done_lanman2(struct tevent_req
*subreq
);
1937 static void cli_session_setup_done_spnego(struct tevent_req
*subreq
);
1938 static void cli_session_setup_done_guest(struct tevent_req
*subreq
);
1939 static void cli_session_setup_done_plain(struct tevent_req
*subreq
);
1940 static void cli_session_setup_done_nt1(struct tevent_req
*subreq
);
1942 /****************************************************************************
1943 Send a session setup. The username and workgroup is in UNIX character
1944 format and must be converted to DOS codepage format before sending. If the
1945 password is in plaintext, the same should be done.
1946 ****************************************************************************/
1948 struct tevent_req
*cli_session_setup_send(TALLOC_CTX
*mem_ctx
,
1949 struct tevent_context
*ev
,
1950 struct cli_state
*cli
,
1952 const char *pass
, int passlen
,
1953 const char *ntpass
, int ntpasslen
,
1954 const char *workgroup
)
1956 struct tevent_req
*req
, *subreq
;
1957 struct cli_session_setup_state
*state
;
1960 uint16_t sec_mode
= smb1cli_conn_server_security_mode(cli
->conn
);
1962 req
= tevent_req_create(mem_ctx
, &state
,
1963 struct cli_session_setup_state
);
1969 user2
= talloc_strdup(state
, user
);
1971 user2
= talloc_strdup(state
, "");
1973 if (user2
== NULL
) {
1974 tevent_req_oom(req
);
1975 return tevent_req_post(req
, ev
);
1982 /* allow for workgroups as part of the username */
1983 if ((p
=strchr_m(user2
,'\\')) || (p
=strchr_m(user2
,'/')) ||
1984 (p
=strchr_m(user2
,*lp_winbind_separator()))) {
1987 if (!strupper_m(user2
)) {
1988 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1989 return tevent_req_post(req
, ev
);
1994 if (smbXcli_conn_protocol(cli
->conn
) < PROTOCOL_LANMAN1
) {
1995 tevent_req_done(req
);
1996 return tevent_req_post(req
, ev
);
1999 /* now work out what sort of session setup we are going to
2000 do. I have split this into separate functions to make the
2001 flow a bit easier to understand (tridge) */
2003 /* if its an older server then we have to use the older request format */
2005 if (smbXcli_conn_protocol(cli
->conn
) < PROTOCOL_NT1
) {
2006 if (!lp_client_lanman_auth() && passlen
!= 24 && (*pass
)) {
2007 DEBUG(1, ("Server requested LM password but 'client lanman auth = no'"
2008 " or 'client ntlmv2 auth = yes'\n"));
2009 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
2010 return tevent_req_post(req
, ev
);
2013 if ((sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
) == 0 &&
2014 !lp_client_plaintext_auth() && (*pass
)) {
2015 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
2016 " or 'client ntlmv2 auth = yes'\n"));
2017 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
2018 return tevent_req_post(req
, ev
);
2021 subreq
= cli_session_setup_lanman2_send(
2022 state
, ev
, cli
, user
, pass
, passlen
, workgroup
);
2023 if (tevent_req_nomem(subreq
, req
)) {
2024 return tevent_req_post(req
, ev
);
2026 tevent_req_set_callback(subreq
, cli_session_setup_done_lanman2
,
2031 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
2032 const char *remote_realm
= cli_state_remote_realm(cli
);
2034 subreq
= cli_session_setup_spnego_send(
2035 state
, ev
, cli
, user
, pass
, workgroup
, remote_realm
);
2036 if (tevent_req_nomem(subreq
, req
)) {
2037 return tevent_req_post(req
, ev
);
2039 tevent_req_set_callback(subreq
, cli_session_setup_done_spnego
,
2044 /* if no user is supplied then we have to do an anonymous connection.
2045 passwords are ignored */
2047 if (!user
|| !*user
) {
2048 subreq
= cli_session_setup_guest_send(state
, ev
, cli
);
2049 if (tevent_req_nomem(subreq
, req
)) {
2050 return tevent_req_post(req
, ev
);
2052 tevent_req_set_callback(subreq
, cli_session_setup_done_guest
,
2057 /* if the server is share level then send a plaintext null
2058 password at this point. The password is sent in the tree
2061 if ((sec_mode
& NEGOTIATE_SECURITY_USER_LEVEL
) == 0) {
2062 subreq
= cli_session_setup_plain_send(
2063 state
, ev
, cli
, user
, "", workgroup
);
2064 if (tevent_req_nomem(subreq
, req
)) {
2065 return tevent_req_post(req
, ev
);
2067 tevent_req_set_callback(subreq
, cli_session_setup_done_plain
,
2072 /* if the server doesn't support encryption then we have to use
2073 plaintext. The second password is ignored */
2075 if ((sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
) == 0) {
2076 if (!lp_client_plaintext_auth() && (*pass
)) {
2077 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
2078 " or 'client ntlmv2 auth = yes'\n"));
2079 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
2080 return tevent_req_post(req
, ev
);
2082 subreq
= cli_session_setup_plain_send(
2083 state
, ev
, cli
, user
, pass
, workgroup
);
2084 if (tevent_req_nomem(subreq
, req
)) {
2085 return tevent_req_post(req
, ev
);
2087 tevent_req_set_callback(subreq
, cli_session_setup_done_plain
,
2092 /* if the server supports extended security then use SPNEGO */
2094 if (smb1cli_conn_capabilities(cli
->conn
) & CAP_EXTENDED_SECURITY
) {
2095 const char *remote_realm
= cli_state_remote_realm(cli
);
2097 subreq
= cli_session_setup_spnego_send(
2098 state
, ev
, cli
, user
, pass
, workgroup
, remote_realm
);
2099 if (tevent_req_nomem(subreq
, req
)) {
2100 return tevent_req_post(req
, ev
);
2102 tevent_req_set_callback(subreq
, cli_session_setup_done_spnego
,
2106 /* otherwise do a NT1 style session setup */
2108 subreq
= cli_session_setup_nt1_send(
2109 state
, ev
, cli
, user
, pass
, passlen
, ntpass
, ntpasslen
,
2111 if (tevent_req_nomem(subreq
, req
)) {
2112 return tevent_req_post(req
, ev
);
2114 tevent_req_set_callback(subreq
, cli_session_setup_done_nt1
,
2119 tevent_req_done(req
);
2120 return tevent_req_post(req
, ev
);
2123 static void cli_session_setup_done_lanman2(struct tevent_req
*subreq
)
2125 struct tevent_req
*req
= tevent_req_callback_data(
2126 subreq
, struct tevent_req
);
2129 status
= cli_session_setup_lanman2_recv(subreq
);
2130 TALLOC_FREE(subreq
);
2131 if (!NT_STATUS_IS_OK(status
)) {
2132 tevent_req_nterror(req
, status
);
2135 tevent_req_done(req
);
2138 static void cli_session_setup_done_spnego(struct tevent_req
*subreq
)
2140 struct tevent_req
*req
= tevent_req_callback_data(
2141 subreq
, struct tevent_req
);
2144 status
= cli_session_setup_spnego_recv(subreq
);
2145 TALLOC_FREE(subreq
);
2146 if (!ADS_ERR_OK(status
)) {
2147 DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status
)));
2148 tevent_req_nterror(req
, ads_ntstatus(status
));
2151 tevent_req_done(req
);
2154 static void cli_session_setup_done_guest(struct tevent_req
*subreq
)
2156 struct tevent_req
*req
= tevent_req_callback_data(
2157 subreq
, struct tevent_req
);
2160 status
= cli_session_setup_guest_recv(subreq
);
2161 TALLOC_FREE(subreq
);
2162 if (!NT_STATUS_IS_OK(status
)) {
2163 tevent_req_nterror(req
, status
);
2166 tevent_req_done(req
);
2169 static void cli_session_setup_done_plain(struct tevent_req
*subreq
)
2171 struct tevent_req
*req
= tevent_req_callback_data(
2172 subreq
, struct tevent_req
);
2175 status
= cli_session_setup_plain_recv(subreq
);
2176 TALLOC_FREE(subreq
);
2177 if (!NT_STATUS_IS_OK(status
)) {
2178 tevent_req_nterror(req
, status
);
2181 tevent_req_done(req
);
2184 static void cli_session_setup_done_nt1(struct tevent_req
*subreq
)
2186 struct tevent_req
*req
= tevent_req_callback_data(
2187 subreq
, struct tevent_req
);
2190 status
= cli_session_setup_nt1_recv(subreq
);
2191 TALLOC_FREE(subreq
);
2192 if (!NT_STATUS_IS_OK(status
)) {
2193 DEBUG(3, ("cli_session_setup: NT1 session setup "
2194 "failed: %s\n", nt_errstr(status
)));
2195 tevent_req_nterror(req
, status
);
2198 tevent_req_done(req
);
2201 NTSTATUS
cli_session_setup_recv(struct tevent_req
*req
)
2203 return tevent_req_simple_recv_ntstatus(req
);
2206 NTSTATUS
cli_session_setup(struct cli_state
*cli
,
2208 const char *pass
, int passlen
,
2209 const char *ntpass
, int ntpasslen
,
2210 const char *workgroup
)
2212 struct tevent_context
*ev
;
2213 struct tevent_req
*req
;
2214 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2216 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
2217 return NT_STATUS_INVALID_PARAMETER
;
2219 ev
= samba_tevent_context_init(talloc_tos());
2223 req
= cli_session_setup_send(ev
, ev
, cli
, user
, pass
, passlen
,
2224 ntpass
, ntpasslen
, workgroup
);
2228 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2231 status
= cli_session_setup_recv(req
);
2237 /****************************************************************************
2239 *****************************************************************************/
2241 struct cli_ulogoff_state
{
2242 struct cli_state
*cli
;
2246 static void cli_ulogoff_done(struct tevent_req
*subreq
);
2248 static struct tevent_req
*cli_ulogoff_send(TALLOC_CTX
*mem_ctx
,
2249 struct tevent_context
*ev
,
2250 struct cli_state
*cli
)
2252 struct tevent_req
*req
, *subreq
;
2253 struct cli_ulogoff_state
*state
;
2255 req
= tevent_req_create(mem_ctx
, &state
, struct cli_ulogoff_state
);
2261 SCVAL(state
->vwv
+0, 0, 0xFF);
2262 SCVAL(state
->vwv
+1, 0, 0);
2263 SSVAL(state
->vwv
+2, 0, 0);
2265 subreq
= cli_smb_send(state
, ev
, cli
, SMBulogoffX
, 0, 2, state
->vwv
,
2267 if (tevent_req_nomem(subreq
, req
)) {
2268 return tevent_req_post(req
, ev
);
2270 tevent_req_set_callback(subreq
, cli_ulogoff_done
, req
);
2274 static void cli_ulogoff_done(struct tevent_req
*subreq
)
2276 struct tevent_req
*req
= tevent_req_callback_data(
2277 subreq
, struct tevent_req
);
2278 struct cli_ulogoff_state
*state
= tevent_req_data(
2279 req
, struct cli_ulogoff_state
);
2282 status
= cli_smb_recv(subreq
, NULL
, NULL
, 0, NULL
, NULL
, NULL
, NULL
);
2283 if (!NT_STATUS_IS_OK(status
)) {
2284 tevent_req_nterror(req
, status
);
2287 cli_state_set_uid(state
->cli
, UID_FIELD_INVALID
);
2288 tevent_req_done(req
);
2291 static NTSTATUS
cli_ulogoff_recv(struct tevent_req
*req
)
2293 return tevent_req_simple_recv_ntstatus(req
);
2296 NTSTATUS
cli_ulogoff(struct cli_state
*cli
)
2298 struct tevent_context
*ev
;
2299 struct tevent_req
*req
;
2300 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2302 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
2303 status
= smb2cli_logoff(cli
->conn
,
2306 if (!NT_STATUS_IS_OK(status
)) {
2309 smb2cli_session_set_id_and_flags(cli
->smb2
.session
,
2311 return NT_STATUS_OK
;
2314 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
2315 return NT_STATUS_INVALID_PARAMETER
;
2317 ev
= samba_tevent_context_init(talloc_tos());
2321 req
= cli_ulogoff_send(ev
, ev
, cli
);
2325 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2328 status
= cli_ulogoff_recv(req
);
2334 /****************************************************************************
2336 ****************************************************************************/
2338 struct cli_tcon_andx_state
{
2339 struct cli_state
*cli
;
2344 static void cli_tcon_andx_done(struct tevent_req
*subreq
);
2346 struct tevent_req
*cli_tcon_andx_create(TALLOC_CTX
*mem_ctx
,
2347 struct tevent_context
*ev
,
2348 struct cli_state
*cli
,
2349 const char *share
, const char *dev
,
2350 const char *pass
, int passlen
,
2351 struct tevent_req
**psmbreq
)
2353 struct tevent_req
*req
, *subreq
;
2354 struct cli_tcon_andx_state
*state
;
2359 uint16_t sec_mode
= smb1cli_conn_server_security_mode(cli
->conn
);
2360 uint16_t tcon_flags
= 0;
2364 req
= tevent_req_create(mem_ctx
, &state
, struct cli_tcon_andx_state
);
2371 cli
->share
= talloc_strdup(cli
, share
);
2376 /* in user level security don't send a password now */
2377 if (sec_mode
& NEGOTIATE_SECURITY_USER_LEVEL
) {
2380 } else if (pass
== NULL
) {
2381 DEBUG(1, ("Server not using user level security and no "
2382 "password supplied.\n"));
2386 if ((sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
) &&
2387 *pass
&& passlen
!= 24) {
2388 if (!lp_client_lanman_auth()) {
2389 DEBUG(1, ("Server requested LANMAN password "
2390 "(share-level security) but "
2391 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2396 * Non-encrypted passwords - convert to DOS codepage before
2399 SMBencrypt(pass
, smb1cli_conn_server_challenge(cli
->conn
), p24
);
2401 pass
= (const char *)p24
;
2403 if((sec_mode
& (NEGOTIATE_SECURITY_USER_LEVEL
2404 |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
))
2408 if (!lp_client_plaintext_auth() && (*pass
)) {
2409 DEBUG(1, ("Server requested PLAINTEXT "
2411 "'client plaintext auth = no' or 'client ntlmv2 auth = yes'\n"));
2416 * Non-encrypted passwords - convert to DOS codepage
2419 tmp_pass
= talloc_array(talloc_tos(), uint8
, 0);
2420 if (tevent_req_nomem(tmp_pass
, req
)) {
2421 return tevent_req_post(req
, ev
);
2423 tmp_pass
= trans2_bytes_push_str(tmp_pass
,
2424 false, /* always DOS */
2428 if (tevent_req_nomem(tmp_pass
, req
)) {
2429 return tevent_req_post(req
, ev
);
2431 pass
= (const char *)tmp_pass
;
2432 passlen
= talloc_get_size(tmp_pass
);
2436 tcon_flags
|= TCONX_FLAG_EXTENDED_RESPONSE
;
2437 tcon_flags
|= TCONX_FLAG_EXTENDED_SIGNATURES
;
2439 SCVAL(vwv
+0, 0, 0xFF);
2442 SSVAL(vwv
+2, 0, tcon_flags
);
2443 SSVAL(vwv
+3, 0, passlen
);
2445 if (passlen
&& pass
) {
2446 bytes
= (uint8_t *)talloc_memdup(state
, pass
, passlen
);
2448 bytes
= talloc_array(state
, uint8_t, 0);
2454 tmp
= talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
2455 smbXcli_conn_remote_name(cli
->conn
), share
);
2460 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), tmp
, strlen(tmp
)+1,
2465 * Add the devicetype
2467 tmp
= talloc_strdup_upper(talloc_tos(), dev
);
2472 bytes
= smb_bytes_push_str(bytes
, false, tmp
, strlen(tmp
)+1, NULL
);
2475 if (bytes
== NULL
) {
2480 state
->bytes
.iov_base
= (void *)bytes
;
2481 state
->bytes
.iov_len
= talloc_get_size(bytes
);
2483 subreq
= cli_smb_req_create(state
, ev
, cli
, SMBtconX
, 0, 4, vwv
,
2485 if (subreq
== NULL
) {
2489 tevent_req_set_callback(subreq
, cli_tcon_andx_done
, req
);
2494 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
2495 return tevent_req_post(req
, ev
);
2498 struct tevent_req
*cli_tcon_andx_send(TALLOC_CTX
*mem_ctx
,
2499 struct tevent_context
*ev
,
2500 struct cli_state
*cli
,
2501 const char *share
, const char *dev
,
2502 const char *pass
, int passlen
)
2504 struct tevent_req
*req
, *subreq
;
2507 req
= cli_tcon_andx_create(mem_ctx
, ev
, cli
, share
, dev
, pass
, passlen
,
2512 if (subreq
== NULL
) {
2515 status
= smb1cli_req_chain_submit(&subreq
, 1);
2516 if (!NT_STATUS_IS_OK(status
)) {
2517 tevent_req_nterror(req
, status
);
2518 return tevent_req_post(req
, ev
);
2523 static void cli_tcon_andx_done(struct tevent_req
*subreq
)
2525 struct tevent_req
*req
= tevent_req_callback_data(
2526 subreq
, struct tevent_req
);
2527 struct cli_tcon_andx_state
*state
= tevent_req_data(
2528 req
, struct cli_tcon_andx_state
);
2529 struct cli_state
*cli
= state
->cli
;
2537 uint16_t optional_support
= 0;
2539 status
= cli_smb_recv(subreq
, state
, &in
, 0, &wct
, &vwv
,
2540 &num_bytes
, &bytes
);
2541 TALLOC_FREE(subreq
);
2542 if (!NT_STATUS_IS_OK(status
)) {
2543 tevent_req_nterror(req
, status
);
2547 inhdr
= in
+ NBT_HDR_SIZE
;
2550 if (clistr_pull_talloc(cli
,
2551 (const char *)inhdr
,
2552 SVAL(inhdr
, HDR_FLG2
),
2556 STR_TERMINATE
|STR_ASCII
) == -1) {
2557 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
2561 cli
->dev
= talloc_strdup(cli
, "");
2562 if (cli
->dev
== NULL
) {
2563 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
2568 if ((smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_NT1
) && (num_bytes
== 3)) {
2569 /* almost certainly win95 - enable bug fixes */
2574 * Make sure that we have the optional support 16-bit field. WCT > 2.
2575 * Avoids issues when connecting to Win9x boxes sharing files
2578 if ((wct
> 2) && (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_LANMAN2
)) {
2579 optional_support
= SVAL(vwv
+2, 0);
2582 if (optional_support
& SMB_EXTENDED_SIGNATURES
) {
2583 smb1cli_session_protect_session_key(cli
->smb1
.session
);
2586 smb1cli_tcon_set_values(state
->cli
->smb1
.tcon
,
2587 SVAL(inhdr
, HDR_TID
),
2589 0, /* maximal_access */
2590 0, /* guest_maximal_access */
2592 NULL
); /* fs_type */
2594 tevent_req_done(req
);
2597 NTSTATUS
cli_tcon_andx_recv(struct tevent_req
*req
)
2599 return tevent_req_simple_recv_ntstatus(req
);
2602 NTSTATUS
cli_tcon_andx(struct cli_state
*cli
, const char *share
,
2603 const char *dev
, const char *pass
, int passlen
)
2605 TALLOC_CTX
*frame
= talloc_stackframe();
2606 struct tevent_context
*ev
;
2607 struct tevent_req
*req
;
2608 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2610 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
2612 * Can't use sync call while an async call is in flight
2614 status
= NT_STATUS_INVALID_PARAMETER
;
2618 ev
= samba_tevent_context_init(frame
);
2623 req
= cli_tcon_andx_send(frame
, ev
, cli
, share
, dev
, pass
, passlen
);
2628 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2632 status
= cli_tcon_andx_recv(req
);
2638 struct cli_tree_connect_state
{
2639 struct cli_state
*cli
;
2642 static struct tevent_req
*cli_raw_tcon_send(
2643 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
2644 const char *service
, const char *pass
, const char *dev
);
2645 static NTSTATUS
cli_raw_tcon_recv(struct tevent_req
*req
,
2646 uint16
*max_xmit
, uint16
*tid
);
2648 static void cli_tree_connect_smb2_done(struct tevent_req
*subreq
);
2649 static void cli_tree_connect_andx_done(struct tevent_req
*subreq
);
2650 static void cli_tree_connect_raw_done(struct tevent_req
*subreq
);
2652 static struct tevent_req
*cli_tree_connect_send(
2653 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
2654 const char *share
, const char *dev
, const char *pass
, int passlen
)
2656 struct tevent_req
*req
, *subreq
;
2657 struct cli_tree_connect_state
*state
;
2659 req
= tevent_req_create(mem_ctx
, &state
,
2660 struct cli_tree_connect_state
);
2666 cli
->share
= talloc_strdup(cli
, share
);
2667 if (tevent_req_nomem(cli
->share
, req
)) {
2668 return tevent_req_post(req
, ev
);
2671 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
2672 subreq
= smb2cli_tcon_send(state
, ev
, cli
, share
);
2673 if (tevent_req_nomem(subreq
, req
)) {
2674 return tevent_req_post(req
, ev
);
2676 tevent_req_set_callback(subreq
, cli_tree_connect_smb2_done
,
2681 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_LANMAN1
) {
2682 subreq
= cli_tcon_andx_send(state
, ev
, cli
, share
, dev
,
2684 if (tevent_req_nomem(subreq
, req
)) {
2685 return tevent_req_post(req
, ev
);
2687 tevent_req_set_callback(subreq
, cli_tree_connect_andx_done
,
2692 subreq
= cli_raw_tcon_send(state
, ev
, cli
, share
, pass
, dev
);
2693 if (tevent_req_nomem(subreq
, req
)) {
2694 return tevent_req_post(req
, ev
);
2696 tevent_req_set_callback(subreq
, cli_tree_connect_raw_done
, req
);
2701 static void cli_tree_connect_smb2_done(struct tevent_req
*subreq
)
2703 tevent_req_simple_finish_ntstatus(
2704 subreq
, smb2cli_tcon_recv(subreq
));
2707 static void cli_tree_connect_andx_done(struct tevent_req
*subreq
)
2709 tevent_req_simple_finish_ntstatus(
2710 subreq
, cli_tcon_andx_recv(subreq
));
2713 static void cli_tree_connect_raw_done(struct tevent_req
*subreq
)
2715 struct tevent_req
*req
= tevent_req_callback_data(
2716 subreq
, struct tevent_req
);
2717 struct cli_tree_connect_state
*state
= tevent_req_data(
2718 req
, struct cli_tree_connect_state
);
2720 uint16_t max_xmit
= 0;
2723 status
= cli_raw_tcon_recv(subreq
, &max_xmit
, &tid
);
2724 if (tevent_req_nterror(req
, status
)) {
2728 smb1cli_tcon_set_values(state
->cli
->smb1
.tcon
,
2730 0, /* optional_support */
2731 0, /* maximal_access */
2732 0, /* guest_maximal_access */
2734 NULL
); /* fs_type */
2736 tevent_req_done(req
);
2739 static NTSTATUS
cli_tree_connect_recv(struct tevent_req
*req
)
2741 return tevent_req_simple_recv_ntstatus(req
);
2744 NTSTATUS
cli_tree_connect(struct cli_state
*cli
, const char *share
,
2745 const char *dev
, const char *pass
, int passlen
)
2747 struct tevent_context
*ev
;
2748 struct tevent_req
*req
;
2749 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2751 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
2752 return NT_STATUS_INVALID_PARAMETER
;
2754 ev
= samba_tevent_context_init(talloc_tos());
2758 req
= cli_tree_connect_send(ev
, ev
, cli
, share
, dev
, pass
, passlen
);
2762 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2765 status
= cli_tree_connect_recv(req
);
2771 /****************************************************************************
2772 Send a tree disconnect.
2773 ****************************************************************************/
2775 struct cli_tdis_state
{
2776 struct cli_state
*cli
;
2779 static void cli_tdis_done(struct tevent_req
*subreq
);
2781 static struct tevent_req
*cli_tdis_send(TALLOC_CTX
*mem_ctx
,
2782 struct tevent_context
*ev
,
2783 struct cli_state
*cli
)
2785 struct tevent_req
*req
, *subreq
;
2786 struct cli_tdis_state
*state
;
2788 req
= tevent_req_create(mem_ctx
, &state
, struct cli_tdis_state
);
2794 subreq
= cli_smb_send(state
, ev
, cli
, SMBtdis
, 0, 0, NULL
, 0, NULL
);
2795 if (tevent_req_nomem(subreq
, req
)) {
2796 return tevent_req_post(req
, ev
);
2798 tevent_req_set_callback(subreq
, cli_tdis_done
, req
);
2802 static void cli_tdis_done(struct tevent_req
*subreq
)
2804 struct tevent_req
*req
= tevent_req_callback_data(
2805 subreq
, struct tevent_req
);
2806 struct cli_tdis_state
*state
= tevent_req_data(
2807 req
, struct cli_tdis_state
);
2810 status
= cli_smb_recv(subreq
, NULL
, NULL
, 0, NULL
, NULL
, NULL
, NULL
);
2811 TALLOC_FREE(subreq
);
2812 if (!NT_STATUS_IS_OK(status
)) {
2813 tevent_req_nterror(req
, status
);
2816 cli_state_set_tid(state
->cli
, UINT16_MAX
);
2817 tevent_req_done(req
);
2820 static NTSTATUS
cli_tdis_recv(struct tevent_req
*req
)
2822 return tevent_req_simple_recv_ntstatus(req
);
2825 NTSTATUS
cli_tdis(struct cli_state
*cli
)
2827 struct tevent_context
*ev
;
2828 struct tevent_req
*req
;
2829 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2831 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
2832 return smb2cli_tdis(cli
);
2835 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
2836 return NT_STATUS_INVALID_PARAMETER
;
2838 ev
= samba_tevent_context_init(talloc_tos());
2842 req
= cli_tdis_send(ev
, ev
, cli
);
2846 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2849 status
= cli_tdis_recv(req
);
2855 struct cli_connect_sock_state
{
2856 const char **called_names
;
2857 const char **calling_names
;
2863 static void cli_connect_sock_done(struct tevent_req
*subreq
);
2866 * Async only if we don't have to look up the name, i.e. "pss" is set with a
2870 static struct tevent_req
*cli_connect_sock_send(
2871 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
2872 const char *host
, int name_type
, const struct sockaddr_storage
*pss
,
2873 const char *myname
, uint16_t port
)
2875 struct tevent_req
*req
, *subreq
;
2876 struct cli_connect_sock_state
*state
;
2878 unsigned i
, num_addrs
;
2881 req
= tevent_req_create(mem_ctx
, &state
,
2882 struct cli_connect_sock_state
);
2887 prog
= getenv("LIBSMB_PROG");
2889 state
->fd
= sock_exec(prog
);
2890 if (state
->fd
== -1) {
2891 status
= map_nt_error_from_unix(errno
);
2892 tevent_req_nterror(req
, status
);
2895 tevent_req_done(req
);
2897 return tevent_req_post(req
, ev
);
2900 if ((pss
== NULL
) || is_zero_addr(pss
)) {
2901 struct sockaddr_storage
*addrs
;
2904 * Here we cheat. resolve_name_list is not async at all. So
2905 * this call will only be really async if the name lookup has
2906 * been done externally.
2909 status
= resolve_name_list(state
, host
, name_type
,
2910 &addrs
, &num_addrs
);
2911 if (!NT_STATUS_IS_OK(status
)) {
2912 tevent_req_nterror(req
, status
);
2913 return tevent_req_post(req
, ev
);
2920 state
->called_names
= talloc_array(state
, const char *, num_addrs
);
2921 if (tevent_req_nomem(state
->called_names
, req
)) {
2922 return tevent_req_post(req
, ev
);
2924 state
->called_types
= talloc_array(state
, int, num_addrs
);
2925 if (tevent_req_nomem(state
->called_types
, req
)) {
2926 return tevent_req_post(req
, ev
);
2928 state
->calling_names
= talloc_array(state
, const char *, num_addrs
);
2929 if (tevent_req_nomem(state
->calling_names
, req
)) {
2930 return tevent_req_post(req
, ev
);
2932 for (i
=0; i
<num_addrs
; i
++) {
2933 state
->called_names
[i
] = host
;
2934 state
->called_types
[i
] = name_type
;
2935 state
->calling_names
[i
] = myname
;
2938 subreq
= smbsock_any_connect_send(
2939 state
, ev
, pss
, state
->called_names
, state
->called_types
,
2940 state
->calling_names
, NULL
, num_addrs
, port
);
2941 if (tevent_req_nomem(subreq
, req
)) {
2942 return tevent_req_post(req
, ev
);
2944 tevent_req_set_callback(subreq
, cli_connect_sock_done
, req
);
2948 static void cli_connect_sock_done(struct tevent_req
*subreq
)
2950 struct tevent_req
*req
= tevent_req_callback_data(
2951 subreq
, struct tevent_req
);
2952 struct cli_connect_sock_state
*state
= tevent_req_data(
2953 req
, struct cli_connect_sock_state
);
2956 status
= smbsock_any_connect_recv(subreq
, &state
->fd
, NULL
,
2958 TALLOC_FREE(subreq
);
2959 if (tevent_req_nterror(req
, status
)) {
2962 set_socket_options(state
->fd
, lp_socket_options());
2963 tevent_req_done(req
);
2966 static NTSTATUS
cli_connect_sock_recv(struct tevent_req
*req
,
2967 int *pfd
, uint16_t *pport
)
2969 struct cli_connect_sock_state
*state
= tevent_req_data(
2970 req
, struct cli_connect_sock_state
);
2973 if (tevent_req_is_nterror(req
, &status
)) {
2977 *pport
= state
->port
;
2978 return NT_STATUS_OK
;
2981 struct cli_connect_nb_state
{
2982 const char *desthost
;
2985 struct cli_state
*cli
;
2988 static void cli_connect_nb_done(struct tevent_req
*subreq
);
2990 static struct tevent_req
*cli_connect_nb_send(
2991 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
2992 const char *host
, const struct sockaddr_storage
*dest_ss
,
2993 uint16_t port
, int name_type
, const char *myname
,
2994 int signing_state
, int flags
)
2996 struct tevent_req
*req
, *subreq
;
2997 struct cli_connect_nb_state
*state
;
3000 req
= tevent_req_create(mem_ctx
, &state
, struct cli_connect_nb_state
);
3004 state
->desthost
= host
;
3005 state
->signing_state
= signing_state
;
3006 state
->flags
= flags
;
3008 p
= strchr(host
, '#');
3010 name_type
= strtol(p
+1, NULL
, 16);
3011 host
= talloc_strndup(state
, host
, p
- host
);
3012 if (tevent_req_nomem(host
, req
)) {
3013 return tevent_req_post(req
, ev
);
3017 subreq
= cli_connect_sock_send(state
, ev
, host
, name_type
, dest_ss
,
3019 if (tevent_req_nomem(subreq
, req
)) {
3020 return tevent_req_post(req
, ev
);
3022 tevent_req_set_callback(subreq
, cli_connect_nb_done
, req
);
3026 static void cli_connect_nb_done(struct tevent_req
*subreq
)
3028 struct tevent_req
*req
= tevent_req_callback_data(
3029 subreq
, struct tevent_req
);
3030 struct cli_connect_nb_state
*state
= tevent_req_data(
3031 req
, struct cli_connect_nb_state
);
3036 status
= cli_connect_sock_recv(subreq
, &fd
, &port
);
3037 TALLOC_FREE(subreq
);
3038 if (tevent_req_nterror(req
, status
)) {
3042 state
->cli
= cli_state_create(state
, fd
, state
->desthost
, NULL
,
3043 state
->signing_state
, state
->flags
);
3044 if (tevent_req_nomem(state
->cli
, req
)) {
3048 tevent_req_done(req
);
3051 static NTSTATUS
cli_connect_nb_recv(struct tevent_req
*req
,
3052 struct cli_state
**pcli
)
3054 struct cli_connect_nb_state
*state
= tevent_req_data(
3055 req
, struct cli_connect_nb_state
);
3058 if (tevent_req_is_nterror(req
, &status
)) {
3061 *pcli
= talloc_move(NULL
, &state
->cli
);
3062 return NT_STATUS_OK
;
3065 NTSTATUS
cli_connect_nb(const char *host
, const struct sockaddr_storage
*dest_ss
,
3066 uint16_t port
, int name_type
, const char *myname
,
3067 int signing_state
, int flags
, struct cli_state
**pcli
)
3069 struct tevent_context
*ev
;
3070 struct tevent_req
*req
;
3071 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
3073 ev
= samba_tevent_context_init(talloc_tos());
3077 req
= cli_connect_nb_send(ev
, ev
, host
, dest_ss
, port
, name_type
,
3078 myname
, signing_state
, flags
);
3082 if (!tevent_req_set_endtime(req
, ev
, timeval_current_ofs(20, 0))) {
3085 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
3088 status
= cli_connect_nb_recv(req
, pcli
);
3094 struct cli_start_connection_state
{
3095 struct tevent_context
*ev
;
3096 struct cli_state
*cli
;
3099 static void cli_start_connection_connected(struct tevent_req
*subreq
);
3100 static void cli_start_connection_done(struct tevent_req
*subreq
);
3103 establishes a connection to after the negprot.
3104 @param output_cli A fully initialised cli structure, non-null only on success
3105 @param dest_host The netbios name of the remote host
3106 @param dest_ss (optional) The the destination IP, NULL for name based lookup
3107 @param port (optional) The destination port (0 for default)
3110 static struct tevent_req
*cli_start_connection_send(
3111 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
3112 const char *my_name
, const char *dest_host
,
3113 const struct sockaddr_storage
*dest_ss
, int port
,
3114 int signing_state
, int flags
)
3116 struct tevent_req
*req
, *subreq
;
3117 struct cli_start_connection_state
*state
;
3119 req
= tevent_req_create(mem_ctx
, &state
,
3120 struct cli_start_connection_state
);
3126 subreq
= cli_connect_nb_send(state
, ev
, dest_host
, dest_ss
, port
,
3127 0x20, my_name
, signing_state
, flags
);
3128 if (tevent_req_nomem(subreq
, req
)) {
3129 return tevent_req_post(req
, ev
);
3131 tevent_req_set_callback(subreq
, cli_start_connection_connected
, req
);
3135 static void cli_start_connection_connected(struct tevent_req
*subreq
)
3137 struct tevent_req
*req
= tevent_req_callback_data(
3138 subreq
, struct tevent_req
);
3139 struct cli_start_connection_state
*state
= tevent_req_data(
3140 req
, struct cli_start_connection_state
);
3143 status
= cli_connect_nb_recv(subreq
, &state
->cli
);
3144 TALLOC_FREE(subreq
);
3145 if (tevent_req_nterror(req
, status
)) {
3149 subreq
= smbXcli_negprot_send(state
, state
->ev
, state
->cli
->conn
,
3150 state
->cli
->timeout
,
3151 lp_cli_minprotocol(),
3152 lp_cli_maxprotocol());
3153 if (tevent_req_nomem(subreq
, req
)) {
3156 tevent_req_set_callback(subreq
, cli_start_connection_done
, req
);
3159 static void cli_start_connection_done(struct tevent_req
*subreq
)
3161 struct tevent_req
*req
= tevent_req_callback_data(
3162 subreq
, struct tevent_req
);
3163 struct cli_start_connection_state
*state
= tevent_req_data(
3164 req
, struct cli_start_connection_state
);
3167 status
= smbXcli_negprot_recv(subreq
);
3168 TALLOC_FREE(subreq
);
3169 if (tevent_req_nterror(req
, status
)) {
3173 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
3174 /* Ensure we ask for some initial credits. */
3175 smb2cli_conn_set_max_credits(state
->cli
->conn
,
3176 DEFAULT_SMB2_MAX_CREDITS
);
3179 tevent_req_done(req
);
3182 static NTSTATUS
cli_start_connection_recv(struct tevent_req
*req
,
3183 struct cli_state
**output_cli
)
3185 struct cli_start_connection_state
*state
= tevent_req_data(
3186 req
, struct cli_start_connection_state
);
3189 if (tevent_req_is_nterror(req
, &status
)) {
3192 *output_cli
= state
->cli
;
3194 return NT_STATUS_OK
;
3197 NTSTATUS
cli_start_connection(struct cli_state
**output_cli
,
3198 const char *my_name
,
3199 const char *dest_host
,
3200 const struct sockaddr_storage
*dest_ss
, int port
,
3201 int signing_state
, int flags
)
3203 struct tevent_context
*ev
;
3204 struct tevent_req
*req
;
3205 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
3207 ev
= samba_tevent_context_init(talloc_tos());
3211 req
= cli_start_connection_send(ev
, ev
, my_name
, dest_host
, dest_ss
,
3212 port
, signing_state
, flags
);
3216 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
3219 status
= cli_start_connection_recv(req
, output_cli
);
3226 establishes a connection right up to doing tconX, password specified.
3227 @param output_cli A fully initialised cli structure, non-null only on success
3228 @param dest_host The netbios name of the remote host
3229 @param dest_ip (optional) The the destination IP, NULL for name based lookup
3230 @param port (optional) The destination port (0 for default)
3231 @param service (optional) The share to make the connection to. Should be 'unqualified' in any way.
3232 @param service_type The 'type' of serivice.
3233 @param user Username, unix string
3234 @param domain User's domain
3235 @param password User's password, unencrypted unix string.
3238 struct cli_full_connection_state
{
3239 struct tevent_context
*ev
;
3240 const char *service
;
3241 const char *service_type
;
3244 const char *password
;
3247 struct cli_state
*cli
;
3250 static int cli_full_connection_state_destructor(
3251 struct cli_full_connection_state
*s
);
3252 static void cli_full_connection_started(struct tevent_req
*subreq
);
3253 static void cli_full_connection_sess_set_up(struct tevent_req
*subreq
);
3254 static void cli_full_connection_done(struct tevent_req
*subreq
);
3256 struct tevent_req
*cli_full_connection_send(
3257 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
3258 const char *my_name
, const char *dest_host
,
3259 const struct sockaddr_storage
*dest_ss
, int port
,
3260 const char *service
, const char *service_type
,
3261 const char *user
, const char *domain
,
3262 const char *password
, int flags
, int signing_state
)
3264 struct tevent_req
*req
, *subreq
;
3265 struct cli_full_connection_state
*state
;
3267 req
= tevent_req_create(mem_ctx
, &state
,
3268 struct cli_full_connection_state
);
3272 talloc_set_destructor(state
, cli_full_connection_state_destructor
);
3275 state
->service
= service
;
3276 state
->service_type
= service_type
;
3278 state
->domain
= domain
;
3279 state
->password
= password
;
3280 state
->flags
= flags
;
3282 state
->pw_len
= state
->password
? strlen(state
->password
)+1 : 0;
3283 if (state
->password
== NULL
) {
3284 state
->password
= "";
3287 subreq
= cli_start_connection_send(
3288 state
, ev
, my_name
, dest_host
, dest_ss
, port
,
3289 signing_state
, flags
);
3290 if (tevent_req_nomem(subreq
, req
)) {
3291 return tevent_req_post(req
, ev
);
3293 tevent_req_set_callback(subreq
, cli_full_connection_started
, req
);
3297 static int cli_full_connection_state_destructor(
3298 struct cli_full_connection_state
*s
)
3300 if (s
->cli
!= NULL
) {
3301 cli_shutdown(s
->cli
);
3307 static void cli_full_connection_started(struct tevent_req
*subreq
)
3309 struct tevent_req
*req
= tevent_req_callback_data(
3310 subreq
, struct tevent_req
);
3311 struct cli_full_connection_state
*state
= tevent_req_data(
3312 req
, struct cli_full_connection_state
);
3315 status
= cli_start_connection_recv(subreq
, &state
->cli
);
3316 TALLOC_FREE(subreq
);
3317 if (tevent_req_nterror(req
, status
)) {
3320 subreq
= cli_session_setup_send(
3321 state
, state
->ev
, state
->cli
, state
->user
,
3322 state
->password
, state
->pw_len
, state
->password
, state
->pw_len
,
3324 if (tevent_req_nomem(subreq
, req
)) {
3327 tevent_req_set_callback(subreq
, cli_full_connection_sess_set_up
, req
);
3330 static void cli_full_connection_sess_set_up(struct tevent_req
*subreq
)
3332 struct tevent_req
*req
= tevent_req_callback_data(
3333 subreq
, struct tevent_req
);
3334 struct cli_full_connection_state
*state
= tevent_req_data(
3335 req
, struct cli_full_connection_state
);
3338 status
= cli_session_setup_recv(subreq
);
3339 TALLOC_FREE(subreq
);
3341 if (!NT_STATUS_IS_OK(status
) &&
3342 (state
->flags
& CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK
)) {
3344 state
->flags
&= ~CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK
;
3346 subreq
= cli_session_setup_send(
3347 state
, state
->ev
, state
->cli
, "", "", 0, "", 0,
3349 if (tevent_req_nomem(subreq
, req
)) {
3352 tevent_req_set_callback(
3353 subreq
, cli_full_connection_sess_set_up
, req
);
3357 if (tevent_req_nterror(req
, status
)) {
3361 if (state
->service
!= NULL
) {
3362 subreq
= cli_tree_connect_send(
3363 state
, state
->ev
, state
->cli
,
3364 state
->service
, state
->service_type
,
3365 state
->password
, state
->pw_len
);
3366 if (tevent_req_nomem(subreq
, req
)) {
3369 tevent_req_set_callback(subreq
, cli_full_connection_done
, req
);
3373 status
= cli_init_creds(state
->cli
, state
->user
, state
->domain
,
3375 if (tevent_req_nterror(req
, status
)) {
3378 tevent_req_done(req
);
3381 static void cli_full_connection_done(struct tevent_req
*subreq
)
3383 struct tevent_req
*req
= tevent_req_callback_data(
3384 subreq
, struct tevent_req
);
3385 struct cli_full_connection_state
*state
= tevent_req_data(
3386 req
, struct cli_full_connection_state
);
3389 status
= cli_tree_connect_recv(subreq
);
3390 TALLOC_FREE(subreq
);
3391 if (tevent_req_nterror(req
, status
)) {
3394 status
= cli_init_creds(state
->cli
, state
->user
, state
->domain
,
3396 if (tevent_req_nterror(req
, status
)) {
3399 tevent_req_done(req
);
3402 NTSTATUS
cli_full_connection_recv(struct tevent_req
*req
,
3403 struct cli_state
**output_cli
)
3405 struct cli_full_connection_state
*state
= tevent_req_data(
3406 req
, struct cli_full_connection_state
);
3409 if (tevent_req_is_nterror(req
, &status
)) {
3412 *output_cli
= state
->cli
;
3413 talloc_set_destructor(state
, NULL
);
3414 return NT_STATUS_OK
;
3417 NTSTATUS
cli_full_connection(struct cli_state
**output_cli
,
3418 const char *my_name
,
3419 const char *dest_host
,
3420 const struct sockaddr_storage
*dest_ss
, int port
,
3421 const char *service
, const char *service_type
,
3422 const char *user
, const char *domain
,
3423 const char *password
, int flags
,
3426 struct tevent_context
*ev
;
3427 struct tevent_req
*req
;
3428 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
3430 ev
= samba_tevent_context_init(talloc_tos());
3434 req
= cli_full_connection_send(
3435 ev
, ev
, my_name
, dest_host
, dest_ss
, port
, service
,
3436 service_type
, user
, domain
, password
, flags
, signing_state
);
3440 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
3443 status
= cli_full_connection_recv(req
, output_cli
);
3449 /****************************************************************************
3450 Send an old style tcon.
3451 ****************************************************************************/
3452 struct cli_raw_tcon_state
{
3456 static void cli_raw_tcon_done(struct tevent_req
*subreq
);
3458 static struct tevent_req
*cli_raw_tcon_send(
3459 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
3460 const char *service
, const char *pass
, const char *dev
)
3462 struct tevent_req
*req
, *subreq
;
3463 struct cli_raw_tcon_state
*state
;
3466 req
= tevent_req_create(mem_ctx
, &state
, struct cli_raw_tcon_state
);
3471 if (!lp_client_plaintext_auth() && (*pass
)) {
3472 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
3473 " or 'client ntlmv2 auth = yes'\n"));
3474 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
3475 return tevent_req_post(req
, ev
);
3478 bytes
= talloc_array(state
, uint8_t, 0);
3479 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
3480 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
3481 service
, strlen(service
)+1, NULL
);
3482 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
3483 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
3484 pass
, strlen(pass
)+1, NULL
);
3485 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
3486 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
3487 dev
, strlen(dev
)+1, NULL
);
3489 if (tevent_req_nomem(bytes
, req
)) {
3490 return tevent_req_post(req
, ev
);
3493 subreq
= cli_smb_send(state
, ev
, cli
, SMBtcon
, 0, 0, NULL
,
3494 talloc_get_size(bytes
), bytes
);
3495 if (tevent_req_nomem(subreq
, req
)) {
3496 return tevent_req_post(req
, ev
);
3498 tevent_req_set_callback(subreq
, cli_raw_tcon_done
, req
);
3502 static void cli_raw_tcon_done(struct tevent_req
*subreq
)
3504 struct tevent_req
*req
= tevent_req_callback_data(
3505 subreq
, struct tevent_req
);
3506 struct cli_raw_tcon_state
*state
= tevent_req_data(
3507 req
, struct cli_raw_tcon_state
);
3510 status
= cli_smb_recv(subreq
, state
, NULL
, 2, NULL
, &state
->ret_vwv
,
3512 TALLOC_FREE(subreq
);
3513 if (tevent_req_nterror(req
, status
)) {
3516 tevent_req_done(req
);
3519 static NTSTATUS
cli_raw_tcon_recv(struct tevent_req
*req
,
3520 uint16
*max_xmit
, uint16
*tid
)
3522 struct cli_raw_tcon_state
*state
= tevent_req_data(
3523 req
, struct cli_raw_tcon_state
);
3526 if (tevent_req_is_nterror(req
, &status
)) {
3529 *max_xmit
= SVAL(state
->ret_vwv
+ 0, 0);
3530 *tid
= SVAL(state
->ret_vwv
+ 1, 0);
3531 return NT_STATUS_OK
;
3534 NTSTATUS
cli_raw_tcon(struct cli_state
*cli
,
3535 const char *service
, const char *pass
, const char *dev
,
3536 uint16
*max_xmit
, uint16
*tid
)
3538 struct tevent_context
*ev
;
3539 struct tevent_req
*req
;
3540 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
3542 ev
= samba_tevent_context_init(talloc_tos());
3546 req
= cli_raw_tcon_send(ev
, ev
, cli
, service
, pass
, dev
);
3550 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
3553 status
= cli_raw_tcon_recv(req
, max_xmit
, tid
);
3559 /* Return a cli_state pointing at the IPC$ share for the given server */
3561 struct cli_state
*get_ipc_connect(char *server
,
3562 struct sockaddr_storage
*server_ss
,
3563 const struct user_auth_info
*user_info
)
3565 struct cli_state
*cli
;
3567 uint32_t flags
= CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK
;
3569 if (user_info
->use_kerberos
) {
3570 flags
|= CLI_FULL_CONNECTION_USE_KERBEROS
;
3573 nt_status
= cli_full_connection(&cli
, NULL
, server
, server_ss
, 0, "IPC$", "IPC",
3574 user_info
->username
? user_info
->username
: "",
3576 user_info
->password
? user_info
->password
: "",
3578 SMB_SIGNING_DEFAULT
);
3580 if (NT_STATUS_IS_OK(nt_status
)) {
3582 } else if (is_ipaddress(server
)) {
3583 /* windows 9* needs a correct NMB name for connections */
3584 fstring remote_name
;
3586 if (name_status_find("*", 0, 0, server_ss
, remote_name
)) {
3587 cli
= get_ipc_connect(remote_name
, server_ss
, user_info
);
3596 * Given the IP address of a master browser on the network, return its
3597 * workgroup and connect to it.
3599 * This function is provided to allow additional processing beyond what
3600 * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
3601 * browsers and obtain each master browsers' list of domains (in case the
3602 * first master browser is recently on the network and has not yet
3603 * synchronized with other master browsers and therefore does not yet have the
3604 * entire network browse list)
3607 struct cli_state
*get_ipc_connect_master_ip(TALLOC_CTX
*ctx
,
3608 struct sockaddr_storage
*mb_ip
,
3609 const struct user_auth_info
*user_info
,
3610 char **pp_workgroup_out
)
3612 char addr
[INET6_ADDRSTRLEN
];
3614 struct cli_state
*cli
;
3615 struct sockaddr_storage server_ss
;
3617 *pp_workgroup_out
= NULL
;
3619 print_sockaddr(addr
, sizeof(addr
), mb_ip
);
3620 DEBUG(99, ("Looking up name of master browser %s\n",
3624 * Do a name status query to find out the name of the master browser.
3625 * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
3626 * master browser will not respond to a wildcard query (or, at least,
3627 * an NT4 server acting as the domain master browser will not).
3629 * We might be able to use ONLY the query on MSBROWSE, but that's not
3630 * yet been tested with all Windows versions, so until it is, leave
3631 * the original wildcard query as the first choice and fall back to
3632 * MSBROWSE if the wildcard query fails.
3634 if (!name_status_find("*", 0, 0x1d, mb_ip
, name
) &&
3635 !name_status_find(MSBROWSE
, 1, 0x1d, mb_ip
, name
)) {
3637 DEBUG(99, ("Could not retrieve name status for %s\n",
3642 if (!find_master_ip(name
, &server_ss
)) {
3643 DEBUG(99, ("Could not find master ip for %s\n", name
));
3647 *pp_workgroup_out
= talloc_strdup(ctx
, name
);
3649 DEBUG(4, ("found master browser %s, %s\n", name
, addr
));
3651 print_sockaddr(addr
, sizeof(addr
), &server_ss
);
3652 cli
= get_ipc_connect(addr
, &server_ss
, user_info
);
3658 * Return the IP address and workgroup of a master browser on the network, and
3662 struct cli_state
*get_ipc_connect_master_ip_bcast(TALLOC_CTX
*ctx
,
3663 const struct user_auth_info
*user_info
,
3664 char **pp_workgroup_out
)
3666 struct sockaddr_storage
*ip_list
;
3667 struct cli_state
*cli
;
3671 *pp_workgroup_out
= NULL
;
3673 DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
3675 /* Go looking for workgroups by broadcasting on the local network */
3677 status
= name_resolve_bcast(MSBROWSE
, 1, talloc_tos(),
3679 if (!NT_STATUS_IS_OK(status
)) {
3680 DEBUG(99, ("No master browsers responded: %s\n",
3681 nt_errstr(status
)));
3685 for (i
= 0; i
< count
; i
++) {
3686 char addr
[INET6_ADDRSTRLEN
];
3687 print_sockaddr(addr
, sizeof(addr
), &ip_list
[i
]);
3688 DEBUG(99, ("Found master browser %s\n", addr
));
3690 cli
= get_ipc_connect_master_ip(ctx
, &ip_list
[i
],
3691 user_info
, pp_workgroup_out
);