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 "popt_common.h"
26 #include "../libcli/auth/libcli_auth.h"
27 #include "../libcli/auth/spnego.h"
29 #include "../libcli/auth/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"
41 {PROTOCOL_CORE
, "PC NETWORK PROGRAM 1.0"},
42 {PROTOCOL_COREPLUS
, "MICROSOFT NETWORKS 1.03"},
43 {PROTOCOL_LANMAN1
, "MICROSOFT NETWORKS 3.0"},
44 {PROTOCOL_LANMAN1
, "LANMAN1.0"},
45 {PROTOCOL_LANMAN2
, "LM1.2X002"},
46 {PROTOCOL_LANMAN2
, "DOS LANMAN2.1"},
47 {PROTOCOL_LANMAN2
, "LANMAN2.1"},
48 {PROTOCOL_LANMAN2
, "Samba"},
49 {PROTOCOL_NT1
, "NT LANMAN 1.0"},
50 {PROTOCOL_NT1
, "NT LM 0.12"},
53 #define STAR_SMBSERVER "*SMBSERVER"
55 /********************************************************
56 Utility function to ensure we always return at least
57 a valid char * pointer to an empty string for the
58 cli->server_os, cli->server_type and cli->server_domain
60 *******************************************************/
62 static NTSTATUS
smb_bytes_talloc_string(TALLOC_CTX
*mem_ctx
,
69 *destlen
= clistr_pull_talloc(mem_ctx
,
71 SVAL(inbuf
, smb_flg2
),
77 return NT_STATUS_NO_MEMORY
;
81 *dest
= talloc_strdup(mem_ctx
, "");
83 return NT_STATUS_NO_MEMORY
;
90 * Set the user session key for a connection
91 * @param cli The cli structure to add it too
92 * @param session_key The session key used. (A copy of this is taken for the cli struct)
96 static void cli_set_session_key (struct cli_state
*cli
, const DATA_BLOB session_key
)
98 cli
->user_session_key
= data_blob(session_key
.data
, session_key
.length
);
101 /****************************************************************************
102 Do an old lanman2 style session setup.
103 ****************************************************************************/
105 struct cli_session_setup_lanman2_state
{
106 struct cli_state
*cli
;
111 static void cli_session_setup_lanman2_done(struct tevent_req
*subreq
);
113 static struct tevent_req
*cli_session_setup_lanman2_send(
114 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
115 struct cli_state
*cli
, const char *user
,
116 const char *pass
, size_t passlen
,
117 const char *workgroup
)
119 struct tevent_req
*req
, *subreq
;
120 struct cli_session_setup_lanman2_state
*state
;
121 DATA_BLOB lm_response
= data_blob_null
;
126 req
= tevent_req_create(mem_ctx
, &state
,
127 struct cli_session_setup_lanman2_state
);
136 * LANMAN servers predate NT status codes and Unicode and
137 * ignore those smb flags so we must disable the corresponding
138 * default capabilities that would otherwise cause the Unicode
139 * and NT Status flags to be set (and even returned by the
143 cli
->capabilities
&= ~(CAP_UNICODE
| CAP_STATUS32
);
146 * if in share level security then don't send a password now
148 if (!(cli
->sec_mode
& NEGOTIATE_SECURITY_USER_LEVEL
)) {
153 && (cli
->sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
)
156 * Encrypted mode needed, and non encrypted password
159 lm_response
= data_blob(NULL
, 24);
160 if (tevent_req_nomem(lm_response
.data
, req
)) {
161 return tevent_req_post(req
, ev
);
164 if (!SMBencrypt(pass
, cli
->secblob
.data
,
165 (uint8_t *)lm_response
.data
)) {
166 DEBUG(1, ("Password is > 14 chars in length, and is "
167 "therefore incompatible with Lanman "
168 "authentication\n"));
169 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
170 return tevent_req_post(req
, ev
);
172 } else if ((cli
->sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
)
175 * Encrypted mode needed, and encrypted password
178 lm_response
= data_blob(pass
, passlen
);
179 if (tevent_req_nomem(lm_response
.data
, req
)) {
180 return tevent_req_post(req
, ev
);
182 } else if (passlen
> 0) {
184 size_t converted_size
;
186 * Plaintext mode needed, assume plaintext supplied.
188 buf
= talloc_array(talloc_tos(), uint8_t, 0);
189 buf
= smb_bytes_push_str(buf
, cli_ucs2(cli
), pass
, passlen
+1,
191 if (tevent_req_nomem(buf
, req
)) {
192 return tevent_req_post(req
, ev
);
194 lm_response
= data_blob(pass
, passlen
);
196 if (tevent_req_nomem(lm_response
.data
, req
)) {
197 return tevent_req_post(req
, ev
);
201 SCVAL(vwv
+0, 0, 0xff);
204 SSVAL(vwv
+2, 0, CLI_BUFFER_SIZE
);
207 SIVAL(vwv
+5, 0, cli
->sesskey
);
208 SSVAL(vwv
+7, 0, lm_response
.length
);
210 bytes
= talloc_array(state
, uint8_t, lm_response
.length
);
211 if (tevent_req_nomem(bytes
, req
)) {
212 return tevent_req_post(req
, ev
);
214 if (lm_response
.length
!= 0) {
215 memcpy(bytes
, lm_response
.data
, lm_response
.length
);
217 data_blob_free(&lm_response
);
219 tmp
= talloc_strdup_upper(talloc_tos(), user
);
220 if (tevent_req_nomem(tmp
, req
)) {
221 return tevent_req_post(req
, ev
);
223 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), tmp
, strlen(tmp
)+1,
227 tmp
= talloc_strdup_upper(talloc_tos(), workgroup
);
228 if (tevent_req_nomem(tmp
, req
)) {
229 return tevent_req_post(req
, ev
);
231 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), tmp
, strlen(tmp
)+1,
233 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), "Unix", 5, NULL
);
234 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), "Samba", 6, NULL
);
236 if (tevent_req_nomem(bytes
, req
)) {
237 return tevent_req_post(req
, ev
);
240 subreq
= cli_smb_send(state
, ev
, cli
, SMBsesssetupX
, 0, 10, vwv
,
241 talloc_get_size(bytes
), bytes
);
242 if (tevent_req_nomem(subreq
, req
)) {
243 return tevent_req_post(req
, ev
);
245 tevent_req_set_callback(subreq
, cli_session_setup_lanman2_done
, req
);
249 static void cli_session_setup_lanman2_done(struct tevent_req
*subreq
)
251 struct tevent_req
*req
= tevent_req_callback_data(
252 subreq
, struct tevent_req
);
253 struct cli_session_setup_lanman2_state
*state
= tevent_req_data(
254 req
, struct cli_session_setup_lanman2_state
);
255 struct cli_state
*cli
= state
->cli
;
266 status
= cli_smb_recv(subreq
, state
, &in
, 3, &wct
, &vwv
,
269 if (!NT_STATUS_IS_OK(status
)) {
270 tevent_req_nterror(req
, status
);
277 cli_state_set_uid(state
->cli
, SVAL(inbuf
, smb_uid
));
278 cli
->is_guestlogin
= ((SVAL(vwv
+2, 0) & 1) != 0);
280 status
= smb_bytes_talloc_string(cli
,
287 if (!NT_STATUS_IS_OK(status
)) {
288 tevent_req_nterror(req
, status
);
293 status
= smb_bytes_talloc_string(cli
,
300 if (!NT_STATUS_IS_OK(status
)) {
301 tevent_req_nterror(req
, status
);
306 status
= smb_bytes_talloc_string(cli
,
313 if (!NT_STATUS_IS_OK(status
)) {
314 tevent_req_nterror(req
, status
);
319 if (strstr(cli
->server_type
, "Samba")) {
320 cli
->is_samba
= True
;
322 status
= cli_set_username(cli
, state
->user
);
323 if (tevent_req_nterror(req
, status
)) {
326 tevent_req_done(req
);
329 static NTSTATUS
cli_session_setup_lanman2_recv(struct tevent_req
*req
)
331 return tevent_req_simple_recv_ntstatus(req
);
334 static NTSTATUS
cli_session_setup_lanman2(struct cli_state
*cli
, const char *user
,
335 const char *pass
, size_t passlen
,
336 const char *workgroup
)
338 TALLOC_CTX
*frame
= talloc_stackframe();
339 struct event_context
*ev
;
340 struct tevent_req
*req
;
341 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
343 if (cli_has_async_calls(cli
)) {
345 * Can't use sync call while an async call is in flight
347 status
= NT_STATUS_INVALID_PARAMETER
;
350 ev
= event_context_init(frame
);
354 req
= cli_session_setup_lanman2_send(frame
, ev
, cli
, user
, pass
, passlen
,
359 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
362 status
= cli_session_setup_lanman2_recv(req
);
368 /****************************************************************************
369 Work out suitable capabilities to offer the server.
370 ****************************************************************************/
372 static uint32
cli_session_setup_capabilities(struct cli_state
*cli
)
374 uint32 capabilities
= CAP_NT_SMBS
;
376 if (!cli
->force_dos_errors
)
377 capabilities
|= CAP_STATUS32
;
379 if (cli
->use_level_II_oplocks
)
380 capabilities
|= CAP_LEVEL_II_OPLOCKS
;
382 capabilities
|= (cli
->capabilities
& (CAP_UNICODE
|CAP_LARGE_FILES
|CAP_LARGE_READX
|CAP_LARGE_WRITEX
|CAP_DFS
));
386 /****************************************************************************
387 Do a NT1 guest session setup.
388 ****************************************************************************/
390 struct cli_session_setup_guest_state
{
391 struct cli_state
*cli
;
396 static void cli_session_setup_guest_done(struct tevent_req
*subreq
);
398 struct tevent_req
*cli_session_setup_guest_create(TALLOC_CTX
*mem_ctx
,
399 struct event_context
*ev
,
400 struct cli_state
*cli
,
401 struct tevent_req
**psmbreq
)
403 struct tevent_req
*req
, *subreq
;
404 struct cli_session_setup_guest_state
*state
;
408 req
= tevent_req_create(mem_ctx
, &state
,
409 struct cli_session_setup_guest_state
);
416 SCVAL(vwv
+0, 0, 0xFF);
419 SSVAL(vwv
+2, 0, CLI_BUFFER_SIZE
);
421 SSVAL(vwv
+4, 0, cli_state_get_vc_num(cli
));
422 SIVAL(vwv
+5, 0, cli
->sesskey
);
427 SIVAL(vwv
+11, 0, cli_session_setup_capabilities(cli
));
429 bytes
= talloc_array(state
, uint8_t, 0);
431 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), "", 1, /* username */
433 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), "", 1, /* workgroup */
435 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), "Unix", 5, NULL
);
436 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), "Samba", 6, NULL
);
443 state
->bytes
.iov_base
= (void *)bytes
;
444 state
->bytes
.iov_len
= talloc_get_size(bytes
);
446 subreq
= cli_smb_req_create(state
, ev
, cli
, SMBsesssetupX
, 0, 13, vwv
,
448 if (subreq
== NULL
) {
452 tevent_req_set_callback(subreq
, cli_session_setup_guest_done
, req
);
457 struct tevent_req
*cli_session_setup_guest_send(TALLOC_CTX
*mem_ctx
,
458 struct event_context
*ev
,
459 struct cli_state
*cli
)
461 struct tevent_req
*req
, *subreq
;
464 req
= cli_session_setup_guest_create(mem_ctx
, ev
, cli
, &subreq
);
469 status
= cli_smb_req_send(subreq
);
470 if (NT_STATUS_IS_OK(status
)) {
471 tevent_req_nterror(req
, status
);
472 return tevent_req_post(req
, ev
);
477 static void cli_session_setup_guest_done(struct tevent_req
*subreq
)
479 struct tevent_req
*req
= tevent_req_callback_data(
480 subreq
, struct tevent_req
);
481 struct cli_session_setup_guest_state
*state
= tevent_req_data(
482 req
, struct cli_session_setup_guest_state
);
483 struct cli_state
*cli
= state
->cli
;
494 status
= cli_smb_recv(subreq
, state
, &in
, 3, &wct
, &vwv
,
497 if (!NT_STATUS_IS_OK(status
)) {
498 tevent_req_nterror(req
, status
);
505 cli_state_set_uid(state
->cli
, SVAL(inbuf
, smb_uid
));
506 cli
->is_guestlogin
= ((SVAL(vwv
+2, 0) & 1) != 0);
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
= smb_bytes_talloc_string(cli
,
541 if (!NT_STATUS_IS_OK(status
)) {
542 tevent_req_nterror(req
, status
);
547 if (strstr(cli
->server_type
, "Samba")) {
548 cli
->is_samba
= True
;
551 status
= cli_set_username(cli
, "");
552 if (!NT_STATUS_IS_OK(status
)) {
553 tevent_req_nterror(req
, status
);
556 tevent_req_done(req
);
559 NTSTATUS
cli_session_setup_guest_recv(struct tevent_req
*req
)
561 return tevent_req_simple_recv_ntstatus(req
);
564 static NTSTATUS
cli_session_setup_guest(struct cli_state
*cli
)
566 TALLOC_CTX
*frame
= talloc_stackframe();
567 struct event_context
*ev
;
568 struct tevent_req
*req
;
569 NTSTATUS status
= NT_STATUS_OK
;
571 if (cli_has_async_calls(cli
)) {
573 * Can't use sync call while an async call is in flight
575 status
= NT_STATUS_INVALID_PARAMETER
;
579 ev
= event_context_init(frame
);
581 status
= NT_STATUS_NO_MEMORY
;
585 req
= cli_session_setup_guest_send(frame
, ev
, cli
);
587 status
= NT_STATUS_NO_MEMORY
;
591 if (!tevent_req_poll(req
, ev
)) {
592 status
= map_nt_error_from_unix(errno
);
596 status
= cli_session_setup_guest_recv(req
);
602 /****************************************************************************
603 Do a NT1 plaintext session setup.
604 ****************************************************************************/
606 struct cli_session_setup_plain_state
{
607 struct cli_state
*cli
;
612 static void cli_session_setup_plain_done(struct tevent_req
*subreq
);
614 static struct tevent_req
*cli_session_setup_plain_send(
615 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
616 struct cli_state
*cli
,
617 const char *user
, const char *pass
, const char *workgroup
)
619 struct tevent_req
*req
, *subreq
;
620 struct cli_session_setup_plain_state
*state
;
626 req
= tevent_req_create(mem_ctx
, &state
,
627 struct cli_session_setup_plain_state
);
635 SCVAL(vwv
+0, 0, 0xff);
638 SSVAL(vwv
+2, 0, CLI_BUFFER_SIZE
);
640 SSVAL(vwv
+4, 0, cli_state_get_vc_num(cli
));
641 SIVAL(vwv
+5, 0, cli
->sesskey
);
646 SIVAL(vwv
+11, 0, cli_session_setup_capabilities(cli
));
648 bytes
= talloc_array(state
, uint8_t, 0);
649 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), pass
, strlen(pass
)+1,
651 if (tevent_req_nomem(bytes
, req
)) {
652 return tevent_req_post(req
, ev
);
654 SSVAL(vwv
+ (cli_ucs2(cli
) ? 8 : 7), 0, passlen
);
656 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
),
657 user
, strlen(user
)+1, NULL
);
658 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
),
659 workgroup
, strlen(workgroup
)+1, NULL
);
660 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
),
663 version
= talloc_asprintf(talloc_tos(), "Samba %s",
664 samba_version_string());
665 if (tevent_req_nomem(version
, req
)){
666 return tevent_req_post(req
, ev
);
668 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
),
669 version
, strlen(version
)+1, NULL
);
670 TALLOC_FREE(version
);
672 if (tevent_req_nomem(bytes
, req
)) {
673 return tevent_req_post(req
, ev
);
676 subreq
= cli_smb_send(state
, ev
, cli
, SMBsesssetupX
, 0, 13, vwv
,
677 talloc_get_size(bytes
), bytes
);
678 if (tevent_req_nomem(subreq
, req
)) {
679 return tevent_req_post(req
, ev
);
681 tevent_req_set_callback(subreq
, cli_session_setup_plain_done
, req
);
685 static void cli_session_setup_plain_done(struct tevent_req
*subreq
)
687 struct tevent_req
*req
= tevent_req_callback_data(
688 subreq
, struct tevent_req
);
689 struct cli_session_setup_plain_state
*state
= tevent_req_data(
690 req
, struct cli_session_setup_plain_state
);
691 struct cli_state
*cli
= state
->cli
;
702 status
= cli_smb_recv(subreq
, state
, &in
, 3, &wct
, &vwv
,
705 if (tevent_req_nterror(req
, status
)) {
712 cli_state_set_uid(state
->cli
, SVAL(inbuf
, smb_uid
));
713 cli
->is_guestlogin
= ((SVAL(vwv
+2, 0) & 1) != 0);
715 status
= smb_bytes_talloc_string(cli
,
722 if (!NT_STATUS_IS_OK(status
)) {
723 tevent_req_nterror(req
, status
);
728 status
= smb_bytes_talloc_string(cli
,
735 if (!NT_STATUS_IS_OK(status
)) {
736 tevent_req_nterror(req
, status
);
741 status
= smb_bytes_talloc_string(cli
,
748 if (!NT_STATUS_IS_OK(status
)) {
749 tevent_req_nterror(req
, status
);
754 status
= cli_set_username(cli
, state
->user
);
755 if (tevent_req_nterror(req
, status
)) {
758 if (strstr(cli
->server_type
, "Samba")) {
759 cli
->is_samba
= True
;
761 tevent_req_done(req
);
764 static NTSTATUS
cli_session_setup_plain_recv(struct tevent_req
*req
)
766 return tevent_req_simple_recv_ntstatus(req
);
769 static NTSTATUS
cli_session_setup_plain(struct cli_state
*cli
,
770 const char *user
, const char *pass
,
771 const char *workgroup
)
773 TALLOC_CTX
*frame
= talloc_stackframe();
774 struct event_context
*ev
;
775 struct tevent_req
*req
;
776 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
778 if (cli_has_async_calls(cli
)) {
780 * Can't use sync call while an async call is in flight
782 status
= NT_STATUS_INVALID_PARAMETER
;
785 ev
= event_context_init(frame
);
789 req
= cli_session_setup_plain_send(frame
, ev
, cli
, user
, pass
,
794 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
797 status
= cli_session_setup_plain_recv(req
);
803 /****************************************************************************
804 do a NT1 NTLM/LM encrypted session setup - for when extended security
806 @param cli client state to create do session setup on
808 @param pass *either* cleartext password (passlen !=24) or LM response.
809 @param ntpass NT response, implies ntpasslen >=24, implies pass is not clear
810 @param workgroup The user's domain.
811 ****************************************************************************/
813 struct cli_session_setup_nt1_state
{
814 struct cli_state
*cli
;
817 DATA_BLOB session_key
;
821 static void cli_session_setup_nt1_done(struct tevent_req
*subreq
);
823 static struct tevent_req
*cli_session_setup_nt1_send(
824 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
825 struct cli_state
*cli
, const char *user
,
826 const char *pass
, size_t passlen
,
827 const char *ntpass
, size_t ntpasslen
,
828 const char *workgroup
)
830 struct tevent_req
*req
, *subreq
;
831 struct cli_session_setup_nt1_state
*state
;
832 DATA_BLOB lm_response
= data_blob_null
;
833 DATA_BLOB nt_response
= data_blob_null
;
834 DATA_BLOB session_key
= data_blob_null
;
837 char *workgroup_upper
;
839 req
= tevent_req_create(mem_ctx
, &state
,
840 struct cli_session_setup_nt1_state
);
849 /* do nothing - guest login */
850 } else if (passlen
!= 24) {
851 if (lp_client_ntlmv2_auth()) {
852 DATA_BLOB server_chal
;
853 DATA_BLOB names_blob
;
855 server_chal
= data_blob(cli
->secblob
.data
,
856 MIN(cli
->secblob
.length
, 8));
857 if (tevent_req_nomem(server_chal
.data
, req
)) {
858 return tevent_req_post(req
, ev
);
862 * note that the 'workgroup' here is a best
863 * guess - we don't know the server's domain
864 * at this point. The 'server name' is also
867 names_blob
= NTLMv2_generate_names_blob(
868 NULL
, cli
->called
.name
, workgroup
);
870 if (tevent_req_nomem(names_blob
.data
, req
)) {
871 return tevent_req_post(req
, ev
);
874 if (!SMBNTLMv2encrypt(NULL
, user
, workgroup
, pass
,
875 &server_chal
, &names_blob
,
876 &lm_response
, &nt_response
,
877 NULL
, &session_key
)) {
878 data_blob_free(&names_blob
);
879 data_blob_free(&server_chal
);
881 req
, NT_STATUS_ACCESS_DENIED
);
882 return tevent_req_post(req
, ev
);
884 data_blob_free(&names_blob
);
885 data_blob_free(&server_chal
);
889 E_md4hash(pass
, nt_hash
);
892 nt_response
= data_blob_null
;
894 nt_response
= data_blob(NULL
, 24);
895 if (tevent_req_nomem(nt_response
.data
, req
)) {
896 return tevent_req_post(req
, ev
);
899 SMBNTencrypt(pass
, cli
->secblob
.data
,
902 /* non encrypted password supplied. Ignore ntpass. */
903 if (lp_client_lanman_auth()) {
905 lm_response
= data_blob(NULL
, 24);
906 if (tevent_req_nomem(lm_response
.data
, req
)) {
907 return tevent_req_post(req
, ev
);
910 if (!SMBencrypt(pass
,cli
->secblob
.data
,
913 * Oops, the LM response is
914 * invalid, just put the NT
915 * response there instead
917 data_blob_free(&lm_response
);
918 lm_response
= data_blob(
924 * LM disabled, place NT# in LM field
927 lm_response
= data_blob(
928 nt_response
.data
, nt_response
.length
);
931 if (tevent_req_nomem(lm_response
.data
, req
)) {
932 return tevent_req_post(req
, ev
);
935 session_key
= data_blob(NULL
, 16);
936 if (tevent_req_nomem(session_key
.data
, req
)) {
937 return tevent_req_post(req
, ev
);
940 E_deshash(pass
, session_key
.data
);
941 memset(&session_key
.data
[8], '\0', 8);
943 SMBsesskeygen_ntv1(nt_hash
, session_key
.data
);
946 cli_temp_set_signing(cli
);
948 /* pre-encrypted password supplied. Only used for
949 security=server, can't do
950 signing because we don't have original key */
952 lm_response
= data_blob(pass
, passlen
);
953 if (tevent_req_nomem(lm_response
.data
, req
)) {
954 return tevent_req_post(req
, ev
);
957 nt_response
= data_blob(ntpass
, ntpasslen
);
958 if (tevent_req_nomem(nt_response
.data
, req
)) {
959 return tevent_req_post(req
, ev
);
964 state
->response
= data_blob_talloc(
965 state
, lm_response
.data
, lm_response
.length
);
967 state
->response
= data_blob_talloc(
968 state
, nt_response
.data
, nt_response
.length
);
970 if (tevent_req_nomem(state
->response
.data
, req
)) {
971 return tevent_req_post(req
, ev
);
974 if (session_key
.data
) {
975 state
->session_key
= data_blob_talloc(
976 state
, session_key
.data
, session_key
.length
);
977 if (tevent_req_nomem(state
->session_key
.data
, req
)) {
978 return tevent_req_post(req
, ev
);
981 data_blob_free(&session_key
);
983 SCVAL(vwv
+0, 0, 0xff);
986 SSVAL(vwv
+2, 0, CLI_BUFFER_SIZE
);
988 SSVAL(vwv
+4, 0, cli_state_get_vc_num(cli
));
989 SIVAL(vwv
+5, 0, cli
->sesskey
);
990 SSVAL(vwv
+7, 0, lm_response
.length
);
991 SSVAL(vwv
+8, 0, nt_response
.length
);
994 SIVAL(vwv
+11, 0, cli_session_setup_capabilities(cli
));
996 bytes
= talloc_array(state
, uint8_t,
997 lm_response
.length
+ nt_response
.length
);
998 if (tevent_req_nomem(bytes
, req
)) {
999 return tevent_req_post(req
, ev
);
1001 if (lm_response
.length
!= 0) {
1002 memcpy(bytes
, lm_response
.data
, lm_response
.length
);
1004 if (nt_response
.length
!= 0) {
1005 memcpy(bytes
+ lm_response
.length
,
1006 nt_response
.data
, nt_response
.length
);
1008 data_blob_free(&lm_response
);
1009 data_blob_free(&nt_response
);
1011 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
),
1012 user
, strlen(user
)+1, NULL
);
1015 * Upper case here might help some NTLMv2 implementations
1017 workgroup_upper
= talloc_strdup_upper(talloc_tos(), workgroup
);
1018 if (tevent_req_nomem(workgroup_upper
, req
)) {
1019 return tevent_req_post(req
, ev
);
1021 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
),
1022 workgroup_upper
, strlen(workgroup_upper
)+1,
1024 TALLOC_FREE(workgroup_upper
);
1026 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), "Unix", 5, NULL
);
1027 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), "Samba", 6, NULL
);
1028 if (tevent_req_nomem(bytes
, req
)) {
1029 return tevent_req_post(req
, ev
);
1032 subreq
= cli_smb_send(state
, ev
, cli
, SMBsesssetupX
, 0, 13, vwv
,
1033 talloc_get_size(bytes
), bytes
);
1034 if (tevent_req_nomem(subreq
, req
)) {
1035 return tevent_req_post(req
, ev
);
1037 tevent_req_set_callback(subreq
, cli_session_setup_nt1_done
, req
);
1041 static void cli_session_setup_nt1_done(struct tevent_req
*subreq
)
1043 struct tevent_req
*req
= tevent_req_callback_data(
1044 subreq
, struct tevent_req
);
1045 struct cli_session_setup_nt1_state
*state
= tevent_req_data(
1046 req
, struct cli_session_setup_nt1_state
);
1047 struct cli_state
*cli
= state
->cli
;
1058 status
= cli_smb_recv(subreq
, state
, &in
, 3, &wct
, &vwv
,
1059 &num_bytes
, &bytes
);
1060 TALLOC_FREE(subreq
);
1061 if (!NT_STATUS_IS_OK(status
)) {
1062 tevent_req_nterror(req
, status
);
1069 cli_state_set_uid(state
->cli
, SVAL(inbuf
, smb_uid
));
1070 cli
->is_guestlogin
= ((SVAL(vwv
+2, 0) & 1) != 0);
1072 status
= smb_bytes_talloc_string(cli
,
1078 if (!NT_STATUS_IS_OK(status
)) {
1079 tevent_req_nterror(req
, status
);
1084 status
= smb_bytes_talloc_string(cli
,
1090 if (!NT_STATUS_IS_OK(status
)) {
1091 tevent_req_nterror(req
, status
);
1096 status
= smb_bytes_talloc_string(cli
,
1098 &cli
->server_domain
,
1102 if (!NT_STATUS_IS_OK(status
)) {
1103 tevent_req_nterror(req
, status
);
1108 if (strstr(cli
->server_type
, "Samba")) {
1109 cli
->is_samba
= True
;
1112 status
= cli_set_username(cli
, state
->user
);
1113 if (tevent_req_nterror(req
, status
)) {
1116 if (cli_simple_set_signing(cli
, state
->session_key
, state
->response
)
1117 && !cli_check_sign_mac(cli
, (char *)in
, 1)) {
1118 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1121 if (state
->session_key
.data
) {
1122 /* Have plaintext orginal */
1123 cli_set_session_key(cli
, state
->session_key
);
1125 tevent_req_done(req
);
1128 static NTSTATUS
cli_session_setup_nt1_recv(struct tevent_req
*req
)
1130 return tevent_req_simple_recv_ntstatus(req
);
1133 static NTSTATUS
cli_session_setup_nt1(struct cli_state
*cli
, const char *user
,
1134 const char *pass
, size_t passlen
,
1135 const char *ntpass
, size_t ntpasslen
,
1136 const char *workgroup
)
1138 TALLOC_CTX
*frame
= talloc_stackframe();
1139 struct event_context
*ev
;
1140 struct tevent_req
*req
;
1141 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
1143 if (cli_has_async_calls(cli
)) {
1145 * Can't use sync call while an async call is in flight
1147 status
= NT_STATUS_INVALID_PARAMETER
;
1150 ev
= event_context_init(frame
);
1154 req
= cli_session_setup_nt1_send(frame
, ev
, cli
, user
, pass
, passlen
,
1155 ntpass
, ntpasslen
, workgroup
);
1159 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
1162 status
= cli_session_setup_nt1_recv(req
);
1168 /* The following is calculated from :
1170 * (smb_wcnt * 2) = 24 (smb_wcnt == 12 in cli_session_setup_blob_send() )
1171 * (strlen("Unix") + 1 + strlen("Samba") + 1) * 2 = 22 (unicode strings at
1175 #define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22)
1177 struct cli_sesssetup_blob_state
{
1178 struct tevent_context
*ev
;
1179 struct cli_state
*cli
;
1181 uint16_t max_blob_size
;
1190 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state
*state
,
1191 struct tevent_req
**psubreq
);
1192 static void cli_sesssetup_blob_done(struct tevent_req
*subreq
);
1194 static struct tevent_req
*cli_sesssetup_blob_send(TALLOC_CTX
*mem_ctx
,
1195 struct tevent_context
*ev
,
1196 struct cli_state
*cli
,
1199 struct tevent_req
*req
, *subreq
;
1200 struct cli_sesssetup_blob_state
*state
;
1202 req
= tevent_req_create(mem_ctx
, &state
,
1203 struct cli_sesssetup_blob_state
);
1211 if (cli
->max_xmit
< BASE_SESSSETUP_BLOB_PACKET_SIZE
+ 1) {
1212 DEBUG(1, ("cli_session_setup_blob: cli->max_xmit too small "
1213 "(was %u, need minimum %u)\n",
1214 (unsigned int)cli
->max_xmit
,
1215 BASE_SESSSETUP_BLOB_PACKET_SIZE
));
1216 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1217 return tevent_req_post(req
, ev
);
1219 state
->max_blob_size
=
1220 MIN(cli
->max_xmit
- BASE_SESSSETUP_BLOB_PACKET_SIZE
, 0xFFFF);
1222 if (!cli_sesssetup_blob_next(state
, &subreq
)) {
1223 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
1224 return tevent_req_post(req
, ev
);
1226 tevent_req_set_callback(subreq
, cli_sesssetup_blob_done
, req
);
1230 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state
*state
,
1231 struct tevent_req
**psubreq
)
1233 struct tevent_req
*subreq
;
1236 SCVAL(state
->vwv
+0, 0, 0xFF);
1237 SCVAL(state
->vwv
+0, 1, 0);
1238 SSVAL(state
->vwv
+1, 0, 0);
1239 SSVAL(state
->vwv
+2, 0, CLI_BUFFER_SIZE
);
1240 SSVAL(state
->vwv
+3, 0, 2);
1241 SSVAL(state
->vwv
+4, 0, 1);
1242 SIVAL(state
->vwv
+5, 0, 0);
1244 thistime
= MIN(state
->blob
.length
, state
->max_blob_size
);
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
)
1251 | CAP_EXTENDED_SECURITY
);
1253 state
->buf
= (uint8_t *)talloc_memdup(state
, state
->blob
.data
,
1255 if (state
->buf
== NULL
) {
1258 state
->blob
.data
+= thistime
;
1259 state
->blob
.length
-= thistime
;
1261 state
->buf
= smb_bytes_push_str(state
->buf
, cli_ucs2(state
->cli
),
1263 state
->buf
= smb_bytes_push_str(state
->buf
, cli_ucs2(state
->cli
),
1265 if (state
->buf
== NULL
) {
1268 subreq
= cli_smb_send(state
, state
->ev
, state
->cli
, SMBsesssetupX
, 0,
1270 talloc_get_size(state
->buf
), state
->buf
);
1271 if (subreq
== NULL
) {
1278 static void cli_sesssetup_blob_done(struct tevent_req
*subreq
)
1280 struct tevent_req
*req
= tevent_req_callback_data(
1281 subreq
, struct tevent_req
);
1282 struct cli_sesssetup_blob_state
*state
= tevent_req_data(
1283 req
, struct cli_sesssetup_blob_state
);
1284 struct cli_state
*cli
= state
->cli
;
1291 uint16_t blob_length
;
1295 status
= cli_smb_recv(subreq
, state
, &inbuf
, 4, &wct
, &vwv
,
1296 &num_bytes
, &bytes
);
1297 TALLOC_FREE(subreq
);
1298 if (!NT_STATUS_IS_OK(status
)
1299 && !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1300 tevent_req_nterror(req
, status
);
1304 state
->status
= status
;
1305 TALLOC_FREE(state
->buf
);
1307 state
->inbuf
= (char *)inbuf
;
1308 cli_state_set_uid(state
->cli
, SVAL(inbuf
, smb_uid
));
1309 cli
->is_guestlogin
= ((SVAL(vwv
+2, 0) & 1) != 0);
1311 blob_length
= SVAL(vwv
+3, 0);
1312 if (blob_length
> num_bytes
) {
1313 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
1316 state
->ret_blob
= data_blob_const(bytes
, blob_length
);
1318 p
= bytes
+ blob_length
;
1320 status
= smb_bytes_talloc_string(cli
,
1327 if (!NT_STATUS_IS_OK(status
)) {
1328 tevent_req_nterror(req
, status
);
1333 status
= smb_bytes_talloc_string(cli
,
1340 if (!NT_STATUS_IS_OK(status
)) {
1341 tevent_req_nterror(req
, status
);
1346 status
= smb_bytes_talloc_string(cli
,
1348 &cli
->server_domain
,
1353 if (!NT_STATUS_IS_OK(status
)) {
1354 tevent_req_nterror(req
, status
);
1359 if (strstr(cli
->server_type
, "Samba")) {
1360 cli
->is_samba
= True
;
1363 if (state
->blob
.length
!= 0) {
1367 if (!cli_sesssetup_blob_next(state
, &subreq
)) {
1368 tevent_req_oom(req
);
1371 tevent_req_set_callback(subreq
, cli_sesssetup_blob_done
, req
);
1374 tevent_req_done(req
);
1377 static NTSTATUS
cli_sesssetup_blob_recv(struct tevent_req
*req
,
1378 TALLOC_CTX
*mem_ctx
,
1382 struct cli_sesssetup_blob_state
*state
= tevent_req_data(
1383 req
, struct cli_sesssetup_blob_state
);
1387 if (tevent_req_is_nterror(req
, &status
)) {
1388 cli_state_set_uid(state
->cli
, UID_FIELD_INVALID
);
1392 inbuf
= talloc_move(mem_ctx
, &state
->inbuf
);
1393 if (pblob
!= NULL
) {
1394 *pblob
= state
->ret_blob
;
1396 if (pinbuf
!= NULL
) {
1399 /* could be NT_STATUS_MORE_PROCESSING_REQUIRED */
1400 return state
->status
;
1405 /****************************************************************************
1406 Use in-memory credentials cache
1407 ****************************************************************************/
1409 static void use_in_memory_ccache(void) {
1410 setenv(KRB5_ENV_CCNAME
, "MEMORY:cliconnect", 1);
1413 /****************************************************************************
1414 Do a spnego/kerberos encrypted session setup.
1415 ****************************************************************************/
1417 struct cli_session_setup_kerberos_state
{
1418 struct cli_state
*cli
;
1419 DATA_BLOB negTokenTarg
;
1420 DATA_BLOB session_key_krb5
;
1421 ADS_STATUS ads_status
;
1424 static void cli_session_setup_kerberos_done(struct tevent_req
*subreq
);
1426 static struct tevent_req
*cli_session_setup_kerberos_send(
1427 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
1428 const char *principal
)
1430 struct tevent_req
*req
, *subreq
;
1431 struct cli_session_setup_kerberos_state
*state
;
1434 DEBUG(2,("Doing kerberos session setup\n"));
1436 req
= tevent_req_create(mem_ctx
, &state
,
1437 struct cli_session_setup_kerberos_state
);
1442 state
->ads_status
= ADS_SUCCESS
;
1444 cli_temp_set_signing(cli
);
1447 * Ok, this is cheating: spnego_gen_krb5_negTokenInit can block if
1448 * we have to acquire a ticket. To be fixed later :-)
1450 rc
= spnego_gen_krb5_negTokenInit(state
, principal
, 0, &state
->negTokenTarg
,
1451 &state
->session_key_krb5
, 0, NULL
);
1453 DEBUG(1, ("cli_session_setup_kerberos: "
1454 "spnego_gen_krb5_negTokenInit failed: %s\n",
1455 error_message(rc
)));
1456 state
->ads_status
= ADS_ERROR_KRB5(rc
);
1457 tevent_req_nterror(req
, NT_STATUS_UNSUCCESSFUL
);
1458 return tevent_req_post(req
, ev
);
1462 file_save("negTokenTarg.dat", state
->negTokenTarg
.data
,
1463 state
->negTokenTarg
.length
);
1466 subreq
= cli_sesssetup_blob_send(state
, ev
, cli
, state
->negTokenTarg
);
1467 if (tevent_req_nomem(subreq
, req
)) {
1468 return tevent_req_post(req
, ev
);
1470 tevent_req_set_callback(subreq
, cli_session_setup_kerberos_done
, req
);
1474 static void cli_session_setup_kerberos_done(struct tevent_req
*subreq
)
1476 struct tevent_req
*req
= tevent_req_callback_data(
1477 subreq
, struct tevent_req
);
1478 struct cli_session_setup_kerberos_state
*state
= tevent_req_data(
1479 req
, struct cli_session_setup_kerberos_state
);
1483 status
= cli_sesssetup_blob_recv(subreq
, talloc_tos(), NULL
, &inbuf
);
1484 if (!NT_STATUS_IS_OK(status
)) {
1485 TALLOC_FREE(subreq
);
1486 tevent_req_nterror(req
, status
);
1490 cli_set_session_key(state
->cli
, state
->session_key_krb5
);
1492 if (cli_simple_set_signing(state
->cli
, state
->session_key_krb5
,
1494 && !cli_check_sign_mac(state
->cli
, inbuf
, 1)) {
1495 TALLOC_FREE(subreq
);
1496 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1499 TALLOC_FREE(subreq
);
1500 tevent_req_done(req
);
1503 static ADS_STATUS
cli_session_setup_kerberos_recv(struct tevent_req
*req
)
1505 struct cli_session_setup_kerberos_state
*state
= tevent_req_data(
1506 req
, struct cli_session_setup_kerberos_state
);
1509 if (tevent_req_is_nterror(req
, &status
)) {
1510 return ADS_ERROR_NT(status
);
1512 return state
->ads_status
;
1515 static ADS_STATUS
cli_session_setup_kerberos(struct cli_state
*cli
,
1516 const char *principal
)
1518 struct tevent_context
*ev
;
1519 struct tevent_req
*req
;
1520 ADS_STATUS status
= ADS_ERROR_NT(NT_STATUS_NO_MEMORY
);
1522 if (cli_has_async_calls(cli
)) {
1523 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
1525 ev
= tevent_context_init(talloc_tos());
1529 req
= cli_session_setup_kerberos_send(ev
, ev
, cli
, principal
);
1533 if (!tevent_req_poll(req
, ev
)) {
1534 status
= ADS_ERROR_SYSTEM(errno
);
1537 status
= cli_session_setup_kerberos_recv(req
);
1542 #endif /* HAVE_KRB5 */
1544 /****************************************************************************
1545 Do a spnego/NTLMSSP encrypted session setup.
1546 ****************************************************************************/
1548 struct cli_session_setup_ntlmssp_state
{
1549 struct tevent_context
*ev
;
1550 struct cli_state
*cli
;
1551 struct ntlmssp_state
*ntlmssp_state
;
1556 static int cli_session_setup_ntlmssp_state_destructor(
1557 struct cli_session_setup_ntlmssp_state
*state
)
1559 if (state
->ntlmssp_state
!= NULL
) {
1560 TALLOC_FREE(state
->ntlmssp_state
);
1565 static void cli_session_setup_ntlmssp_done(struct tevent_req
*req
);
1567 static struct tevent_req
*cli_session_setup_ntlmssp_send(
1568 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
1569 const char *user
, const char *pass
, const char *domain
)
1571 struct tevent_req
*req
, *subreq
;
1572 struct cli_session_setup_ntlmssp_state
*state
;
1575 const char *OIDs_ntlm
[] = {OID_NTLMSSP
, NULL
};
1577 req
= tevent_req_create(mem_ctx
, &state
,
1578 struct cli_session_setup_ntlmssp_state
);
1586 state
->ntlmssp_state
= NULL
;
1587 talloc_set_destructor(
1588 state
, cli_session_setup_ntlmssp_state_destructor
);
1590 cli_temp_set_signing(cli
);
1592 status
= ntlmssp_client_start(state
,
1595 lp_client_ntlmv2_auth(),
1596 &state
->ntlmssp_state
);
1597 if (!NT_STATUS_IS_OK(status
)) {
1600 ntlmssp_want_feature(state
->ntlmssp_state
,
1601 NTLMSSP_FEATURE_SESSION_KEY
);
1602 if (cli
->use_ccache
) {
1603 ntlmssp_want_feature(state
->ntlmssp_state
,
1604 NTLMSSP_FEATURE_CCACHE
);
1606 status
= ntlmssp_set_username(state
->ntlmssp_state
, user
);
1607 if (!NT_STATUS_IS_OK(status
)) {
1610 status
= ntlmssp_set_domain(state
->ntlmssp_state
, domain
);
1611 if (!NT_STATUS_IS_OK(status
)) {
1614 status
= ntlmssp_set_password(state
->ntlmssp_state
, pass
);
1615 if (!NT_STATUS_IS_OK(status
)) {
1618 status
= ntlmssp_update(state
->ntlmssp_state
, data_blob_null
,
1620 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1624 state
->blob_out
= spnego_gen_negTokenInit(state
, OIDs_ntlm
, &blob_out
, NULL
);
1625 data_blob_free(&blob_out
);
1627 subreq
= cli_sesssetup_blob_send(state
, ev
, cli
, state
->blob_out
);
1628 if (tevent_req_nomem(subreq
, req
)) {
1629 return tevent_req_post(req
, ev
);
1631 tevent_req_set_callback(subreq
, cli_session_setup_ntlmssp_done
, req
);
1634 tevent_req_nterror(req
, status
);
1635 return tevent_req_post(req
, ev
);
1638 static void cli_session_setup_ntlmssp_done(struct tevent_req
*subreq
)
1640 struct tevent_req
*req
= tevent_req_callback_data(
1641 subreq
, struct tevent_req
);
1642 struct cli_session_setup_ntlmssp_state
*state
= tevent_req_data(
1643 req
, struct cli_session_setup_ntlmssp_state
);
1644 DATA_BLOB blob_in
, msg_in
, blob_out
;
1649 status
= cli_sesssetup_blob_recv(subreq
, talloc_tos(), &blob_in
,
1651 TALLOC_FREE(subreq
);
1652 data_blob_free(&state
->blob_out
);
1654 if (NT_STATUS_IS_OK(status
)) {
1655 if (state
->cli
->server_domain
[0] == '\0') {
1656 TALLOC_FREE(state
->cli
->server_domain
);
1657 state
->cli
->server_domain
= talloc_strdup(state
->cli
,
1658 state
->ntlmssp_state
->server
.netbios_domain
);
1659 if (state
->cli
->server_domain
== NULL
) {
1660 TALLOC_FREE(subreq
);
1661 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
1665 cli_set_session_key(
1666 state
->cli
, state
->ntlmssp_state
->session_key
);
1668 if (cli_simple_set_signing(
1669 state
->cli
, state
->ntlmssp_state
->session_key
,
1671 && !cli_check_sign_mac(state
->cli
, inbuf
, 1)) {
1672 TALLOC_FREE(subreq
);
1673 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1676 TALLOC_FREE(subreq
);
1677 TALLOC_FREE(state
->ntlmssp_state
);
1678 tevent_req_done(req
);
1681 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1682 tevent_req_nterror(req
, status
);
1686 if (blob_in
.length
== 0) {
1687 tevent_req_nterror(req
, NT_STATUS_UNSUCCESSFUL
);
1691 if ((state
->turn
== 1)
1692 && NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1693 DATA_BLOB tmp_blob
= data_blob_null
;
1694 /* the server might give us back two challenges */
1695 parse_ret
= spnego_parse_challenge(state
, blob_in
, &msg_in
,
1697 data_blob_free(&tmp_blob
);
1699 parse_ret
= spnego_parse_auth_response(state
, blob_in
, status
,
1700 OID_NTLMSSP
, &msg_in
);
1705 DEBUG(3,("Failed to parse auth response\n"));
1706 if (NT_STATUS_IS_OK(status
)
1707 || NT_STATUS_EQUAL(status
,
1708 NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1710 req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
1715 status
= ntlmssp_update(state
->ntlmssp_state
, msg_in
, &blob_out
);
1717 if (!NT_STATUS_IS_OK(status
)
1718 && !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1719 TALLOC_FREE(subreq
);
1720 TALLOC_FREE(state
->ntlmssp_state
);
1721 tevent_req_nterror(req
, status
);
1725 state
->blob_out
= spnego_gen_auth(state
, blob_out
);
1726 TALLOC_FREE(subreq
);
1727 if (tevent_req_nomem(state
->blob_out
.data
, req
)) {
1731 subreq
= cli_sesssetup_blob_send(state
, state
->ev
, state
->cli
,
1733 if (tevent_req_nomem(subreq
, req
)) {
1736 tevent_req_set_callback(subreq
, cli_session_setup_ntlmssp_done
, req
);
1739 static NTSTATUS
cli_session_setup_ntlmssp_recv(struct tevent_req
*req
)
1741 struct cli_session_setup_ntlmssp_state
*state
= tevent_req_data(
1742 req
, struct cli_session_setup_ntlmssp_state
);
1745 if (tevent_req_is_nterror(req
, &status
)) {
1746 cli_state_set_uid(state
->cli
, UID_FIELD_INVALID
);
1749 return NT_STATUS_OK
;
1752 static NTSTATUS
cli_session_setup_ntlmssp(struct cli_state
*cli
,
1757 struct tevent_context
*ev
;
1758 struct tevent_req
*req
;
1759 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
1761 if (cli_has_async_calls(cli
)) {
1762 return NT_STATUS_INVALID_PARAMETER
;
1764 ev
= tevent_context_init(talloc_tos());
1768 req
= cli_session_setup_ntlmssp_send(ev
, ev
, cli
, user
, pass
, domain
);
1772 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
1775 status
= cli_session_setup_ntlmssp_recv(req
);
1781 /****************************************************************************
1782 Do a spnego encrypted session setup.
1784 user_domain: The shortname of the domain the user/machine is a member of.
1785 dest_realm: The realm we're connecting to, if NULL we use our default realm.
1786 ****************************************************************************/
1788 ADS_STATUS
cli_session_setup_spnego(struct cli_state
*cli
, const char *user
,
1789 const char *pass
, const char *user_domain
,
1790 const char * dest_realm
)
1792 char *principal
= NULL
;
1793 char *OIDs
[ASN1_MAX_OIDS
];
1796 const char *p
= NULL
;
1797 char *account
= NULL
;
1800 DEBUG(3,("Doing spnego session setup (blob length=%lu)\n", (unsigned long)cli
->secblob
.length
));
1802 /* the server might not even do spnego */
1803 if (cli
->secblob
.length
<= 16) {
1804 DEBUG(3,("server didn't supply a full spnego negprot\n"));
1809 file_save("negprot.dat", cli
->secblob
.data
, cli
->secblob
.length
);
1812 /* there is 16 bytes of GUID before the real spnego packet starts */
1813 blob
= data_blob(cli
->secblob
.data
+16, cli
->secblob
.length
-16);
1815 /* The server sent us the first part of the SPNEGO exchange in the
1816 * negprot reply. It is WRONG to depend on the principal sent in the
1817 * negprot reply, but right now we do it. If we don't receive one,
1818 * we try to best guess, then fall back to NTLM. */
1819 if (!spnego_parse_negTokenInit(talloc_tos(), blob
, OIDs
, &principal
, NULL
) ||
1821 data_blob_free(&blob
);
1822 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
1824 data_blob_free(&blob
);
1826 /* make sure the server understands kerberos */
1827 for (i
=0;OIDs
[i
];i
++) {
1829 DEBUG(3,("got OID=%s\n", OIDs
[i
]));
1831 DEBUGADD(3,("got OID=%s\n", OIDs
[i
]));
1832 if (strcmp(OIDs
[i
], OID_KERBEROS5_OLD
) == 0 ||
1833 strcmp(OIDs
[i
], OID_KERBEROS5
) == 0) {
1834 cli
->got_kerberos_mechanism
= True
;
1836 talloc_free(OIDs
[i
]);
1839 DEBUG(3,("got principal=%s\n", principal
? principal
: "<null>"));
1841 status
= cli_set_username(cli
, user
);
1842 if (!NT_STATUS_IS_OK(status
)) {
1843 TALLOC_FREE(principal
);
1844 return ADS_ERROR_NT(status
);
1848 /* If password is set we reauthenticate to kerberos server
1849 * and do not store results */
1851 if (cli
->got_kerberos_mechanism
&& cli
->use_kerberos
) {
1854 if (pass
&& *pass
) {
1857 use_in_memory_ccache();
1858 ret
= kerberos_kinit_password(user
, pass
, 0 /* no time correction for now */, NULL
);
1861 TALLOC_FREE(principal
);
1862 DEBUG(0, ("Kinit failed: %s\n", error_message(ret
)));
1863 if (cli
->fallback_after_kerberos
)
1865 return ADS_ERROR_KRB5(ret
);
1869 /* We may not be allowed to use the server-supplied SPNEGO principal, or it may not have been supplied to us
1871 if (!lp_client_use_spnego_principal() || strequal(principal
, ADS_IGNORE_PRINCIPAL
)) {
1872 TALLOC_FREE(principal
);
1875 if (principal
== NULL
&&
1876 !is_ipaddress(cli
->desthost
) &&
1877 !strequal(STAR_SMBSERVER
,
1881 DEBUG(3,("cli_session_setup_spnego: using target "
1882 "hostname not SPNEGO principal\n"));
1884 host
= strchr_m(cli
->desthost
, '.');
1886 realm
= SMB_STRDUP(dest_realm
);
1888 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY
);
1894 realm
= kerberos_get_realm_from_hostname(cli
->desthost
);
1896 /* NetBIOS name - use our realm. */
1897 realm
= kerberos_get_default_realm_from_ccache();
1901 if (realm
== NULL
|| *realm
== '\0') {
1902 realm
= SMB_STRDUP(lp_realm());
1904 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY
);
1907 DEBUG(3,("cli_session_setup_spnego: cannot "
1908 "get realm from dest_realm %s, "
1909 "desthost %s. Using default "
1910 "smb.conf realm %s\n",
1911 dest_realm
? dest_realm
: "<null>",
1916 principal
= talloc_asprintf(talloc_tos(),
1922 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY
);
1924 DEBUG(3,("cli_session_setup_spnego: guessed "
1925 "server principal=%s\n",
1926 principal
? principal
: "<null>"));
1932 rc
= cli_session_setup_kerberos(cli
, principal
);
1933 if (ADS_ERR_OK(rc
) || !cli
->fallback_after_kerberos
) {
1934 TALLOC_FREE(principal
);
1941 TALLOC_FREE(principal
);
1945 account
= talloc_strdup(talloc_tos(), user
);
1947 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY
);
1950 /* when falling back to ntlmssp while authenticating with a machine
1951 * account strip off the realm - gd */
1953 if ((p
= strchr_m(user
, '@')) != NULL
) {
1954 account
[PTR_DIFF(p
,user
)] = '\0';
1957 return ADS_ERROR_NT(cli_session_setup_ntlmssp(cli
, account
, pass
, user_domain
));
1960 /****************************************************************************
1961 Send a session setup. The username and workgroup is in UNIX character
1962 format and must be converted to DOS codepage format before sending. If the
1963 password is in plaintext, the same should be done.
1964 ****************************************************************************/
1966 NTSTATUS
cli_session_setup(struct cli_state
*cli
,
1968 const char *pass
, int passlen
,
1969 const char *ntpass
, int ntpasslen
,
1970 const char *workgroup
)
1976 user2
= talloc_strdup(talloc_tos(), user
);
1978 user2
= talloc_strdup(talloc_tos(), "");
1980 if (user2
== NULL
) {
1981 return NT_STATUS_NO_MEMORY
;
1988 /* allow for workgroups as part of the username */
1989 if ((p
=strchr_m(user2
,'\\')) || (p
=strchr_m(user2
,'/')) ||
1990 (p
=strchr_m(user2
,*lp_winbind_separator()))) {
1997 if (cli
->protocol
< PROTOCOL_LANMAN1
) {
1998 return NT_STATUS_OK
;
2001 /* now work out what sort of session setup we are going to
2002 do. I have split this into separate functions to make the
2003 flow a bit easier to understand (tridge) */
2005 /* if its an older server then we have to use the older request format */
2007 if (cli
->protocol
< PROTOCOL_NT1
) {
2008 if (!lp_client_lanman_auth() && passlen
!= 24 && (*pass
)) {
2009 DEBUG(1, ("Server requested LM password but 'client lanman auth = no'"
2010 " or 'client ntlmv2 auth = yes'\n"));
2011 return NT_STATUS_ACCESS_DENIED
;
2014 if ((cli
->sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
) == 0 &&
2015 !lp_client_plaintext_auth() && (*pass
)) {
2016 DEBUG(1, ("Server requested LM password but 'client plaintext auth = no'"
2017 " or 'client ntlmv2 auth = yes'\n"));
2018 return NT_STATUS_ACCESS_DENIED
;
2021 return cli_session_setup_lanman2(cli
, user
, pass
, passlen
,
2025 /* if no user is supplied then we have to do an anonymous connection.
2026 passwords are ignored */
2028 if (!user
|| !*user
)
2029 return cli_session_setup_guest(cli
);
2031 /* if the server is share level then send a plaintext null
2032 password at this point. The password is sent in the tree
2035 if ((cli
->sec_mode
& NEGOTIATE_SECURITY_USER_LEVEL
) == 0)
2036 return cli_session_setup_plain(cli
, user
, "", workgroup
);
2038 /* if the server doesn't support encryption then we have to use
2039 plaintext. The second password is ignored */
2041 if ((cli
->sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
) == 0) {
2042 if (!lp_client_plaintext_auth() && (*pass
)) {
2043 DEBUG(1, ("Server requested LM password but 'client plaintext auth = no'"
2044 " or 'client ntlmv2 auth = yes'\n"));
2045 return NT_STATUS_ACCESS_DENIED
;
2047 return cli_session_setup_plain(cli
, user
, pass
, workgroup
);
2050 /* if the server supports extended security then use SPNEGO */
2052 if (cli
->capabilities
& CAP_EXTENDED_SECURITY
) {
2053 ADS_STATUS status
= cli_session_setup_spnego(cli
, user
, pass
,
2055 if (!ADS_ERR_OK(status
)) {
2056 DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status
)));
2057 return ads_ntstatus(status
);
2062 /* otherwise do a NT1 style session setup */
2063 status
= cli_session_setup_nt1(cli
, user
, pass
, passlen
,
2064 ntpass
, ntpasslen
, workgroup
);
2065 if (!NT_STATUS_IS_OK(status
)) {
2066 DEBUG(3,("cli_session_setup: NT1 session setup "
2067 "failed: %s\n", nt_errstr(status
)));
2072 if (strstr(cli
->server_type
, "Samba")) {
2073 cli
->is_samba
= True
;
2076 return NT_STATUS_OK
;
2079 /****************************************************************************
2081 *****************************************************************************/
2083 struct cli_ulogoff_state
{
2084 struct cli_state
*cli
;
2088 static void cli_ulogoff_done(struct tevent_req
*subreq
);
2090 struct tevent_req
*cli_ulogoff_send(TALLOC_CTX
*mem_ctx
,
2091 struct tevent_context
*ev
,
2092 struct cli_state
*cli
)
2094 struct tevent_req
*req
, *subreq
;
2095 struct cli_ulogoff_state
*state
;
2097 req
= tevent_req_create(mem_ctx
, &state
, struct cli_ulogoff_state
);
2103 SCVAL(state
->vwv
+0, 0, 0xFF);
2104 SCVAL(state
->vwv
+1, 0, 0);
2105 SSVAL(state
->vwv
+2, 0, 0);
2107 subreq
= cli_smb_send(state
, ev
, cli
, SMBulogoffX
, 0, 2, state
->vwv
,
2109 if (tevent_req_nomem(subreq
, req
)) {
2110 return tevent_req_post(req
, ev
);
2112 tevent_req_set_callback(subreq
, cli_ulogoff_done
, req
);
2116 static void cli_ulogoff_done(struct tevent_req
*subreq
)
2118 struct tevent_req
*req
= tevent_req_callback_data(
2119 subreq
, struct tevent_req
);
2120 struct cli_ulogoff_state
*state
= tevent_req_data(
2121 req
, struct cli_ulogoff_state
);
2124 status
= cli_smb_recv(subreq
, NULL
, NULL
, 0, NULL
, NULL
, NULL
, NULL
);
2125 if (!NT_STATUS_IS_OK(status
)) {
2126 tevent_req_nterror(req
, status
);
2129 cli_state_set_uid(state
->cli
, UID_FIELD_INVALID
);
2130 tevent_req_done(req
);
2133 NTSTATUS
cli_ulogoff_recv(struct tevent_req
*req
)
2135 return tevent_req_simple_recv_ntstatus(req
);
2138 NTSTATUS
cli_ulogoff(struct cli_state
*cli
)
2140 struct tevent_context
*ev
;
2141 struct tevent_req
*req
;
2142 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2144 if (cli_has_async_calls(cli
)) {
2145 return NT_STATUS_INVALID_PARAMETER
;
2147 ev
= tevent_context_init(talloc_tos());
2151 req
= cli_ulogoff_send(ev
, ev
, cli
);
2155 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2158 status
= cli_ulogoff_recv(req
);
2164 /****************************************************************************
2166 ****************************************************************************/
2168 struct cli_tcon_andx_state
{
2169 struct cli_state
*cli
;
2174 static void cli_tcon_andx_done(struct tevent_req
*subreq
);
2176 struct tevent_req
*cli_tcon_andx_create(TALLOC_CTX
*mem_ctx
,
2177 struct event_context
*ev
,
2178 struct cli_state
*cli
,
2179 const char *share
, const char *dev
,
2180 const char *pass
, int passlen
,
2181 struct tevent_req
**psmbreq
)
2183 struct tevent_req
*req
, *subreq
;
2184 struct cli_tcon_andx_state
*state
;
2192 req
= tevent_req_create(mem_ctx
, &state
, struct cli_tcon_andx_state
);
2199 cli
->share
= talloc_strdup(cli
, share
);
2204 /* in user level security don't send a password now */
2205 if (cli
->sec_mode
& NEGOTIATE_SECURITY_USER_LEVEL
) {
2208 } else if (pass
== NULL
) {
2209 DEBUG(1, ("Server not using user level security and no "
2210 "password supplied.\n"));
2214 if ((cli
->sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
) &&
2215 *pass
&& passlen
!= 24) {
2216 if (!lp_client_lanman_auth()) {
2217 DEBUG(1, ("Server requested LANMAN password "
2218 "(share-level security) but "
2219 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2224 * Non-encrypted passwords - convert to DOS codepage before
2227 SMBencrypt(pass
, cli
->secblob
.data
, p24
);
2229 pass
= (const char *)p24
;
2231 if((cli
->sec_mode
& (NEGOTIATE_SECURITY_USER_LEVEL
2232 |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
))
2236 if (!lp_client_plaintext_auth() && (*pass
)) {
2237 DEBUG(1, ("Server requested plaintext "
2239 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2244 * Non-encrypted passwords - convert to DOS codepage
2247 tmp_pass
= talloc_array(talloc_tos(), uint8
, 0);
2248 if (tevent_req_nomem(tmp_pass
, req
)) {
2249 return tevent_req_post(req
, ev
);
2251 tmp_pass
= trans2_bytes_push_str(tmp_pass
,
2252 false, /* always DOS */
2256 if (tevent_req_nomem(tmp_pass
, req
)) {
2257 return tevent_req_post(req
, ev
);
2259 pass
= (const char *)tmp_pass
;
2260 passlen
= talloc_get_size(tmp_pass
);
2264 SCVAL(vwv
+0, 0, 0xFF);
2267 SSVAL(vwv
+2, 0, TCONX_FLAG_EXTENDED_RESPONSE
);
2268 SSVAL(vwv
+3, 0, passlen
);
2270 if (passlen
&& pass
) {
2271 bytes
= (uint8_t *)talloc_memdup(state
, pass
, passlen
);
2273 bytes
= talloc_array(state
, uint8_t, 0);
2279 tmp
= talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
2280 cli
->desthost
, share
);
2285 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), tmp
, strlen(tmp
)+1,
2290 * Add the devicetype
2292 tmp
= talloc_strdup_upper(talloc_tos(), dev
);
2297 bytes
= smb_bytes_push_str(bytes
, false, tmp
, strlen(tmp
)+1, NULL
);
2300 if (bytes
== NULL
) {
2305 state
->bytes
.iov_base
= (void *)bytes
;
2306 state
->bytes
.iov_len
= talloc_get_size(bytes
);
2308 subreq
= cli_smb_req_create(state
, ev
, cli
, SMBtconX
, 0, 4, vwv
,
2310 if (subreq
== NULL
) {
2314 tevent_req_set_callback(subreq
, cli_tcon_andx_done
, req
);
2319 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
2320 return tevent_req_post(req
, ev
);
2323 struct tevent_req
*cli_tcon_andx_send(TALLOC_CTX
*mem_ctx
,
2324 struct event_context
*ev
,
2325 struct cli_state
*cli
,
2326 const char *share
, const char *dev
,
2327 const char *pass
, int passlen
)
2329 struct tevent_req
*req
, *subreq
;
2332 req
= cli_tcon_andx_create(mem_ctx
, ev
, cli
, share
, dev
, pass
, passlen
,
2337 if (subreq
== NULL
) {
2340 status
= cli_smb_req_send(subreq
);
2341 if (!NT_STATUS_IS_OK(status
)) {
2342 tevent_req_nterror(req
, status
);
2343 return tevent_req_post(req
, ev
);
2348 static void cli_tcon_andx_done(struct tevent_req
*subreq
)
2350 struct tevent_req
*req
= tevent_req_callback_data(
2351 subreq
, struct tevent_req
);
2352 struct cli_tcon_andx_state
*state
= tevent_req_data(
2353 req
, struct cli_tcon_andx_state
);
2354 struct cli_state
*cli
= state
->cli
;
2363 status
= cli_smb_recv(subreq
, state
, &in
, 0, &wct
, &vwv
,
2364 &num_bytes
, &bytes
);
2365 TALLOC_FREE(subreq
);
2366 if (!NT_STATUS_IS_OK(status
)) {
2367 tevent_req_nterror(req
, status
);
2374 if (clistr_pull_talloc(cli
,
2376 SVAL(inbuf
, smb_flg2
),
2380 STR_TERMINATE
|STR_ASCII
) == -1) {
2381 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
2385 cli
->dev
= talloc_strdup(cli
, "");
2386 if (cli
->dev
== NULL
) {
2387 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
2392 if ((cli
->protocol
>= PROTOCOL_NT1
) && (num_bytes
== 3)) {
2393 /* almost certainly win95 - enable bug fixes */
2398 * Make sure that we have the optional support 16-bit field. WCT > 2.
2399 * Avoids issues when connecting to Win9x boxes sharing files
2402 cli
->dfsroot
= false;
2404 if ((wct
> 2) && (cli
->protocol
>= PROTOCOL_LANMAN2
)) {
2405 cli
->dfsroot
= ((SVAL(vwv
+2, 0) & SMB_SHARE_IN_DFS
) != 0);
2408 cli
->smb1
.tid
= SVAL(inbuf
,smb_tid
);
2409 tevent_req_done(req
);
2412 NTSTATUS
cli_tcon_andx_recv(struct tevent_req
*req
)
2414 return tevent_req_simple_recv_ntstatus(req
);
2417 NTSTATUS
cli_tcon_andx(struct cli_state
*cli
, const char *share
,
2418 const char *dev
, const char *pass
, int passlen
)
2420 TALLOC_CTX
*frame
= talloc_stackframe();
2421 struct event_context
*ev
;
2422 struct tevent_req
*req
;
2423 NTSTATUS status
= NT_STATUS_OK
;
2425 if (cli_has_async_calls(cli
)) {
2427 * Can't use sync call while an async call is in flight
2429 status
= NT_STATUS_INVALID_PARAMETER
;
2433 ev
= event_context_init(frame
);
2435 status
= NT_STATUS_NO_MEMORY
;
2439 req
= cli_tcon_andx_send(frame
, ev
, cli
, share
, dev
, pass
, passlen
);
2441 status
= NT_STATUS_NO_MEMORY
;
2445 if (!tevent_req_poll(req
, ev
)) {
2446 status
= map_nt_error_from_unix(errno
);
2450 status
= cli_tcon_andx_recv(req
);
2456 /****************************************************************************
2457 Send a tree disconnect.
2458 ****************************************************************************/
2460 struct cli_tdis_state
{
2461 struct cli_state
*cli
;
2464 static void cli_tdis_done(struct tevent_req
*subreq
);
2466 struct tevent_req
*cli_tdis_send(TALLOC_CTX
*mem_ctx
,
2467 struct tevent_context
*ev
,
2468 struct cli_state
*cli
)
2470 struct tevent_req
*req
, *subreq
;
2471 struct cli_tdis_state
*state
;
2473 req
= tevent_req_create(mem_ctx
, &state
, struct cli_tdis_state
);
2479 subreq
= cli_smb_send(state
, ev
, cli
, SMBtdis
, 0, 0, NULL
, 0, NULL
);
2480 if (tevent_req_nomem(subreq
, req
)) {
2481 return tevent_req_post(req
, ev
);
2483 tevent_req_set_callback(subreq
, cli_tdis_done
, req
);
2487 static void cli_tdis_done(struct tevent_req
*subreq
)
2489 struct tevent_req
*req
= tevent_req_callback_data(
2490 subreq
, struct tevent_req
);
2491 struct cli_tdis_state
*state
= tevent_req_data(
2492 req
, struct cli_tdis_state
);
2495 status
= cli_smb_recv(subreq
, NULL
, NULL
, 0, NULL
, NULL
, NULL
, NULL
);
2496 TALLOC_FREE(subreq
);
2497 if (!NT_STATUS_IS_OK(status
)) {
2498 tevent_req_nterror(req
, status
);
2501 state
->cli
->smb1
.tid
= UINT16_MAX
;
2502 tevent_req_done(req
);
2505 NTSTATUS
cli_tdis_recv(struct tevent_req
*req
)
2507 return tevent_req_simple_recv_ntstatus(req
);
2510 NTSTATUS
cli_tdis(struct cli_state
*cli
)
2512 struct tevent_context
*ev
;
2513 struct tevent_req
*req
;
2514 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2516 if (cli_has_async_calls(cli
)) {
2517 return NT_STATUS_INVALID_PARAMETER
;
2519 ev
= tevent_context_init(talloc_tos());
2523 req
= cli_tdis_send(ev
, ev
, cli
);
2527 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2530 status
= cli_tdis_recv(req
);
2536 /****************************************************************************
2537 Send a negprot command.
2538 ****************************************************************************/
2540 struct cli_negprot_state
{
2541 struct cli_state
*cli
;
2544 static void cli_negprot_done(struct tevent_req
*subreq
);
2546 struct tevent_req
*cli_negprot_send(TALLOC_CTX
*mem_ctx
,
2547 struct event_context
*ev
,
2548 struct cli_state
*cli
)
2550 struct tevent_req
*req
, *subreq
;
2551 struct cli_negprot_state
*state
;
2552 uint8_t *bytes
= NULL
;
2555 req
= tevent_req_create(mem_ctx
, &state
, struct cli_negprot_state
);
2561 if (cli
->protocol
< PROTOCOL_NT1
)
2562 cli
->use_spnego
= False
;
2564 /* setup the protocol strings */
2565 for (numprots
=0; numprots
< ARRAY_SIZE(prots
); numprots
++) {
2567 if (prots
[numprots
].prot
> cli
->protocol
) {
2570 bytes
= (uint8_t *)talloc_append_blob(
2571 state
, bytes
, data_blob_const(&c
, sizeof(c
)));
2572 if (tevent_req_nomem(bytes
, req
)) {
2573 return tevent_req_post(req
, ev
);
2575 bytes
= smb_bytes_push_str(bytes
, false,
2576 prots
[numprots
].name
,
2577 strlen(prots
[numprots
].name
)+1,
2579 if (tevent_req_nomem(bytes
, req
)) {
2580 return tevent_req_post(req
, ev
);
2584 subreq
= cli_smb_send(state
, ev
, cli
, SMBnegprot
, 0, 0, NULL
,
2585 talloc_get_size(bytes
), bytes
);
2587 if (tevent_req_nomem(subreq
, req
)) {
2588 return tevent_req_post(req
, ev
);
2590 tevent_req_set_callback(subreq
, cli_negprot_done
, req
);
2594 static void cli_negprot_done(struct tevent_req
*subreq
)
2596 struct tevent_req
*req
= tevent_req_callback_data(
2597 subreq
, struct tevent_req
);
2598 struct cli_negprot_state
*state
= tevent_req_data(
2599 req
, struct cli_negprot_state
);
2600 struct cli_state
*cli
= state
->cli
;
2609 status
= cli_smb_recv(subreq
, state
, &inbuf
, 1, &wct
, &vwv
,
2610 &num_bytes
, &bytes
);
2611 TALLOC_FREE(subreq
);
2612 if (!NT_STATUS_IS_OK(status
)) {
2613 tevent_req_nterror(req
, status
);
2617 protnum
= SVAL(vwv
, 0);
2619 if ((protnum
>= ARRAY_SIZE(prots
))
2620 || (prots
[protnum
].prot
> cli
->protocol
)) {
2621 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
2625 cli
->protocol
= prots
[protnum
].prot
;
2627 if ((cli
->protocol
< PROTOCOL_NT1
) &&
2628 client_is_signing_mandatory(cli
)) {
2629 DEBUG(0,("cli_negprot: SMB signing is mandatory and the selected protocol level doesn't support it.\n"));
2630 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
2634 if (cli
->protocol
>= PROTOCOL_NT1
) {
2636 bool negotiated_smb_signing
= false;
2639 cli
->sec_mode
= CVAL(vwv
+ 1, 0);
2640 cli
->max_mux
= SVAL(vwv
+ 1, 1);
2641 cli
->max_xmit
= IVAL(vwv
+ 3, 1);
2642 cli
->sesskey
= IVAL(vwv
+ 7, 1);
2643 cli
->serverzone
= SVALS(vwv
+ 15, 1);
2644 cli
->serverzone
*= 60;
2645 /* this time arrives in real GMT */
2646 ts
= interpret_long_date(((char *)(vwv
+11))+1);
2647 cli
->servertime
= ts
.tv_sec
;
2648 cli
->secblob
= data_blob(bytes
, num_bytes
);
2649 cli
->capabilities
= IVAL(vwv
+ 9, 1);
2650 if (cli
->capabilities
& CAP_RAW_MODE
) {
2651 cli
->readbraw_supported
= True
;
2652 cli
->writebraw_supported
= True
;
2654 /* work out if they sent us a workgroup */
2655 if (!(cli
->capabilities
& CAP_EXTENDED_SECURITY
) &&
2656 smb_buflen(inbuf
) > 8) {
2658 status
= smb_bytes_talloc_string(
2659 cli
, (char *)inbuf
, &cli
->server_domain
,
2660 bytes
+ 8, num_bytes
- 8, &ret
);
2661 if (tevent_req_nterror(req
, status
)) {
2667 * As signing is slow we only turn it on if either the client or
2668 * the server require it. JRA.
2671 if (cli
->sec_mode
& NEGOTIATE_SECURITY_SIGNATURES_REQUIRED
) {
2672 /* Fail if server says signing is mandatory and we don't want to support it. */
2673 if (!client_is_signing_allowed(cli
)) {
2674 DEBUG(0,("cli_negprot: SMB signing is mandatory and we have disabled it.\n"));
2675 tevent_req_nterror(req
,
2676 NT_STATUS_ACCESS_DENIED
);
2679 negotiated_smb_signing
= true;
2680 } else if (client_is_signing_mandatory(cli
) && client_is_signing_allowed(cli
)) {
2681 /* Fail if client says signing is mandatory and the server doesn't support it. */
2682 if (!(cli
->sec_mode
& NEGOTIATE_SECURITY_SIGNATURES_ENABLED
)) {
2683 DEBUG(1,("cli_negprot: SMB signing is mandatory and the server doesn't support it.\n"));
2684 tevent_req_nterror(req
,
2685 NT_STATUS_ACCESS_DENIED
);
2688 negotiated_smb_signing
= true;
2689 } else if (cli
->sec_mode
& NEGOTIATE_SECURITY_SIGNATURES_ENABLED
) {
2690 negotiated_smb_signing
= true;
2693 if (negotiated_smb_signing
) {
2694 cli_set_signing_negotiated(cli
);
2697 } else if (cli
->protocol
>= PROTOCOL_LANMAN1
) {
2698 cli
->use_spnego
= False
;
2699 cli
->sec_mode
= SVAL(vwv
+ 1, 0);
2700 cli
->max_xmit
= SVAL(vwv
+ 2, 0);
2701 cli
->max_mux
= SVAL(vwv
+ 3, 0);
2702 cli
->sesskey
= IVAL(vwv
+ 6, 0);
2703 cli
->serverzone
= SVALS(vwv
+ 10, 0);
2704 cli
->serverzone
*= 60;
2705 /* this time is converted to GMT by make_unix_date */
2706 cli
->servertime
= make_unix_date(
2707 (char *)(vwv
+ 8), cli
->serverzone
);
2708 cli
->readbraw_supported
= ((SVAL(vwv
+ 5, 0) & 0x1) != 0);
2709 cli
->writebraw_supported
= ((SVAL(vwv
+ 5, 0) & 0x2) != 0);
2710 cli
->secblob
= data_blob(bytes
, num_bytes
);
2712 /* the old core protocol */
2713 cli
->use_spnego
= False
;
2715 cli
->serverzone
= get_time_zone(time(NULL
));
2718 cli
->max_xmit
= MIN(cli
->max_xmit
, CLI_BUFFER_SIZE
);
2720 /* a way to force ascii SMB */
2721 if (getenv("CLI_FORCE_ASCII"))
2722 cli
->capabilities
&= ~CAP_UNICODE
;
2724 tevent_req_done(req
);
2727 NTSTATUS
cli_negprot_recv(struct tevent_req
*req
)
2729 return tevent_req_simple_recv_ntstatus(req
);
2732 NTSTATUS
cli_negprot(struct cli_state
*cli
)
2734 TALLOC_CTX
*frame
= talloc_stackframe();
2735 struct event_context
*ev
;
2736 struct tevent_req
*req
;
2737 NTSTATUS status
= NT_STATUS_OK
;
2739 if (cli_has_async_calls(cli
)) {
2741 * Can't use sync call while an async call is in flight
2743 status
= NT_STATUS_INVALID_PARAMETER
;
2747 ev
= event_context_init(frame
);
2749 status
= NT_STATUS_NO_MEMORY
;
2753 req
= cli_negprot_send(frame
, ev
, cli
);
2755 status
= NT_STATUS_NO_MEMORY
;
2759 if (!tevent_req_poll(req
, ev
)) {
2760 status
= map_nt_error_from_unix(errno
);
2764 status
= cli_negprot_recv(req
);
2770 static NTSTATUS
cli_connect_sock(const char *host
, int name_type
,
2771 const struct sockaddr_storage
*pss
,
2772 const char *myname
, uint16_t port
,
2773 int sec_timeout
, int *pfd
, uint16_t *pport
)
2775 TALLOC_CTX
*frame
= talloc_stackframe();
2777 unsigned int i
, num_addrs
;
2778 const char **called_names
;
2779 const char **calling_names
;
2784 prog
= getenv("LIBSMB_PROG");
2786 fd
= sock_exec(prog
);
2788 return map_nt_error_from_unix(errno
);
2794 if ((pss
== NULL
) || is_zero_addr(pss
)) {
2795 struct sockaddr_storage
*addrs
;
2796 status
= resolve_name_list(talloc_tos(), host
, name_type
,
2797 &addrs
, &num_addrs
);
2798 if (!NT_STATUS_IS_OK(status
)) {
2806 called_names
= talloc_array(talloc_tos(), const char *, num_addrs
);
2807 if (called_names
== NULL
) {
2808 status
= NT_STATUS_NO_MEMORY
;
2811 called_types
= talloc_array(talloc_tos(), int, num_addrs
);
2812 if (called_types
== NULL
) {
2813 status
= NT_STATUS_NO_MEMORY
;
2816 calling_names
= talloc_array(talloc_tos(), const char *, num_addrs
);
2817 if (calling_names
== NULL
) {
2818 status
= NT_STATUS_NO_MEMORY
;
2821 for (i
=0; i
<num_addrs
; i
++) {
2822 called_names
[i
] = host
;
2823 called_types
[i
] = name_type
;
2824 calling_names
[i
] = myname
;
2826 status
= smbsock_any_connect(pss
, called_names
, called_types
,
2827 calling_names
, NULL
, num_addrs
, port
,
2828 sec_timeout
, &fd
, NULL
, &port
);
2829 if (!NT_STATUS_IS_OK(status
)) {
2832 set_socket_options(fd
, lp_socket_options());
2836 status
= NT_STATUS_OK
;
2842 NTSTATUS
cli_connect_nb(const char *host
, struct sockaddr_storage
*pss
,
2843 uint16_t port
, int name_type
, const char *myname
,
2844 int signing_state
, struct cli_state
**pcli
)
2846 TALLOC_CTX
*frame
= talloc_stackframe();
2847 struct cli_state
*cli
;
2848 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2855 desthost
= talloc_strdup(talloc_tos(), host
);
2856 if (desthost
== NULL
) {
2860 p
= strchr(host
, '#');
2862 name_type
= strtol(p
+1, NULL
, 16);
2863 host
= talloc_strndup(talloc_tos(), host
, p
- host
);
2869 cli
= cli_initialise_ex(signing_state
);
2873 cli
->desthost
= talloc_move(cli
, &desthost
);
2875 status
= cli_connect_sock(host
, name_type
, pss
, myname
, port
, 20, &fd
,
2877 if (!NT_STATUS_IS_OK(status
)) {
2883 length
= sizeof(cli
->src_ss
);
2884 ret
= getsockname(fd
, (struct sockaddr
*)(void *)&cli
->src_ss
,
2887 status
= map_nt_error_from_unix(errno
);
2891 length
= sizeof(cli
->dest_ss
);
2892 ret
= getpeername(fd
, (struct sockaddr
*)(void *)&cli
->dest_ss
,
2895 status
= map_nt_error_from_unix(errno
);
2901 *pss
= cli
->dest_ss
;
2905 status
= NT_STATUS_OK
;
2912 establishes a connection to after the negprot.
2913 @param output_cli A fully initialised cli structure, non-null only on success
2914 @param dest_host The netbios name of the remote host
2915 @param dest_ss (optional) The the destination IP, NULL for name based lookup
2916 @param port (optional) The destination port (0 for default)
2918 NTSTATUS
cli_start_connection(struct cli_state
**output_cli
,
2919 const char *my_name
,
2920 const char *dest_host
,
2921 struct sockaddr_storage
*dest_ss
, int port
,
2922 int signing_state
, int flags
)
2925 struct cli_state
*cli
;
2927 nt_status
= cli_connect_nb(dest_host
, dest_ss
, port
, 0x20, my_name
,
2928 signing_state
, &cli
);
2929 if (!NT_STATUS_IS_OK(nt_status
)) {
2930 DEBUG(10, ("cli_connect_nb failed: %s\n",
2931 nt_errstr(nt_status
)));
2935 if (flags
& CLI_FULL_CONNECTION_DONT_SPNEGO
)
2936 cli
->use_spnego
= False
;
2937 else if (flags
& CLI_FULL_CONNECTION_USE_KERBEROS
)
2938 cli
->use_kerberos
= True
;
2940 if ((flags
& CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS
) &&
2941 cli
->use_kerberos
) {
2942 cli
->fallback_after_kerberos
= true;
2944 if (flags
& CLI_FULL_CONNECTION_USE_CCACHE
) {
2945 cli
->use_ccache
= true;
2948 nt_status
= cli_negprot(cli
);
2949 if (!NT_STATUS_IS_OK(nt_status
)) {
2950 DEBUG(1, ("failed negprot: %s\n", nt_errstr(nt_status
)));
2956 return NT_STATUS_OK
;
2961 establishes a connection right up to doing tconX, password specified.
2962 @param output_cli A fully initialised cli structure, non-null only on success
2963 @param dest_host The netbios name of the remote host
2964 @param dest_ip (optional) The the destination IP, NULL for name based lookup
2965 @param port (optional) The destination port (0 for default)
2966 @param service (optional) The share to make the connection to. Should be 'unqualified' in any way.
2967 @param service_type The 'type' of serivice.
2968 @param user Username, unix string
2969 @param domain User's domain
2970 @param password User's password, unencrypted unix string.
2973 NTSTATUS
cli_full_connection(struct cli_state
**output_cli
,
2974 const char *my_name
,
2975 const char *dest_host
,
2976 struct sockaddr_storage
*dest_ss
, int port
,
2977 const char *service
, const char *service_type
,
2978 const char *user
, const char *domain
,
2979 const char *password
, int flags
,
2983 struct cli_state
*cli
= NULL
;
2984 int pw_len
= password
? strlen(password
)+1 : 0;
2988 if (password
== NULL
) {
2992 nt_status
= cli_start_connection(&cli
, my_name
, dest_host
,
2993 dest_ss
, port
, signing_state
,
2996 if (!NT_STATUS_IS_OK(nt_status
)) {
3000 cli
->use_oplocks
= ((flags
& CLI_FULL_CONNECTION_OPLOCKS
) != 0);
3001 cli
->use_level_II_oplocks
=
3002 ((flags
& CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS
) != 0);
3004 nt_status
= cli_session_setup(cli
, user
, password
, pw_len
, password
,
3006 if (!NT_STATUS_IS_OK(nt_status
)) {
3008 if (!(flags
& CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK
)) {
3009 DEBUG(1,("failed session setup with %s\n",
3010 nt_errstr(nt_status
)));
3015 nt_status
= cli_session_setup(cli
, "", "", 0, "", 0, domain
);
3016 if (!NT_STATUS_IS_OK(nt_status
)) {
3017 DEBUG(1,("anonymous failed session setup with %s\n",
3018 nt_errstr(nt_status
)));
3025 nt_status
= cli_tcon_andx(cli
, service
, service_type
, password
,
3027 if (!NT_STATUS_IS_OK(nt_status
)) {
3028 DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status
)));
3030 if (NT_STATUS_IS_OK(nt_status
)) {
3031 nt_status
= NT_STATUS_UNSUCCESSFUL
;
3037 nt_status
= cli_init_creds(cli
, user
, domain
, password
);
3038 if (!NT_STATUS_IS_OK(nt_status
)) {
3044 return NT_STATUS_OK
;
3047 /****************************************************************************
3048 Send an old style tcon.
3049 ****************************************************************************/
3050 NTSTATUS
cli_raw_tcon(struct cli_state
*cli
,
3051 const char *service
, const char *pass
, const char *dev
,
3052 uint16
*max_xmit
, uint16
*tid
)
3054 struct tevent_req
*req
;
3059 if (!lp_client_plaintext_auth() && (*pass
)) {
3060 DEBUG(1, ("Server requested plaintext password but 'client "
3061 "plaintext auth' is disabled\n"));
3062 return NT_STATUS_ACCESS_DENIED
;
3065 bytes
= talloc_array(talloc_tos(), uint8_t, 0);
3066 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
3067 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
),
3068 service
, strlen(service
)+1, NULL
);
3069 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
3070 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
),
3071 pass
, strlen(pass
)+1, NULL
);
3072 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
3073 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
),
3074 dev
, strlen(dev
)+1, NULL
);
3076 status
= cli_smb(talloc_tos(), cli
, SMBtcon
, 0, 0, NULL
,
3077 talloc_get_size(bytes
), bytes
, &req
,
3078 2, NULL
, &ret_vwv
, NULL
, NULL
);
3079 if (!NT_STATUS_IS_OK(status
)) {
3083 *max_xmit
= SVAL(ret_vwv
+ 0, 0);
3084 *tid
= SVAL(ret_vwv
+ 1, 0);
3086 return NT_STATUS_OK
;
3089 /* Return a cli_state pointing at the IPC$ share for the given server */
3091 struct cli_state
*get_ipc_connect(char *server
,
3092 struct sockaddr_storage
*server_ss
,
3093 const struct user_auth_info
*user_info
)
3095 struct cli_state
*cli
;
3097 uint32_t flags
= CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK
;
3099 if (user_info
->use_kerberos
) {
3100 flags
|= CLI_FULL_CONNECTION_USE_KERBEROS
;
3103 nt_status
= cli_full_connection(&cli
, NULL
, server
, server_ss
, 0, "IPC$", "IPC",
3104 user_info
->username
? user_info
->username
: "",
3106 user_info
->password
? user_info
->password
: "",
3110 if (NT_STATUS_IS_OK(nt_status
)) {
3112 } else if (is_ipaddress(server
)) {
3113 /* windows 9* needs a correct NMB name for connections */
3114 fstring remote_name
;
3116 if (name_status_find("*", 0, 0, server_ss
, remote_name
)) {
3117 cli
= get_ipc_connect(remote_name
, server_ss
, user_info
);
3126 * Given the IP address of a master browser on the network, return its
3127 * workgroup and connect to it.
3129 * This function is provided to allow additional processing beyond what
3130 * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
3131 * browsers and obtain each master browsers' list of domains (in case the
3132 * first master browser is recently on the network and has not yet
3133 * synchronized with other master browsers and therefore does not yet have the
3134 * entire network browse list)
3137 struct cli_state
*get_ipc_connect_master_ip(TALLOC_CTX
*ctx
,
3138 struct sockaddr_storage
*mb_ip
,
3139 const struct user_auth_info
*user_info
,
3140 char **pp_workgroup_out
)
3142 char addr
[INET6_ADDRSTRLEN
];
3144 struct cli_state
*cli
;
3145 struct sockaddr_storage server_ss
;
3147 *pp_workgroup_out
= NULL
;
3149 print_sockaddr(addr
, sizeof(addr
), mb_ip
);
3150 DEBUG(99, ("Looking up name of master browser %s\n",
3154 * Do a name status query to find out the name of the master browser.
3155 * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
3156 * master browser will not respond to a wildcard query (or, at least,
3157 * an NT4 server acting as the domain master browser will not).
3159 * We might be able to use ONLY the query on MSBROWSE, but that's not
3160 * yet been tested with all Windows versions, so until it is, leave
3161 * the original wildcard query as the first choice and fall back to
3162 * MSBROWSE if the wildcard query fails.
3164 if (!name_status_find("*", 0, 0x1d, mb_ip
, name
) &&
3165 !name_status_find(MSBROWSE
, 1, 0x1d, mb_ip
, name
)) {
3167 DEBUG(99, ("Could not retrieve name status for %s\n",
3172 if (!find_master_ip(name
, &server_ss
)) {
3173 DEBUG(99, ("Could not find master ip for %s\n", name
));
3177 *pp_workgroup_out
= talloc_strdup(ctx
, name
);
3179 DEBUG(4, ("found master browser %s, %s\n", name
, addr
));
3181 print_sockaddr(addr
, sizeof(addr
), &server_ss
);
3182 cli
= get_ipc_connect(addr
, &server_ss
, user_info
);
3188 * Return the IP address and workgroup of a master browser on the network, and
3192 struct cli_state
*get_ipc_connect_master_ip_bcast(TALLOC_CTX
*ctx
,
3193 const struct user_auth_info
*user_info
,
3194 char **pp_workgroup_out
)
3196 struct sockaddr_storage
*ip_list
;
3197 struct cli_state
*cli
;
3201 *pp_workgroup_out
= NULL
;
3203 DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
3205 /* Go looking for workgroups by broadcasting on the local network */
3207 status
= name_resolve_bcast(MSBROWSE
, 1, talloc_tos(),
3209 if (!NT_STATUS_IS_OK(status
)) {
3210 DEBUG(99, ("No master browsers responded: %s\n",
3211 nt_errstr(status
)));
3215 for (i
= 0; i
< count
; i
++) {
3216 char addr
[INET6_ADDRSTRLEN
];
3217 print_sockaddr(addr
, sizeof(addr
), &ip_list
[i
]);
3218 DEBUG(99, ("Found master browser %s\n", addr
));
3220 cli
= get_ipc_connect_master_ip(ctx
, &ip_list
[i
],
3221 user_info
, pp_workgroup_out
);