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 static NTSTATUS
cli_session_setup_lanman2(struct cli_state
*cli
, const char *user
,
297 const char *pass
, size_t passlen
,
298 const char *workgroup
)
300 TALLOC_CTX
*frame
= talloc_stackframe();
301 struct event_context
*ev
;
302 struct tevent_req
*req
;
303 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
305 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
307 * Can't use sync call while an async call is in flight
309 status
= NT_STATUS_INVALID_PARAMETER
;
312 ev
= event_context_init(frame
);
316 req
= cli_session_setup_lanman2_send(frame
, ev
, cli
, user
, pass
, passlen
,
321 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
324 status
= cli_session_setup_lanman2_recv(req
);
330 /****************************************************************************
331 Work out suitable capabilities to offer the server.
332 ****************************************************************************/
334 static uint32_t cli_session_setup_capabilities(struct cli_state
*cli
,
335 uint32_t sesssetup_capabilities
)
337 uint32_t client_capabilities
= smb1cli_conn_capabilities(cli
->conn
);
340 * We only send capabilities based on the mask for:
341 * - client only flags
342 * - flags used in both directions
344 * We do not echo the server only flags.
346 client_capabilities
&= (SMB_CAP_BOTH_MASK
| SMB_CAP_CLIENT_MASK
);
349 * Session Setup specific flags CAP_DYNAMIC_REAUTH
350 * and CAP_EXTENDED_SECURITY are passed by the caller.
351 * We need that in order to do guest logins even if
352 * CAP_EXTENDED_SECURITY is negotiated.
354 client_capabilities
&= ~(CAP_DYNAMIC_REAUTH
|CAP_EXTENDED_SECURITY
);
355 sesssetup_capabilities
&= (CAP_DYNAMIC_REAUTH
|CAP_EXTENDED_SECURITY
);
356 client_capabilities
|= sesssetup_capabilities
;
358 return client_capabilities
;
361 /****************************************************************************
362 Do a NT1 guest session setup.
363 ****************************************************************************/
365 struct cli_session_setup_guest_state
{
366 struct cli_state
*cli
;
371 static void cli_session_setup_guest_done(struct tevent_req
*subreq
);
373 struct tevent_req
*cli_session_setup_guest_create(TALLOC_CTX
*mem_ctx
,
374 struct event_context
*ev
,
375 struct cli_state
*cli
,
376 struct tevent_req
**psmbreq
)
378 struct tevent_req
*req
, *subreq
;
379 struct cli_session_setup_guest_state
*state
;
383 req
= tevent_req_create(mem_ctx
, &state
,
384 struct cli_session_setup_guest_state
);
391 SCVAL(vwv
+0, 0, 0xFF);
394 SSVAL(vwv
+2, 0, CLI_BUFFER_SIZE
);
396 SSVAL(vwv
+4, 0, cli_state_get_vc_num(cli
));
397 SIVAL(vwv
+5, 0, smb1cli_conn_server_session_key(cli
->conn
));
402 SIVAL(vwv
+11, 0, cli_session_setup_capabilities(cli
, 0));
404 bytes
= talloc_array(state
, uint8_t, 0);
406 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "", 1, /* username */
408 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "", 1, /* workgroup */
410 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "Unix", 5, NULL
);
411 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "Samba", 6, NULL
);
418 state
->bytes
.iov_base
= (void *)bytes
;
419 state
->bytes
.iov_len
= talloc_get_size(bytes
);
421 subreq
= cli_smb_req_create(state
, ev
, cli
, SMBsesssetupX
, 0, 13, vwv
,
423 if (subreq
== NULL
) {
427 tevent_req_set_callback(subreq
, cli_session_setup_guest_done
, req
);
432 struct tevent_req
*cli_session_setup_guest_send(TALLOC_CTX
*mem_ctx
,
433 struct event_context
*ev
,
434 struct cli_state
*cli
)
436 struct tevent_req
*req
, *subreq
;
439 req
= cli_session_setup_guest_create(mem_ctx
, ev
, cli
, &subreq
);
444 status
= smb1cli_req_chain_submit(&subreq
, 1);
445 if (NT_STATUS_IS_OK(status
)) {
446 tevent_req_nterror(req
, status
);
447 return tevent_req_post(req
, ev
);
452 static void cli_session_setup_guest_done(struct tevent_req
*subreq
)
454 struct tevent_req
*req
= tevent_req_callback_data(
455 subreq
, struct tevent_req
);
456 struct cli_session_setup_guest_state
*state
= tevent_req_data(
457 req
, struct cli_session_setup_guest_state
);
458 struct cli_state
*cli
= state
->cli
;
469 status
= cli_smb_recv(subreq
, state
, &in
, 3, &wct
, &vwv
,
472 if (!NT_STATUS_IS_OK(status
)) {
473 tevent_req_nterror(req
, status
);
477 inhdr
= in
+ NBT_HDR_SIZE
;
480 cli_state_set_uid(state
->cli
, SVAL(inhdr
, HDR_UID
));
481 cli
->is_guestlogin
= ((SVAL(vwv
+2, 0) & 1) != 0);
483 status
= smb_bytes_talloc_string(cli
,
490 if (!NT_STATUS_IS_OK(status
)) {
491 tevent_req_nterror(req
, status
);
496 status
= smb_bytes_talloc_string(cli
,
503 if (!NT_STATUS_IS_OK(status
)) {
504 tevent_req_nterror(req
, status
);
509 status
= smb_bytes_talloc_string(cli
,
516 if (!NT_STATUS_IS_OK(status
)) {
517 tevent_req_nterror(req
, status
);
522 status
= cli_set_username(cli
, "");
523 if (!NT_STATUS_IS_OK(status
)) {
524 tevent_req_nterror(req
, status
);
527 tevent_req_done(req
);
530 NTSTATUS
cli_session_setup_guest_recv(struct tevent_req
*req
)
532 return tevent_req_simple_recv_ntstatus(req
);
535 static NTSTATUS
cli_session_setup_guest(struct cli_state
*cli
)
537 TALLOC_CTX
*frame
= talloc_stackframe();
538 struct event_context
*ev
;
539 struct tevent_req
*req
;
540 NTSTATUS status
= NT_STATUS_OK
;
542 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
544 * Can't use sync call while an async call is in flight
546 status
= NT_STATUS_INVALID_PARAMETER
;
550 ev
= event_context_init(frame
);
552 status
= NT_STATUS_NO_MEMORY
;
556 req
= cli_session_setup_guest_send(frame
, ev
, cli
);
558 status
= NT_STATUS_NO_MEMORY
;
562 if (!tevent_req_poll(req
, ev
)) {
563 status
= map_nt_error_from_unix(errno
);
567 status
= cli_session_setup_guest_recv(req
);
573 /****************************************************************************
574 Do a NT1 plaintext session setup.
575 ****************************************************************************/
577 struct cli_session_setup_plain_state
{
578 struct cli_state
*cli
;
583 static void cli_session_setup_plain_done(struct tevent_req
*subreq
);
585 static struct tevent_req
*cli_session_setup_plain_send(
586 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
587 struct cli_state
*cli
,
588 const char *user
, const char *pass
, const char *workgroup
)
590 struct tevent_req
*req
, *subreq
;
591 struct cli_session_setup_plain_state
*state
;
597 req
= tevent_req_create(mem_ctx
, &state
,
598 struct cli_session_setup_plain_state
);
606 SCVAL(vwv
+0, 0, 0xff);
609 SSVAL(vwv
+2, 0, CLI_BUFFER_SIZE
);
611 SSVAL(vwv
+4, 0, cli_state_get_vc_num(cli
));
612 SIVAL(vwv
+5, 0, smb1cli_conn_server_session_key(cli
->conn
));
617 SIVAL(vwv
+11, 0, cli_session_setup_capabilities(cli
, 0));
619 bytes
= talloc_array(state
, uint8_t, 0);
620 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), pass
, strlen(pass
)+1,
622 if (tevent_req_nomem(bytes
, req
)) {
623 return tevent_req_post(req
, ev
);
625 SSVAL(vwv
+ (smbXcli_conn_use_unicode(cli
->conn
) ? 8 : 7), 0, passlen
);
627 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
628 user
, strlen(user
)+1, NULL
);
629 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
630 workgroup
, strlen(workgroup
)+1, NULL
);
631 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
634 version
= talloc_asprintf(talloc_tos(), "Samba %s",
635 samba_version_string());
636 if (tevent_req_nomem(version
, req
)){
637 return tevent_req_post(req
, ev
);
639 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
640 version
, strlen(version
)+1, NULL
);
641 TALLOC_FREE(version
);
643 if (tevent_req_nomem(bytes
, req
)) {
644 return tevent_req_post(req
, ev
);
647 subreq
= cli_smb_send(state
, ev
, cli
, SMBsesssetupX
, 0, 13, vwv
,
648 talloc_get_size(bytes
), bytes
);
649 if (tevent_req_nomem(subreq
, req
)) {
650 return tevent_req_post(req
, ev
);
652 tevent_req_set_callback(subreq
, cli_session_setup_plain_done
, req
);
656 static void cli_session_setup_plain_done(struct tevent_req
*subreq
)
658 struct tevent_req
*req
= tevent_req_callback_data(
659 subreq
, struct tevent_req
);
660 struct cli_session_setup_plain_state
*state
= tevent_req_data(
661 req
, struct cli_session_setup_plain_state
);
662 struct cli_state
*cli
= state
->cli
;
673 status
= cli_smb_recv(subreq
, state
, &in
, 3, &wct
, &vwv
,
676 if (tevent_req_nterror(req
, status
)) {
680 inhdr
= in
+ NBT_HDR_SIZE
;
683 cli_state_set_uid(state
->cli
, SVAL(inhdr
, HDR_UID
));
684 cli
->is_guestlogin
= ((SVAL(vwv
+2, 0) & 1) != 0);
686 status
= smb_bytes_talloc_string(cli
,
693 if (!NT_STATUS_IS_OK(status
)) {
694 tevent_req_nterror(req
, status
);
699 status
= smb_bytes_talloc_string(cli
,
706 if (!NT_STATUS_IS_OK(status
)) {
707 tevent_req_nterror(req
, status
);
712 status
= smb_bytes_talloc_string(cli
,
719 if (!NT_STATUS_IS_OK(status
)) {
720 tevent_req_nterror(req
, status
);
725 status
= cli_set_username(cli
, state
->user
);
726 if (tevent_req_nterror(req
, status
)) {
730 tevent_req_done(req
);
733 static NTSTATUS
cli_session_setup_plain_recv(struct tevent_req
*req
)
735 return tevent_req_simple_recv_ntstatus(req
);
738 static NTSTATUS
cli_session_setup_plain(struct cli_state
*cli
,
739 const char *user
, const char *pass
,
740 const char *workgroup
)
742 TALLOC_CTX
*frame
= talloc_stackframe();
743 struct event_context
*ev
;
744 struct tevent_req
*req
;
745 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
747 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
749 * Can't use sync call while an async call is in flight
751 status
= NT_STATUS_INVALID_PARAMETER
;
754 ev
= event_context_init(frame
);
758 req
= cli_session_setup_plain_send(frame
, ev
, cli
, user
, pass
,
763 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
766 status
= cli_session_setup_plain_recv(req
);
772 /****************************************************************************
773 do a NT1 NTLM/LM encrypted session setup - for when extended security
775 @param cli client state to create do session setup on
777 @param pass *either* cleartext password (passlen !=24) or LM response.
778 @param ntpass NT response, implies ntpasslen >=24, implies pass is not clear
779 @param workgroup The user's domain.
780 ****************************************************************************/
782 struct cli_session_setup_nt1_state
{
783 struct cli_state
*cli
;
786 DATA_BLOB session_key
;
790 static void cli_session_setup_nt1_done(struct tevent_req
*subreq
);
792 static struct tevent_req
*cli_session_setup_nt1_send(
793 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
794 struct cli_state
*cli
, const char *user
,
795 const char *pass
, size_t passlen
,
796 const char *ntpass
, size_t ntpasslen
,
797 const char *workgroup
)
799 struct tevent_req
*req
, *subreq
;
800 struct cli_session_setup_nt1_state
*state
;
801 DATA_BLOB lm_response
= data_blob_null
;
802 DATA_BLOB nt_response
= data_blob_null
;
803 DATA_BLOB session_key
= data_blob_null
;
806 char *workgroup_upper
;
808 req
= tevent_req_create(mem_ctx
, &state
,
809 struct cli_session_setup_nt1_state
);
818 /* do nothing - guest login */
819 } else if (passlen
!= 24) {
820 if (lp_client_ntlmv2_auth()) {
821 DATA_BLOB server_chal
;
822 DATA_BLOB names_blob
;
825 data_blob_const(smb1cli_conn_server_challenge(cli
->conn
),
829 * note that the 'workgroup' here is a best
830 * guess - we don't know the server's domain
831 * at this point. Windows clients also don't
834 names_blob
= NTLMv2_generate_names_blob(
835 NULL
, NULL
, workgroup
);
837 if (tevent_req_nomem(names_blob
.data
, req
)) {
838 return tevent_req_post(req
, ev
);
841 if (!SMBNTLMv2encrypt(NULL
, user
, workgroup
, pass
,
842 &server_chal
, &names_blob
,
843 &lm_response
, &nt_response
,
844 NULL
, &session_key
)) {
845 data_blob_free(&names_blob
);
847 req
, NT_STATUS_ACCESS_DENIED
);
848 return tevent_req_post(req
, ev
);
850 data_blob_free(&names_blob
);
854 E_md4hash(pass
, nt_hash
);
857 nt_response
= data_blob_null
;
859 nt_response
= data_blob(NULL
, 24);
860 if (tevent_req_nomem(nt_response
.data
, req
)) {
861 return tevent_req_post(req
, ev
);
864 SMBNTencrypt(pass
, smb1cli_conn_server_challenge(cli
->conn
),
867 /* non encrypted password supplied. Ignore ntpass. */
868 if (lp_client_lanman_auth()) {
870 lm_response
= data_blob(NULL
, 24);
871 if (tevent_req_nomem(lm_response
.data
, req
)) {
872 return tevent_req_post(req
, ev
);
875 if (!SMBencrypt(pass
,
876 smb1cli_conn_server_challenge(cli
->conn
),
879 * Oops, the LM response is
880 * invalid, just put the NT
881 * response there instead
883 data_blob_free(&lm_response
);
884 lm_response
= data_blob(
890 * LM disabled, place NT# in LM field
893 lm_response
= data_blob(
894 nt_response
.data
, nt_response
.length
);
897 if (tevent_req_nomem(lm_response
.data
, req
)) {
898 return tevent_req_post(req
, ev
);
901 session_key
= data_blob(NULL
, 16);
902 if (tevent_req_nomem(session_key
.data
, req
)) {
903 return tevent_req_post(req
, ev
);
906 E_deshash(pass
, session_key
.data
);
907 memset(&session_key
.data
[8], '\0', 8);
909 SMBsesskeygen_ntv1(nt_hash
, session_key
.data
);
913 /* pre-encrypted password supplied. Only used for
914 security=server, can't do
915 signing because we don't have original key */
917 lm_response
= data_blob(pass
, passlen
);
918 if (tevent_req_nomem(lm_response
.data
, req
)) {
919 return tevent_req_post(req
, ev
);
922 nt_response
= data_blob(ntpass
, ntpasslen
);
923 if (tevent_req_nomem(nt_response
.data
, req
)) {
924 return tevent_req_post(req
, ev
);
929 state
->response
= data_blob_talloc(
930 state
, lm_response
.data
, lm_response
.length
);
932 state
->response
= data_blob_talloc(
933 state
, nt_response
.data
, nt_response
.length
);
935 if (tevent_req_nomem(state
->response
.data
, req
)) {
936 return tevent_req_post(req
, ev
);
939 if (session_key
.data
) {
940 state
->session_key
= data_blob_talloc(
941 state
, session_key
.data
, session_key
.length
);
942 if (tevent_req_nomem(state
->session_key
.data
, req
)) {
943 return tevent_req_post(req
, ev
);
946 data_blob_free(&session_key
);
948 SCVAL(vwv
+0, 0, 0xff);
951 SSVAL(vwv
+2, 0, CLI_BUFFER_SIZE
);
953 SSVAL(vwv
+4, 0, cli_state_get_vc_num(cli
));
954 SIVAL(vwv
+5, 0, smb1cli_conn_server_session_key(cli
->conn
));
955 SSVAL(vwv
+7, 0, lm_response
.length
);
956 SSVAL(vwv
+8, 0, nt_response
.length
);
959 SIVAL(vwv
+11, 0, cli_session_setup_capabilities(cli
, 0));
961 bytes
= talloc_array(state
, uint8_t,
962 lm_response
.length
+ nt_response
.length
);
963 if (tevent_req_nomem(bytes
, req
)) {
964 return tevent_req_post(req
, ev
);
966 if (lm_response
.length
!= 0) {
967 memcpy(bytes
, lm_response
.data
, lm_response
.length
);
969 if (nt_response
.length
!= 0) {
970 memcpy(bytes
+ lm_response
.length
,
971 nt_response
.data
, nt_response
.length
);
973 data_blob_free(&lm_response
);
974 data_blob_free(&nt_response
);
976 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
977 user
, strlen(user
)+1, NULL
);
980 * Upper case here might help some NTLMv2 implementations
982 workgroup_upper
= talloc_strdup_upper(talloc_tos(), workgroup
);
983 if (tevent_req_nomem(workgroup_upper
, req
)) {
984 return tevent_req_post(req
, ev
);
986 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
987 workgroup_upper
, strlen(workgroup_upper
)+1,
989 TALLOC_FREE(workgroup_upper
);
991 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "Unix", 5, NULL
);
992 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "Samba", 6, NULL
);
993 if (tevent_req_nomem(bytes
, req
)) {
994 return tevent_req_post(req
, ev
);
997 subreq
= cli_smb_send(state
, ev
, cli
, SMBsesssetupX
, 0, 13, vwv
,
998 talloc_get_size(bytes
), bytes
);
999 if (tevent_req_nomem(subreq
, req
)) {
1000 return tevent_req_post(req
, ev
);
1002 tevent_req_set_callback(subreq
, cli_session_setup_nt1_done
, req
);
1006 static void cli_session_setup_nt1_done(struct tevent_req
*subreq
)
1008 struct tevent_req
*req
= tevent_req_callback_data(
1009 subreq
, struct tevent_req
);
1010 struct cli_session_setup_nt1_state
*state
= tevent_req_data(
1011 req
, struct cli_session_setup_nt1_state
);
1012 struct cli_state
*cli
= state
->cli
;
1023 status
= cli_smb_recv(subreq
, state
, &in
, 3, &wct
, &vwv
,
1024 &num_bytes
, &bytes
);
1025 TALLOC_FREE(subreq
);
1026 if (!NT_STATUS_IS_OK(status
)) {
1027 tevent_req_nterror(req
, status
);
1031 inhdr
= in
+ NBT_HDR_SIZE
;
1034 cli_state_set_uid(state
->cli
, SVAL(inhdr
, HDR_UID
));
1035 cli
->is_guestlogin
= ((SVAL(vwv
+2, 0) & 1) != 0);
1037 status
= smb_bytes_talloc_string(cli
,
1043 if (!NT_STATUS_IS_OK(status
)) {
1044 tevent_req_nterror(req
, status
);
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
,
1063 &cli
->server_domain
,
1067 if (!NT_STATUS_IS_OK(status
)) {
1068 tevent_req_nterror(req
, status
);
1073 status
= cli_set_username(cli
, state
->user
);
1074 if (tevent_req_nterror(req
, status
)) {
1077 if (smb1cli_conn_activate_signing(cli
->conn
, state
->session_key
, state
->response
)
1078 && !smb1cli_conn_check_signing(cli
->conn
, (uint8_t *)in
, 1)) {
1079 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1082 if (state
->session_key
.data
) {
1083 struct smbXcli_session
*session
= state
->cli
->smb1
.session
;
1085 status
= smb1cli_session_set_session_key(session
,
1086 state
->session_key
);
1087 if (tevent_req_nterror(req
, status
)) {
1091 tevent_req_done(req
);
1094 static NTSTATUS
cli_session_setup_nt1_recv(struct tevent_req
*req
)
1096 return tevent_req_simple_recv_ntstatus(req
);
1099 static NTSTATUS
cli_session_setup_nt1(struct cli_state
*cli
, const char *user
,
1100 const char *pass
, size_t passlen
,
1101 const char *ntpass
, size_t ntpasslen
,
1102 const char *workgroup
)
1104 TALLOC_CTX
*frame
= talloc_stackframe();
1105 struct event_context
*ev
;
1106 struct tevent_req
*req
;
1107 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
1109 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
1111 * Can't use sync call while an async call is in flight
1113 status
= NT_STATUS_INVALID_PARAMETER
;
1116 ev
= event_context_init(frame
);
1120 req
= cli_session_setup_nt1_send(frame
, ev
, cli
, user
, pass
, passlen
,
1121 ntpass
, ntpasslen
, workgroup
);
1125 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
1128 status
= cli_session_setup_nt1_recv(req
);
1134 /* The following is calculated from :
1136 * (smb_wcnt * 2) = 24 (smb_wcnt == 12 in cli_session_setup_blob_send() )
1137 * (strlen("Unix") + 1 + strlen("Samba") + 1) * 2 = 22 (unicode strings at
1141 #define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22)
1143 struct cli_sesssetup_blob_state
{
1144 struct tevent_context
*ev
;
1145 struct cli_state
*cli
;
1147 uint16_t max_blob_size
;
1151 DATA_BLOB smb2_blob
;
1152 struct iovec
*recv_iov
;
1159 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state
*state
,
1160 struct tevent_req
**psubreq
);
1161 static void cli_sesssetup_blob_done(struct tevent_req
*subreq
);
1163 static struct tevent_req
*cli_sesssetup_blob_send(TALLOC_CTX
*mem_ctx
,
1164 struct tevent_context
*ev
,
1165 struct cli_state
*cli
,
1168 struct tevent_req
*req
, *subreq
;
1169 struct cli_sesssetup_blob_state
*state
;
1170 uint32_t usable_space
;
1172 req
= tevent_req_create(mem_ctx
, &state
,
1173 struct cli_sesssetup_blob_state
);
1181 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
1182 usable_space
= UINT16_MAX
;
1184 usable_space
= cli_state_available_size(cli
,
1185 BASE_SESSSETUP_BLOB_PACKET_SIZE
);
1188 if (usable_space
== 0) {
1189 DEBUG(1, ("cli_session_setup_blob: cli->max_xmit too small "
1190 "(not possible to send %u bytes)\n",
1191 BASE_SESSSETUP_BLOB_PACKET_SIZE
+ 1));
1192 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1193 return tevent_req_post(req
, ev
);
1195 state
->max_blob_size
= MIN(usable_space
, 0xFFFF);
1197 if (!cli_sesssetup_blob_next(state
, &subreq
)) {
1198 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
1199 return tevent_req_post(req
, ev
);
1201 tevent_req_set_callback(subreq
, cli_sesssetup_blob_done
, req
);
1205 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state
*state
,
1206 struct tevent_req
**psubreq
)
1208 struct tevent_req
*subreq
;
1211 thistime
= MIN(state
->blob
.length
, state
->max_blob_size
);
1213 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
1215 state
->smb2_blob
.data
= state
->blob
.data
;
1216 state
->smb2_blob
.length
= thistime
;
1218 state
->blob
.data
+= thistime
;
1219 state
->blob
.length
-= thistime
;
1221 subreq
= smb2cli_session_setup_send(state
, state
->ev
,
1223 state
->cli
->timeout
,
1224 state
->cli
->smb2
.session
,
1226 SMB2_CAP_DFS
, /* in_capabilities */
1228 0, /* in_previous_session_id */
1230 if (subreq
== NULL
) {
1237 SCVAL(state
->vwv
+0, 0, 0xFF);
1238 SCVAL(state
->vwv
+0, 1, 0);
1239 SSVAL(state
->vwv
+1, 0, 0);
1240 SSVAL(state
->vwv
+2, 0, CLI_BUFFER_SIZE
);
1241 SSVAL(state
->vwv
+3, 0, 2);
1242 SSVAL(state
->vwv
+4, 0, 1);
1243 SIVAL(state
->vwv
+5, 0, 0);
1245 SSVAL(state
->vwv
+7, 0, thistime
);
1247 SSVAL(state
->vwv
+8, 0, 0);
1248 SSVAL(state
->vwv
+9, 0, 0);
1249 SIVAL(state
->vwv
+10, 0,
1250 cli_session_setup_capabilities(state
->cli
, CAP_EXTENDED_SECURITY
));
1252 state
->buf
= (uint8_t *)talloc_memdup(state
, state
->blob
.data
,
1254 if (state
->buf
== NULL
) {
1257 state
->blob
.data
+= thistime
;
1258 state
->blob
.length
-= thistime
;
1260 state
->buf
= smb_bytes_push_str(state
->buf
, smbXcli_conn_use_unicode(state
->cli
->conn
),
1262 state
->buf
= smb_bytes_push_str(state
->buf
, smbXcli_conn_use_unicode(state
->cli
->conn
),
1264 if (state
->buf
== NULL
) {
1267 subreq
= cli_smb_send(state
, state
->ev
, state
->cli
, SMBsesssetupX
, 0,
1269 talloc_get_size(state
->buf
), state
->buf
);
1270 if (subreq
== NULL
) {
1277 static void cli_sesssetup_blob_done(struct tevent_req
*subreq
)
1279 struct tevent_req
*req
= tevent_req_callback_data(
1280 subreq
, struct tevent_req
);
1281 struct cli_sesssetup_blob_state
*state
= tevent_req_data(
1282 req
, struct cli_sesssetup_blob_state
);
1283 struct cli_state
*cli
= state
->cli
;
1290 uint16_t blob_length
;
1295 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
1296 status
= smb2cli_session_setup_recv(subreq
, state
,
1300 status
= cli_smb_recv(subreq
, state
, &in
, 4, &wct
, &vwv
,
1301 &num_bytes
, &bytes
);
1302 TALLOC_FREE(state
->buf
);
1304 TALLOC_FREE(subreq
);
1305 if (!NT_STATUS_IS_OK(status
)
1306 && !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1307 tevent_req_nterror(req
, status
);
1311 state
->status
= status
;
1313 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
1318 inhdr
= in
+ NBT_HDR_SIZE
;
1319 cli_state_set_uid(state
->cli
, SVAL(inhdr
, HDR_UID
));
1320 cli
->is_guestlogin
= ((SVAL(vwv
+2, 0) & 1) != 0);
1322 blob_length
= SVAL(vwv
+3, 0);
1323 if (blob_length
> num_bytes
) {
1324 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
1327 state
->ret_blob
= data_blob_const(bytes
, blob_length
);
1329 p
= bytes
+ blob_length
;
1331 status
= smb_bytes_talloc_string(cli
,
1338 if (!NT_STATUS_IS_OK(status
)) {
1339 tevent_req_nterror(req
, status
);
1344 status
= smb_bytes_talloc_string(cli
,
1351 if (!NT_STATUS_IS_OK(status
)) {
1352 tevent_req_nterror(req
, status
);
1357 status
= smb_bytes_talloc_string(cli
,
1359 &cli
->server_domain
,
1364 if (!NT_STATUS_IS_OK(status
)) {
1365 tevent_req_nterror(req
, status
);
1371 if (state
->blob
.length
!= 0) {
1375 if (!cli_sesssetup_blob_next(state
, &subreq
)) {
1376 tevent_req_oom(req
);
1379 tevent_req_set_callback(subreq
, cli_sesssetup_blob_done
, req
);
1382 tevent_req_done(req
);
1385 static NTSTATUS
cli_sesssetup_blob_recv(struct tevent_req
*req
,
1386 TALLOC_CTX
*mem_ctx
,
1389 struct iovec
**precv_iov
)
1391 struct cli_sesssetup_blob_state
*state
= tevent_req_data(
1392 req
, struct cli_sesssetup_blob_state
);
1395 struct iovec
*recv_iov
;
1397 if (tevent_req_is_nterror(req
, &status
)) {
1398 TALLOC_FREE(state
->cli
->smb2
.session
);
1399 cli_state_set_uid(state
->cli
, UID_FIELD_INVALID
);
1403 inbuf
= talloc_move(mem_ctx
, &state
->inbuf
);
1404 recv_iov
= talloc_move(mem_ctx
, &state
->recv_iov
);
1405 if (pblob
!= NULL
) {
1406 *pblob
= state
->ret_blob
;
1408 if (pinbuf
!= NULL
) {
1411 if (precv_iov
!= NULL
) {
1412 *precv_iov
= recv_iov
;
1414 /* could be NT_STATUS_MORE_PROCESSING_REQUIRED */
1415 return state
->status
;
1420 /****************************************************************************
1421 Use in-memory credentials cache
1422 ****************************************************************************/
1424 static void use_in_memory_ccache(void) {
1425 setenv(KRB5_ENV_CCNAME
, "MEMORY:cliconnect", 1);
1428 /****************************************************************************
1429 Do a spnego/kerberos encrypted session setup.
1430 ****************************************************************************/
1432 struct cli_session_setup_kerberos_state
{
1433 struct cli_state
*cli
;
1434 DATA_BLOB negTokenTarg
;
1435 DATA_BLOB session_key_krb5
;
1436 ADS_STATUS ads_status
;
1439 static void cli_session_setup_kerberos_done(struct tevent_req
*subreq
);
1441 static struct tevent_req
*cli_session_setup_kerberos_send(
1442 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
1443 const char *principal
)
1445 struct tevent_req
*req
, *subreq
;
1446 struct cli_session_setup_kerberos_state
*state
;
1449 DEBUG(2,("Doing kerberos session setup\n"));
1451 req
= tevent_req_create(mem_ctx
, &state
,
1452 struct cli_session_setup_kerberos_state
);
1457 state
->ads_status
= ADS_SUCCESS
;
1460 * Ok, this is cheating: spnego_gen_krb5_negTokenInit can block if
1461 * we have to acquire a ticket. To be fixed later :-)
1463 rc
= spnego_gen_krb5_negTokenInit(state
, principal
, 0, &state
->negTokenTarg
,
1464 &state
->session_key_krb5
, 0, NULL
, NULL
);
1466 DEBUG(1, ("cli_session_setup_kerberos: "
1467 "spnego_gen_krb5_negTokenInit failed: %s\n",
1468 error_message(rc
)));
1469 state
->ads_status
= ADS_ERROR_KRB5(rc
);
1470 tevent_req_nterror(req
, NT_STATUS_UNSUCCESSFUL
);
1471 return tevent_req_post(req
, ev
);
1475 file_save("negTokenTarg.dat", state
->negTokenTarg
.data
,
1476 state
->negTokenTarg
.length
);
1479 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
1480 state
->cli
->smb2
.session
= smbXcli_session_create(cli
,
1482 if (tevent_req_nomem(state
->cli
->smb2
.session
, req
)) {
1483 return tevent_req_post(req
, ev
);
1487 subreq
= cli_sesssetup_blob_send(state
, ev
, cli
, state
->negTokenTarg
);
1488 if (tevent_req_nomem(subreq
, req
)) {
1489 return tevent_req_post(req
, ev
);
1491 tevent_req_set_callback(subreq
, cli_session_setup_kerberos_done
, req
);
1495 static void cli_session_setup_kerberos_done(struct tevent_req
*subreq
)
1497 struct tevent_req
*req
= tevent_req_callback_data(
1498 subreq
, struct tevent_req
);
1499 struct cli_session_setup_kerberos_state
*state
= tevent_req_data(
1500 req
, struct cli_session_setup_kerberos_state
);
1501 uint8_t *inbuf
= NULL
;
1502 struct iovec
*recv_iov
= NULL
;
1505 status
= cli_sesssetup_blob_recv(subreq
, state
,
1506 NULL
, &inbuf
, &recv_iov
);
1507 TALLOC_FREE(subreq
);
1508 if (!NT_STATUS_IS_OK(status
)) {
1509 tevent_req_nterror(req
, status
);
1513 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
1514 struct smbXcli_session
*session
= state
->cli
->smb2
.session
;
1515 status
= smb2cli_session_set_session_key(session
,
1516 state
->session_key_krb5
,
1518 if (tevent_req_nterror(req
, status
)) {
1522 struct smbXcli_session
*session
= state
->cli
->smb1
.session
;
1524 status
= smb1cli_session_set_session_key(session
,
1525 state
->session_key_krb5
);
1526 if (tevent_req_nterror(req
, status
)) {
1530 if (smb1cli_conn_activate_signing(state
->cli
->conn
, state
->session_key_krb5
,
1532 && !smb1cli_conn_check_signing(state
->cli
->conn
, inbuf
, 1)) {
1533 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1538 tevent_req_done(req
);
1541 static ADS_STATUS
cli_session_setup_kerberos_recv(struct tevent_req
*req
)
1543 struct cli_session_setup_kerberos_state
*state
= tevent_req_data(
1544 req
, struct cli_session_setup_kerberos_state
);
1547 if (tevent_req_is_nterror(req
, &status
)) {
1548 return ADS_ERROR_NT(status
);
1550 return state
->ads_status
;
1553 static ADS_STATUS
cli_session_setup_kerberos(struct cli_state
*cli
,
1554 const char *principal
)
1556 struct tevent_context
*ev
;
1557 struct tevent_req
*req
;
1558 ADS_STATUS status
= ADS_ERROR_NT(NT_STATUS_NO_MEMORY
);
1560 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
1561 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
1563 ev
= tevent_context_init(talloc_tos());
1567 req
= cli_session_setup_kerberos_send(ev
, ev
, cli
, principal
);
1571 if (!tevent_req_poll(req
, ev
)) {
1572 status
= ADS_ERROR_SYSTEM(errno
);
1575 status
= cli_session_setup_kerberos_recv(req
);
1580 #endif /* HAVE_KRB5 */
1582 /****************************************************************************
1583 Do a spnego/NTLMSSP encrypted session setup.
1584 ****************************************************************************/
1586 struct cli_session_setup_ntlmssp_state
{
1587 struct tevent_context
*ev
;
1588 struct cli_state
*cli
;
1589 struct ntlmssp_state
*ntlmssp_state
;
1594 static int cli_session_setup_ntlmssp_state_destructor(
1595 struct cli_session_setup_ntlmssp_state
*state
)
1597 if (state
->ntlmssp_state
!= NULL
) {
1598 TALLOC_FREE(state
->ntlmssp_state
);
1603 static void cli_session_setup_ntlmssp_done(struct tevent_req
*req
);
1605 static struct tevent_req
*cli_session_setup_ntlmssp_send(
1606 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
1607 const char *user
, const char *pass
, const char *domain
)
1609 struct tevent_req
*req
, *subreq
;
1610 struct cli_session_setup_ntlmssp_state
*state
;
1613 const char *OIDs_ntlm
[] = {OID_NTLMSSP
, NULL
};
1615 req
= tevent_req_create(mem_ctx
, &state
,
1616 struct cli_session_setup_ntlmssp_state
);
1624 state
->ntlmssp_state
= NULL
;
1625 talloc_set_destructor(
1626 state
, cli_session_setup_ntlmssp_state_destructor
);
1628 status
= ntlmssp_client_start(state
,
1631 lp_client_ntlmv2_auth(),
1632 &state
->ntlmssp_state
);
1633 if (!NT_STATUS_IS_OK(status
)) {
1636 ntlmssp_want_feature(state
->ntlmssp_state
,
1637 NTLMSSP_FEATURE_SESSION_KEY
);
1638 if (cli
->use_ccache
) {
1639 ntlmssp_want_feature(state
->ntlmssp_state
,
1640 NTLMSSP_FEATURE_CCACHE
);
1642 status
= ntlmssp_set_username(state
->ntlmssp_state
, user
);
1643 if (!NT_STATUS_IS_OK(status
)) {
1646 status
= ntlmssp_set_domain(state
->ntlmssp_state
, domain
);
1647 if (!NT_STATUS_IS_OK(status
)) {
1650 if (cli
->pw_nt_hash
) {
1651 status
= ntlmssp_set_password_hash(state
->ntlmssp_state
, pass
);
1653 status
= ntlmssp_set_password(state
->ntlmssp_state
, pass
);
1655 if (!NT_STATUS_IS_OK(status
)) {
1658 status
= ntlmssp_update(state
->ntlmssp_state
, data_blob_null
,
1660 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1664 state
->blob_out
= spnego_gen_negTokenInit(state
, OIDs_ntlm
, &blob_out
, NULL
);
1665 data_blob_free(&blob_out
);
1667 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
1668 state
->cli
->smb2
.session
= smbXcli_session_create(cli
,
1670 if (tevent_req_nomem(state
->cli
->smb2
.session
, req
)) {
1671 return tevent_req_post(req
, ev
);
1675 subreq
= cli_sesssetup_blob_send(state
, ev
, cli
, state
->blob_out
);
1676 if (tevent_req_nomem(subreq
, req
)) {
1677 return tevent_req_post(req
, ev
);
1679 tevent_req_set_callback(subreq
, cli_session_setup_ntlmssp_done
, req
);
1682 tevent_req_nterror(req
, status
);
1683 return tevent_req_post(req
, ev
);
1686 static void cli_session_setup_ntlmssp_done(struct tevent_req
*subreq
)
1688 struct tevent_req
*req
= tevent_req_callback_data(
1689 subreq
, struct tevent_req
);
1690 struct cli_session_setup_ntlmssp_state
*state
= tevent_req_data(
1691 req
, struct cli_session_setup_ntlmssp_state
);
1692 DATA_BLOB blob_in
, msg_in
, blob_out
;
1693 uint8_t *inbuf
= NULL
;
1694 struct iovec
*recv_iov
= NULL
;
1698 status
= cli_sesssetup_blob_recv(subreq
, talloc_tos(), &blob_in
,
1700 TALLOC_FREE(subreq
);
1701 data_blob_free(&state
->blob_out
);
1703 if (NT_STATUS_IS_OK(status
)) {
1704 if (state
->cli
->server_domain
[0] == '\0') {
1705 TALLOC_FREE(state
->cli
->server_domain
);
1706 state
->cli
->server_domain
= talloc_strdup(state
->cli
,
1707 state
->ntlmssp_state
->server
.netbios_domain
);
1708 if (state
->cli
->server_domain
== NULL
) {
1709 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
1714 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
1715 struct smbXcli_session
*session
= state
->cli
->smb2
.session
;
1717 if (ntlmssp_is_anonymous(state
->ntlmssp_state
)) {
1719 * Windows server does not set the
1720 * SMB2_SESSION_FLAG_IS_GUEST nor
1721 * SMB2_SESSION_FLAG_IS_NULL flag.
1723 * This fix makes sure we do not try
1724 * to verify a signature on the final
1725 * session setup response.
1727 TALLOC_FREE(state
->ntlmssp_state
);
1728 tevent_req_done(req
);
1732 status
= smb2cli_session_set_session_key(session
,
1733 state
->ntlmssp_state
->session_key
,
1735 if (tevent_req_nterror(req
, status
)) {
1739 struct smbXcli_session
*session
= state
->cli
->smb1
.session
;
1741 status
= smb1cli_session_set_session_key(session
,
1742 state
->ntlmssp_state
->session_key
);
1743 if (tevent_req_nterror(req
, status
)) {
1747 if (smb1cli_conn_activate_signing(
1748 state
->cli
->conn
, state
->ntlmssp_state
->session_key
,
1750 && !smb1cli_conn_check_signing(state
->cli
->conn
, inbuf
, 1)) {
1751 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1755 TALLOC_FREE(state
->ntlmssp_state
);
1756 tevent_req_done(req
);
1759 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1760 tevent_req_nterror(req
, status
);
1764 if (blob_in
.length
== 0) {
1765 tevent_req_nterror(req
, NT_STATUS_UNSUCCESSFUL
);
1769 if ((state
->turn
== 1)
1770 && NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1771 DATA_BLOB tmp_blob
= data_blob_null
;
1772 /* the server might give us back two challenges */
1773 parse_ret
= spnego_parse_challenge(state
, blob_in
, &msg_in
,
1775 data_blob_free(&tmp_blob
);
1777 parse_ret
= spnego_parse_auth_response(state
, blob_in
, status
,
1778 OID_NTLMSSP
, &msg_in
);
1783 DEBUG(3,("Failed to parse auth response\n"));
1784 if (NT_STATUS_IS_OK(status
)
1785 || NT_STATUS_EQUAL(status
,
1786 NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1788 req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
1793 status
= ntlmssp_update(state
->ntlmssp_state
, msg_in
, &blob_out
);
1795 if (!NT_STATUS_IS_OK(status
)
1796 && !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1797 TALLOC_FREE(state
->ntlmssp_state
);
1798 tevent_req_nterror(req
, status
);
1802 state
->blob_out
= spnego_gen_auth(state
, blob_out
);
1803 if (tevent_req_nomem(state
->blob_out
.data
, req
)) {
1807 subreq
= cli_sesssetup_blob_send(state
, state
->ev
, state
->cli
,
1809 if (tevent_req_nomem(subreq
, req
)) {
1812 tevent_req_set_callback(subreq
, cli_session_setup_ntlmssp_done
, req
);
1815 static NTSTATUS
cli_session_setup_ntlmssp_recv(struct tevent_req
*req
)
1817 struct cli_session_setup_ntlmssp_state
*state
= tevent_req_data(
1818 req
, struct cli_session_setup_ntlmssp_state
);
1821 if (tevent_req_is_nterror(req
, &status
)) {
1822 cli_state_set_uid(state
->cli
, UID_FIELD_INVALID
);
1825 return NT_STATUS_OK
;
1828 static NTSTATUS
cli_session_setup_ntlmssp(struct cli_state
*cli
,
1833 struct tevent_context
*ev
;
1834 struct tevent_req
*req
;
1835 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
1837 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
1838 return NT_STATUS_INVALID_PARAMETER
;
1840 ev
= tevent_context_init(talloc_tos());
1844 req
= cli_session_setup_ntlmssp_send(ev
, ev
, cli
, user
, pass
, domain
);
1848 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
1851 status
= cli_session_setup_ntlmssp_recv(req
);
1857 /****************************************************************************
1858 Do a spnego encrypted session setup.
1860 user_domain: The shortname of the domain the user/machine is a member of.
1861 dest_realm: The realm we're connecting to, if NULL we use our default realm.
1862 ****************************************************************************/
1864 static ADS_STATUS
cli_session_setup_spnego(struct cli_state
*cli
,
1867 const char *user_domain
,
1868 const char * dest_realm
)
1870 char *principal
= NULL
;
1871 char *OIDs
[ASN1_MAX_OIDS
];
1873 const DATA_BLOB
*server_blob
;
1874 DATA_BLOB blob
= data_blob_null
;
1875 const char *p
= NULL
;
1876 char *account
= NULL
;
1879 server_blob
= smbXcli_conn_server_gss_blob(cli
->conn
);
1881 blob
= data_blob(server_blob
->data
, server_blob
->length
);
1884 DEBUG(3,("Doing spnego session setup (blob length=%lu)\n", (unsigned long)blob
.length
));
1886 /* the server might not even do spnego */
1887 if (blob
.length
== 0) {
1888 DEBUG(3,("server didn't supply a full spnego negprot\n"));
1893 file_save("negprot.dat", cli
->secblob
.data
, cli
->secblob
.length
);
1896 /* The server sent us the first part of the SPNEGO exchange in the
1897 * negprot reply. It is WRONG to depend on the principal sent in the
1898 * negprot reply, but right now we do it. If we don't receive one,
1899 * we try to best guess, then fall back to NTLM. */
1900 if (!spnego_parse_negTokenInit(talloc_tos(), blob
, OIDs
, &principal
, NULL
) ||
1902 data_blob_free(&blob
);
1903 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
1905 data_blob_free(&blob
);
1907 /* make sure the server understands kerberos */
1908 for (i
=0;OIDs
[i
];i
++) {
1910 DEBUG(3,("got OID=%s\n", OIDs
[i
]));
1912 DEBUGADD(3,("got OID=%s\n", OIDs
[i
]));
1913 if (strcmp(OIDs
[i
], OID_KERBEROS5_OLD
) == 0 ||
1914 strcmp(OIDs
[i
], OID_KERBEROS5
) == 0) {
1915 cli
->got_kerberos_mechanism
= True
;
1917 talloc_free(OIDs
[i
]);
1920 DEBUG(3,("got principal=%s\n", principal
? principal
: "<null>"));
1922 status
= cli_set_username(cli
, user
);
1923 if (!NT_STATUS_IS_OK(status
)) {
1924 TALLOC_FREE(principal
);
1925 return ADS_ERROR_NT(status
);
1929 /* If password is set we reauthenticate to kerberos server
1930 * and do not store results */
1932 if (user
&& *user
&& cli
->got_kerberos_mechanism
&& cli
->use_kerberos
) {
1934 const char *remote_name
= smbXcli_conn_remote_name(cli
->conn
);
1936 if (pass
&& *pass
) {
1939 use_in_memory_ccache();
1940 ret
= kerberos_kinit_password(user
, pass
, 0 /* no time correction for now */, NULL
);
1943 TALLOC_FREE(principal
);
1944 DEBUG(0, ("Kinit failed: %s\n", error_message(ret
)));
1945 if (cli
->fallback_after_kerberos
)
1947 return ADS_ERROR_KRB5(ret
);
1951 /* We may not be allowed to use the server-supplied SPNEGO principal, or it may not have been supplied to us
1953 if (!lp_client_use_spnego_principal() || strequal(principal
, ADS_IGNORE_PRINCIPAL
)) {
1954 TALLOC_FREE(principal
);
1957 if (principal
== NULL
&&
1958 !is_ipaddress(remote_name
) &&
1959 !strequal(STAR_SMBSERVER
,
1961 DEBUG(3,("cli_session_setup_spnego: using target "
1962 "hostname not SPNEGO principal\n"));
1965 char *realm
= strupper_talloc(talloc_tos(), dest_realm
);
1967 principal
= talloc_asprintf(talloc_tos(),
1974 principal
= kerberos_get_principal_from_service_hostname(talloc_tos(),
1981 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY
);
1983 DEBUG(3,("cli_session_setup_spnego: guessed "
1984 "server principal=%s\n",
1985 principal
? principal
: "<null>"));
1989 rc
= cli_session_setup_kerberos(cli
, principal
);
1990 if (ADS_ERR_OK(rc
) || !cli
->fallback_after_kerberos
) {
1991 TALLOC_FREE(principal
);
1998 TALLOC_FREE(principal
);
2002 account
= talloc_strdup(talloc_tos(), user
);
2004 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY
);
2007 /* when falling back to ntlmssp while authenticating with a machine
2008 * account strip off the realm - gd */
2010 if ((p
= strchr_m(user
, '@')) != NULL
) {
2011 account
[PTR_DIFF(p
,user
)] = '\0';
2014 return ADS_ERROR_NT(cli_session_setup_ntlmssp(cli
, account
, pass
, user_domain
));
2017 /****************************************************************************
2018 Send a session setup. The username and workgroup is in UNIX character
2019 format and must be converted to DOS codepage format before sending. If the
2020 password is in plaintext, the same should be done.
2021 ****************************************************************************/
2023 NTSTATUS
cli_session_setup(struct cli_state
*cli
,
2025 const char *pass
, int passlen
,
2026 const char *ntpass
, int ntpasslen
,
2027 const char *workgroup
)
2031 uint16_t sec_mode
= smb1cli_conn_server_security_mode(cli
->conn
);
2034 user2
= talloc_strdup(talloc_tos(), user
);
2036 user2
= talloc_strdup(talloc_tos(), "");
2038 if (user2
== NULL
) {
2039 return NT_STATUS_NO_MEMORY
;
2046 /* allow for workgroups as part of the username */
2047 if ((p
=strchr_m(user2
,'\\')) || (p
=strchr_m(user2
,'/')) ||
2048 (p
=strchr_m(user2
,*lp_winbind_separator()))) {
2051 if (!strupper_m(user2
)) {
2052 return NT_STATUS_INVALID_PARAMETER
;
2057 if (smbXcli_conn_protocol(cli
->conn
) < PROTOCOL_LANMAN1
) {
2058 return NT_STATUS_OK
;
2061 /* now work out what sort of session setup we are going to
2062 do. I have split this into separate functions to make the
2063 flow a bit easier to understand (tridge) */
2065 /* if its an older server then we have to use the older request format */
2067 if (smbXcli_conn_protocol(cli
->conn
) < PROTOCOL_NT1
) {
2068 if (!lp_client_lanman_auth() && passlen
!= 24 && (*pass
)) {
2069 DEBUG(1, ("Server requested LM password but 'client lanman auth = no'"
2070 " or 'client ntlmv2 auth = yes'\n"));
2071 return NT_STATUS_ACCESS_DENIED
;
2074 if ((sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
) == 0 &&
2075 !lp_client_plaintext_auth() && (*pass
)) {
2076 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
2077 " or 'client ntlmv2 auth = yes'\n"));
2078 return NT_STATUS_ACCESS_DENIED
;
2081 return cli_session_setup_lanman2(cli
, user
, pass
, passlen
,
2085 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
2086 const char *remote_realm
= cli_state_remote_realm(cli
);
2087 ADS_STATUS status
= cli_session_setup_spnego(cli
, user
, pass
,
2090 if (!ADS_ERR_OK(status
)) {
2091 DEBUG(3, ("SMB2-SPNEGO login failed: %s\n", ads_errstr(status
)));
2092 return ads_ntstatus(status
);
2094 return NT_STATUS_OK
;
2097 /* if no user is supplied then we have to do an anonymous connection.
2098 passwords are ignored */
2100 if (!user
|| !*user
)
2101 return cli_session_setup_guest(cli
);
2103 /* if the server is share level then send a plaintext null
2104 password at this point. The password is sent in the tree
2107 if ((sec_mode
& NEGOTIATE_SECURITY_USER_LEVEL
) == 0)
2108 return cli_session_setup_plain(cli
, user
, "", workgroup
);
2110 /* if the server doesn't support encryption then we have to use
2111 plaintext. The second password is ignored */
2113 if ((sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
) == 0) {
2114 if (!lp_client_plaintext_auth() && (*pass
)) {
2115 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
2116 " or 'client ntlmv2 auth = yes'\n"));
2117 return NT_STATUS_ACCESS_DENIED
;
2119 return cli_session_setup_plain(cli
, user
, pass
, workgroup
);
2122 /* if the server supports extended security then use SPNEGO */
2124 if (smb1cli_conn_capabilities(cli
->conn
) & CAP_EXTENDED_SECURITY
) {
2125 const char *remote_realm
= cli_state_remote_realm(cli
);
2126 ADS_STATUS status
= cli_session_setup_spnego(cli
, user
, pass
,
2129 if (!ADS_ERR_OK(status
)) {
2130 DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status
)));
2131 return ads_ntstatus(status
);
2136 /* otherwise do a NT1 style session setup */
2137 status
= cli_session_setup_nt1(cli
, user
, pass
, passlen
,
2138 ntpass
, ntpasslen
, workgroup
);
2139 if (!NT_STATUS_IS_OK(status
)) {
2140 DEBUG(3,("cli_session_setup: NT1 session setup "
2141 "failed: %s\n", nt_errstr(status
)));
2146 return NT_STATUS_OK
;
2149 /****************************************************************************
2151 *****************************************************************************/
2153 struct cli_ulogoff_state
{
2154 struct cli_state
*cli
;
2158 static void cli_ulogoff_done(struct tevent_req
*subreq
);
2160 struct tevent_req
*cli_ulogoff_send(TALLOC_CTX
*mem_ctx
,
2161 struct tevent_context
*ev
,
2162 struct cli_state
*cli
)
2164 struct tevent_req
*req
, *subreq
;
2165 struct cli_ulogoff_state
*state
;
2167 req
= tevent_req_create(mem_ctx
, &state
, struct cli_ulogoff_state
);
2173 SCVAL(state
->vwv
+0, 0, 0xFF);
2174 SCVAL(state
->vwv
+1, 0, 0);
2175 SSVAL(state
->vwv
+2, 0, 0);
2177 subreq
= cli_smb_send(state
, ev
, cli
, SMBulogoffX
, 0, 2, state
->vwv
,
2179 if (tevent_req_nomem(subreq
, req
)) {
2180 return tevent_req_post(req
, ev
);
2182 tevent_req_set_callback(subreq
, cli_ulogoff_done
, req
);
2186 static void cli_ulogoff_done(struct tevent_req
*subreq
)
2188 struct tevent_req
*req
= tevent_req_callback_data(
2189 subreq
, struct tevent_req
);
2190 struct cli_ulogoff_state
*state
= tevent_req_data(
2191 req
, struct cli_ulogoff_state
);
2194 status
= cli_smb_recv(subreq
, NULL
, NULL
, 0, NULL
, NULL
, NULL
, NULL
);
2195 if (!NT_STATUS_IS_OK(status
)) {
2196 tevent_req_nterror(req
, status
);
2199 cli_state_set_uid(state
->cli
, UID_FIELD_INVALID
);
2200 tevent_req_done(req
);
2203 NTSTATUS
cli_ulogoff_recv(struct tevent_req
*req
)
2205 return tevent_req_simple_recv_ntstatus(req
);
2208 NTSTATUS
cli_ulogoff(struct cli_state
*cli
)
2210 struct tevent_context
*ev
;
2211 struct tevent_req
*req
;
2212 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2214 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
2215 return NT_STATUS_INVALID_PARAMETER
;
2217 ev
= tevent_context_init(talloc_tos());
2221 req
= cli_ulogoff_send(ev
, ev
, cli
);
2225 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2228 status
= cli_ulogoff_recv(req
);
2234 /****************************************************************************
2236 ****************************************************************************/
2238 struct cli_tcon_andx_state
{
2239 struct cli_state
*cli
;
2244 static void cli_tcon_andx_done(struct tevent_req
*subreq
);
2246 struct tevent_req
*cli_tcon_andx_create(TALLOC_CTX
*mem_ctx
,
2247 struct event_context
*ev
,
2248 struct cli_state
*cli
,
2249 const char *share
, const char *dev
,
2250 const char *pass
, int passlen
,
2251 struct tevent_req
**psmbreq
)
2253 struct tevent_req
*req
, *subreq
;
2254 struct cli_tcon_andx_state
*state
;
2259 uint16_t sec_mode
= smb1cli_conn_server_security_mode(cli
->conn
);
2260 uint16_t tcon_flags
= 0;
2264 req
= tevent_req_create(mem_ctx
, &state
, struct cli_tcon_andx_state
);
2271 cli
->share
= talloc_strdup(cli
, share
);
2276 /* in user level security don't send a password now */
2277 if (sec_mode
& NEGOTIATE_SECURITY_USER_LEVEL
) {
2280 } else if (pass
== NULL
) {
2281 DEBUG(1, ("Server not using user level security and no "
2282 "password supplied.\n"));
2286 if ((sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
) &&
2287 *pass
&& passlen
!= 24) {
2288 if (!lp_client_lanman_auth()) {
2289 DEBUG(1, ("Server requested LANMAN password "
2290 "(share-level security) but "
2291 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2296 * Non-encrypted passwords - convert to DOS codepage before
2299 SMBencrypt(pass
, smb1cli_conn_server_challenge(cli
->conn
), p24
);
2301 pass
= (const char *)p24
;
2303 if((sec_mode
& (NEGOTIATE_SECURITY_USER_LEVEL
2304 |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
))
2308 if (!lp_client_plaintext_auth() && (*pass
)) {
2309 DEBUG(1, ("Server requested PLAINTEXT "
2311 "'client plaintext auth = no' or 'client ntlmv2 auth = yes'\n"));
2316 * Non-encrypted passwords - convert to DOS codepage
2319 tmp_pass
= talloc_array(talloc_tos(), uint8
, 0);
2320 if (tevent_req_nomem(tmp_pass
, req
)) {
2321 return tevent_req_post(req
, ev
);
2323 tmp_pass
= trans2_bytes_push_str(tmp_pass
,
2324 false, /* always DOS */
2328 if (tevent_req_nomem(tmp_pass
, req
)) {
2329 return tevent_req_post(req
, ev
);
2331 pass
= (const char *)tmp_pass
;
2332 passlen
= talloc_get_size(tmp_pass
);
2336 tcon_flags
|= TCONX_FLAG_EXTENDED_RESPONSE
;
2337 tcon_flags
|= TCONX_FLAG_EXTENDED_SIGNATURES
;
2339 SCVAL(vwv
+0, 0, 0xFF);
2342 SSVAL(vwv
+2, 0, tcon_flags
);
2343 SSVAL(vwv
+3, 0, passlen
);
2345 if (passlen
&& pass
) {
2346 bytes
= (uint8_t *)talloc_memdup(state
, pass
, passlen
);
2348 bytes
= talloc_array(state
, uint8_t, 0);
2354 tmp
= talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
2355 smbXcli_conn_remote_name(cli
->conn
), share
);
2360 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), tmp
, strlen(tmp
)+1,
2365 * Add the devicetype
2367 tmp
= talloc_strdup_upper(talloc_tos(), dev
);
2372 bytes
= smb_bytes_push_str(bytes
, false, tmp
, strlen(tmp
)+1, NULL
);
2375 if (bytes
== NULL
) {
2380 state
->bytes
.iov_base
= (void *)bytes
;
2381 state
->bytes
.iov_len
= talloc_get_size(bytes
);
2383 subreq
= cli_smb_req_create(state
, ev
, cli
, SMBtconX
, 0, 4, vwv
,
2385 if (subreq
== NULL
) {
2389 tevent_req_set_callback(subreq
, cli_tcon_andx_done
, req
);
2394 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
2395 return tevent_req_post(req
, ev
);
2398 struct tevent_req
*cli_tcon_andx_send(TALLOC_CTX
*mem_ctx
,
2399 struct event_context
*ev
,
2400 struct cli_state
*cli
,
2401 const char *share
, const char *dev
,
2402 const char *pass
, int passlen
)
2404 struct tevent_req
*req
, *subreq
;
2407 req
= cli_tcon_andx_create(mem_ctx
, ev
, cli
, share
, dev
, pass
, passlen
,
2412 if (subreq
== NULL
) {
2415 status
= smb1cli_req_chain_submit(&subreq
, 1);
2416 if (!NT_STATUS_IS_OK(status
)) {
2417 tevent_req_nterror(req
, status
);
2418 return tevent_req_post(req
, ev
);
2423 static void cli_tcon_andx_done(struct tevent_req
*subreq
)
2425 struct tevent_req
*req
= tevent_req_callback_data(
2426 subreq
, struct tevent_req
);
2427 struct cli_tcon_andx_state
*state
= tevent_req_data(
2428 req
, struct cli_tcon_andx_state
);
2429 struct cli_state
*cli
= state
->cli
;
2437 uint16_t optional_support
= 0;
2439 status
= cli_smb_recv(subreq
, state
, &in
, 0, &wct
, &vwv
,
2440 &num_bytes
, &bytes
);
2441 TALLOC_FREE(subreq
);
2442 if (!NT_STATUS_IS_OK(status
)) {
2443 tevent_req_nterror(req
, status
);
2447 inhdr
= in
+ NBT_HDR_SIZE
;
2450 if (clistr_pull_talloc(cli
,
2451 (const char *)inhdr
,
2452 SVAL(inhdr
, HDR_FLG2
),
2456 STR_TERMINATE
|STR_ASCII
) == -1) {
2457 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
2461 cli
->dev
= talloc_strdup(cli
, "");
2462 if (cli
->dev
== NULL
) {
2463 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
2468 if ((smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_NT1
) && (num_bytes
== 3)) {
2469 /* almost certainly win95 - enable bug fixes */
2474 * Make sure that we have the optional support 16-bit field. WCT > 2.
2475 * Avoids issues when connecting to Win9x boxes sharing files
2478 cli
->dfsroot
= false;
2480 if ((wct
> 2) && (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_LANMAN2
)) {
2481 optional_support
= SVAL(vwv
+2, 0);
2484 if (optional_support
& SMB_SHARE_IN_DFS
) {
2485 cli
->dfsroot
= true;
2488 if (optional_support
& SMB_EXTENDED_SIGNATURES
) {
2489 smb1cli_session_protect_session_key(cli
->smb1
.session
);
2492 cli_state_set_tid(cli
, SVAL(inhdr
, HDR_TID
));
2493 tevent_req_done(req
);
2496 NTSTATUS
cli_tcon_andx_recv(struct tevent_req
*req
)
2498 return tevent_req_simple_recv_ntstatus(req
);
2501 NTSTATUS
cli_tcon_andx(struct cli_state
*cli
, const char *share
,
2502 const char *dev
, const char *pass
, int passlen
)
2504 TALLOC_CTX
*frame
= talloc_stackframe();
2505 struct event_context
*ev
;
2506 struct tevent_req
*req
;
2507 NTSTATUS status
= NT_STATUS_OK
;
2509 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
2511 * Can't use sync call while an async call is in flight
2513 status
= NT_STATUS_INVALID_PARAMETER
;
2517 ev
= event_context_init(frame
);
2519 status
= NT_STATUS_NO_MEMORY
;
2523 req
= cli_tcon_andx_send(frame
, ev
, cli
, share
, dev
, pass
, passlen
);
2525 status
= NT_STATUS_NO_MEMORY
;
2529 if (!tevent_req_poll(req
, ev
)) {
2530 status
= map_nt_error_from_unix(errno
);
2534 status
= cli_tcon_andx_recv(req
);
2540 NTSTATUS
cli_tree_connect(struct cli_state
*cli
, const char *share
,
2541 const char *dev
, const char *pass
, int passlen
)
2544 uint16_t max_xmit
= 0;
2547 cli
->share
= talloc_strdup(cli
, share
);
2549 return NT_STATUS_NO_MEMORY
;
2552 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
2553 return smb2cli_tcon(cli
, share
);
2556 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_LANMAN1
) {
2557 return cli_tcon_andx(cli
, share
, dev
, pass
, passlen
);
2560 status
= cli_raw_tcon(cli
, share
, pass
, dev
, &max_xmit
, &tid
);
2561 if (!NT_STATUS_IS_OK(status
)) {
2565 cli_state_set_tid(cli
, tid
);
2567 return NT_STATUS_OK
;
2570 /****************************************************************************
2571 Send a tree disconnect.
2572 ****************************************************************************/
2574 struct cli_tdis_state
{
2575 struct cli_state
*cli
;
2578 static void cli_tdis_done(struct tevent_req
*subreq
);
2580 struct tevent_req
*cli_tdis_send(TALLOC_CTX
*mem_ctx
,
2581 struct tevent_context
*ev
,
2582 struct cli_state
*cli
)
2584 struct tevent_req
*req
, *subreq
;
2585 struct cli_tdis_state
*state
;
2587 req
= tevent_req_create(mem_ctx
, &state
, struct cli_tdis_state
);
2593 subreq
= cli_smb_send(state
, ev
, cli
, SMBtdis
, 0, 0, NULL
, 0, NULL
);
2594 if (tevent_req_nomem(subreq
, req
)) {
2595 return tevent_req_post(req
, ev
);
2597 tevent_req_set_callback(subreq
, cli_tdis_done
, req
);
2601 static void cli_tdis_done(struct tevent_req
*subreq
)
2603 struct tevent_req
*req
= tevent_req_callback_data(
2604 subreq
, struct tevent_req
);
2605 struct cli_tdis_state
*state
= tevent_req_data(
2606 req
, struct cli_tdis_state
);
2609 status
= cli_smb_recv(subreq
, NULL
, NULL
, 0, NULL
, NULL
, NULL
, NULL
);
2610 TALLOC_FREE(subreq
);
2611 if (!NT_STATUS_IS_OK(status
)) {
2612 tevent_req_nterror(req
, status
);
2615 cli_state_set_tid(state
->cli
, UINT16_MAX
);
2616 tevent_req_done(req
);
2619 NTSTATUS
cli_tdis_recv(struct tevent_req
*req
)
2621 return tevent_req_simple_recv_ntstatus(req
);
2624 NTSTATUS
cli_tdis(struct cli_state
*cli
)
2626 struct tevent_context
*ev
;
2627 struct tevent_req
*req
;
2628 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2630 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
2631 return NT_STATUS_INVALID_PARAMETER
;
2633 ev
= tevent_context_init(talloc_tos());
2637 req
= cli_tdis_send(ev
, ev
, cli
);
2641 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2644 status
= cli_tdis_recv(req
);
2650 static NTSTATUS
cli_connect_sock(const char *host
, int name_type
,
2651 const struct sockaddr_storage
*pss
,
2652 const char *myname
, uint16_t port
,
2653 int sec_timeout
, int *pfd
, uint16_t *pport
)
2655 TALLOC_CTX
*frame
= talloc_stackframe();
2657 unsigned int i
, num_addrs
;
2658 const char **called_names
;
2659 const char **calling_names
;
2664 prog
= getenv("LIBSMB_PROG");
2666 fd
= sock_exec(prog
);
2668 return map_nt_error_from_unix(errno
);
2674 if ((pss
== NULL
) || is_zero_addr(pss
)) {
2675 struct sockaddr_storage
*addrs
;
2676 status
= resolve_name_list(talloc_tos(), host
, name_type
,
2677 &addrs
, &num_addrs
);
2678 if (!NT_STATUS_IS_OK(status
)) {
2686 called_names
= talloc_array(talloc_tos(), const char *, num_addrs
);
2687 if (called_names
== NULL
) {
2688 status
= NT_STATUS_NO_MEMORY
;
2691 called_types
= talloc_array(talloc_tos(), int, num_addrs
);
2692 if (called_types
== NULL
) {
2693 status
= NT_STATUS_NO_MEMORY
;
2696 calling_names
= talloc_array(talloc_tos(), const char *, num_addrs
);
2697 if (calling_names
== NULL
) {
2698 status
= NT_STATUS_NO_MEMORY
;
2701 for (i
=0; i
<num_addrs
; i
++) {
2702 called_names
[i
] = host
;
2703 called_types
[i
] = name_type
;
2704 calling_names
[i
] = myname
;
2706 status
= smbsock_any_connect(pss
, called_names
, called_types
,
2707 calling_names
, NULL
, num_addrs
, port
,
2708 sec_timeout
, &fd
, NULL
, &port
);
2709 if (!NT_STATUS_IS_OK(status
)) {
2712 set_socket_options(fd
, lp_socket_options());
2716 status
= NT_STATUS_OK
;
2722 NTSTATUS
cli_connect_nb(const char *host
, const struct sockaddr_storage
*dest_ss
,
2723 uint16_t port
, int name_type
, const char *myname
,
2724 int signing_state
, int flags
, struct cli_state
**pcli
)
2726 TALLOC_CTX
*frame
= talloc_stackframe();
2727 struct cli_state
*cli
;
2728 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2733 desthost
= talloc_strdup(talloc_tos(), host
);
2734 if (desthost
== NULL
) {
2738 p
= strchr(host
, '#');
2740 name_type
= strtol(p
+1, NULL
, 16);
2741 host
= talloc_strndup(talloc_tos(), host
, p
- host
);
2747 status
= cli_connect_sock(host
, name_type
, dest_ss
, myname
, port
,
2749 if (!NT_STATUS_IS_OK(status
)) {
2753 cli
= cli_state_create(NULL
, fd
, desthost
, NULL
, signing_state
, flags
);
2761 status
= NT_STATUS_OK
;
2768 establishes a connection to after the negprot.
2769 @param output_cli A fully initialised cli structure, non-null only on success
2770 @param dest_host The netbios name of the remote host
2771 @param dest_ss (optional) The the destination IP, NULL for name based lookup
2772 @param port (optional) The destination port (0 for default)
2774 NTSTATUS
cli_start_connection(struct cli_state
**output_cli
,
2775 const char *my_name
,
2776 const char *dest_host
,
2777 const struct sockaddr_storage
*dest_ss
, int port
,
2778 int signing_state
, int flags
)
2781 struct cli_state
*cli
;
2783 nt_status
= cli_connect_nb(dest_host
, dest_ss
, port
, 0x20, my_name
,
2784 signing_state
, flags
, &cli
);
2785 if (!NT_STATUS_IS_OK(nt_status
)) {
2786 DEBUG(10, ("cli_connect_nb failed: %s\n",
2787 nt_errstr(nt_status
)));
2791 nt_status
= smbXcli_negprot(cli
->conn
, cli
->timeout
, PROTOCOL_CORE
,
2793 if (!NT_STATUS_IS_OK(nt_status
)) {
2794 DEBUG(1, ("failed negprot: %s\n", nt_errstr(nt_status
)));
2800 return NT_STATUS_OK
;
2805 establishes a connection right up to doing tconX, password specified.
2806 @param output_cli A fully initialised cli structure, non-null only on success
2807 @param dest_host The netbios name of the remote host
2808 @param dest_ip (optional) The the destination IP, NULL for name based lookup
2809 @param port (optional) The destination port (0 for default)
2810 @param service (optional) The share to make the connection to. Should be 'unqualified' in any way.
2811 @param service_type The 'type' of serivice.
2812 @param user Username, unix string
2813 @param domain User's domain
2814 @param password User's password, unencrypted unix string.
2817 NTSTATUS
cli_full_connection(struct cli_state
**output_cli
,
2818 const char *my_name
,
2819 const char *dest_host
,
2820 const struct sockaddr_storage
*dest_ss
, int port
,
2821 const char *service
, const char *service_type
,
2822 const char *user
, const char *domain
,
2823 const char *password
, int flags
,
2827 struct cli_state
*cli
= NULL
;
2828 int pw_len
= password
? strlen(password
)+1 : 0;
2832 if (password
== NULL
) {
2836 nt_status
= cli_start_connection(&cli
, my_name
, dest_host
,
2837 dest_ss
, port
, signing_state
,
2840 if (!NT_STATUS_IS_OK(nt_status
)) {
2844 nt_status
= cli_session_setup(cli
, user
, password
, pw_len
, password
,
2846 if (!NT_STATUS_IS_OK(nt_status
)) {
2848 if (!(flags
& CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK
)) {
2849 DEBUG(1,("failed session setup with %s\n",
2850 nt_errstr(nt_status
)));
2855 nt_status
= cli_session_setup(cli
, "", "", 0, "", 0, domain
);
2856 if (!NT_STATUS_IS_OK(nt_status
)) {
2857 DEBUG(1,("anonymous failed session setup with %s\n",
2858 nt_errstr(nt_status
)));
2865 nt_status
= cli_tree_connect(cli
, service
, service_type
,
2867 if (!NT_STATUS_IS_OK(nt_status
)) {
2868 DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status
)));
2870 if (NT_STATUS_IS_OK(nt_status
)) {
2871 nt_status
= NT_STATUS_UNSUCCESSFUL
;
2877 nt_status
= cli_init_creds(cli
, user
, domain
, password
);
2878 if (!NT_STATUS_IS_OK(nt_status
)) {
2884 return NT_STATUS_OK
;
2887 /****************************************************************************
2888 Send an old style tcon.
2889 ****************************************************************************/
2890 NTSTATUS
cli_raw_tcon(struct cli_state
*cli
,
2891 const char *service
, const char *pass
, const char *dev
,
2892 uint16
*max_xmit
, uint16
*tid
)
2894 struct tevent_req
*req
;
2899 if (!lp_client_plaintext_auth() && (*pass
)) {
2900 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
2901 " or 'client ntlmv2 auth = yes'\n"));
2902 return NT_STATUS_ACCESS_DENIED
;
2905 bytes
= talloc_array(talloc_tos(), uint8_t, 0);
2906 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
2907 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
2908 service
, strlen(service
)+1, NULL
);
2909 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
2910 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
2911 pass
, strlen(pass
)+1, NULL
);
2912 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
2913 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
2914 dev
, strlen(dev
)+1, NULL
);
2916 status
= cli_smb(talloc_tos(), cli
, SMBtcon
, 0, 0, NULL
,
2917 talloc_get_size(bytes
), bytes
, &req
,
2918 2, NULL
, &ret_vwv
, NULL
, NULL
);
2919 if (!NT_STATUS_IS_OK(status
)) {
2923 *max_xmit
= SVAL(ret_vwv
+ 0, 0);
2924 *tid
= SVAL(ret_vwv
+ 1, 0);
2926 return NT_STATUS_OK
;
2929 /* Return a cli_state pointing at the IPC$ share for the given server */
2931 struct cli_state
*get_ipc_connect(char *server
,
2932 struct sockaddr_storage
*server_ss
,
2933 const struct user_auth_info
*user_info
)
2935 struct cli_state
*cli
;
2937 uint32_t flags
= CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK
;
2939 if (user_info
->use_kerberos
) {
2940 flags
|= CLI_FULL_CONNECTION_USE_KERBEROS
;
2943 nt_status
= cli_full_connection(&cli
, NULL
, server
, server_ss
, 0, "IPC$", "IPC",
2944 user_info
->username
? user_info
->username
: "",
2946 user_info
->password
? user_info
->password
: "",
2948 SMB_SIGNING_DEFAULT
);
2950 if (NT_STATUS_IS_OK(nt_status
)) {
2952 } else if (is_ipaddress(server
)) {
2953 /* windows 9* needs a correct NMB name for connections */
2954 fstring remote_name
;
2956 if (name_status_find("*", 0, 0, server_ss
, remote_name
)) {
2957 cli
= get_ipc_connect(remote_name
, server_ss
, user_info
);
2966 * Given the IP address of a master browser on the network, return its
2967 * workgroup and connect to it.
2969 * This function is provided to allow additional processing beyond what
2970 * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
2971 * browsers and obtain each master browsers' list of domains (in case the
2972 * first master browser is recently on the network and has not yet
2973 * synchronized with other master browsers and therefore does not yet have the
2974 * entire network browse list)
2977 struct cli_state
*get_ipc_connect_master_ip(TALLOC_CTX
*ctx
,
2978 struct sockaddr_storage
*mb_ip
,
2979 const struct user_auth_info
*user_info
,
2980 char **pp_workgroup_out
)
2982 char addr
[INET6_ADDRSTRLEN
];
2984 struct cli_state
*cli
;
2985 struct sockaddr_storage server_ss
;
2987 *pp_workgroup_out
= NULL
;
2989 print_sockaddr(addr
, sizeof(addr
), mb_ip
);
2990 DEBUG(99, ("Looking up name of master browser %s\n",
2994 * Do a name status query to find out the name of the master browser.
2995 * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
2996 * master browser will not respond to a wildcard query (or, at least,
2997 * an NT4 server acting as the domain master browser will not).
2999 * We might be able to use ONLY the query on MSBROWSE, but that's not
3000 * yet been tested with all Windows versions, so until it is, leave
3001 * the original wildcard query as the first choice and fall back to
3002 * MSBROWSE if the wildcard query fails.
3004 if (!name_status_find("*", 0, 0x1d, mb_ip
, name
) &&
3005 !name_status_find(MSBROWSE
, 1, 0x1d, mb_ip
, name
)) {
3007 DEBUG(99, ("Could not retrieve name status for %s\n",
3012 if (!find_master_ip(name
, &server_ss
)) {
3013 DEBUG(99, ("Could not find master ip for %s\n", name
));
3017 *pp_workgroup_out
= talloc_strdup(ctx
, name
);
3019 DEBUG(4, ("found master browser %s, %s\n", name
, addr
));
3021 print_sockaddr(addr
, sizeof(addr
), &server_ss
);
3022 cli
= get_ipc_connect(addr
, &server_ss
, user_info
);
3028 * Return the IP address and workgroup of a master browser on the network, and
3032 struct cli_state
*get_ipc_connect_master_ip_bcast(TALLOC_CTX
*ctx
,
3033 const struct user_auth_info
*user_info
,
3034 char **pp_workgroup_out
)
3036 struct sockaddr_storage
*ip_list
;
3037 struct cli_state
*cli
;
3041 *pp_workgroup_out
= NULL
;
3043 DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
3045 /* Go looking for workgroups by broadcasting on the local network */
3047 status
= name_resolve_bcast(MSBROWSE
, 1, talloc_tos(),
3049 if (!NT_STATUS_IS_OK(status
)) {
3050 DEBUG(99, ("No master browsers responded: %s\n",
3051 nt_errstr(status
)));
3055 for (i
= 0; i
< count
; i
++) {
3056 char addr
[INET6_ADDRSTRLEN
];
3057 print_sockaddr(addr
, sizeof(addr
), &ip_list
[i
]);
3058 DEBUG(99, ("Found master browser %s\n", addr
));
3060 cli
= get_ipc_connect_master_ip(ctx
, &ip_list
[i
],
3061 user_info
, pp_workgroup_out
);