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
;
2999 req
= tevent_req_create(mem_ctx
, &state
, struct cli_connect_nb_state
);
3003 state
->signing_state
= signing_state
;
3004 state
->flags
= flags
;
3007 char *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 state
->desthost
= host
;
3019 state
->desthost
= print_canonical_sockaddr(state
, dest_ss
);
3020 if (tevent_req_nomem(state
->desthost
, req
)) {
3021 return tevent_req_post(req
, ev
);
3025 subreq
= cli_connect_sock_send(state
, ev
, host
, name_type
, dest_ss
,
3027 if (tevent_req_nomem(subreq
, req
)) {
3028 return tevent_req_post(req
, ev
);
3030 tevent_req_set_callback(subreq
, cli_connect_nb_done
, req
);
3034 static void cli_connect_nb_done(struct tevent_req
*subreq
)
3036 struct tevent_req
*req
= tevent_req_callback_data(
3037 subreq
, struct tevent_req
);
3038 struct cli_connect_nb_state
*state
= tevent_req_data(
3039 req
, struct cli_connect_nb_state
);
3044 status
= cli_connect_sock_recv(subreq
, &fd
, &port
);
3045 TALLOC_FREE(subreq
);
3046 if (tevent_req_nterror(req
, status
)) {
3050 state
->cli
= cli_state_create(state
, fd
, state
->desthost
, NULL
,
3051 state
->signing_state
, state
->flags
);
3052 if (tevent_req_nomem(state
->cli
, req
)) {
3056 tevent_req_done(req
);
3059 static NTSTATUS
cli_connect_nb_recv(struct tevent_req
*req
,
3060 struct cli_state
**pcli
)
3062 struct cli_connect_nb_state
*state
= tevent_req_data(
3063 req
, struct cli_connect_nb_state
);
3066 if (tevent_req_is_nterror(req
, &status
)) {
3069 *pcli
= talloc_move(NULL
, &state
->cli
);
3070 return NT_STATUS_OK
;
3073 NTSTATUS
cli_connect_nb(const char *host
, const struct sockaddr_storage
*dest_ss
,
3074 uint16_t port
, int name_type
, const char *myname
,
3075 int signing_state
, int flags
, struct cli_state
**pcli
)
3077 struct tevent_context
*ev
;
3078 struct tevent_req
*req
;
3079 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
3081 ev
= samba_tevent_context_init(talloc_tos());
3085 req
= cli_connect_nb_send(ev
, ev
, host
, dest_ss
, port
, name_type
,
3086 myname
, signing_state
, flags
);
3090 if (!tevent_req_set_endtime(req
, ev
, timeval_current_ofs(20, 0))) {
3093 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
3096 status
= cli_connect_nb_recv(req
, pcli
);
3102 struct cli_start_connection_state
{
3103 struct tevent_context
*ev
;
3104 struct cli_state
*cli
;
3107 static void cli_start_connection_connected(struct tevent_req
*subreq
);
3108 static void cli_start_connection_done(struct tevent_req
*subreq
);
3111 establishes a connection to after the negprot.
3112 @param output_cli A fully initialised cli structure, non-null only on success
3113 @param dest_host The netbios name of the remote host
3114 @param dest_ss (optional) The the destination IP, NULL for name based lookup
3115 @param port (optional) The destination port (0 for default)
3118 static struct tevent_req
*cli_start_connection_send(
3119 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
3120 const char *my_name
, const char *dest_host
,
3121 const struct sockaddr_storage
*dest_ss
, int port
,
3122 int signing_state
, int flags
)
3124 struct tevent_req
*req
, *subreq
;
3125 struct cli_start_connection_state
*state
;
3127 req
= tevent_req_create(mem_ctx
, &state
,
3128 struct cli_start_connection_state
);
3134 subreq
= cli_connect_nb_send(state
, ev
, dest_host
, dest_ss
, port
,
3135 0x20, my_name
, signing_state
, flags
);
3136 if (tevent_req_nomem(subreq
, req
)) {
3137 return tevent_req_post(req
, ev
);
3139 tevent_req_set_callback(subreq
, cli_start_connection_connected
, req
);
3143 static void cli_start_connection_connected(struct tevent_req
*subreq
)
3145 struct tevent_req
*req
= tevent_req_callback_data(
3146 subreq
, struct tevent_req
);
3147 struct cli_start_connection_state
*state
= tevent_req_data(
3148 req
, struct cli_start_connection_state
);
3151 status
= cli_connect_nb_recv(subreq
, &state
->cli
);
3152 TALLOC_FREE(subreq
);
3153 if (tevent_req_nterror(req
, status
)) {
3157 subreq
= smbXcli_negprot_send(state
, state
->ev
, state
->cli
->conn
,
3158 state
->cli
->timeout
,
3159 lp_cli_minprotocol(),
3160 lp_cli_maxprotocol());
3161 if (tevent_req_nomem(subreq
, req
)) {
3164 tevent_req_set_callback(subreq
, cli_start_connection_done
, req
);
3167 static void cli_start_connection_done(struct tevent_req
*subreq
)
3169 struct tevent_req
*req
= tevent_req_callback_data(
3170 subreq
, struct tevent_req
);
3171 struct cli_start_connection_state
*state
= tevent_req_data(
3172 req
, struct cli_start_connection_state
);
3175 status
= smbXcli_negprot_recv(subreq
);
3176 TALLOC_FREE(subreq
);
3177 if (tevent_req_nterror(req
, status
)) {
3181 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
3182 /* Ensure we ask for some initial credits. */
3183 smb2cli_conn_set_max_credits(state
->cli
->conn
,
3184 DEFAULT_SMB2_MAX_CREDITS
);
3187 tevent_req_done(req
);
3190 static NTSTATUS
cli_start_connection_recv(struct tevent_req
*req
,
3191 struct cli_state
**output_cli
)
3193 struct cli_start_connection_state
*state
= tevent_req_data(
3194 req
, struct cli_start_connection_state
);
3197 if (tevent_req_is_nterror(req
, &status
)) {
3200 *output_cli
= state
->cli
;
3202 return NT_STATUS_OK
;
3205 NTSTATUS
cli_start_connection(struct cli_state
**output_cli
,
3206 const char *my_name
,
3207 const char *dest_host
,
3208 const struct sockaddr_storage
*dest_ss
, int port
,
3209 int signing_state
, int flags
)
3211 struct tevent_context
*ev
;
3212 struct tevent_req
*req
;
3213 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
3215 ev
= samba_tevent_context_init(talloc_tos());
3219 req
= cli_start_connection_send(ev
, ev
, my_name
, dest_host
, dest_ss
,
3220 port
, signing_state
, flags
);
3224 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
3227 status
= cli_start_connection_recv(req
, output_cli
);
3234 establishes a connection right up to doing tconX, password specified.
3235 @param output_cli A fully initialised cli structure, non-null only on success
3236 @param dest_host The netbios name of the remote host
3237 @param dest_ip (optional) The the destination IP, NULL for name based lookup
3238 @param port (optional) The destination port (0 for default)
3239 @param service (optional) The share to make the connection to. Should be 'unqualified' in any way.
3240 @param service_type The 'type' of serivice.
3241 @param user Username, unix string
3242 @param domain User's domain
3243 @param password User's password, unencrypted unix string.
3246 struct cli_full_connection_state
{
3247 struct tevent_context
*ev
;
3248 const char *service
;
3249 const char *service_type
;
3252 const char *password
;
3255 struct cli_state
*cli
;
3258 static int cli_full_connection_state_destructor(
3259 struct cli_full_connection_state
*s
);
3260 static void cli_full_connection_started(struct tevent_req
*subreq
);
3261 static void cli_full_connection_sess_set_up(struct tevent_req
*subreq
);
3262 static void cli_full_connection_done(struct tevent_req
*subreq
);
3264 struct tevent_req
*cli_full_connection_send(
3265 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
3266 const char *my_name
, const char *dest_host
,
3267 const struct sockaddr_storage
*dest_ss
, int port
,
3268 const char *service
, const char *service_type
,
3269 const char *user
, const char *domain
,
3270 const char *password
, int flags
, int signing_state
)
3272 struct tevent_req
*req
, *subreq
;
3273 struct cli_full_connection_state
*state
;
3275 req
= tevent_req_create(mem_ctx
, &state
,
3276 struct cli_full_connection_state
);
3280 talloc_set_destructor(state
, cli_full_connection_state_destructor
);
3283 state
->service
= service
;
3284 state
->service_type
= service_type
;
3286 state
->domain
= domain
;
3287 state
->password
= password
;
3288 state
->flags
= flags
;
3290 state
->pw_len
= state
->password
? strlen(state
->password
)+1 : 0;
3291 if (state
->password
== NULL
) {
3292 state
->password
= "";
3295 subreq
= cli_start_connection_send(
3296 state
, ev
, my_name
, dest_host
, dest_ss
, port
,
3297 signing_state
, flags
);
3298 if (tevent_req_nomem(subreq
, req
)) {
3299 return tevent_req_post(req
, ev
);
3301 tevent_req_set_callback(subreq
, cli_full_connection_started
, req
);
3305 static int cli_full_connection_state_destructor(
3306 struct cli_full_connection_state
*s
)
3308 if (s
->cli
!= NULL
) {
3309 cli_shutdown(s
->cli
);
3315 static void cli_full_connection_started(struct tevent_req
*subreq
)
3317 struct tevent_req
*req
= tevent_req_callback_data(
3318 subreq
, struct tevent_req
);
3319 struct cli_full_connection_state
*state
= tevent_req_data(
3320 req
, struct cli_full_connection_state
);
3323 status
= cli_start_connection_recv(subreq
, &state
->cli
);
3324 TALLOC_FREE(subreq
);
3325 if (tevent_req_nterror(req
, status
)) {
3328 subreq
= cli_session_setup_send(
3329 state
, state
->ev
, state
->cli
, state
->user
,
3330 state
->password
, state
->pw_len
, state
->password
, state
->pw_len
,
3332 if (tevent_req_nomem(subreq
, req
)) {
3335 tevent_req_set_callback(subreq
, cli_full_connection_sess_set_up
, req
);
3338 static void cli_full_connection_sess_set_up(struct tevent_req
*subreq
)
3340 struct tevent_req
*req
= tevent_req_callback_data(
3341 subreq
, struct tevent_req
);
3342 struct cli_full_connection_state
*state
= tevent_req_data(
3343 req
, struct cli_full_connection_state
);
3346 status
= cli_session_setup_recv(subreq
);
3347 TALLOC_FREE(subreq
);
3349 if (!NT_STATUS_IS_OK(status
) &&
3350 (state
->flags
& CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK
)) {
3352 state
->flags
&= ~CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK
;
3354 subreq
= cli_session_setup_send(
3355 state
, state
->ev
, state
->cli
, "", "", 0, "", 0,
3357 if (tevent_req_nomem(subreq
, req
)) {
3360 tevent_req_set_callback(
3361 subreq
, cli_full_connection_sess_set_up
, req
);
3365 if (tevent_req_nterror(req
, status
)) {
3369 if (state
->service
!= NULL
) {
3370 subreq
= cli_tree_connect_send(
3371 state
, state
->ev
, state
->cli
,
3372 state
->service
, state
->service_type
,
3373 state
->password
, state
->pw_len
);
3374 if (tevent_req_nomem(subreq
, req
)) {
3377 tevent_req_set_callback(subreq
, cli_full_connection_done
, req
);
3381 status
= cli_init_creds(state
->cli
, state
->user
, state
->domain
,
3383 if (tevent_req_nterror(req
, status
)) {
3386 tevent_req_done(req
);
3389 static void cli_full_connection_done(struct tevent_req
*subreq
)
3391 struct tevent_req
*req
= tevent_req_callback_data(
3392 subreq
, struct tevent_req
);
3393 struct cli_full_connection_state
*state
= tevent_req_data(
3394 req
, struct cli_full_connection_state
);
3397 status
= cli_tree_connect_recv(subreq
);
3398 TALLOC_FREE(subreq
);
3399 if (tevent_req_nterror(req
, status
)) {
3402 status
= cli_init_creds(state
->cli
, state
->user
, state
->domain
,
3404 if (tevent_req_nterror(req
, status
)) {
3407 tevent_req_done(req
);
3410 NTSTATUS
cli_full_connection_recv(struct tevent_req
*req
,
3411 struct cli_state
**output_cli
)
3413 struct cli_full_connection_state
*state
= tevent_req_data(
3414 req
, struct cli_full_connection_state
);
3417 if (tevent_req_is_nterror(req
, &status
)) {
3420 *output_cli
= state
->cli
;
3421 talloc_set_destructor(state
, NULL
);
3422 return NT_STATUS_OK
;
3425 NTSTATUS
cli_full_connection(struct cli_state
**output_cli
,
3426 const char *my_name
,
3427 const char *dest_host
,
3428 const struct sockaddr_storage
*dest_ss
, int port
,
3429 const char *service
, const char *service_type
,
3430 const char *user
, const char *domain
,
3431 const char *password
, int flags
,
3434 struct tevent_context
*ev
;
3435 struct tevent_req
*req
;
3436 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
3438 ev
= samba_tevent_context_init(talloc_tos());
3442 req
= cli_full_connection_send(
3443 ev
, ev
, my_name
, dest_host
, dest_ss
, port
, service
,
3444 service_type
, user
, domain
, password
, flags
, signing_state
);
3448 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
3451 status
= cli_full_connection_recv(req
, output_cli
);
3457 /****************************************************************************
3458 Send an old style tcon.
3459 ****************************************************************************/
3460 struct cli_raw_tcon_state
{
3464 static void cli_raw_tcon_done(struct tevent_req
*subreq
);
3466 static struct tevent_req
*cli_raw_tcon_send(
3467 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
3468 const char *service
, const char *pass
, const char *dev
)
3470 struct tevent_req
*req
, *subreq
;
3471 struct cli_raw_tcon_state
*state
;
3474 req
= tevent_req_create(mem_ctx
, &state
, struct cli_raw_tcon_state
);
3479 if (!lp_client_plaintext_auth() && (*pass
)) {
3480 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
3481 " or 'client ntlmv2 auth = yes'\n"));
3482 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
3483 return tevent_req_post(req
, ev
);
3486 bytes
= talloc_array(state
, uint8_t, 0);
3487 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
3488 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
3489 service
, strlen(service
)+1, NULL
);
3490 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
3491 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
3492 pass
, strlen(pass
)+1, NULL
);
3493 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
3494 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
3495 dev
, strlen(dev
)+1, NULL
);
3497 if (tevent_req_nomem(bytes
, req
)) {
3498 return tevent_req_post(req
, ev
);
3501 subreq
= cli_smb_send(state
, ev
, cli
, SMBtcon
, 0, 0, NULL
,
3502 talloc_get_size(bytes
), bytes
);
3503 if (tevent_req_nomem(subreq
, req
)) {
3504 return tevent_req_post(req
, ev
);
3506 tevent_req_set_callback(subreq
, cli_raw_tcon_done
, req
);
3510 static void cli_raw_tcon_done(struct tevent_req
*subreq
)
3512 struct tevent_req
*req
= tevent_req_callback_data(
3513 subreq
, struct tevent_req
);
3514 struct cli_raw_tcon_state
*state
= tevent_req_data(
3515 req
, struct cli_raw_tcon_state
);
3518 status
= cli_smb_recv(subreq
, state
, NULL
, 2, NULL
, &state
->ret_vwv
,
3520 TALLOC_FREE(subreq
);
3521 if (tevent_req_nterror(req
, status
)) {
3524 tevent_req_done(req
);
3527 static NTSTATUS
cli_raw_tcon_recv(struct tevent_req
*req
,
3528 uint16
*max_xmit
, uint16
*tid
)
3530 struct cli_raw_tcon_state
*state
= tevent_req_data(
3531 req
, struct cli_raw_tcon_state
);
3534 if (tevent_req_is_nterror(req
, &status
)) {
3537 *max_xmit
= SVAL(state
->ret_vwv
+ 0, 0);
3538 *tid
= SVAL(state
->ret_vwv
+ 1, 0);
3539 return NT_STATUS_OK
;
3542 NTSTATUS
cli_raw_tcon(struct cli_state
*cli
,
3543 const char *service
, const char *pass
, const char *dev
,
3544 uint16
*max_xmit
, uint16
*tid
)
3546 struct tevent_context
*ev
;
3547 struct tevent_req
*req
;
3548 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
3550 ev
= samba_tevent_context_init(talloc_tos());
3554 req
= cli_raw_tcon_send(ev
, ev
, cli
, service
, pass
, dev
);
3558 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
3561 status
= cli_raw_tcon_recv(req
, max_xmit
, tid
);
3567 /* Return a cli_state pointing at the IPC$ share for the given server */
3569 struct cli_state
*get_ipc_connect(char *server
,
3570 struct sockaddr_storage
*server_ss
,
3571 const struct user_auth_info
*user_info
)
3573 struct cli_state
*cli
;
3575 uint32_t flags
= CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK
;
3577 if (user_info
->use_kerberos
) {
3578 flags
|= CLI_FULL_CONNECTION_USE_KERBEROS
;
3581 nt_status
= cli_full_connection(&cli
, NULL
, server
, server_ss
, 0, "IPC$", "IPC",
3582 user_info
->username
? user_info
->username
: "",
3584 user_info
->password
? user_info
->password
: "",
3586 SMB_SIGNING_DEFAULT
);
3588 if (NT_STATUS_IS_OK(nt_status
)) {
3590 } else if (is_ipaddress(server
)) {
3591 /* windows 9* needs a correct NMB name for connections */
3592 fstring remote_name
;
3594 if (name_status_find("*", 0, 0, server_ss
, remote_name
)) {
3595 cli
= get_ipc_connect(remote_name
, server_ss
, user_info
);
3604 * Given the IP address of a master browser on the network, return its
3605 * workgroup and connect to it.
3607 * This function is provided to allow additional processing beyond what
3608 * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
3609 * browsers and obtain each master browsers' list of domains (in case the
3610 * first master browser is recently on the network and has not yet
3611 * synchronized with other master browsers and therefore does not yet have the
3612 * entire network browse list)
3615 struct cli_state
*get_ipc_connect_master_ip(TALLOC_CTX
*ctx
,
3616 struct sockaddr_storage
*mb_ip
,
3617 const struct user_auth_info
*user_info
,
3618 char **pp_workgroup_out
)
3620 char addr
[INET6_ADDRSTRLEN
];
3622 struct cli_state
*cli
;
3623 struct sockaddr_storage server_ss
;
3625 *pp_workgroup_out
= NULL
;
3627 print_sockaddr(addr
, sizeof(addr
), mb_ip
);
3628 DEBUG(99, ("Looking up name of master browser %s\n",
3632 * Do a name status query to find out the name of the master browser.
3633 * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
3634 * master browser will not respond to a wildcard query (or, at least,
3635 * an NT4 server acting as the domain master browser will not).
3637 * We might be able to use ONLY the query on MSBROWSE, but that's not
3638 * yet been tested with all Windows versions, so until it is, leave
3639 * the original wildcard query as the first choice and fall back to
3640 * MSBROWSE if the wildcard query fails.
3642 if (!name_status_find("*", 0, 0x1d, mb_ip
, name
) &&
3643 !name_status_find(MSBROWSE
, 1, 0x1d, mb_ip
, name
)) {
3645 DEBUG(99, ("Could not retrieve name status for %s\n",
3650 if (!find_master_ip(name
, &server_ss
)) {
3651 DEBUG(99, ("Could not find master ip for %s\n", name
));
3655 *pp_workgroup_out
= talloc_strdup(ctx
, name
);
3657 DEBUG(4, ("found master browser %s, %s\n", name
, addr
));
3659 print_sockaddr(addr
, sizeof(addr
), &server_ss
);
3660 cli
= get_ipc_connect(addr
, &server_ss
, user_info
);
3666 * Return the IP address and workgroup of a master browser on the network, and
3670 struct cli_state
*get_ipc_connect_master_ip_bcast(TALLOC_CTX
*ctx
,
3671 const struct user_auth_info
*user_info
,
3672 char **pp_workgroup_out
)
3674 struct sockaddr_storage
*ip_list
;
3675 struct cli_state
*cli
;
3679 *pp_workgroup_out
= NULL
;
3681 DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
3683 /* Go looking for workgroups by broadcasting on the local network */
3685 status
= name_resolve_bcast(MSBROWSE
, 1, talloc_tos(),
3687 if (!NT_STATUS_IS_OK(status
)) {
3688 DEBUG(99, ("No master browsers responded: %s\n",
3689 nt_errstr(status
)));
3693 for (i
= 0; i
< count
; i
++) {
3694 char addr
[INET6_ADDRSTRLEN
];
3695 print_sockaddr(addr
, sizeof(addr
), &ip_list
[i
]);
3696 DEBUG(99, ("Found master browser %s\n", addr
));
3698 cli
= get_ipc_connect_master_ip(ctx
, &ip_list
[i
],
3699 user_info
, pp_workgroup_out
);