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
;
76 * Set the user session key for a connection
77 * @param cli The cli structure to add it too
78 * @param session_key The session key used. (A copy of this is taken for the cli struct)
82 static void cli_set_session_key (struct cli_state
*cli
, const DATA_BLOB session_key
)
84 cli
->user_session_key
= data_blob(session_key
.data
, session_key
.length
);
87 /****************************************************************************
88 Do an old lanman2 style session setup.
89 ****************************************************************************/
91 struct cli_session_setup_lanman2_state
{
92 struct cli_state
*cli
;
97 static void cli_session_setup_lanman2_done(struct tevent_req
*subreq
);
99 static struct tevent_req
*cli_session_setup_lanman2_send(
100 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
101 struct cli_state
*cli
, const char *user
,
102 const char *pass
, size_t passlen
,
103 const char *workgroup
)
105 struct tevent_req
*req
, *subreq
;
106 struct cli_session_setup_lanman2_state
*state
;
107 DATA_BLOB lm_response
= data_blob_null
;
111 uint16_t sec_mode
= smb1cli_conn_server_security_mode(cli
->conn
);
113 req
= tevent_req_create(mem_ctx
, &state
,
114 struct cli_session_setup_lanman2_state
);
123 * if in share level security then don't send a password now
125 if (!(sec_mode
& NEGOTIATE_SECURITY_USER_LEVEL
)) {
130 && (sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
)
133 * Encrypted mode needed, and non encrypted password
136 lm_response
= data_blob(NULL
, 24);
137 if (tevent_req_nomem(lm_response
.data
, req
)) {
138 return tevent_req_post(req
, ev
);
141 if (!SMBencrypt(pass
, smb1cli_conn_server_challenge(cli
->conn
),
142 (uint8_t *)lm_response
.data
)) {
143 DEBUG(1, ("Password is > 14 chars in length, and is "
144 "therefore incompatible with Lanman "
145 "authentication\n"));
146 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
147 return tevent_req_post(req
, ev
);
149 } else if ((sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
)
152 * Encrypted mode needed, and encrypted password
155 lm_response
= data_blob(pass
, passlen
);
156 if (tevent_req_nomem(lm_response
.data
, req
)) {
157 return tevent_req_post(req
, ev
);
159 } else if (passlen
> 0) {
161 size_t converted_size
;
163 * Plaintext mode needed, assume plaintext supplied.
165 buf
= talloc_array(talloc_tos(), uint8_t, 0);
166 buf
= smb_bytes_push_str(buf
, smbXcli_conn_use_unicode(cli
->conn
), pass
, passlen
+1,
168 if (tevent_req_nomem(buf
, req
)) {
169 return tevent_req_post(req
, ev
);
171 lm_response
= data_blob(pass
, passlen
);
173 if (tevent_req_nomem(lm_response
.data
, req
)) {
174 return tevent_req_post(req
, ev
);
178 SCVAL(vwv
+0, 0, 0xff);
181 SSVAL(vwv
+2, 0, CLI_BUFFER_SIZE
);
184 SIVAL(vwv
+5, 0, smb1cli_conn_server_session_key(cli
->conn
));
185 SSVAL(vwv
+7, 0, lm_response
.length
);
187 bytes
= talloc_array(state
, uint8_t, lm_response
.length
);
188 if (tevent_req_nomem(bytes
, req
)) {
189 return tevent_req_post(req
, ev
);
191 if (lm_response
.length
!= 0) {
192 memcpy(bytes
, lm_response
.data
, lm_response
.length
);
194 data_blob_free(&lm_response
);
196 tmp
= talloc_strdup_upper(talloc_tos(), user
);
197 if (tevent_req_nomem(tmp
, req
)) {
198 return tevent_req_post(req
, ev
);
200 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), tmp
, strlen(tmp
)+1,
204 tmp
= talloc_strdup_upper(talloc_tos(), workgroup
);
205 if (tevent_req_nomem(tmp
, req
)) {
206 return tevent_req_post(req
, ev
);
208 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), tmp
, strlen(tmp
)+1,
210 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "Unix", 5, NULL
);
211 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "Samba", 6, NULL
);
213 if (tevent_req_nomem(bytes
, req
)) {
214 return tevent_req_post(req
, ev
);
217 subreq
= cli_smb_send(state
, ev
, cli
, SMBsesssetupX
, 0, 10, vwv
,
218 talloc_get_size(bytes
), bytes
);
219 if (tevent_req_nomem(subreq
, req
)) {
220 return tevent_req_post(req
, ev
);
222 tevent_req_set_callback(subreq
, cli_session_setup_lanman2_done
, req
);
226 static void cli_session_setup_lanman2_done(struct tevent_req
*subreq
)
228 struct tevent_req
*req
= tevent_req_callback_data(
229 subreq
, struct tevent_req
);
230 struct cli_session_setup_lanman2_state
*state
= tevent_req_data(
231 req
, struct cli_session_setup_lanman2_state
);
232 struct cli_state
*cli
= state
->cli
;
243 status
= cli_smb_recv(subreq
, state
, &in
, 3, &wct
, &vwv
,
246 if (!NT_STATUS_IS_OK(status
)) {
247 tevent_req_nterror(req
, status
);
251 inhdr
= in
+ NBT_HDR_SIZE
;
254 cli_state_set_uid(state
->cli
, SVAL(inhdr
, HDR_UID
));
255 cli
->is_guestlogin
= ((SVAL(vwv
+2, 0) & 1) != 0);
257 status
= smb_bytes_talloc_string(cli
,
264 if (!NT_STATUS_IS_OK(status
)) {
265 tevent_req_nterror(req
, status
);
270 status
= smb_bytes_talloc_string(cli
,
277 if (!NT_STATUS_IS_OK(status
)) {
278 tevent_req_nterror(req
, status
);
283 status
= smb_bytes_talloc_string(cli
,
290 if (!NT_STATUS_IS_OK(status
)) {
291 tevent_req_nterror(req
, status
);
296 status
= cli_set_username(cli
, state
->user
);
297 if (tevent_req_nterror(req
, status
)) {
300 tevent_req_done(req
);
303 static NTSTATUS
cli_session_setup_lanman2_recv(struct tevent_req
*req
)
305 return tevent_req_simple_recv_ntstatus(req
);
308 static NTSTATUS
cli_session_setup_lanman2(struct cli_state
*cli
, const char *user
,
309 const char *pass
, size_t passlen
,
310 const char *workgroup
)
312 TALLOC_CTX
*frame
= talloc_stackframe();
313 struct event_context
*ev
;
314 struct tevent_req
*req
;
315 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
317 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
319 * Can't use sync call while an async call is in flight
321 status
= NT_STATUS_INVALID_PARAMETER
;
324 ev
= event_context_init(frame
);
328 req
= cli_session_setup_lanman2_send(frame
, ev
, cli
, user
, pass
, passlen
,
333 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
336 status
= cli_session_setup_lanman2_recv(req
);
342 /****************************************************************************
343 Work out suitable capabilities to offer the server.
344 ****************************************************************************/
346 static uint32_t cli_session_setup_capabilities(struct cli_state
*cli
,
347 uint32_t sesssetup_capabilities
)
349 uint32_t client_capabilities
= smb1cli_conn_capabilities(cli
->conn
);
352 * We only send capabilities based on the mask for:
353 * - client only flags
354 * - flags used in both directions
356 * We do not echo the server only flags.
358 client_capabilities
&= (SMB_CAP_BOTH_MASK
| SMB_CAP_CLIENT_MASK
);
361 * Session Setup specific flags CAP_DYNAMIC_REAUTH
362 * and CAP_EXTENDED_SECURITY are passed by the caller.
363 * We need that in order to do guest logins even if
364 * CAP_EXTENDED_SECURITY is negotiated.
366 client_capabilities
&= ~(CAP_DYNAMIC_REAUTH
|CAP_EXTENDED_SECURITY
);
367 sesssetup_capabilities
&= (CAP_DYNAMIC_REAUTH
|CAP_EXTENDED_SECURITY
);
368 client_capabilities
|= sesssetup_capabilities
;
370 return client_capabilities
;
373 /****************************************************************************
374 Do a NT1 guest session setup.
375 ****************************************************************************/
377 struct cli_session_setup_guest_state
{
378 struct cli_state
*cli
;
383 static void cli_session_setup_guest_done(struct tevent_req
*subreq
);
385 struct tevent_req
*cli_session_setup_guest_create(TALLOC_CTX
*mem_ctx
,
386 struct event_context
*ev
,
387 struct cli_state
*cli
,
388 struct tevent_req
**psmbreq
)
390 struct tevent_req
*req
, *subreq
;
391 struct cli_session_setup_guest_state
*state
;
395 req
= tevent_req_create(mem_ctx
, &state
,
396 struct cli_session_setup_guest_state
);
403 SCVAL(vwv
+0, 0, 0xFF);
406 SSVAL(vwv
+2, 0, CLI_BUFFER_SIZE
);
408 SSVAL(vwv
+4, 0, cli_state_get_vc_num(cli
));
409 SIVAL(vwv
+5, 0, smb1cli_conn_server_session_key(cli
->conn
));
414 SIVAL(vwv
+11, 0, cli_session_setup_capabilities(cli
, 0));
416 bytes
= talloc_array(state
, uint8_t, 0);
418 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "", 1, /* username */
420 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "", 1, /* workgroup */
422 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "Unix", 5, NULL
);
423 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "Samba", 6, NULL
);
430 state
->bytes
.iov_base
= (void *)bytes
;
431 state
->bytes
.iov_len
= talloc_get_size(bytes
);
433 subreq
= cli_smb_req_create(state
, ev
, cli
, SMBsesssetupX
, 0, 13, vwv
,
435 if (subreq
== NULL
) {
439 tevent_req_set_callback(subreq
, cli_session_setup_guest_done
, req
);
444 struct tevent_req
*cli_session_setup_guest_send(TALLOC_CTX
*mem_ctx
,
445 struct event_context
*ev
,
446 struct cli_state
*cli
)
448 struct tevent_req
*req
, *subreq
;
451 req
= cli_session_setup_guest_create(mem_ctx
, ev
, cli
, &subreq
);
456 status
= smb1cli_req_chain_submit(&subreq
, 1);
457 if (NT_STATUS_IS_OK(status
)) {
458 tevent_req_nterror(req
, status
);
459 return tevent_req_post(req
, ev
);
464 static void cli_session_setup_guest_done(struct tevent_req
*subreq
)
466 struct tevent_req
*req
= tevent_req_callback_data(
467 subreq
, struct tevent_req
);
468 struct cli_session_setup_guest_state
*state
= tevent_req_data(
469 req
, struct cli_session_setup_guest_state
);
470 struct cli_state
*cli
= state
->cli
;
481 status
= cli_smb_recv(subreq
, state
, &in
, 3, &wct
, &vwv
,
484 if (!NT_STATUS_IS_OK(status
)) {
485 tevent_req_nterror(req
, status
);
489 inhdr
= in
+ NBT_HDR_SIZE
;
492 cli_state_set_uid(state
->cli
, SVAL(inhdr
, HDR_UID
));
493 cli
->is_guestlogin
= ((SVAL(vwv
+2, 0) & 1) != 0);
495 status
= smb_bytes_talloc_string(cli
,
502 if (!NT_STATUS_IS_OK(status
)) {
503 tevent_req_nterror(req
, status
);
508 status
= smb_bytes_talloc_string(cli
,
515 if (!NT_STATUS_IS_OK(status
)) {
516 tevent_req_nterror(req
, status
);
521 status
= smb_bytes_talloc_string(cli
,
528 if (!NT_STATUS_IS_OK(status
)) {
529 tevent_req_nterror(req
, status
);
534 status
= cli_set_username(cli
, "");
535 if (!NT_STATUS_IS_OK(status
)) {
536 tevent_req_nterror(req
, status
);
539 tevent_req_done(req
);
542 NTSTATUS
cli_session_setup_guest_recv(struct tevent_req
*req
)
544 return tevent_req_simple_recv_ntstatus(req
);
547 static NTSTATUS
cli_session_setup_guest(struct cli_state
*cli
)
549 TALLOC_CTX
*frame
= talloc_stackframe();
550 struct event_context
*ev
;
551 struct tevent_req
*req
;
552 NTSTATUS status
= NT_STATUS_OK
;
554 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
556 * Can't use sync call while an async call is in flight
558 status
= NT_STATUS_INVALID_PARAMETER
;
562 ev
= event_context_init(frame
);
564 status
= NT_STATUS_NO_MEMORY
;
568 req
= cli_session_setup_guest_send(frame
, ev
, cli
);
570 status
= NT_STATUS_NO_MEMORY
;
574 if (!tevent_req_poll(req
, ev
)) {
575 status
= map_nt_error_from_unix(errno
);
579 status
= cli_session_setup_guest_recv(req
);
585 /****************************************************************************
586 Do a NT1 plaintext session setup.
587 ****************************************************************************/
589 struct cli_session_setup_plain_state
{
590 struct cli_state
*cli
;
595 static void cli_session_setup_plain_done(struct tevent_req
*subreq
);
597 static struct tevent_req
*cli_session_setup_plain_send(
598 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
599 struct cli_state
*cli
,
600 const char *user
, const char *pass
, const char *workgroup
)
602 struct tevent_req
*req
, *subreq
;
603 struct cli_session_setup_plain_state
*state
;
609 req
= tevent_req_create(mem_ctx
, &state
,
610 struct cli_session_setup_plain_state
);
618 SCVAL(vwv
+0, 0, 0xff);
621 SSVAL(vwv
+2, 0, CLI_BUFFER_SIZE
);
623 SSVAL(vwv
+4, 0, cli_state_get_vc_num(cli
));
624 SIVAL(vwv
+5, 0, smb1cli_conn_server_session_key(cli
->conn
));
629 SIVAL(vwv
+11, 0, cli_session_setup_capabilities(cli
, 0));
631 bytes
= talloc_array(state
, uint8_t, 0);
632 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), pass
, strlen(pass
)+1,
634 if (tevent_req_nomem(bytes
, req
)) {
635 return tevent_req_post(req
, ev
);
637 SSVAL(vwv
+ (smbXcli_conn_use_unicode(cli
->conn
) ? 8 : 7), 0, passlen
);
639 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
640 user
, strlen(user
)+1, NULL
);
641 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
642 workgroup
, strlen(workgroup
)+1, NULL
);
643 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
646 version
= talloc_asprintf(talloc_tos(), "Samba %s",
647 samba_version_string());
648 if (tevent_req_nomem(version
, req
)){
649 return tevent_req_post(req
, ev
);
651 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
652 version
, strlen(version
)+1, NULL
);
653 TALLOC_FREE(version
);
655 if (tevent_req_nomem(bytes
, req
)) {
656 return tevent_req_post(req
, ev
);
659 subreq
= cli_smb_send(state
, ev
, cli
, SMBsesssetupX
, 0, 13, vwv
,
660 talloc_get_size(bytes
), bytes
);
661 if (tevent_req_nomem(subreq
, req
)) {
662 return tevent_req_post(req
, ev
);
664 tevent_req_set_callback(subreq
, cli_session_setup_plain_done
, req
);
668 static void cli_session_setup_plain_done(struct tevent_req
*subreq
)
670 struct tevent_req
*req
= tevent_req_callback_data(
671 subreq
, struct tevent_req
);
672 struct cli_session_setup_plain_state
*state
= tevent_req_data(
673 req
, struct cli_session_setup_plain_state
);
674 struct cli_state
*cli
= state
->cli
;
685 status
= cli_smb_recv(subreq
, state
, &in
, 3, &wct
, &vwv
,
688 if (tevent_req_nterror(req
, status
)) {
692 inhdr
= in
+ NBT_HDR_SIZE
;
695 cli_state_set_uid(state
->cli
, SVAL(inhdr
, HDR_UID
));
696 cli
->is_guestlogin
= ((SVAL(vwv
+2, 0) & 1) != 0);
698 status
= smb_bytes_talloc_string(cli
,
705 if (!NT_STATUS_IS_OK(status
)) {
706 tevent_req_nterror(req
, status
);
711 status
= smb_bytes_talloc_string(cli
,
718 if (!NT_STATUS_IS_OK(status
)) {
719 tevent_req_nterror(req
, status
);
724 status
= smb_bytes_talloc_string(cli
,
731 if (!NT_STATUS_IS_OK(status
)) {
732 tevent_req_nterror(req
, status
);
737 status
= cli_set_username(cli
, state
->user
);
738 if (tevent_req_nterror(req
, status
)) {
742 tevent_req_done(req
);
745 static NTSTATUS
cli_session_setup_plain_recv(struct tevent_req
*req
)
747 return tevent_req_simple_recv_ntstatus(req
);
750 static NTSTATUS
cli_session_setup_plain(struct cli_state
*cli
,
751 const char *user
, const char *pass
,
752 const char *workgroup
)
754 TALLOC_CTX
*frame
= talloc_stackframe();
755 struct event_context
*ev
;
756 struct tevent_req
*req
;
757 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
759 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
761 * Can't use sync call while an async call is in flight
763 status
= NT_STATUS_INVALID_PARAMETER
;
766 ev
= event_context_init(frame
);
770 req
= cli_session_setup_plain_send(frame
, ev
, cli
, user
, pass
,
775 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
778 status
= cli_session_setup_plain_recv(req
);
784 /****************************************************************************
785 do a NT1 NTLM/LM encrypted session setup - for when extended security
787 @param cli client state to create do session setup on
789 @param pass *either* cleartext password (passlen !=24) or LM response.
790 @param ntpass NT response, implies ntpasslen >=24, implies pass is not clear
791 @param workgroup The user's domain.
792 ****************************************************************************/
794 struct cli_session_setup_nt1_state
{
795 struct cli_state
*cli
;
798 DATA_BLOB session_key
;
802 static void cli_session_setup_nt1_done(struct tevent_req
*subreq
);
804 static struct tevent_req
*cli_session_setup_nt1_send(
805 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
806 struct cli_state
*cli
, const char *user
,
807 const char *pass
, size_t passlen
,
808 const char *ntpass
, size_t ntpasslen
,
809 const char *workgroup
)
811 struct tevent_req
*req
, *subreq
;
812 struct cli_session_setup_nt1_state
*state
;
813 DATA_BLOB lm_response
= data_blob_null
;
814 DATA_BLOB nt_response
= data_blob_null
;
815 DATA_BLOB session_key
= data_blob_null
;
818 char *workgroup_upper
;
820 req
= tevent_req_create(mem_ctx
, &state
,
821 struct cli_session_setup_nt1_state
);
830 /* do nothing - guest login */
831 } else if (passlen
!= 24) {
832 if (lp_client_ntlmv2_auth()) {
833 DATA_BLOB server_chal
;
834 DATA_BLOB names_blob
;
837 data_blob_const(smb1cli_conn_server_challenge(cli
->conn
),
841 * note that the 'workgroup' here is a best
842 * guess - we don't know the server's domain
843 * at this point. Windows clients also don't
846 names_blob
= NTLMv2_generate_names_blob(
847 NULL
, NULL
, workgroup
);
849 if (tevent_req_nomem(names_blob
.data
, req
)) {
850 return tevent_req_post(req
, ev
);
853 if (!SMBNTLMv2encrypt(NULL
, user
, workgroup
, pass
,
854 &server_chal
, &names_blob
,
855 &lm_response
, &nt_response
,
856 NULL
, &session_key
)) {
857 data_blob_free(&names_blob
);
859 req
, NT_STATUS_ACCESS_DENIED
);
860 return tevent_req_post(req
, ev
);
862 data_blob_free(&names_blob
);
866 E_md4hash(pass
, nt_hash
);
869 nt_response
= data_blob_null
;
871 nt_response
= data_blob(NULL
, 24);
872 if (tevent_req_nomem(nt_response
.data
, req
)) {
873 return tevent_req_post(req
, ev
);
876 SMBNTencrypt(pass
, smb1cli_conn_server_challenge(cli
->conn
),
879 /* non encrypted password supplied. Ignore ntpass. */
880 if (lp_client_lanman_auth()) {
882 lm_response
= data_blob(NULL
, 24);
883 if (tevent_req_nomem(lm_response
.data
, req
)) {
884 return tevent_req_post(req
, ev
);
887 if (!SMBencrypt(pass
,
888 smb1cli_conn_server_challenge(cli
->conn
),
891 * Oops, the LM response is
892 * invalid, just put the NT
893 * response there instead
895 data_blob_free(&lm_response
);
896 lm_response
= data_blob(
902 * LM disabled, place NT# in LM field
905 lm_response
= data_blob(
906 nt_response
.data
, nt_response
.length
);
909 if (tevent_req_nomem(lm_response
.data
, req
)) {
910 return tevent_req_post(req
, ev
);
913 session_key
= data_blob(NULL
, 16);
914 if (tevent_req_nomem(session_key
.data
, req
)) {
915 return tevent_req_post(req
, ev
);
918 E_deshash(pass
, session_key
.data
);
919 memset(&session_key
.data
[8], '\0', 8);
921 SMBsesskeygen_ntv1(nt_hash
, session_key
.data
);
925 /* pre-encrypted password supplied. Only used for
926 security=server, can't do
927 signing because we don't have original key */
929 lm_response
= data_blob(pass
, passlen
);
930 if (tevent_req_nomem(lm_response
.data
, req
)) {
931 return tevent_req_post(req
, ev
);
934 nt_response
= data_blob(ntpass
, ntpasslen
);
935 if (tevent_req_nomem(nt_response
.data
, req
)) {
936 return tevent_req_post(req
, ev
);
941 state
->response
= data_blob_talloc(
942 state
, lm_response
.data
, lm_response
.length
);
944 state
->response
= data_blob_talloc(
945 state
, nt_response
.data
, nt_response
.length
);
947 if (tevent_req_nomem(state
->response
.data
, req
)) {
948 return tevent_req_post(req
, ev
);
951 if (session_key
.data
) {
952 state
->session_key
= data_blob_talloc(
953 state
, session_key
.data
, session_key
.length
);
954 if (tevent_req_nomem(state
->session_key
.data
, req
)) {
955 return tevent_req_post(req
, ev
);
958 data_blob_free(&session_key
);
960 SCVAL(vwv
+0, 0, 0xff);
963 SSVAL(vwv
+2, 0, CLI_BUFFER_SIZE
);
965 SSVAL(vwv
+4, 0, cli_state_get_vc_num(cli
));
966 SIVAL(vwv
+5, 0, smb1cli_conn_server_session_key(cli
->conn
));
967 SSVAL(vwv
+7, 0, lm_response
.length
);
968 SSVAL(vwv
+8, 0, nt_response
.length
);
971 SIVAL(vwv
+11, 0, cli_session_setup_capabilities(cli
, 0));
973 bytes
= talloc_array(state
, uint8_t,
974 lm_response
.length
+ nt_response
.length
);
975 if (tevent_req_nomem(bytes
, req
)) {
976 return tevent_req_post(req
, ev
);
978 if (lm_response
.length
!= 0) {
979 memcpy(bytes
, lm_response
.data
, lm_response
.length
);
981 if (nt_response
.length
!= 0) {
982 memcpy(bytes
+ lm_response
.length
,
983 nt_response
.data
, nt_response
.length
);
985 data_blob_free(&lm_response
);
986 data_blob_free(&nt_response
);
988 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
989 user
, strlen(user
)+1, NULL
);
992 * Upper case here might help some NTLMv2 implementations
994 workgroup_upper
= talloc_strdup_upper(talloc_tos(), workgroup
);
995 if (tevent_req_nomem(workgroup_upper
, req
)) {
996 return tevent_req_post(req
, ev
);
998 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
999 workgroup_upper
, strlen(workgroup_upper
)+1,
1001 TALLOC_FREE(workgroup_upper
);
1003 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "Unix", 5, NULL
);
1004 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "Samba", 6, NULL
);
1005 if (tevent_req_nomem(bytes
, req
)) {
1006 return tevent_req_post(req
, ev
);
1009 subreq
= cli_smb_send(state
, ev
, cli
, SMBsesssetupX
, 0, 13, vwv
,
1010 talloc_get_size(bytes
), bytes
);
1011 if (tevent_req_nomem(subreq
, req
)) {
1012 return tevent_req_post(req
, ev
);
1014 tevent_req_set_callback(subreq
, cli_session_setup_nt1_done
, req
);
1018 static void cli_session_setup_nt1_done(struct tevent_req
*subreq
)
1020 struct tevent_req
*req
= tevent_req_callback_data(
1021 subreq
, struct tevent_req
);
1022 struct cli_session_setup_nt1_state
*state
= tevent_req_data(
1023 req
, struct cli_session_setup_nt1_state
);
1024 struct cli_state
*cli
= state
->cli
;
1035 status
= cli_smb_recv(subreq
, state
, &in
, 3, &wct
, &vwv
,
1036 &num_bytes
, &bytes
);
1037 TALLOC_FREE(subreq
);
1038 if (!NT_STATUS_IS_OK(status
)) {
1039 tevent_req_nterror(req
, status
);
1043 inhdr
= in
+ NBT_HDR_SIZE
;
1046 cli_state_set_uid(state
->cli
, SVAL(inhdr
, HDR_UID
));
1047 cli
->is_guestlogin
= ((SVAL(vwv
+2, 0) & 1) != 0);
1049 status
= smb_bytes_talloc_string(cli
,
1055 if (!NT_STATUS_IS_OK(status
)) {
1056 tevent_req_nterror(req
, status
);
1061 status
= smb_bytes_talloc_string(cli
,
1067 if (!NT_STATUS_IS_OK(status
)) {
1068 tevent_req_nterror(req
, status
);
1073 status
= smb_bytes_talloc_string(cli
,
1075 &cli
->server_domain
,
1079 if (!NT_STATUS_IS_OK(status
)) {
1080 tevent_req_nterror(req
, status
);
1085 status
= cli_set_username(cli
, state
->user
);
1086 if (tevent_req_nterror(req
, status
)) {
1089 if (smb1cli_conn_activate_signing(cli
->conn
, state
->session_key
, state
->response
)
1090 && !smb1cli_conn_check_signing(cli
->conn
, (uint8_t *)in
, 1)) {
1091 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1094 if (state
->session_key
.data
) {
1095 /* Have plaintext orginal */
1096 cli_set_session_key(cli
, state
->session_key
);
1098 tevent_req_done(req
);
1101 static NTSTATUS
cli_session_setup_nt1_recv(struct tevent_req
*req
)
1103 return tevent_req_simple_recv_ntstatus(req
);
1106 static NTSTATUS
cli_session_setup_nt1(struct cli_state
*cli
, const char *user
,
1107 const char *pass
, size_t passlen
,
1108 const char *ntpass
, size_t ntpasslen
,
1109 const char *workgroup
)
1111 TALLOC_CTX
*frame
= talloc_stackframe();
1112 struct event_context
*ev
;
1113 struct tevent_req
*req
;
1114 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
1116 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
1118 * Can't use sync call while an async call is in flight
1120 status
= NT_STATUS_INVALID_PARAMETER
;
1123 ev
= event_context_init(frame
);
1127 req
= cli_session_setup_nt1_send(frame
, ev
, cli
, user
, pass
, passlen
,
1128 ntpass
, ntpasslen
, workgroup
);
1132 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
1135 status
= cli_session_setup_nt1_recv(req
);
1141 /* The following is calculated from :
1143 * (smb_wcnt * 2) = 24 (smb_wcnt == 12 in cli_session_setup_blob_send() )
1144 * (strlen("Unix") + 1 + strlen("Samba") + 1) * 2 = 22 (unicode strings at
1148 #define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22)
1150 struct cli_sesssetup_blob_state
{
1151 struct tevent_context
*ev
;
1152 struct cli_state
*cli
;
1154 uint16_t max_blob_size
;
1158 DATA_BLOB smb2_blob
;
1159 struct iovec
*recv_iov
;
1166 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state
*state
,
1167 struct tevent_req
**psubreq
);
1168 static void cli_sesssetup_blob_done(struct tevent_req
*subreq
);
1170 static struct tevent_req
*cli_sesssetup_blob_send(TALLOC_CTX
*mem_ctx
,
1171 struct tevent_context
*ev
,
1172 struct cli_state
*cli
,
1175 struct tevent_req
*req
, *subreq
;
1176 struct cli_sesssetup_blob_state
*state
;
1177 uint32_t usable_space
;
1179 req
= tevent_req_create(mem_ctx
, &state
,
1180 struct cli_sesssetup_blob_state
);
1188 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
1189 usable_space
= UINT16_MAX
;
1191 usable_space
= cli_state_available_size(cli
,
1192 BASE_SESSSETUP_BLOB_PACKET_SIZE
);
1195 if (usable_space
== 0) {
1196 DEBUG(1, ("cli_session_setup_blob: cli->max_xmit too small "
1197 "(not possible to send %u bytes)\n",
1198 BASE_SESSSETUP_BLOB_PACKET_SIZE
+ 1));
1199 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1200 return tevent_req_post(req
, ev
);
1202 state
->max_blob_size
= MIN(usable_space
, 0xFFFF);
1204 if (!cli_sesssetup_blob_next(state
, &subreq
)) {
1205 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
1206 return tevent_req_post(req
, ev
);
1208 tevent_req_set_callback(subreq
, cli_sesssetup_blob_done
, req
);
1212 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state
*state
,
1213 struct tevent_req
**psubreq
)
1215 struct tevent_req
*subreq
;
1218 thistime
= MIN(state
->blob
.length
, state
->max_blob_size
);
1220 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
1222 state
->smb2_blob
.data
= state
->blob
.data
;
1223 state
->smb2_blob
.length
= thistime
;
1225 state
->blob
.data
+= thistime
;
1226 state
->blob
.length
-= thistime
;
1228 subreq
= smb2cli_session_setup_send(state
, state
->ev
,
1230 state
->cli
->timeout
,
1231 state
->cli
->smb2
.session
,
1233 SMB2_CAP_DFS
, /* in_capabilities */
1235 0, /* in_previous_session_id */
1237 if (subreq
== NULL
) {
1244 SCVAL(state
->vwv
+0, 0, 0xFF);
1245 SCVAL(state
->vwv
+0, 1, 0);
1246 SSVAL(state
->vwv
+1, 0, 0);
1247 SSVAL(state
->vwv
+2, 0, CLI_BUFFER_SIZE
);
1248 SSVAL(state
->vwv
+3, 0, 2);
1249 SSVAL(state
->vwv
+4, 0, 1);
1250 SIVAL(state
->vwv
+5, 0, 0);
1252 SSVAL(state
->vwv
+7, 0, thistime
);
1254 SSVAL(state
->vwv
+8, 0, 0);
1255 SSVAL(state
->vwv
+9, 0, 0);
1256 SIVAL(state
->vwv
+10, 0,
1257 cli_session_setup_capabilities(state
->cli
, CAP_EXTENDED_SECURITY
));
1259 state
->buf
= (uint8_t *)talloc_memdup(state
, state
->blob
.data
,
1261 if (state
->buf
== NULL
) {
1264 state
->blob
.data
+= thistime
;
1265 state
->blob
.length
-= thistime
;
1267 state
->buf
= smb_bytes_push_str(state
->buf
, smbXcli_conn_use_unicode(state
->cli
->conn
),
1269 state
->buf
= smb_bytes_push_str(state
->buf
, smbXcli_conn_use_unicode(state
->cli
->conn
),
1271 if (state
->buf
== NULL
) {
1274 subreq
= cli_smb_send(state
, state
->ev
, state
->cli
, SMBsesssetupX
, 0,
1276 talloc_get_size(state
->buf
), state
->buf
);
1277 if (subreq
== NULL
) {
1284 static void cli_sesssetup_blob_done(struct tevent_req
*subreq
)
1286 struct tevent_req
*req
= tevent_req_callback_data(
1287 subreq
, struct tevent_req
);
1288 struct cli_sesssetup_blob_state
*state
= tevent_req_data(
1289 req
, struct cli_sesssetup_blob_state
);
1290 struct cli_state
*cli
= state
->cli
;
1297 uint16_t blob_length
;
1302 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
1303 status
= smb2cli_session_setup_recv(subreq
, state
,
1307 status
= cli_smb_recv(subreq
, state
, &in
, 4, &wct
, &vwv
,
1308 &num_bytes
, &bytes
);
1309 TALLOC_FREE(state
->buf
);
1311 TALLOC_FREE(subreq
);
1312 if (!NT_STATUS_IS_OK(status
)
1313 && !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1314 tevent_req_nterror(req
, status
);
1318 state
->status
= status
;
1320 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
1325 inhdr
= in
+ NBT_HDR_SIZE
;
1326 cli_state_set_uid(state
->cli
, SVAL(inhdr
, HDR_UID
));
1327 cli
->is_guestlogin
= ((SVAL(vwv
+2, 0) & 1) != 0);
1329 blob_length
= SVAL(vwv
+3, 0);
1330 if (blob_length
> num_bytes
) {
1331 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
1334 state
->ret_blob
= data_blob_const(bytes
, blob_length
);
1336 p
= bytes
+ blob_length
;
1338 status
= smb_bytes_talloc_string(cli
,
1345 if (!NT_STATUS_IS_OK(status
)) {
1346 tevent_req_nterror(req
, status
);
1351 status
= smb_bytes_talloc_string(cli
,
1358 if (!NT_STATUS_IS_OK(status
)) {
1359 tevent_req_nterror(req
, status
);
1364 status
= smb_bytes_talloc_string(cli
,
1366 &cli
->server_domain
,
1371 if (!NT_STATUS_IS_OK(status
)) {
1372 tevent_req_nterror(req
, status
);
1378 if (state
->blob
.length
!= 0) {
1382 if (!cli_sesssetup_blob_next(state
, &subreq
)) {
1383 tevent_req_oom(req
);
1386 tevent_req_set_callback(subreq
, cli_sesssetup_blob_done
, req
);
1389 tevent_req_done(req
);
1392 static NTSTATUS
cli_sesssetup_blob_recv(struct tevent_req
*req
,
1393 TALLOC_CTX
*mem_ctx
,
1396 struct iovec
**precv_iov
)
1398 struct cli_sesssetup_blob_state
*state
= tevent_req_data(
1399 req
, struct cli_sesssetup_blob_state
);
1402 struct iovec
*recv_iov
;
1404 if (tevent_req_is_nterror(req
, &status
)) {
1405 TALLOC_FREE(state
->cli
->smb2
.session
);
1406 cli_state_set_uid(state
->cli
, UID_FIELD_INVALID
);
1410 inbuf
= talloc_move(mem_ctx
, &state
->inbuf
);
1411 recv_iov
= talloc_move(mem_ctx
, &state
->recv_iov
);
1412 if (pblob
!= NULL
) {
1413 *pblob
= state
->ret_blob
;
1415 if (pinbuf
!= NULL
) {
1418 if (precv_iov
!= NULL
) {
1419 *precv_iov
= recv_iov
;
1421 /* could be NT_STATUS_MORE_PROCESSING_REQUIRED */
1422 return state
->status
;
1427 /****************************************************************************
1428 Use in-memory credentials cache
1429 ****************************************************************************/
1431 static void use_in_memory_ccache(void) {
1432 setenv(KRB5_ENV_CCNAME
, "MEMORY:cliconnect", 1);
1435 /****************************************************************************
1436 Do a spnego/kerberos encrypted session setup.
1437 ****************************************************************************/
1439 struct cli_session_setup_kerberos_state
{
1440 struct cli_state
*cli
;
1441 DATA_BLOB negTokenTarg
;
1442 DATA_BLOB session_key_krb5
;
1443 ADS_STATUS ads_status
;
1446 static void cli_session_setup_kerberos_done(struct tevent_req
*subreq
);
1448 static struct tevent_req
*cli_session_setup_kerberos_send(
1449 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
1450 const char *principal
)
1452 struct tevent_req
*req
, *subreq
;
1453 struct cli_session_setup_kerberos_state
*state
;
1456 DEBUG(2,("Doing kerberos session setup\n"));
1458 req
= tevent_req_create(mem_ctx
, &state
,
1459 struct cli_session_setup_kerberos_state
);
1464 state
->ads_status
= ADS_SUCCESS
;
1467 * Ok, this is cheating: spnego_gen_krb5_negTokenInit can block if
1468 * we have to acquire a ticket. To be fixed later :-)
1470 rc
= spnego_gen_krb5_negTokenInit(state
, principal
, 0, &state
->negTokenTarg
,
1471 &state
->session_key_krb5
, 0, NULL
);
1473 DEBUG(1, ("cli_session_setup_kerberos: "
1474 "spnego_gen_krb5_negTokenInit failed: %s\n",
1475 error_message(rc
)));
1476 state
->ads_status
= ADS_ERROR_KRB5(rc
);
1477 tevent_req_nterror(req
, NT_STATUS_UNSUCCESSFUL
);
1478 return tevent_req_post(req
, ev
);
1482 file_save("negTokenTarg.dat", state
->negTokenTarg
.data
,
1483 state
->negTokenTarg
.length
);
1486 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
1487 state
->cli
->smb2
.session
= smbXcli_session_create(cli
,
1489 if (tevent_req_nomem(state
->cli
->smb2
.session
, req
)) {
1490 return tevent_req_post(req
, ev
);
1494 subreq
= cli_sesssetup_blob_send(state
, ev
, cli
, state
->negTokenTarg
);
1495 if (tevent_req_nomem(subreq
, req
)) {
1496 return tevent_req_post(req
, ev
);
1498 tevent_req_set_callback(subreq
, cli_session_setup_kerberos_done
, req
);
1502 static void cli_session_setup_kerberos_done(struct tevent_req
*subreq
)
1504 struct tevent_req
*req
= tevent_req_callback_data(
1505 subreq
, struct tevent_req
);
1506 struct cli_session_setup_kerberos_state
*state
= tevent_req_data(
1507 req
, struct cli_session_setup_kerberos_state
);
1508 uint8_t *inbuf
= NULL
;
1509 struct iovec
*recv_iov
= NULL
;
1512 status
= cli_sesssetup_blob_recv(subreq
, state
,
1513 NULL
, &inbuf
, &recv_iov
);
1514 TALLOC_FREE(subreq
);
1515 if (!NT_STATUS_IS_OK(status
)) {
1516 tevent_req_nterror(req
, status
);
1520 cli_set_session_key(state
->cli
, state
->session_key_krb5
);
1522 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
1523 struct smbXcli_session
*session
= state
->cli
->smb2
.session
;
1524 status
= smb2cli_session_set_session_key(session
,
1525 state
->session_key_krb5
,
1527 if (tevent_req_nterror(req
, status
)) {
1531 if (smb1cli_conn_activate_signing(state
->cli
->conn
, state
->session_key_krb5
,
1533 && !smb1cli_conn_check_signing(state
->cli
->conn
, inbuf
, 1)) {
1534 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1539 tevent_req_done(req
);
1542 static ADS_STATUS
cli_session_setup_kerberos_recv(struct tevent_req
*req
)
1544 struct cli_session_setup_kerberos_state
*state
= tevent_req_data(
1545 req
, struct cli_session_setup_kerberos_state
);
1548 if (tevent_req_is_nterror(req
, &status
)) {
1549 return ADS_ERROR_NT(status
);
1551 return state
->ads_status
;
1554 static ADS_STATUS
cli_session_setup_kerberos(struct cli_state
*cli
,
1555 const char *principal
)
1557 struct tevent_context
*ev
;
1558 struct tevent_req
*req
;
1559 ADS_STATUS status
= ADS_ERROR_NT(NT_STATUS_NO_MEMORY
);
1561 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
1562 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
1564 ev
= tevent_context_init(talloc_tos());
1568 req
= cli_session_setup_kerberos_send(ev
, ev
, cli
, principal
);
1572 if (!tevent_req_poll(req
, ev
)) {
1573 status
= ADS_ERROR_SYSTEM(errno
);
1576 status
= cli_session_setup_kerberos_recv(req
);
1581 #endif /* HAVE_KRB5 */
1583 /****************************************************************************
1584 Do a spnego/NTLMSSP encrypted session setup.
1585 ****************************************************************************/
1587 struct cli_session_setup_ntlmssp_state
{
1588 struct tevent_context
*ev
;
1589 struct cli_state
*cli
;
1590 struct ntlmssp_state
*ntlmssp_state
;
1595 static int cli_session_setup_ntlmssp_state_destructor(
1596 struct cli_session_setup_ntlmssp_state
*state
)
1598 if (state
->ntlmssp_state
!= NULL
) {
1599 TALLOC_FREE(state
->ntlmssp_state
);
1604 static void cli_session_setup_ntlmssp_done(struct tevent_req
*req
);
1606 static struct tevent_req
*cli_session_setup_ntlmssp_send(
1607 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
1608 const char *user
, const char *pass
, const char *domain
)
1610 struct tevent_req
*req
, *subreq
;
1611 struct cli_session_setup_ntlmssp_state
*state
;
1614 const char *OIDs_ntlm
[] = {OID_NTLMSSP
, NULL
};
1616 req
= tevent_req_create(mem_ctx
, &state
,
1617 struct cli_session_setup_ntlmssp_state
);
1625 state
->ntlmssp_state
= NULL
;
1626 talloc_set_destructor(
1627 state
, cli_session_setup_ntlmssp_state_destructor
);
1629 status
= ntlmssp_client_start(state
,
1632 lp_client_ntlmv2_auth(),
1633 &state
->ntlmssp_state
);
1634 if (!NT_STATUS_IS_OK(status
)) {
1637 ntlmssp_want_feature(state
->ntlmssp_state
,
1638 NTLMSSP_FEATURE_SESSION_KEY
);
1639 if (cli
->use_ccache
) {
1640 ntlmssp_want_feature(state
->ntlmssp_state
,
1641 NTLMSSP_FEATURE_CCACHE
);
1643 status
= ntlmssp_set_username(state
->ntlmssp_state
, user
);
1644 if (!NT_STATUS_IS_OK(status
)) {
1647 status
= ntlmssp_set_domain(state
->ntlmssp_state
, domain
);
1648 if (!NT_STATUS_IS_OK(status
)) {
1651 status
= ntlmssp_set_password(state
->ntlmssp_state
, pass
);
1652 if (!NT_STATUS_IS_OK(status
)) {
1655 status
= ntlmssp_update(state
->ntlmssp_state
, data_blob_null
,
1657 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1661 state
->blob_out
= spnego_gen_negTokenInit(state
, OIDs_ntlm
, &blob_out
, NULL
);
1662 data_blob_free(&blob_out
);
1664 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
1665 state
->cli
->smb2
.session
= smbXcli_session_create(cli
,
1667 if (tevent_req_nomem(state
->cli
->smb2
.session
, req
)) {
1668 return tevent_req_post(req
, ev
);
1672 subreq
= cli_sesssetup_blob_send(state
, ev
, cli
, state
->blob_out
);
1673 if (tevent_req_nomem(subreq
, req
)) {
1674 return tevent_req_post(req
, ev
);
1676 tevent_req_set_callback(subreq
, cli_session_setup_ntlmssp_done
, req
);
1679 tevent_req_nterror(req
, status
);
1680 return tevent_req_post(req
, ev
);
1683 static void cli_session_setup_ntlmssp_done(struct tevent_req
*subreq
)
1685 struct tevent_req
*req
= tevent_req_callback_data(
1686 subreq
, struct tevent_req
);
1687 struct cli_session_setup_ntlmssp_state
*state
= tevent_req_data(
1688 req
, struct cli_session_setup_ntlmssp_state
);
1689 DATA_BLOB blob_in
, msg_in
, blob_out
;
1690 uint8_t *inbuf
= NULL
;
1691 struct iovec
*recv_iov
= NULL
;
1695 status
= cli_sesssetup_blob_recv(subreq
, talloc_tos(), &blob_in
,
1697 TALLOC_FREE(subreq
);
1698 data_blob_free(&state
->blob_out
);
1700 if (NT_STATUS_IS_OK(status
)) {
1701 if (state
->cli
->server_domain
[0] == '\0') {
1702 TALLOC_FREE(state
->cli
->server_domain
);
1703 state
->cli
->server_domain
= talloc_strdup(state
->cli
,
1704 state
->ntlmssp_state
->server
.netbios_domain
);
1705 if (state
->cli
->server_domain
== NULL
) {
1706 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
1710 cli_set_session_key(
1711 state
->cli
, state
->ntlmssp_state
->session_key
);
1713 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
1714 struct smbXcli_session
*session
= state
->cli
->smb2
.session
;
1716 if (ntlmssp_is_anonymous(state
->ntlmssp_state
)) {
1718 * Windows server does not set the
1719 * SMB2_SESSION_FLAG_IS_GUEST nor
1720 * SMB2_SESSION_FLAG_IS_NULL flag.
1722 * This fix makes sure we do not try
1723 * to verify a signature on the final
1724 * session setup response.
1726 TALLOC_FREE(state
->ntlmssp_state
);
1727 tevent_req_done(req
);
1731 status
= smb2cli_session_set_session_key(session
,
1732 state
->ntlmssp_state
->session_key
,
1734 if (tevent_req_nterror(req
, status
)) {
1738 if (smb1cli_conn_activate_signing(
1739 state
->cli
->conn
, state
->ntlmssp_state
->session_key
,
1741 && !smb1cli_conn_check_signing(state
->cli
->conn
, inbuf
, 1)) {
1742 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1746 TALLOC_FREE(state
->ntlmssp_state
);
1747 tevent_req_done(req
);
1750 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1751 tevent_req_nterror(req
, status
);
1755 if (blob_in
.length
== 0) {
1756 tevent_req_nterror(req
, NT_STATUS_UNSUCCESSFUL
);
1760 if ((state
->turn
== 1)
1761 && NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1762 DATA_BLOB tmp_blob
= data_blob_null
;
1763 /* the server might give us back two challenges */
1764 parse_ret
= spnego_parse_challenge(state
, blob_in
, &msg_in
,
1766 data_blob_free(&tmp_blob
);
1768 parse_ret
= spnego_parse_auth_response(state
, blob_in
, status
,
1769 OID_NTLMSSP
, &msg_in
);
1774 DEBUG(3,("Failed to parse auth response\n"));
1775 if (NT_STATUS_IS_OK(status
)
1776 || NT_STATUS_EQUAL(status
,
1777 NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1779 req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
1784 status
= ntlmssp_update(state
->ntlmssp_state
, msg_in
, &blob_out
);
1786 if (!NT_STATUS_IS_OK(status
)
1787 && !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1788 TALLOC_FREE(state
->ntlmssp_state
);
1789 tevent_req_nterror(req
, status
);
1793 state
->blob_out
= spnego_gen_auth(state
, blob_out
);
1794 if (tevent_req_nomem(state
->blob_out
.data
, req
)) {
1798 subreq
= cli_sesssetup_blob_send(state
, state
->ev
, state
->cli
,
1800 if (tevent_req_nomem(subreq
, req
)) {
1803 tevent_req_set_callback(subreq
, cli_session_setup_ntlmssp_done
, req
);
1806 static NTSTATUS
cli_session_setup_ntlmssp_recv(struct tevent_req
*req
)
1808 struct cli_session_setup_ntlmssp_state
*state
= tevent_req_data(
1809 req
, struct cli_session_setup_ntlmssp_state
);
1812 if (tevent_req_is_nterror(req
, &status
)) {
1813 cli_state_set_uid(state
->cli
, UID_FIELD_INVALID
);
1816 return NT_STATUS_OK
;
1819 static NTSTATUS
cli_session_setup_ntlmssp(struct cli_state
*cli
,
1824 struct tevent_context
*ev
;
1825 struct tevent_req
*req
;
1826 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
1828 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
1829 return NT_STATUS_INVALID_PARAMETER
;
1831 ev
= tevent_context_init(talloc_tos());
1835 req
= cli_session_setup_ntlmssp_send(ev
, ev
, cli
, user
, pass
, domain
);
1839 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
1842 status
= cli_session_setup_ntlmssp_recv(req
);
1848 /****************************************************************************
1849 Do a spnego encrypted session setup.
1851 user_domain: The shortname of the domain the user/machine is a member of.
1852 dest_realm: The realm we're connecting to, if NULL we use our default realm.
1853 ****************************************************************************/
1855 static ADS_STATUS
cli_session_setup_spnego(struct cli_state
*cli
,
1858 const char *user_domain
,
1859 const char * dest_realm
)
1861 char *principal
= NULL
;
1862 char *OIDs
[ASN1_MAX_OIDS
];
1864 const DATA_BLOB
*server_blob
;
1865 DATA_BLOB blob
= data_blob_null
;
1866 const char *p
= NULL
;
1867 char *account
= NULL
;
1870 server_blob
= smbXcli_conn_server_gss_blob(cli
->conn
);
1872 blob
= data_blob(server_blob
->data
, server_blob
->length
);
1875 DEBUG(3,("Doing spnego session setup (blob length=%lu)\n", (unsigned long)blob
.length
));
1877 /* the server might not even do spnego */
1878 if (blob
.length
== 0) {
1879 DEBUG(3,("server didn't supply a full spnego negprot\n"));
1884 file_save("negprot.dat", cli
->secblob
.data
, cli
->secblob
.length
);
1887 /* The server sent us the first part of the SPNEGO exchange in the
1888 * negprot reply. It is WRONG to depend on the principal sent in the
1889 * negprot reply, but right now we do it. If we don't receive one,
1890 * we try to best guess, then fall back to NTLM. */
1891 if (!spnego_parse_negTokenInit(talloc_tos(), blob
, OIDs
, &principal
, NULL
) ||
1893 data_blob_free(&blob
);
1894 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
1896 data_blob_free(&blob
);
1898 /* make sure the server understands kerberos */
1899 for (i
=0;OIDs
[i
];i
++) {
1901 DEBUG(3,("got OID=%s\n", OIDs
[i
]));
1903 DEBUGADD(3,("got OID=%s\n", OIDs
[i
]));
1904 if (strcmp(OIDs
[i
], OID_KERBEROS5_OLD
) == 0 ||
1905 strcmp(OIDs
[i
], OID_KERBEROS5
) == 0) {
1906 cli
->got_kerberos_mechanism
= True
;
1908 talloc_free(OIDs
[i
]);
1911 DEBUG(3,("got principal=%s\n", principal
? principal
: "<null>"));
1913 status
= cli_set_username(cli
, user
);
1914 if (!NT_STATUS_IS_OK(status
)) {
1915 TALLOC_FREE(principal
);
1916 return ADS_ERROR_NT(status
);
1920 /* If password is set we reauthenticate to kerberos server
1921 * and do not store results */
1923 if (user
&& *user
&& cli
->got_kerberos_mechanism
&& cli
->use_kerberos
) {
1925 const char *remote_name
= smbXcli_conn_remote_name(cli
->conn
);
1927 if (pass
&& *pass
) {
1930 use_in_memory_ccache();
1931 ret
= kerberos_kinit_password(user
, pass
, 0 /* no time correction for now */, NULL
);
1934 TALLOC_FREE(principal
);
1935 DEBUG(0, ("Kinit failed: %s\n", error_message(ret
)));
1936 if (cli
->fallback_after_kerberos
)
1938 return ADS_ERROR_KRB5(ret
);
1942 /* We may not be allowed to use the server-supplied SPNEGO principal, or it may not have been supplied to us
1944 if (!lp_client_use_spnego_principal() || strequal(principal
, ADS_IGNORE_PRINCIPAL
)) {
1945 TALLOC_FREE(principal
);
1948 if (principal
== NULL
&&
1949 !is_ipaddress(remote_name
) &&
1950 !strequal(STAR_SMBSERVER
,
1952 DEBUG(3,("cli_session_setup_spnego: using target "
1953 "hostname not SPNEGO principal\n"));
1956 char *realm
= strupper_talloc(talloc_tos(), dest_realm
);
1958 principal
= talloc_asprintf(talloc_tos(),
1965 principal
= kerberos_get_principal_from_service_hostname(talloc_tos(),
1972 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY
);
1974 DEBUG(3,("cli_session_setup_spnego: guessed "
1975 "server principal=%s\n",
1976 principal
? principal
: "<null>"));
1980 rc
= cli_session_setup_kerberos(cli
, principal
);
1981 if (ADS_ERR_OK(rc
) || !cli
->fallback_after_kerberos
) {
1982 TALLOC_FREE(principal
);
1989 TALLOC_FREE(principal
);
1993 account
= talloc_strdup(talloc_tos(), user
);
1995 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY
);
1998 /* when falling back to ntlmssp while authenticating with a machine
1999 * account strip off the realm - gd */
2001 if ((p
= strchr_m(user
, '@')) != NULL
) {
2002 account
[PTR_DIFF(p
,user
)] = '\0';
2005 return ADS_ERROR_NT(cli_session_setup_ntlmssp(cli
, account
, pass
, user_domain
));
2008 /****************************************************************************
2009 Send a session setup. The username and workgroup is in UNIX character
2010 format and must be converted to DOS codepage format before sending. If the
2011 password is in plaintext, the same should be done.
2012 ****************************************************************************/
2014 NTSTATUS
cli_session_setup(struct cli_state
*cli
,
2016 const char *pass
, int passlen
,
2017 const char *ntpass
, int ntpasslen
,
2018 const char *workgroup
)
2022 uint16_t sec_mode
= smb1cli_conn_server_security_mode(cli
->conn
);
2025 user2
= talloc_strdup(talloc_tos(), user
);
2027 user2
= talloc_strdup(talloc_tos(), "");
2029 if (user2
== NULL
) {
2030 return NT_STATUS_NO_MEMORY
;
2037 /* allow for workgroups as part of the username */
2038 if ((p
=strchr_m(user2
,'\\')) || (p
=strchr_m(user2
,'/')) ||
2039 (p
=strchr_m(user2
,*lp_winbind_separator()))) {
2046 if (smbXcli_conn_protocol(cli
->conn
) < PROTOCOL_LANMAN1
) {
2047 return NT_STATUS_OK
;
2050 /* now work out what sort of session setup we are going to
2051 do. I have split this into separate functions to make the
2052 flow a bit easier to understand (tridge) */
2054 /* if its an older server then we have to use the older request format */
2056 if (smbXcli_conn_protocol(cli
->conn
) < PROTOCOL_NT1
) {
2057 if (!lp_client_lanman_auth() && passlen
!= 24 && (*pass
)) {
2058 DEBUG(1, ("Server requested LM password but 'client lanman auth = no'"
2059 " or 'client ntlmv2 auth = yes'\n"));
2060 return NT_STATUS_ACCESS_DENIED
;
2063 if ((sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
) == 0 &&
2064 !lp_client_plaintext_auth() && (*pass
)) {
2065 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
2066 " or 'client ntlmv2 auth = yes'\n"));
2067 return NT_STATUS_ACCESS_DENIED
;
2070 return cli_session_setup_lanman2(cli
, user
, pass
, passlen
,
2074 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
2075 const char *remote_realm
= cli_state_remote_realm(cli
);
2076 ADS_STATUS status
= cli_session_setup_spnego(cli
, user
, pass
,
2079 if (!ADS_ERR_OK(status
)) {
2080 DEBUG(3, ("SMB2-SPNEGO login failed: %s\n", ads_errstr(status
)));
2081 return ads_ntstatus(status
);
2083 return NT_STATUS_OK
;
2086 /* if no user is supplied then we have to do an anonymous connection.
2087 passwords are ignored */
2089 if (!user
|| !*user
)
2090 return cli_session_setup_guest(cli
);
2092 /* if the server is share level then send a plaintext null
2093 password at this point. The password is sent in the tree
2096 if ((sec_mode
& NEGOTIATE_SECURITY_USER_LEVEL
) == 0)
2097 return cli_session_setup_plain(cli
, user
, "", workgroup
);
2099 /* if the server doesn't support encryption then we have to use
2100 plaintext. The second password is ignored */
2102 if ((sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
) == 0) {
2103 if (!lp_client_plaintext_auth() && (*pass
)) {
2104 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
2105 " or 'client ntlmv2 auth = yes'\n"));
2106 return NT_STATUS_ACCESS_DENIED
;
2108 return cli_session_setup_plain(cli
, user
, pass
, workgroup
);
2111 /* if the server supports extended security then use SPNEGO */
2113 if (smb1cli_conn_capabilities(cli
->conn
) & CAP_EXTENDED_SECURITY
) {
2114 const char *remote_realm
= cli_state_remote_realm(cli
);
2115 ADS_STATUS status
= cli_session_setup_spnego(cli
, user
, pass
,
2118 if (!ADS_ERR_OK(status
)) {
2119 DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status
)));
2120 return ads_ntstatus(status
);
2125 /* otherwise do a NT1 style session setup */
2126 status
= cli_session_setup_nt1(cli
, user
, pass
, passlen
,
2127 ntpass
, ntpasslen
, workgroup
);
2128 if (!NT_STATUS_IS_OK(status
)) {
2129 DEBUG(3,("cli_session_setup: NT1 session setup "
2130 "failed: %s\n", nt_errstr(status
)));
2135 return NT_STATUS_OK
;
2138 /****************************************************************************
2140 *****************************************************************************/
2142 struct cli_ulogoff_state
{
2143 struct cli_state
*cli
;
2147 static void cli_ulogoff_done(struct tevent_req
*subreq
);
2149 struct tevent_req
*cli_ulogoff_send(TALLOC_CTX
*mem_ctx
,
2150 struct tevent_context
*ev
,
2151 struct cli_state
*cli
)
2153 struct tevent_req
*req
, *subreq
;
2154 struct cli_ulogoff_state
*state
;
2156 req
= tevent_req_create(mem_ctx
, &state
, struct cli_ulogoff_state
);
2162 SCVAL(state
->vwv
+0, 0, 0xFF);
2163 SCVAL(state
->vwv
+1, 0, 0);
2164 SSVAL(state
->vwv
+2, 0, 0);
2166 subreq
= cli_smb_send(state
, ev
, cli
, SMBulogoffX
, 0, 2, state
->vwv
,
2168 if (tevent_req_nomem(subreq
, req
)) {
2169 return tevent_req_post(req
, ev
);
2171 tevent_req_set_callback(subreq
, cli_ulogoff_done
, req
);
2175 static void cli_ulogoff_done(struct tevent_req
*subreq
)
2177 struct tevent_req
*req
= tevent_req_callback_data(
2178 subreq
, struct tevent_req
);
2179 struct cli_ulogoff_state
*state
= tevent_req_data(
2180 req
, struct cli_ulogoff_state
);
2183 status
= cli_smb_recv(subreq
, NULL
, NULL
, 0, NULL
, NULL
, NULL
, NULL
);
2184 if (!NT_STATUS_IS_OK(status
)) {
2185 tevent_req_nterror(req
, status
);
2188 cli_state_set_uid(state
->cli
, UID_FIELD_INVALID
);
2189 tevent_req_done(req
);
2192 NTSTATUS
cli_ulogoff_recv(struct tevent_req
*req
)
2194 return tevent_req_simple_recv_ntstatus(req
);
2197 NTSTATUS
cli_ulogoff(struct cli_state
*cli
)
2199 struct tevent_context
*ev
;
2200 struct tevent_req
*req
;
2201 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2203 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
2204 return NT_STATUS_INVALID_PARAMETER
;
2206 ev
= tevent_context_init(talloc_tos());
2210 req
= cli_ulogoff_send(ev
, ev
, cli
);
2214 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2217 status
= cli_ulogoff_recv(req
);
2223 /****************************************************************************
2225 ****************************************************************************/
2227 struct cli_tcon_andx_state
{
2228 struct cli_state
*cli
;
2233 static void cli_tcon_andx_done(struct tevent_req
*subreq
);
2235 struct tevent_req
*cli_tcon_andx_create(TALLOC_CTX
*mem_ctx
,
2236 struct event_context
*ev
,
2237 struct cli_state
*cli
,
2238 const char *share
, const char *dev
,
2239 const char *pass
, int passlen
,
2240 struct tevent_req
**psmbreq
)
2242 struct tevent_req
*req
, *subreq
;
2243 struct cli_tcon_andx_state
*state
;
2248 uint16_t sec_mode
= smb1cli_conn_server_security_mode(cli
->conn
);
2252 req
= tevent_req_create(mem_ctx
, &state
, struct cli_tcon_andx_state
);
2259 cli
->share
= talloc_strdup(cli
, share
);
2264 /* in user level security don't send a password now */
2265 if (sec_mode
& NEGOTIATE_SECURITY_USER_LEVEL
) {
2268 } else if (pass
== NULL
) {
2269 DEBUG(1, ("Server not using user level security and no "
2270 "password supplied.\n"));
2274 if ((sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
) &&
2275 *pass
&& passlen
!= 24) {
2276 if (!lp_client_lanman_auth()) {
2277 DEBUG(1, ("Server requested LANMAN password "
2278 "(share-level security) but "
2279 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2284 * Non-encrypted passwords - convert to DOS codepage before
2287 SMBencrypt(pass
, smb1cli_conn_server_challenge(cli
->conn
), p24
);
2289 pass
= (const char *)p24
;
2291 if((sec_mode
& (NEGOTIATE_SECURITY_USER_LEVEL
2292 |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
))
2296 if (!lp_client_plaintext_auth() && (*pass
)) {
2297 DEBUG(1, ("Server requested PLAINTEXT "
2299 "'client plaintext auth = no' or 'client ntlmv2 auth = yes'\n"));
2304 * Non-encrypted passwords - convert to DOS codepage
2307 tmp_pass
= talloc_array(talloc_tos(), uint8
, 0);
2308 if (tevent_req_nomem(tmp_pass
, req
)) {
2309 return tevent_req_post(req
, ev
);
2311 tmp_pass
= trans2_bytes_push_str(tmp_pass
,
2312 false, /* always DOS */
2316 if (tevent_req_nomem(tmp_pass
, req
)) {
2317 return tevent_req_post(req
, ev
);
2319 pass
= (const char *)tmp_pass
;
2320 passlen
= talloc_get_size(tmp_pass
);
2324 SCVAL(vwv
+0, 0, 0xFF);
2327 SSVAL(vwv
+2, 0, TCONX_FLAG_EXTENDED_RESPONSE
);
2328 SSVAL(vwv
+3, 0, passlen
);
2330 if (passlen
&& pass
) {
2331 bytes
= (uint8_t *)talloc_memdup(state
, pass
, passlen
);
2333 bytes
= talloc_array(state
, uint8_t, 0);
2339 tmp
= talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
2340 smbXcli_conn_remote_name(cli
->conn
), share
);
2345 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), tmp
, strlen(tmp
)+1,
2350 * Add the devicetype
2352 tmp
= talloc_strdup_upper(talloc_tos(), dev
);
2357 bytes
= smb_bytes_push_str(bytes
, false, tmp
, strlen(tmp
)+1, NULL
);
2360 if (bytes
== NULL
) {
2365 state
->bytes
.iov_base
= (void *)bytes
;
2366 state
->bytes
.iov_len
= talloc_get_size(bytes
);
2368 subreq
= cli_smb_req_create(state
, ev
, cli
, SMBtconX
, 0, 4, vwv
,
2370 if (subreq
== NULL
) {
2374 tevent_req_set_callback(subreq
, cli_tcon_andx_done
, req
);
2379 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
2380 return tevent_req_post(req
, ev
);
2383 struct tevent_req
*cli_tcon_andx_send(TALLOC_CTX
*mem_ctx
,
2384 struct event_context
*ev
,
2385 struct cli_state
*cli
,
2386 const char *share
, const char *dev
,
2387 const char *pass
, int passlen
)
2389 struct tevent_req
*req
, *subreq
;
2392 req
= cli_tcon_andx_create(mem_ctx
, ev
, cli
, share
, dev
, pass
, passlen
,
2397 if (subreq
== NULL
) {
2400 status
= smb1cli_req_chain_submit(&subreq
, 1);
2401 if (!NT_STATUS_IS_OK(status
)) {
2402 tevent_req_nterror(req
, status
);
2403 return tevent_req_post(req
, ev
);
2408 static void cli_tcon_andx_done(struct tevent_req
*subreq
)
2410 struct tevent_req
*req
= tevent_req_callback_data(
2411 subreq
, struct tevent_req
);
2412 struct cli_tcon_andx_state
*state
= tevent_req_data(
2413 req
, struct cli_tcon_andx_state
);
2414 struct cli_state
*cli
= state
->cli
;
2423 status
= cli_smb_recv(subreq
, state
, &in
, 0, &wct
, &vwv
,
2424 &num_bytes
, &bytes
);
2425 TALLOC_FREE(subreq
);
2426 if (!NT_STATUS_IS_OK(status
)) {
2427 tevent_req_nterror(req
, status
);
2431 inhdr
= in
+ NBT_HDR_SIZE
;
2434 if (clistr_pull_talloc(cli
,
2435 (const char *)inhdr
,
2436 SVAL(inhdr
, HDR_FLG2
),
2440 STR_TERMINATE
|STR_ASCII
) == -1) {
2441 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
2445 cli
->dev
= talloc_strdup(cli
, "");
2446 if (cli
->dev
== NULL
) {
2447 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
2452 if ((smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_NT1
) && (num_bytes
== 3)) {
2453 /* almost certainly win95 - enable bug fixes */
2458 * Make sure that we have the optional support 16-bit field. WCT > 2.
2459 * Avoids issues when connecting to Win9x boxes sharing files
2462 cli
->dfsroot
= false;
2464 if ((wct
> 2) && (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_LANMAN2
)) {
2465 cli
->dfsroot
= ((SVAL(vwv
+2, 0) & SMB_SHARE_IN_DFS
) != 0);
2468 cli
->smb1
.tid
= SVAL(inhdr
, HDR_TID
);
2469 tevent_req_done(req
);
2472 NTSTATUS
cli_tcon_andx_recv(struct tevent_req
*req
)
2474 return tevent_req_simple_recv_ntstatus(req
);
2477 NTSTATUS
cli_tcon_andx(struct cli_state
*cli
, const char *share
,
2478 const char *dev
, const char *pass
, int passlen
)
2480 TALLOC_CTX
*frame
= talloc_stackframe();
2481 struct event_context
*ev
;
2482 struct tevent_req
*req
;
2483 NTSTATUS status
= NT_STATUS_OK
;
2485 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
2487 * Can't use sync call while an async call is in flight
2489 status
= NT_STATUS_INVALID_PARAMETER
;
2493 ev
= event_context_init(frame
);
2495 status
= NT_STATUS_NO_MEMORY
;
2499 req
= cli_tcon_andx_send(frame
, ev
, cli
, share
, dev
, pass
, passlen
);
2501 status
= NT_STATUS_NO_MEMORY
;
2505 if (!tevent_req_poll(req
, ev
)) {
2506 status
= map_nt_error_from_unix(errno
);
2510 status
= cli_tcon_andx_recv(req
);
2516 NTSTATUS
cli_tree_connect(struct cli_state
*cli
, const char *share
,
2517 const char *dev
, const char *pass
, int passlen
)
2520 uint16_t max_xmit
= 0;
2523 cli
->share
= talloc_strdup(cli
, share
);
2525 return NT_STATUS_NO_MEMORY
;
2528 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
2529 return smb2cli_tcon(cli
, share
);
2532 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_LANMAN1
) {
2533 return cli_tcon_andx(cli
, share
, dev
, pass
, passlen
);
2536 status
= cli_raw_tcon(cli
, share
, pass
, dev
, &max_xmit
, &tid
);
2537 if (!NT_STATUS_IS_OK(status
)) {
2540 cli
->smb1
.tid
= tid
;
2542 return NT_STATUS_OK
;
2545 /****************************************************************************
2546 Send a tree disconnect.
2547 ****************************************************************************/
2549 struct cli_tdis_state
{
2550 struct cli_state
*cli
;
2553 static void cli_tdis_done(struct tevent_req
*subreq
);
2555 struct tevent_req
*cli_tdis_send(TALLOC_CTX
*mem_ctx
,
2556 struct tevent_context
*ev
,
2557 struct cli_state
*cli
)
2559 struct tevent_req
*req
, *subreq
;
2560 struct cli_tdis_state
*state
;
2562 req
= tevent_req_create(mem_ctx
, &state
, struct cli_tdis_state
);
2568 subreq
= cli_smb_send(state
, ev
, cli
, SMBtdis
, 0, 0, NULL
, 0, NULL
);
2569 if (tevent_req_nomem(subreq
, req
)) {
2570 return tevent_req_post(req
, ev
);
2572 tevent_req_set_callback(subreq
, cli_tdis_done
, req
);
2576 static void cli_tdis_done(struct tevent_req
*subreq
)
2578 struct tevent_req
*req
= tevent_req_callback_data(
2579 subreq
, struct tevent_req
);
2580 struct cli_tdis_state
*state
= tevent_req_data(
2581 req
, struct cli_tdis_state
);
2584 status
= cli_smb_recv(subreq
, NULL
, NULL
, 0, NULL
, NULL
, NULL
, NULL
);
2585 TALLOC_FREE(subreq
);
2586 if (!NT_STATUS_IS_OK(status
)) {
2587 tevent_req_nterror(req
, status
);
2590 state
->cli
->smb1
.tid
= UINT16_MAX
;
2591 tevent_req_done(req
);
2594 NTSTATUS
cli_tdis_recv(struct tevent_req
*req
)
2596 return tevent_req_simple_recv_ntstatus(req
);
2599 NTSTATUS
cli_tdis(struct cli_state
*cli
)
2601 struct tevent_context
*ev
;
2602 struct tevent_req
*req
;
2603 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2605 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
2606 return NT_STATUS_INVALID_PARAMETER
;
2608 ev
= tevent_context_init(talloc_tos());
2612 req
= cli_tdis_send(ev
, ev
, cli
);
2616 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2619 status
= cli_tdis_recv(req
);
2625 static NTSTATUS
cli_connect_sock(const char *host
, int name_type
,
2626 const struct sockaddr_storage
*pss
,
2627 const char *myname
, uint16_t port
,
2628 int sec_timeout
, int *pfd
, uint16_t *pport
)
2630 TALLOC_CTX
*frame
= talloc_stackframe();
2632 unsigned int i
, num_addrs
;
2633 const char **called_names
;
2634 const char **calling_names
;
2639 prog
= getenv("LIBSMB_PROG");
2641 fd
= sock_exec(prog
);
2643 return map_nt_error_from_unix(errno
);
2649 if ((pss
== NULL
) || is_zero_addr(pss
)) {
2650 struct sockaddr_storage
*addrs
;
2651 status
= resolve_name_list(talloc_tos(), host
, name_type
,
2652 &addrs
, &num_addrs
);
2653 if (!NT_STATUS_IS_OK(status
)) {
2661 called_names
= talloc_array(talloc_tos(), const char *, num_addrs
);
2662 if (called_names
== NULL
) {
2663 status
= NT_STATUS_NO_MEMORY
;
2666 called_types
= talloc_array(talloc_tos(), int, num_addrs
);
2667 if (called_types
== NULL
) {
2668 status
= NT_STATUS_NO_MEMORY
;
2671 calling_names
= talloc_array(talloc_tos(), const char *, num_addrs
);
2672 if (calling_names
== NULL
) {
2673 status
= NT_STATUS_NO_MEMORY
;
2676 for (i
=0; i
<num_addrs
; i
++) {
2677 called_names
[i
] = host
;
2678 called_types
[i
] = name_type
;
2679 calling_names
[i
] = myname
;
2681 status
= smbsock_any_connect(pss
, called_names
, called_types
,
2682 calling_names
, NULL
, num_addrs
, port
,
2683 sec_timeout
, &fd
, NULL
, &port
);
2684 if (!NT_STATUS_IS_OK(status
)) {
2687 set_socket_options(fd
, lp_socket_options());
2691 status
= NT_STATUS_OK
;
2697 NTSTATUS
cli_connect_nb(const char *host
, const struct sockaddr_storage
*dest_ss
,
2698 uint16_t port
, int name_type
, const char *myname
,
2699 int signing_state
, int flags
, struct cli_state
**pcli
)
2701 TALLOC_CTX
*frame
= talloc_stackframe();
2702 struct cli_state
*cli
;
2703 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2708 desthost
= talloc_strdup(talloc_tos(), host
);
2709 if (desthost
== NULL
) {
2713 p
= strchr(host
, '#');
2715 name_type
= strtol(p
+1, NULL
, 16);
2716 host
= talloc_strndup(talloc_tos(), host
, p
- host
);
2722 status
= cli_connect_sock(host
, name_type
, dest_ss
, myname
, port
,
2724 if (!NT_STATUS_IS_OK(status
)) {
2728 cli
= cli_state_create(NULL
, fd
, desthost
, NULL
, signing_state
, flags
);
2736 status
= NT_STATUS_OK
;
2743 establishes a connection to after the negprot.
2744 @param output_cli A fully initialised cli structure, non-null only on success
2745 @param dest_host The netbios name of the remote host
2746 @param dest_ss (optional) The the destination IP, NULL for name based lookup
2747 @param port (optional) The destination port (0 for default)
2749 NTSTATUS
cli_start_connection(struct cli_state
**output_cli
,
2750 const char *my_name
,
2751 const char *dest_host
,
2752 const struct sockaddr_storage
*dest_ss
, int port
,
2753 int signing_state
, int flags
)
2756 struct cli_state
*cli
;
2758 nt_status
= cli_connect_nb(dest_host
, dest_ss
, port
, 0x20, my_name
,
2759 signing_state
, flags
, &cli
);
2760 if (!NT_STATUS_IS_OK(nt_status
)) {
2761 DEBUG(10, ("cli_connect_nb failed: %s\n",
2762 nt_errstr(nt_status
)));
2766 nt_status
= smbXcli_negprot(cli
->conn
, cli
->timeout
, PROTOCOL_CORE
,
2768 if (!NT_STATUS_IS_OK(nt_status
)) {
2769 DEBUG(1, ("failed negprot: %s\n", nt_errstr(nt_status
)));
2775 return NT_STATUS_OK
;
2780 establishes a connection right up to doing tconX, password specified.
2781 @param output_cli A fully initialised cli structure, non-null only on success
2782 @param dest_host The netbios name of the remote host
2783 @param dest_ip (optional) The the destination IP, NULL for name based lookup
2784 @param port (optional) The destination port (0 for default)
2785 @param service (optional) The share to make the connection to. Should be 'unqualified' in any way.
2786 @param service_type The 'type' of serivice.
2787 @param user Username, unix string
2788 @param domain User's domain
2789 @param password User's password, unencrypted unix string.
2792 NTSTATUS
cli_full_connection(struct cli_state
**output_cli
,
2793 const char *my_name
,
2794 const char *dest_host
,
2795 const struct sockaddr_storage
*dest_ss
, int port
,
2796 const char *service
, const char *service_type
,
2797 const char *user
, const char *domain
,
2798 const char *password
, int flags
,
2802 struct cli_state
*cli
= NULL
;
2803 int pw_len
= password
? strlen(password
)+1 : 0;
2807 if (password
== NULL
) {
2811 nt_status
= cli_start_connection(&cli
, my_name
, dest_host
,
2812 dest_ss
, port
, signing_state
,
2815 if (!NT_STATUS_IS_OK(nt_status
)) {
2819 nt_status
= cli_session_setup(cli
, user
, password
, pw_len
, password
,
2821 if (!NT_STATUS_IS_OK(nt_status
)) {
2823 if (!(flags
& CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK
)) {
2824 DEBUG(1,("failed session setup with %s\n",
2825 nt_errstr(nt_status
)));
2830 nt_status
= cli_session_setup(cli
, "", "", 0, "", 0, domain
);
2831 if (!NT_STATUS_IS_OK(nt_status
)) {
2832 DEBUG(1,("anonymous failed session setup with %s\n",
2833 nt_errstr(nt_status
)));
2840 nt_status
= cli_tree_connect(cli
, service
, service_type
,
2842 if (!NT_STATUS_IS_OK(nt_status
)) {
2843 DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status
)));
2845 if (NT_STATUS_IS_OK(nt_status
)) {
2846 nt_status
= NT_STATUS_UNSUCCESSFUL
;
2852 nt_status
= cli_init_creds(cli
, user
, domain
, password
);
2853 if (!NT_STATUS_IS_OK(nt_status
)) {
2859 return NT_STATUS_OK
;
2862 /****************************************************************************
2863 Send an old style tcon.
2864 ****************************************************************************/
2865 NTSTATUS
cli_raw_tcon(struct cli_state
*cli
,
2866 const char *service
, const char *pass
, const char *dev
,
2867 uint16
*max_xmit
, uint16
*tid
)
2869 struct tevent_req
*req
;
2874 if (!lp_client_plaintext_auth() && (*pass
)) {
2875 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
2876 " or 'client ntlmv2 auth = yes'\n"));
2877 return NT_STATUS_ACCESS_DENIED
;
2880 bytes
= talloc_array(talloc_tos(), uint8_t, 0);
2881 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
2882 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
2883 service
, strlen(service
)+1, NULL
);
2884 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
2885 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
2886 pass
, strlen(pass
)+1, NULL
);
2887 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
2888 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
2889 dev
, strlen(dev
)+1, NULL
);
2891 status
= cli_smb(talloc_tos(), cli
, SMBtcon
, 0, 0, NULL
,
2892 talloc_get_size(bytes
), bytes
, &req
,
2893 2, NULL
, &ret_vwv
, NULL
, NULL
);
2894 if (!NT_STATUS_IS_OK(status
)) {
2898 *max_xmit
= SVAL(ret_vwv
+ 0, 0);
2899 *tid
= SVAL(ret_vwv
+ 1, 0);
2901 return NT_STATUS_OK
;
2904 /* Return a cli_state pointing at the IPC$ share for the given server */
2906 struct cli_state
*get_ipc_connect(char *server
,
2907 struct sockaddr_storage
*server_ss
,
2908 const struct user_auth_info
*user_info
)
2910 struct cli_state
*cli
;
2912 uint32_t flags
= CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK
;
2914 if (user_info
->use_kerberos
) {
2915 flags
|= CLI_FULL_CONNECTION_USE_KERBEROS
;
2918 nt_status
= cli_full_connection(&cli
, NULL
, server
, server_ss
, 0, "IPC$", "IPC",
2919 user_info
->username
? user_info
->username
: "",
2921 user_info
->password
? user_info
->password
: "",
2923 SMB_SIGNING_DEFAULT
);
2925 if (NT_STATUS_IS_OK(nt_status
)) {
2927 } else if (is_ipaddress(server
)) {
2928 /* windows 9* needs a correct NMB name for connections */
2929 fstring remote_name
;
2931 if (name_status_find("*", 0, 0, server_ss
, remote_name
)) {
2932 cli
= get_ipc_connect(remote_name
, server_ss
, user_info
);
2941 * Given the IP address of a master browser on the network, return its
2942 * workgroup and connect to it.
2944 * This function is provided to allow additional processing beyond what
2945 * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
2946 * browsers and obtain each master browsers' list of domains (in case the
2947 * first master browser is recently on the network and has not yet
2948 * synchronized with other master browsers and therefore does not yet have the
2949 * entire network browse list)
2952 struct cli_state
*get_ipc_connect_master_ip(TALLOC_CTX
*ctx
,
2953 struct sockaddr_storage
*mb_ip
,
2954 const struct user_auth_info
*user_info
,
2955 char **pp_workgroup_out
)
2957 char addr
[INET6_ADDRSTRLEN
];
2959 struct cli_state
*cli
;
2960 struct sockaddr_storage server_ss
;
2962 *pp_workgroup_out
= NULL
;
2964 print_sockaddr(addr
, sizeof(addr
), mb_ip
);
2965 DEBUG(99, ("Looking up name of master browser %s\n",
2969 * Do a name status query to find out the name of the master browser.
2970 * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
2971 * master browser will not respond to a wildcard query (or, at least,
2972 * an NT4 server acting as the domain master browser will not).
2974 * We might be able to use ONLY the query on MSBROWSE, but that's not
2975 * yet been tested with all Windows versions, so until it is, leave
2976 * the original wildcard query as the first choice and fall back to
2977 * MSBROWSE if the wildcard query fails.
2979 if (!name_status_find("*", 0, 0x1d, mb_ip
, name
) &&
2980 !name_status_find(MSBROWSE
, 1, 0x1d, mb_ip
, name
)) {
2982 DEBUG(99, ("Could not retrieve name status for %s\n",
2987 if (!find_master_ip(name
, &server_ss
)) {
2988 DEBUG(99, ("Could not find master ip for %s\n", name
));
2992 *pp_workgroup_out
= talloc_strdup(ctx
, name
);
2994 DEBUG(4, ("found master browser %s, %s\n", name
, addr
));
2996 print_sockaddr(addr
, sizeof(addr
), &server_ss
);
2997 cli
= get_ipc_connect(addr
, &server_ss
, user_info
);
3003 * Return the IP address and workgroup of a master browser on the network, and
3007 struct cli_state
*get_ipc_connect_master_ip_bcast(TALLOC_CTX
*ctx
,
3008 const struct user_auth_info
*user_info
,
3009 char **pp_workgroup_out
)
3011 struct sockaddr_storage
*ip_list
;
3012 struct cli_state
*cli
;
3016 *pp_workgroup_out
= NULL
;
3018 DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
3020 /* Go looking for workgroups by broadcasting on the local network */
3022 status
= name_resolve_bcast(MSBROWSE
, 1, talloc_tos(),
3024 if (!NT_STATUS_IS_OK(status
)) {
3025 DEBUG(99, ("No master browsers responded: %s\n",
3026 nt_errstr(status
)));
3030 for (i
= 0; i
< count
; i
++) {
3031 char addr
[INET6_ADDRSTRLEN
];
3032 print_sockaddr(addr
, sizeof(addr
), &ip_list
[i
]);
3033 DEBUG(99, ("Found master browser %s\n", addr
));
3035 cli
= get_ipc_connect_master_ip(ctx
, &ip_list
[i
],
3036 user_info
, pp_workgroup_out
);