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
;
125 uint16_t sec_mode
= cli_state_security_mode(cli
);
127 req
= tevent_req_create(mem_ctx
, &state
,
128 struct cli_session_setup_lanman2_state
);
137 * LANMAN servers predate NT status codes and Unicode and
138 * ignore those smb flags so we must disable the corresponding
139 * default capabilities that would otherwise cause the Unicode
140 * and NT Status flags to be set (and even returned by the
144 cli
->capabilities
&= ~(CAP_UNICODE
| CAP_STATUS32
);
147 * if in share level security then don't send a password now
149 if (!(sec_mode
& NEGOTIATE_SECURITY_USER_LEVEL
)) {
154 && (sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
)
157 * Encrypted mode needed, and non encrypted password
160 lm_response
= data_blob(NULL
, 24);
161 if (tevent_req_nomem(lm_response
.data
, req
)) {
162 return tevent_req_post(req
, ev
);
165 if (!SMBencrypt(pass
, cli
->secblob
.data
,
166 (uint8_t *)lm_response
.data
)) {
167 DEBUG(1, ("Password is > 14 chars in length, and is "
168 "therefore incompatible with Lanman "
169 "authentication\n"));
170 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
171 return tevent_req_post(req
, ev
);
173 } else if ((sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
)
176 * Encrypted mode needed, and encrypted password
179 lm_response
= data_blob(pass
, passlen
);
180 if (tevent_req_nomem(lm_response
.data
, req
)) {
181 return tevent_req_post(req
, ev
);
183 } else if (passlen
> 0) {
185 size_t converted_size
;
187 * Plaintext mode needed, assume plaintext supplied.
189 buf
= talloc_array(talloc_tos(), uint8_t, 0);
190 buf
= smb_bytes_push_str(buf
, cli_ucs2(cli
), pass
, passlen
+1,
192 if (tevent_req_nomem(buf
, req
)) {
193 return tevent_req_post(req
, ev
);
195 lm_response
= data_blob(pass
, passlen
);
197 if (tevent_req_nomem(lm_response
.data
, req
)) {
198 return tevent_req_post(req
, ev
);
202 SCVAL(vwv
+0, 0, 0xff);
205 SSVAL(vwv
+2, 0, CLI_BUFFER_SIZE
);
208 SIVAL(vwv
+5, 0, cli_state_server_session_key(cli
));
209 SSVAL(vwv
+7, 0, lm_response
.length
);
211 bytes
= talloc_array(state
, uint8_t, lm_response
.length
);
212 if (tevent_req_nomem(bytes
, req
)) {
213 return tevent_req_post(req
, ev
);
215 if (lm_response
.length
!= 0) {
216 memcpy(bytes
, lm_response
.data
, lm_response
.length
);
218 data_blob_free(&lm_response
);
220 tmp
= talloc_strdup_upper(talloc_tos(), user
);
221 if (tevent_req_nomem(tmp
, req
)) {
222 return tevent_req_post(req
, ev
);
224 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), tmp
, strlen(tmp
)+1,
228 tmp
= talloc_strdup_upper(talloc_tos(), workgroup
);
229 if (tevent_req_nomem(tmp
, req
)) {
230 return tevent_req_post(req
, ev
);
232 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), tmp
, strlen(tmp
)+1,
234 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), "Unix", 5, NULL
);
235 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), "Samba", 6, NULL
);
237 if (tevent_req_nomem(bytes
, req
)) {
238 return tevent_req_post(req
, ev
);
241 subreq
= cli_smb_send(state
, ev
, cli
, SMBsesssetupX
, 0, 10, vwv
,
242 talloc_get_size(bytes
), bytes
);
243 if (tevent_req_nomem(subreq
, req
)) {
244 return tevent_req_post(req
, ev
);
246 tevent_req_set_callback(subreq
, cli_session_setup_lanman2_done
, req
);
250 static void cli_session_setup_lanman2_done(struct tevent_req
*subreq
)
252 struct tevent_req
*req
= tevent_req_callback_data(
253 subreq
, struct tevent_req
);
254 struct cli_session_setup_lanman2_state
*state
= tevent_req_data(
255 req
, struct cli_session_setup_lanman2_state
);
256 struct cli_state
*cli
= state
->cli
;
267 status
= cli_smb_recv(subreq
, state
, &in
, 3, &wct
, &vwv
,
270 if (!NT_STATUS_IS_OK(status
)) {
271 tevent_req_nterror(req
, status
);
278 cli_state_set_uid(state
->cli
, SVAL(inbuf
, smb_uid
));
279 cli
->is_guestlogin
= ((SVAL(vwv
+2, 0) & 1) != 0);
281 status
= smb_bytes_talloc_string(cli
,
288 if (!NT_STATUS_IS_OK(status
)) {
289 tevent_req_nterror(req
, status
);
294 status
= smb_bytes_talloc_string(cli
,
301 if (!NT_STATUS_IS_OK(status
)) {
302 tevent_req_nterror(req
, status
);
307 status
= smb_bytes_talloc_string(cli
,
314 if (!NT_STATUS_IS_OK(status
)) {
315 tevent_req_nterror(req
, status
);
320 if (strstr(cli
->server_type
, "Samba")) {
321 cli
->is_samba
= True
;
323 status
= cli_set_username(cli
, state
->user
);
324 if (tevent_req_nterror(req
, status
)) {
327 tevent_req_done(req
);
330 static NTSTATUS
cli_session_setup_lanman2_recv(struct tevent_req
*req
)
332 return tevent_req_simple_recv_ntstatus(req
);
335 static NTSTATUS
cli_session_setup_lanman2(struct cli_state
*cli
, const char *user
,
336 const char *pass
, size_t passlen
,
337 const char *workgroup
)
339 TALLOC_CTX
*frame
= talloc_stackframe();
340 struct event_context
*ev
;
341 struct tevent_req
*req
;
342 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
344 if (cli_has_async_calls(cli
)) {
346 * Can't use sync call while an async call is in flight
348 status
= NT_STATUS_INVALID_PARAMETER
;
351 ev
= event_context_init(frame
);
355 req
= cli_session_setup_lanman2_send(frame
, ev
, cli
, user
, pass
, passlen
,
360 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
363 status
= cli_session_setup_lanman2_recv(req
);
369 /****************************************************************************
370 Work out suitable capabilities to offer the server.
371 ****************************************************************************/
373 static uint32
cli_session_setup_capabilities(struct cli_state
*cli
)
375 uint32 capabilities
= CAP_NT_SMBS
;
377 if (!cli
->force_dos_errors
)
378 capabilities
|= CAP_STATUS32
;
380 if (cli
->use_level_II_oplocks
)
381 capabilities
|= CAP_LEVEL_II_OPLOCKS
;
383 capabilities
|= (cli_state_capabilities(cli
) & (CAP_UNICODE
|CAP_LARGE_FILES
|CAP_LARGE_READX
|CAP_LARGE_WRITEX
|CAP_DFS
));
387 /****************************************************************************
388 Do a NT1 guest session setup.
389 ****************************************************************************/
391 struct cli_session_setup_guest_state
{
392 struct cli_state
*cli
;
397 static void cli_session_setup_guest_done(struct tevent_req
*subreq
);
399 struct tevent_req
*cli_session_setup_guest_create(TALLOC_CTX
*mem_ctx
,
400 struct event_context
*ev
,
401 struct cli_state
*cli
,
402 struct tevent_req
**psmbreq
)
404 struct tevent_req
*req
, *subreq
;
405 struct cli_session_setup_guest_state
*state
;
409 req
= tevent_req_create(mem_ctx
, &state
,
410 struct cli_session_setup_guest_state
);
417 SCVAL(vwv
+0, 0, 0xFF);
420 SSVAL(vwv
+2, 0, CLI_BUFFER_SIZE
);
422 SSVAL(vwv
+4, 0, cli_state_get_vc_num(cli
));
423 SIVAL(vwv
+5, 0, cli_state_server_session_key(cli
));
428 SIVAL(vwv
+11, 0, cli_session_setup_capabilities(cli
));
430 bytes
= talloc_array(state
, uint8_t, 0);
432 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), "", 1, /* username */
434 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), "", 1, /* workgroup */
436 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), "Unix", 5, NULL
);
437 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), "Samba", 6, NULL
);
444 state
->bytes
.iov_base
= (void *)bytes
;
445 state
->bytes
.iov_len
= talloc_get_size(bytes
);
447 subreq
= cli_smb_req_create(state
, ev
, cli
, SMBsesssetupX
, 0, 13, vwv
,
449 if (subreq
== NULL
) {
453 tevent_req_set_callback(subreq
, cli_session_setup_guest_done
, req
);
458 struct tevent_req
*cli_session_setup_guest_send(TALLOC_CTX
*mem_ctx
,
459 struct event_context
*ev
,
460 struct cli_state
*cli
)
462 struct tevent_req
*req
, *subreq
;
465 req
= cli_session_setup_guest_create(mem_ctx
, ev
, cli
, &subreq
);
470 status
= cli_smb_req_send(subreq
);
471 if (NT_STATUS_IS_OK(status
)) {
472 tevent_req_nterror(req
, status
);
473 return tevent_req_post(req
, ev
);
478 static void cli_session_setup_guest_done(struct tevent_req
*subreq
)
480 struct tevent_req
*req
= tevent_req_callback_data(
481 subreq
, struct tevent_req
);
482 struct cli_session_setup_guest_state
*state
= tevent_req_data(
483 req
, struct cli_session_setup_guest_state
);
484 struct cli_state
*cli
= state
->cli
;
495 status
= cli_smb_recv(subreq
, state
, &in
, 3, &wct
, &vwv
,
498 if (!NT_STATUS_IS_OK(status
)) {
499 tevent_req_nterror(req
, status
);
506 cli_state_set_uid(state
->cli
, SVAL(inbuf
, smb_uid
));
507 cli
->is_guestlogin
= ((SVAL(vwv
+2, 0) & 1) != 0);
509 status
= smb_bytes_talloc_string(cli
,
516 if (!NT_STATUS_IS_OK(status
)) {
517 tevent_req_nterror(req
, status
);
522 status
= smb_bytes_talloc_string(cli
,
529 if (!NT_STATUS_IS_OK(status
)) {
530 tevent_req_nterror(req
, status
);
535 status
= smb_bytes_talloc_string(cli
,
542 if (!NT_STATUS_IS_OK(status
)) {
543 tevent_req_nterror(req
, status
);
548 if (strstr(cli
->server_type
, "Samba")) {
549 cli
->is_samba
= True
;
552 status
= cli_set_username(cli
, "");
553 if (!NT_STATUS_IS_OK(status
)) {
554 tevent_req_nterror(req
, status
);
557 tevent_req_done(req
);
560 NTSTATUS
cli_session_setup_guest_recv(struct tevent_req
*req
)
562 return tevent_req_simple_recv_ntstatus(req
);
565 static NTSTATUS
cli_session_setup_guest(struct cli_state
*cli
)
567 TALLOC_CTX
*frame
= talloc_stackframe();
568 struct event_context
*ev
;
569 struct tevent_req
*req
;
570 NTSTATUS status
= NT_STATUS_OK
;
572 if (cli_has_async_calls(cli
)) {
574 * Can't use sync call while an async call is in flight
576 status
= NT_STATUS_INVALID_PARAMETER
;
580 ev
= event_context_init(frame
);
582 status
= NT_STATUS_NO_MEMORY
;
586 req
= cli_session_setup_guest_send(frame
, ev
, cli
);
588 status
= NT_STATUS_NO_MEMORY
;
592 if (!tevent_req_poll(req
, ev
)) {
593 status
= map_nt_error_from_unix(errno
);
597 status
= cli_session_setup_guest_recv(req
);
603 /****************************************************************************
604 Do a NT1 plaintext session setup.
605 ****************************************************************************/
607 struct cli_session_setup_plain_state
{
608 struct cli_state
*cli
;
613 static void cli_session_setup_plain_done(struct tevent_req
*subreq
);
615 static struct tevent_req
*cli_session_setup_plain_send(
616 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
617 struct cli_state
*cli
,
618 const char *user
, const char *pass
, const char *workgroup
)
620 struct tevent_req
*req
, *subreq
;
621 struct cli_session_setup_plain_state
*state
;
627 req
= tevent_req_create(mem_ctx
, &state
,
628 struct cli_session_setup_plain_state
);
636 SCVAL(vwv
+0, 0, 0xff);
639 SSVAL(vwv
+2, 0, CLI_BUFFER_SIZE
);
641 SSVAL(vwv
+4, 0, cli_state_get_vc_num(cli
));
642 SIVAL(vwv
+5, 0, cli_state_server_session_key(cli
));
647 SIVAL(vwv
+11, 0, cli_session_setup_capabilities(cli
));
649 bytes
= talloc_array(state
, uint8_t, 0);
650 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), pass
, strlen(pass
)+1,
652 if (tevent_req_nomem(bytes
, req
)) {
653 return tevent_req_post(req
, ev
);
655 SSVAL(vwv
+ (cli_ucs2(cli
) ? 8 : 7), 0, passlen
);
657 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
),
658 user
, strlen(user
)+1, NULL
);
659 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
),
660 workgroup
, strlen(workgroup
)+1, NULL
);
661 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
),
664 version
= talloc_asprintf(talloc_tos(), "Samba %s",
665 samba_version_string());
666 if (tevent_req_nomem(version
, req
)){
667 return tevent_req_post(req
, ev
);
669 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
),
670 version
, strlen(version
)+1, NULL
);
671 TALLOC_FREE(version
);
673 if (tevent_req_nomem(bytes
, req
)) {
674 return tevent_req_post(req
, ev
);
677 subreq
= cli_smb_send(state
, ev
, cli
, SMBsesssetupX
, 0, 13, vwv
,
678 talloc_get_size(bytes
), bytes
);
679 if (tevent_req_nomem(subreq
, req
)) {
680 return tevent_req_post(req
, ev
);
682 tevent_req_set_callback(subreq
, cli_session_setup_plain_done
, req
);
686 static void cli_session_setup_plain_done(struct tevent_req
*subreq
)
688 struct tevent_req
*req
= tevent_req_callback_data(
689 subreq
, struct tevent_req
);
690 struct cli_session_setup_plain_state
*state
= tevent_req_data(
691 req
, struct cli_session_setup_plain_state
);
692 struct cli_state
*cli
= state
->cli
;
703 status
= cli_smb_recv(subreq
, state
, &in
, 3, &wct
, &vwv
,
706 if (tevent_req_nterror(req
, status
)) {
713 cli_state_set_uid(state
->cli
, SVAL(inbuf
, smb_uid
));
714 cli
->is_guestlogin
= ((SVAL(vwv
+2, 0) & 1) != 0);
716 status
= smb_bytes_talloc_string(cli
,
723 if (!NT_STATUS_IS_OK(status
)) {
724 tevent_req_nterror(req
, status
);
729 status
= smb_bytes_talloc_string(cli
,
736 if (!NT_STATUS_IS_OK(status
)) {
737 tevent_req_nterror(req
, status
);
742 status
= smb_bytes_talloc_string(cli
,
749 if (!NT_STATUS_IS_OK(status
)) {
750 tevent_req_nterror(req
, status
);
755 status
= cli_set_username(cli
, state
->user
);
756 if (tevent_req_nterror(req
, status
)) {
759 if (strstr(cli
->server_type
, "Samba")) {
760 cli
->is_samba
= True
;
762 tevent_req_done(req
);
765 static NTSTATUS
cli_session_setup_plain_recv(struct tevent_req
*req
)
767 return tevent_req_simple_recv_ntstatus(req
);
770 static NTSTATUS
cli_session_setup_plain(struct cli_state
*cli
,
771 const char *user
, const char *pass
,
772 const char *workgroup
)
774 TALLOC_CTX
*frame
= talloc_stackframe();
775 struct event_context
*ev
;
776 struct tevent_req
*req
;
777 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
779 if (cli_has_async_calls(cli
)) {
781 * Can't use sync call while an async call is in flight
783 status
= NT_STATUS_INVALID_PARAMETER
;
786 ev
= event_context_init(frame
);
790 req
= cli_session_setup_plain_send(frame
, ev
, cli
, user
, pass
,
795 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
798 status
= cli_session_setup_plain_recv(req
);
804 /****************************************************************************
805 do a NT1 NTLM/LM encrypted session setup - for when extended security
807 @param cli client state to create do session setup on
809 @param pass *either* cleartext password (passlen !=24) or LM response.
810 @param ntpass NT response, implies ntpasslen >=24, implies pass is not clear
811 @param workgroup The user's domain.
812 ****************************************************************************/
814 struct cli_session_setup_nt1_state
{
815 struct cli_state
*cli
;
818 DATA_BLOB session_key
;
822 static void cli_session_setup_nt1_done(struct tevent_req
*subreq
);
824 static struct tevent_req
*cli_session_setup_nt1_send(
825 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
826 struct cli_state
*cli
, const char *user
,
827 const char *pass
, size_t passlen
,
828 const char *ntpass
, size_t ntpasslen
,
829 const char *workgroup
)
831 struct tevent_req
*req
, *subreq
;
832 struct cli_session_setup_nt1_state
*state
;
833 DATA_BLOB lm_response
= data_blob_null
;
834 DATA_BLOB nt_response
= data_blob_null
;
835 DATA_BLOB session_key
= data_blob_null
;
838 char *workgroup_upper
;
840 req
= tevent_req_create(mem_ctx
, &state
,
841 struct cli_session_setup_nt1_state
);
850 /* do nothing - guest login */
851 } else if (passlen
!= 24) {
852 if (lp_client_ntlmv2_auth()) {
853 DATA_BLOB server_chal
;
854 DATA_BLOB names_blob
;
856 server_chal
= data_blob(cli
->secblob
.data
,
857 MIN(cli
->secblob
.length
, 8));
858 if (tevent_req_nomem(server_chal
.data
, req
)) {
859 return tevent_req_post(req
, ev
);
863 * note that the 'workgroup' here is a best
864 * guess - we don't know the server's domain
865 * at this point. Windows clients also don't
868 names_blob
= NTLMv2_generate_names_blob(
869 NULL
, NULL
, workgroup
);
871 if (tevent_req_nomem(names_blob
.data
, req
)) {
872 return tevent_req_post(req
, ev
);
875 if (!SMBNTLMv2encrypt(NULL
, user
, workgroup
, pass
,
876 &server_chal
, &names_blob
,
877 &lm_response
, &nt_response
,
878 NULL
, &session_key
)) {
879 data_blob_free(&names_blob
);
880 data_blob_free(&server_chal
);
882 req
, NT_STATUS_ACCESS_DENIED
);
883 return tevent_req_post(req
, ev
);
885 data_blob_free(&names_blob
);
886 data_blob_free(&server_chal
);
890 E_md4hash(pass
, nt_hash
);
893 nt_response
= data_blob_null
;
895 nt_response
= data_blob(NULL
, 24);
896 if (tevent_req_nomem(nt_response
.data
, req
)) {
897 return tevent_req_post(req
, ev
);
900 SMBNTencrypt(pass
, cli
->secblob
.data
,
903 /* non encrypted password supplied. Ignore ntpass. */
904 if (lp_client_lanman_auth()) {
906 lm_response
= data_blob(NULL
, 24);
907 if (tevent_req_nomem(lm_response
.data
, req
)) {
908 return tevent_req_post(req
, ev
);
911 if (!SMBencrypt(pass
,cli
->secblob
.data
,
914 * Oops, the LM response is
915 * invalid, just put the NT
916 * response there instead
918 data_blob_free(&lm_response
);
919 lm_response
= data_blob(
925 * LM disabled, place NT# in LM field
928 lm_response
= data_blob(
929 nt_response
.data
, nt_response
.length
);
932 if (tevent_req_nomem(lm_response
.data
, req
)) {
933 return tevent_req_post(req
, ev
);
936 session_key
= data_blob(NULL
, 16);
937 if (tevent_req_nomem(session_key
.data
, req
)) {
938 return tevent_req_post(req
, ev
);
941 E_deshash(pass
, session_key
.data
);
942 memset(&session_key
.data
[8], '\0', 8);
944 SMBsesskeygen_ntv1(nt_hash
, session_key
.data
);
947 cli_temp_set_signing(cli
);
949 /* pre-encrypted password supplied. Only used for
950 security=server, can't do
951 signing because we don't have original key */
953 lm_response
= data_blob(pass
, passlen
);
954 if (tevent_req_nomem(lm_response
.data
, req
)) {
955 return tevent_req_post(req
, ev
);
958 nt_response
= data_blob(ntpass
, ntpasslen
);
959 if (tevent_req_nomem(nt_response
.data
, req
)) {
960 return tevent_req_post(req
, ev
);
965 state
->response
= data_blob_talloc(
966 state
, lm_response
.data
, lm_response
.length
);
968 state
->response
= data_blob_talloc(
969 state
, nt_response
.data
, nt_response
.length
);
971 if (tevent_req_nomem(state
->response
.data
, req
)) {
972 return tevent_req_post(req
, ev
);
975 if (session_key
.data
) {
976 state
->session_key
= data_blob_talloc(
977 state
, session_key
.data
, session_key
.length
);
978 if (tevent_req_nomem(state
->session_key
.data
, req
)) {
979 return tevent_req_post(req
, ev
);
982 data_blob_free(&session_key
);
984 SCVAL(vwv
+0, 0, 0xff);
987 SSVAL(vwv
+2, 0, CLI_BUFFER_SIZE
);
989 SSVAL(vwv
+4, 0, cli_state_get_vc_num(cli
));
990 SIVAL(vwv
+5, 0, cli_state_server_session_key(cli
));
991 SSVAL(vwv
+7, 0, lm_response
.length
);
992 SSVAL(vwv
+8, 0, nt_response
.length
);
995 SIVAL(vwv
+11, 0, cli_session_setup_capabilities(cli
));
997 bytes
= talloc_array(state
, uint8_t,
998 lm_response
.length
+ nt_response
.length
);
999 if (tevent_req_nomem(bytes
, req
)) {
1000 return tevent_req_post(req
, ev
);
1002 if (lm_response
.length
!= 0) {
1003 memcpy(bytes
, lm_response
.data
, lm_response
.length
);
1005 if (nt_response
.length
!= 0) {
1006 memcpy(bytes
+ lm_response
.length
,
1007 nt_response
.data
, nt_response
.length
);
1009 data_blob_free(&lm_response
);
1010 data_blob_free(&nt_response
);
1012 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
),
1013 user
, strlen(user
)+1, NULL
);
1016 * Upper case here might help some NTLMv2 implementations
1018 workgroup_upper
= talloc_strdup_upper(talloc_tos(), workgroup
);
1019 if (tevent_req_nomem(workgroup_upper
, req
)) {
1020 return tevent_req_post(req
, ev
);
1022 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
),
1023 workgroup_upper
, strlen(workgroup_upper
)+1,
1025 TALLOC_FREE(workgroup_upper
);
1027 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), "Unix", 5, NULL
);
1028 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), "Samba", 6, NULL
);
1029 if (tevent_req_nomem(bytes
, req
)) {
1030 return tevent_req_post(req
, ev
);
1033 subreq
= cli_smb_send(state
, ev
, cli
, SMBsesssetupX
, 0, 13, vwv
,
1034 talloc_get_size(bytes
), bytes
);
1035 if (tevent_req_nomem(subreq
, req
)) {
1036 return tevent_req_post(req
, ev
);
1038 tevent_req_set_callback(subreq
, cli_session_setup_nt1_done
, req
);
1042 static void cli_session_setup_nt1_done(struct tevent_req
*subreq
)
1044 struct tevent_req
*req
= tevent_req_callback_data(
1045 subreq
, struct tevent_req
);
1046 struct cli_session_setup_nt1_state
*state
= tevent_req_data(
1047 req
, struct cli_session_setup_nt1_state
);
1048 struct cli_state
*cli
= state
->cli
;
1059 status
= cli_smb_recv(subreq
, state
, &in
, 3, &wct
, &vwv
,
1060 &num_bytes
, &bytes
);
1061 TALLOC_FREE(subreq
);
1062 if (!NT_STATUS_IS_OK(status
)) {
1063 tevent_req_nterror(req
, status
);
1070 cli_state_set_uid(state
->cli
, SVAL(inbuf
, smb_uid
));
1071 cli
->is_guestlogin
= ((SVAL(vwv
+2, 0) & 1) != 0);
1073 status
= smb_bytes_talloc_string(cli
,
1079 if (!NT_STATUS_IS_OK(status
)) {
1080 tevent_req_nterror(req
, status
);
1085 status
= smb_bytes_talloc_string(cli
,
1091 if (!NT_STATUS_IS_OK(status
)) {
1092 tevent_req_nterror(req
, status
);
1097 status
= smb_bytes_talloc_string(cli
,
1099 &cli
->server_domain
,
1103 if (!NT_STATUS_IS_OK(status
)) {
1104 tevent_req_nterror(req
, status
);
1109 if (strstr(cli
->server_type
, "Samba")) {
1110 cli
->is_samba
= True
;
1113 status
= cli_set_username(cli
, state
->user
);
1114 if (tevent_req_nterror(req
, status
)) {
1117 if (cli_simple_set_signing(cli
, state
->session_key
, state
->response
)
1118 && !cli_check_sign_mac(cli
, (char *)in
, 1)) {
1119 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1122 if (state
->session_key
.data
) {
1123 /* Have plaintext orginal */
1124 cli_set_session_key(cli
, state
->session_key
);
1126 tevent_req_done(req
);
1129 static NTSTATUS
cli_session_setup_nt1_recv(struct tevent_req
*req
)
1131 return tevent_req_simple_recv_ntstatus(req
);
1134 static NTSTATUS
cli_session_setup_nt1(struct cli_state
*cli
, const char *user
,
1135 const char *pass
, size_t passlen
,
1136 const char *ntpass
, size_t ntpasslen
,
1137 const char *workgroup
)
1139 TALLOC_CTX
*frame
= talloc_stackframe();
1140 struct event_context
*ev
;
1141 struct tevent_req
*req
;
1142 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
1144 if (cli_has_async_calls(cli
)) {
1146 * Can't use sync call while an async call is in flight
1148 status
= NT_STATUS_INVALID_PARAMETER
;
1151 ev
= event_context_init(frame
);
1155 req
= cli_session_setup_nt1_send(frame
, ev
, cli
, user
, pass
, passlen
,
1156 ntpass
, ntpasslen
, workgroup
);
1160 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
1163 status
= cli_session_setup_nt1_recv(req
);
1169 /* The following is calculated from :
1171 * (smb_wcnt * 2) = 24 (smb_wcnt == 12 in cli_session_setup_blob_send() )
1172 * (strlen("Unix") + 1 + strlen("Samba") + 1) * 2 = 22 (unicode strings at
1176 #define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22)
1178 struct cli_sesssetup_blob_state
{
1179 struct tevent_context
*ev
;
1180 struct cli_state
*cli
;
1182 uint16_t max_blob_size
;
1191 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state
*state
,
1192 struct tevent_req
**psubreq
);
1193 static void cli_sesssetup_blob_done(struct tevent_req
*subreq
);
1195 static struct tevent_req
*cli_sesssetup_blob_send(TALLOC_CTX
*mem_ctx
,
1196 struct tevent_context
*ev
,
1197 struct cli_state
*cli
,
1200 struct tevent_req
*req
, *subreq
;
1201 struct cli_sesssetup_blob_state
*state
;
1202 uint32_t usable_space
;
1204 req
= tevent_req_create(mem_ctx
, &state
,
1205 struct cli_sesssetup_blob_state
);
1213 usable_space
= cli_state_available_size(cli
,
1214 BASE_SESSSETUP_BLOB_PACKET_SIZE
);
1216 if (usable_space
== 0) {
1217 DEBUG(1, ("cli_session_setup_blob: cli->max_xmit too small "
1218 "(not possible to send %u bytes)\n",
1219 BASE_SESSSETUP_BLOB_PACKET_SIZE
+ 1));
1220 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1221 return tevent_req_post(req
, ev
);
1223 state
->max_blob_size
= MIN(usable_space
, 0xFFFF);
1225 if (!cli_sesssetup_blob_next(state
, &subreq
)) {
1226 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
1227 return tevent_req_post(req
, ev
);
1229 tevent_req_set_callback(subreq
, cli_sesssetup_blob_done
, req
);
1233 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state
*state
,
1234 struct tevent_req
**psubreq
)
1236 struct tevent_req
*subreq
;
1239 SCVAL(state
->vwv
+0, 0, 0xFF);
1240 SCVAL(state
->vwv
+0, 1, 0);
1241 SSVAL(state
->vwv
+1, 0, 0);
1242 SSVAL(state
->vwv
+2, 0, CLI_BUFFER_SIZE
);
1243 SSVAL(state
->vwv
+3, 0, 2);
1244 SSVAL(state
->vwv
+4, 0, 1);
1245 SIVAL(state
->vwv
+5, 0, 0);
1247 thistime
= MIN(state
->blob
.length
, state
->max_blob_size
);
1248 SSVAL(state
->vwv
+7, 0, thistime
);
1250 SSVAL(state
->vwv
+8, 0, 0);
1251 SSVAL(state
->vwv
+9, 0, 0);
1252 SIVAL(state
->vwv
+10, 0,
1253 cli_session_setup_capabilities(state
->cli
)
1254 | CAP_EXTENDED_SECURITY
);
1256 state
->buf
= (uint8_t *)talloc_memdup(state
, state
->blob
.data
,
1258 if (state
->buf
== NULL
) {
1261 state
->blob
.data
+= thistime
;
1262 state
->blob
.length
-= thistime
;
1264 state
->buf
= smb_bytes_push_str(state
->buf
, cli_ucs2(state
->cli
),
1266 state
->buf
= smb_bytes_push_str(state
->buf
, cli_ucs2(state
->cli
),
1268 if (state
->buf
== NULL
) {
1271 subreq
= cli_smb_send(state
, state
->ev
, state
->cli
, SMBsesssetupX
, 0,
1273 talloc_get_size(state
->buf
), state
->buf
);
1274 if (subreq
== NULL
) {
1281 static void cli_sesssetup_blob_done(struct tevent_req
*subreq
)
1283 struct tevent_req
*req
= tevent_req_callback_data(
1284 subreq
, struct tevent_req
);
1285 struct cli_sesssetup_blob_state
*state
= tevent_req_data(
1286 req
, struct cli_sesssetup_blob_state
);
1287 struct cli_state
*cli
= state
->cli
;
1294 uint16_t blob_length
;
1298 status
= cli_smb_recv(subreq
, state
, &inbuf
, 4, &wct
, &vwv
,
1299 &num_bytes
, &bytes
);
1300 TALLOC_FREE(subreq
);
1301 if (!NT_STATUS_IS_OK(status
)
1302 && !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1303 tevent_req_nterror(req
, status
);
1307 state
->status
= status
;
1308 TALLOC_FREE(state
->buf
);
1310 state
->inbuf
= (char *)inbuf
;
1311 cli_state_set_uid(state
->cli
, SVAL(inbuf
, smb_uid
));
1312 cli
->is_guestlogin
= ((SVAL(vwv
+2, 0) & 1) != 0);
1314 blob_length
= SVAL(vwv
+3, 0);
1315 if (blob_length
> num_bytes
) {
1316 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
1319 state
->ret_blob
= data_blob_const(bytes
, blob_length
);
1321 p
= bytes
+ blob_length
;
1323 status
= smb_bytes_talloc_string(cli
,
1330 if (!NT_STATUS_IS_OK(status
)) {
1331 tevent_req_nterror(req
, status
);
1336 status
= smb_bytes_talloc_string(cli
,
1343 if (!NT_STATUS_IS_OK(status
)) {
1344 tevent_req_nterror(req
, status
);
1349 status
= smb_bytes_talloc_string(cli
,
1351 &cli
->server_domain
,
1356 if (!NT_STATUS_IS_OK(status
)) {
1357 tevent_req_nterror(req
, status
);
1362 if (strstr(cli
->server_type
, "Samba")) {
1363 cli
->is_samba
= True
;
1366 if (state
->blob
.length
!= 0) {
1370 if (!cli_sesssetup_blob_next(state
, &subreq
)) {
1371 tevent_req_oom(req
);
1374 tevent_req_set_callback(subreq
, cli_sesssetup_blob_done
, req
);
1377 tevent_req_done(req
);
1380 static NTSTATUS
cli_sesssetup_blob_recv(struct tevent_req
*req
,
1381 TALLOC_CTX
*mem_ctx
,
1385 struct cli_sesssetup_blob_state
*state
= tevent_req_data(
1386 req
, struct cli_sesssetup_blob_state
);
1390 if (tevent_req_is_nterror(req
, &status
)) {
1391 cli_state_set_uid(state
->cli
, UID_FIELD_INVALID
);
1395 inbuf
= talloc_move(mem_ctx
, &state
->inbuf
);
1396 if (pblob
!= NULL
) {
1397 *pblob
= state
->ret_blob
;
1399 if (pinbuf
!= NULL
) {
1402 /* could be NT_STATUS_MORE_PROCESSING_REQUIRED */
1403 return state
->status
;
1408 /****************************************************************************
1409 Use in-memory credentials cache
1410 ****************************************************************************/
1412 static void use_in_memory_ccache(void) {
1413 setenv(KRB5_ENV_CCNAME
, "MEMORY:cliconnect", 1);
1416 /****************************************************************************
1417 Do a spnego/kerberos encrypted session setup.
1418 ****************************************************************************/
1420 struct cli_session_setup_kerberos_state
{
1421 struct cli_state
*cli
;
1422 DATA_BLOB negTokenTarg
;
1423 DATA_BLOB session_key_krb5
;
1424 ADS_STATUS ads_status
;
1427 static void cli_session_setup_kerberos_done(struct tevent_req
*subreq
);
1429 static struct tevent_req
*cli_session_setup_kerberos_send(
1430 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
1431 const char *principal
)
1433 struct tevent_req
*req
, *subreq
;
1434 struct cli_session_setup_kerberos_state
*state
;
1437 DEBUG(2,("Doing kerberos session setup\n"));
1439 req
= tevent_req_create(mem_ctx
, &state
,
1440 struct cli_session_setup_kerberos_state
);
1445 state
->ads_status
= ADS_SUCCESS
;
1447 cli_temp_set_signing(cli
);
1450 * Ok, this is cheating: spnego_gen_krb5_negTokenInit can block if
1451 * we have to acquire a ticket. To be fixed later :-)
1453 rc
= spnego_gen_krb5_negTokenInit(state
, principal
, 0, &state
->negTokenTarg
,
1454 &state
->session_key_krb5
, 0, NULL
);
1456 DEBUG(1, ("cli_session_setup_kerberos: "
1457 "spnego_gen_krb5_negTokenInit failed: %s\n",
1458 error_message(rc
)));
1459 state
->ads_status
= ADS_ERROR_KRB5(rc
);
1460 tevent_req_nterror(req
, NT_STATUS_UNSUCCESSFUL
);
1461 return tevent_req_post(req
, ev
);
1465 file_save("negTokenTarg.dat", state
->negTokenTarg
.data
,
1466 state
->negTokenTarg
.length
);
1469 subreq
= cli_sesssetup_blob_send(state
, ev
, cli
, state
->negTokenTarg
);
1470 if (tevent_req_nomem(subreq
, req
)) {
1471 return tevent_req_post(req
, ev
);
1473 tevent_req_set_callback(subreq
, cli_session_setup_kerberos_done
, req
);
1477 static void cli_session_setup_kerberos_done(struct tevent_req
*subreq
)
1479 struct tevent_req
*req
= tevent_req_callback_data(
1480 subreq
, struct tevent_req
);
1481 struct cli_session_setup_kerberos_state
*state
= tevent_req_data(
1482 req
, struct cli_session_setup_kerberos_state
);
1486 status
= cli_sesssetup_blob_recv(subreq
, talloc_tos(), NULL
, &inbuf
);
1487 if (!NT_STATUS_IS_OK(status
)) {
1488 TALLOC_FREE(subreq
);
1489 tevent_req_nterror(req
, status
);
1493 cli_set_session_key(state
->cli
, state
->session_key_krb5
);
1495 if (cli_simple_set_signing(state
->cli
, state
->session_key_krb5
,
1497 && !cli_check_sign_mac(state
->cli
, inbuf
, 1)) {
1498 TALLOC_FREE(subreq
);
1499 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1502 TALLOC_FREE(subreq
);
1503 tevent_req_done(req
);
1506 static ADS_STATUS
cli_session_setup_kerberos_recv(struct tevent_req
*req
)
1508 struct cli_session_setup_kerberos_state
*state
= tevent_req_data(
1509 req
, struct cli_session_setup_kerberos_state
);
1512 if (tevent_req_is_nterror(req
, &status
)) {
1513 return ADS_ERROR_NT(status
);
1515 return state
->ads_status
;
1518 static ADS_STATUS
cli_session_setup_kerberos(struct cli_state
*cli
,
1519 const char *principal
)
1521 struct tevent_context
*ev
;
1522 struct tevent_req
*req
;
1523 ADS_STATUS status
= ADS_ERROR_NT(NT_STATUS_NO_MEMORY
);
1525 if (cli_has_async_calls(cli
)) {
1526 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
1528 ev
= tevent_context_init(talloc_tos());
1532 req
= cli_session_setup_kerberos_send(ev
, ev
, cli
, principal
);
1536 if (!tevent_req_poll(req
, ev
)) {
1537 status
= ADS_ERROR_SYSTEM(errno
);
1540 status
= cli_session_setup_kerberos_recv(req
);
1545 #endif /* HAVE_KRB5 */
1547 /****************************************************************************
1548 Do a spnego/NTLMSSP encrypted session setup.
1549 ****************************************************************************/
1551 struct cli_session_setup_ntlmssp_state
{
1552 struct tevent_context
*ev
;
1553 struct cli_state
*cli
;
1554 struct ntlmssp_state
*ntlmssp_state
;
1559 static int cli_session_setup_ntlmssp_state_destructor(
1560 struct cli_session_setup_ntlmssp_state
*state
)
1562 if (state
->ntlmssp_state
!= NULL
) {
1563 TALLOC_FREE(state
->ntlmssp_state
);
1568 static void cli_session_setup_ntlmssp_done(struct tevent_req
*req
);
1570 static struct tevent_req
*cli_session_setup_ntlmssp_send(
1571 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
1572 const char *user
, const char *pass
, const char *domain
)
1574 struct tevent_req
*req
, *subreq
;
1575 struct cli_session_setup_ntlmssp_state
*state
;
1578 const char *OIDs_ntlm
[] = {OID_NTLMSSP
, NULL
};
1580 req
= tevent_req_create(mem_ctx
, &state
,
1581 struct cli_session_setup_ntlmssp_state
);
1589 state
->ntlmssp_state
= NULL
;
1590 talloc_set_destructor(
1591 state
, cli_session_setup_ntlmssp_state_destructor
);
1593 cli_temp_set_signing(cli
);
1595 status
= ntlmssp_client_start(state
,
1598 lp_client_ntlmv2_auth(),
1599 &state
->ntlmssp_state
);
1600 if (!NT_STATUS_IS_OK(status
)) {
1603 ntlmssp_want_feature(state
->ntlmssp_state
,
1604 NTLMSSP_FEATURE_SESSION_KEY
);
1605 if (cli
->use_ccache
) {
1606 ntlmssp_want_feature(state
->ntlmssp_state
,
1607 NTLMSSP_FEATURE_CCACHE
);
1609 status
= ntlmssp_set_username(state
->ntlmssp_state
, user
);
1610 if (!NT_STATUS_IS_OK(status
)) {
1613 status
= ntlmssp_set_domain(state
->ntlmssp_state
, domain
);
1614 if (!NT_STATUS_IS_OK(status
)) {
1617 status
= ntlmssp_set_password(state
->ntlmssp_state
, pass
);
1618 if (!NT_STATUS_IS_OK(status
)) {
1621 status
= ntlmssp_update(state
->ntlmssp_state
, data_blob_null
,
1623 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1627 state
->blob_out
= spnego_gen_negTokenInit(state
, OIDs_ntlm
, &blob_out
, NULL
);
1628 data_blob_free(&blob_out
);
1630 subreq
= cli_sesssetup_blob_send(state
, ev
, cli
, state
->blob_out
);
1631 if (tevent_req_nomem(subreq
, req
)) {
1632 return tevent_req_post(req
, ev
);
1634 tevent_req_set_callback(subreq
, cli_session_setup_ntlmssp_done
, req
);
1637 tevent_req_nterror(req
, status
);
1638 return tevent_req_post(req
, ev
);
1641 static void cli_session_setup_ntlmssp_done(struct tevent_req
*subreq
)
1643 struct tevent_req
*req
= tevent_req_callback_data(
1644 subreq
, struct tevent_req
);
1645 struct cli_session_setup_ntlmssp_state
*state
= tevent_req_data(
1646 req
, struct cli_session_setup_ntlmssp_state
);
1647 DATA_BLOB blob_in
, msg_in
, blob_out
;
1652 status
= cli_sesssetup_blob_recv(subreq
, talloc_tos(), &blob_in
,
1654 TALLOC_FREE(subreq
);
1655 data_blob_free(&state
->blob_out
);
1657 if (NT_STATUS_IS_OK(status
)) {
1658 if (state
->cli
->server_domain
[0] == '\0') {
1659 TALLOC_FREE(state
->cli
->server_domain
);
1660 state
->cli
->server_domain
= talloc_strdup(state
->cli
,
1661 state
->ntlmssp_state
->server
.netbios_domain
);
1662 if (state
->cli
->server_domain
== NULL
) {
1663 TALLOC_FREE(subreq
);
1664 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
1668 cli_set_session_key(
1669 state
->cli
, state
->ntlmssp_state
->session_key
);
1671 if (cli_simple_set_signing(
1672 state
->cli
, state
->ntlmssp_state
->session_key
,
1674 && !cli_check_sign_mac(state
->cli
, inbuf
, 1)) {
1675 TALLOC_FREE(subreq
);
1676 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1679 TALLOC_FREE(subreq
);
1680 TALLOC_FREE(state
->ntlmssp_state
);
1681 tevent_req_done(req
);
1684 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1685 tevent_req_nterror(req
, status
);
1689 if (blob_in
.length
== 0) {
1690 tevent_req_nterror(req
, NT_STATUS_UNSUCCESSFUL
);
1694 if ((state
->turn
== 1)
1695 && NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1696 DATA_BLOB tmp_blob
= data_blob_null
;
1697 /* the server might give us back two challenges */
1698 parse_ret
= spnego_parse_challenge(state
, blob_in
, &msg_in
,
1700 data_blob_free(&tmp_blob
);
1702 parse_ret
= spnego_parse_auth_response(state
, blob_in
, status
,
1703 OID_NTLMSSP
, &msg_in
);
1708 DEBUG(3,("Failed to parse auth response\n"));
1709 if (NT_STATUS_IS_OK(status
)
1710 || NT_STATUS_EQUAL(status
,
1711 NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1713 req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
1718 status
= ntlmssp_update(state
->ntlmssp_state
, msg_in
, &blob_out
);
1720 if (!NT_STATUS_IS_OK(status
)
1721 && !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1722 TALLOC_FREE(subreq
);
1723 TALLOC_FREE(state
->ntlmssp_state
);
1724 tevent_req_nterror(req
, status
);
1728 state
->blob_out
= spnego_gen_auth(state
, blob_out
);
1729 TALLOC_FREE(subreq
);
1730 if (tevent_req_nomem(state
->blob_out
.data
, req
)) {
1734 subreq
= cli_sesssetup_blob_send(state
, state
->ev
, state
->cli
,
1736 if (tevent_req_nomem(subreq
, req
)) {
1739 tevent_req_set_callback(subreq
, cli_session_setup_ntlmssp_done
, req
);
1742 static NTSTATUS
cli_session_setup_ntlmssp_recv(struct tevent_req
*req
)
1744 struct cli_session_setup_ntlmssp_state
*state
= tevent_req_data(
1745 req
, struct cli_session_setup_ntlmssp_state
);
1748 if (tevent_req_is_nterror(req
, &status
)) {
1749 cli_state_set_uid(state
->cli
, UID_FIELD_INVALID
);
1752 return NT_STATUS_OK
;
1755 static NTSTATUS
cli_session_setup_ntlmssp(struct cli_state
*cli
,
1760 struct tevent_context
*ev
;
1761 struct tevent_req
*req
;
1762 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
1764 if (cli_has_async_calls(cli
)) {
1765 return NT_STATUS_INVALID_PARAMETER
;
1767 ev
= tevent_context_init(talloc_tos());
1771 req
= cli_session_setup_ntlmssp_send(ev
, ev
, cli
, user
, pass
, domain
);
1775 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
1778 status
= cli_session_setup_ntlmssp_recv(req
);
1784 /****************************************************************************
1785 Do a spnego encrypted session setup.
1787 user_domain: The shortname of the domain the user/machine is a member of.
1788 dest_realm: The realm we're connecting to, if NULL we use our default realm.
1789 ****************************************************************************/
1791 static ADS_STATUS
cli_session_setup_spnego(struct cli_state
*cli
,
1794 const char *user_domain
,
1795 const char * dest_realm
)
1797 char *principal
= NULL
;
1798 char *OIDs
[ASN1_MAX_OIDS
];
1801 const char *p
= NULL
;
1802 char *account
= NULL
;
1805 DEBUG(3,("Doing spnego session setup (blob length=%lu)\n", (unsigned long)cli
->secblob
.length
));
1807 /* the server might not even do spnego */
1808 if (cli
->secblob
.length
<= 16) {
1809 DEBUG(3,("server didn't supply a full spnego negprot\n"));
1814 file_save("negprot.dat", cli
->secblob
.data
, cli
->secblob
.length
);
1817 /* there is 16 bytes of GUID before the real spnego packet starts */
1818 blob
= data_blob(cli
->secblob
.data
+16, cli
->secblob
.length
-16);
1820 /* The server sent us the first part of the SPNEGO exchange in the
1821 * negprot reply. It is WRONG to depend on the principal sent in the
1822 * negprot reply, but right now we do it. If we don't receive one,
1823 * we try to best guess, then fall back to NTLM. */
1824 if (!spnego_parse_negTokenInit(talloc_tos(), blob
, OIDs
, &principal
, NULL
) ||
1826 data_blob_free(&blob
);
1827 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
1829 data_blob_free(&blob
);
1831 /* make sure the server understands kerberos */
1832 for (i
=0;OIDs
[i
];i
++) {
1834 DEBUG(3,("got OID=%s\n", OIDs
[i
]));
1836 DEBUGADD(3,("got OID=%s\n", OIDs
[i
]));
1837 if (strcmp(OIDs
[i
], OID_KERBEROS5_OLD
) == 0 ||
1838 strcmp(OIDs
[i
], OID_KERBEROS5
) == 0) {
1839 cli
->got_kerberos_mechanism
= True
;
1841 talloc_free(OIDs
[i
]);
1844 DEBUG(3,("got principal=%s\n", principal
? principal
: "<null>"));
1846 status
= cli_set_username(cli
, user
);
1847 if (!NT_STATUS_IS_OK(status
)) {
1848 TALLOC_FREE(principal
);
1849 return ADS_ERROR_NT(status
);
1853 /* If password is set we reauthenticate to kerberos server
1854 * and do not store results */
1856 if (cli
->got_kerberos_mechanism
&& cli
->use_kerberos
) {
1858 const char *remote_name
= cli_state_remote_name(cli
);
1860 if (pass
&& *pass
) {
1863 use_in_memory_ccache();
1864 ret
= kerberos_kinit_password(user
, pass
, 0 /* no time correction for now */, NULL
);
1867 TALLOC_FREE(principal
);
1868 DEBUG(0, ("Kinit failed: %s\n", error_message(ret
)));
1869 if (cli
->fallback_after_kerberos
)
1871 return ADS_ERROR_KRB5(ret
);
1875 /* We may not be allowed to use the server-supplied SPNEGO principal, or it may not have been supplied to us
1877 if (!lp_client_use_spnego_principal() || strequal(principal
, ADS_IGNORE_PRINCIPAL
)) {
1878 TALLOC_FREE(principal
);
1881 if (principal
== NULL
&&
1882 !is_ipaddress(remote_name
) &&
1883 !strequal(STAR_SMBSERVER
,
1887 DEBUG(3,("cli_session_setup_spnego: using target "
1888 "hostname not SPNEGO principal\n"));
1890 host
= strchr_m(remote_name
, '.');
1892 realm
= SMB_STRDUP(dest_realm
);
1894 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY
);
1900 realm
= kerberos_get_realm_from_hostname(remote_name
);
1902 /* NetBIOS name - use our realm. */
1903 realm
= kerberos_get_default_realm_from_ccache();
1907 if (realm
== NULL
|| *realm
== '\0') {
1908 realm
= SMB_STRDUP(lp_realm());
1910 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY
);
1913 DEBUG(3,("cli_session_setup_spnego: cannot "
1914 "get realm from dest_realm %s, "
1915 "desthost %s. Using default "
1916 "smb.conf realm %s\n",
1917 dest_realm
? dest_realm
: "<null>",
1922 principal
= talloc_asprintf(talloc_tos(),
1928 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY
);
1930 DEBUG(3,("cli_session_setup_spnego: guessed "
1931 "server principal=%s\n",
1932 principal
? principal
: "<null>"));
1938 rc
= cli_session_setup_kerberos(cli
, principal
);
1939 if (ADS_ERR_OK(rc
) || !cli
->fallback_after_kerberos
) {
1940 TALLOC_FREE(principal
);
1947 TALLOC_FREE(principal
);
1951 account
= talloc_strdup(talloc_tos(), user
);
1953 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY
);
1956 /* when falling back to ntlmssp while authenticating with a machine
1957 * account strip off the realm - gd */
1959 if ((p
= strchr_m(user
, '@')) != NULL
) {
1960 account
[PTR_DIFF(p
,user
)] = '\0';
1963 return ADS_ERROR_NT(cli_session_setup_ntlmssp(cli
, account
, pass
, user_domain
));
1966 /****************************************************************************
1967 Send a session setup. The username and workgroup is in UNIX character
1968 format and must be converted to DOS codepage format before sending. If the
1969 password is in plaintext, the same should be done.
1970 ****************************************************************************/
1972 NTSTATUS
cli_session_setup(struct cli_state
*cli
,
1974 const char *pass
, int passlen
,
1975 const char *ntpass
, int ntpasslen
,
1976 const char *workgroup
)
1980 uint16_t sec_mode
= cli_state_security_mode(cli
);
1983 user2
= talloc_strdup(talloc_tos(), user
);
1985 user2
= talloc_strdup(talloc_tos(), "");
1987 if (user2
== NULL
) {
1988 return NT_STATUS_NO_MEMORY
;
1995 /* allow for workgroups as part of the username */
1996 if ((p
=strchr_m(user2
,'\\')) || (p
=strchr_m(user2
,'/')) ||
1997 (p
=strchr_m(user2
,*lp_winbind_separator()))) {
2004 if (cli_state_protocol(cli
) < PROTOCOL_LANMAN1
) {
2005 return NT_STATUS_OK
;
2008 /* now work out what sort of session setup we are going to
2009 do. I have split this into separate functions to make the
2010 flow a bit easier to understand (tridge) */
2012 /* if its an older server then we have to use the older request format */
2014 if (cli_state_protocol(cli
) < PROTOCOL_NT1
) {
2015 if (!lp_client_lanman_auth() && passlen
!= 24 && (*pass
)) {
2016 DEBUG(1, ("Server requested LM password but 'client lanman auth = no'"
2017 " or 'client ntlmv2 auth = yes'\n"));
2018 return NT_STATUS_ACCESS_DENIED
;
2021 if ((sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
) == 0 &&
2022 !lp_client_plaintext_auth() && (*pass
)) {
2023 DEBUG(1, ("Server requested LM password but 'client plaintext auth = no'"
2024 " or 'client ntlmv2 auth = yes'\n"));
2025 return NT_STATUS_ACCESS_DENIED
;
2028 return cli_session_setup_lanman2(cli
, user
, pass
, passlen
,
2032 /* if no user is supplied then we have to do an anonymous connection.
2033 passwords are ignored */
2035 if (!user
|| !*user
)
2036 return cli_session_setup_guest(cli
);
2038 /* if the server is share level then send a plaintext null
2039 password at this point. The password is sent in the tree
2042 if ((sec_mode
& NEGOTIATE_SECURITY_USER_LEVEL
) == 0)
2043 return cli_session_setup_plain(cli
, user
, "", workgroup
);
2045 /* if the server doesn't support encryption then we have to use
2046 plaintext. The second password is ignored */
2048 if ((sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
) == 0) {
2049 if (!lp_client_plaintext_auth() && (*pass
)) {
2050 DEBUG(1, ("Server requested LM password but 'client plaintext auth = no'"
2051 " or 'client ntlmv2 auth = yes'\n"));
2052 return NT_STATUS_ACCESS_DENIED
;
2054 return cli_session_setup_plain(cli
, user
, pass
, workgroup
);
2057 /* if the server supports extended security then use SPNEGO */
2059 if (cli_state_capabilities(cli
) & CAP_EXTENDED_SECURITY
) {
2060 const char *remote_realm
= cli_state_remote_realm(cli
);
2061 ADS_STATUS status
= cli_session_setup_spnego(cli
, user
, pass
,
2064 if (!ADS_ERR_OK(status
)) {
2065 DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status
)));
2066 return ads_ntstatus(status
);
2071 /* otherwise do a NT1 style session setup */
2072 status
= cli_session_setup_nt1(cli
, user
, pass
, passlen
,
2073 ntpass
, ntpasslen
, workgroup
);
2074 if (!NT_STATUS_IS_OK(status
)) {
2075 DEBUG(3,("cli_session_setup: NT1 session setup "
2076 "failed: %s\n", nt_errstr(status
)));
2081 if (strstr(cli
->server_type
, "Samba")) {
2082 cli
->is_samba
= True
;
2085 return NT_STATUS_OK
;
2088 /****************************************************************************
2090 *****************************************************************************/
2092 struct cli_ulogoff_state
{
2093 struct cli_state
*cli
;
2097 static void cli_ulogoff_done(struct tevent_req
*subreq
);
2099 struct tevent_req
*cli_ulogoff_send(TALLOC_CTX
*mem_ctx
,
2100 struct tevent_context
*ev
,
2101 struct cli_state
*cli
)
2103 struct tevent_req
*req
, *subreq
;
2104 struct cli_ulogoff_state
*state
;
2106 req
= tevent_req_create(mem_ctx
, &state
, struct cli_ulogoff_state
);
2112 SCVAL(state
->vwv
+0, 0, 0xFF);
2113 SCVAL(state
->vwv
+1, 0, 0);
2114 SSVAL(state
->vwv
+2, 0, 0);
2116 subreq
= cli_smb_send(state
, ev
, cli
, SMBulogoffX
, 0, 2, state
->vwv
,
2118 if (tevent_req_nomem(subreq
, req
)) {
2119 return tevent_req_post(req
, ev
);
2121 tevent_req_set_callback(subreq
, cli_ulogoff_done
, req
);
2125 static void cli_ulogoff_done(struct tevent_req
*subreq
)
2127 struct tevent_req
*req
= tevent_req_callback_data(
2128 subreq
, struct tevent_req
);
2129 struct cli_ulogoff_state
*state
= tevent_req_data(
2130 req
, struct cli_ulogoff_state
);
2133 status
= cli_smb_recv(subreq
, NULL
, NULL
, 0, NULL
, NULL
, NULL
, NULL
);
2134 if (!NT_STATUS_IS_OK(status
)) {
2135 tevent_req_nterror(req
, status
);
2138 cli_state_set_uid(state
->cli
, UID_FIELD_INVALID
);
2139 tevent_req_done(req
);
2142 NTSTATUS
cli_ulogoff_recv(struct tevent_req
*req
)
2144 return tevent_req_simple_recv_ntstatus(req
);
2147 NTSTATUS
cli_ulogoff(struct cli_state
*cli
)
2149 struct tevent_context
*ev
;
2150 struct tevent_req
*req
;
2151 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2153 if (cli_has_async_calls(cli
)) {
2154 return NT_STATUS_INVALID_PARAMETER
;
2156 ev
= tevent_context_init(talloc_tos());
2160 req
= cli_ulogoff_send(ev
, ev
, cli
);
2164 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2167 status
= cli_ulogoff_recv(req
);
2173 /****************************************************************************
2175 ****************************************************************************/
2177 struct cli_tcon_andx_state
{
2178 struct cli_state
*cli
;
2183 static void cli_tcon_andx_done(struct tevent_req
*subreq
);
2185 struct tevent_req
*cli_tcon_andx_create(TALLOC_CTX
*mem_ctx
,
2186 struct event_context
*ev
,
2187 struct cli_state
*cli
,
2188 const char *share
, const char *dev
,
2189 const char *pass
, int passlen
,
2190 struct tevent_req
**psmbreq
)
2192 struct tevent_req
*req
, *subreq
;
2193 struct cli_tcon_andx_state
*state
;
2198 uint16_t sec_mode
= cli_state_security_mode(cli
);
2202 req
= tevent_req_create(mem_ctx
, &state
, struct cli_tcon_andx_state
);
2209 cli
->share
= talloc_strdup(cli
, share
);
2214 /* in user level security don't send a password now */
2215 if (sec_mode
& NEGOTIATE_SECURITY_USER_LEVEL
) {
2218 } else if (pass
== NULL
) {
2219 DEBUG(1, ("Server not using user level security and no "
2220 "password supplied.\n"));
2224 if ((sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
) &&
2225 *pass
&& passlen
!= 24) {
2226 if (!lp_client_lanman_auth()) {
2227 DEBUG(1, ("Server requested LANMAN password "
2228 "(share-level security) but "
2229 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2234 * Non-encrypted passwords - convert to DOS codepage before
2237 SMBencrypt(pass
, cli
->secblob
.data
, p24
);
2239 pass
= (const char *)p24
;
2241 if((sec_mode
& (NEGOTIATE_SECURITY_USER_LEVEL
2242 |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
))
2246 if (!lp_client_plaintext_auth() && (*pass
)) {
2247 DEBUG(1, ("Server requested plaintext "
2249 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2254 * Non-encrypted passwords - convert to DOS codepage
2257 tmp_pass
= talloc_array(talloc_tos(), uint8
, 0);
2258 if (tevent_req_nomem(tmp_pass
, req
)) {
2259 return tevent_req_post(req
, ev
);
2261 tmp_pass
= trans2_bytes_push_str(tmp_pass
,
2262 false, /* always DOS */
2266 if (tevent_req_nomem(tmp_pass
, req
)) {
2267 return tevent_req_post(req
, ev
);
2269 pass
= (const char *)tmp_pass
;
2270 passlen
= talloc_get_size(tmp_pass
);
2274 SCVAL(vwv
+0, 0, 0xFF);
2277 SSVAL(vwv
+2, 0, TCONX_FLAG_EXTENDED_RESPONSE
);
2278 SSVAL(vwv
+3, 0, passlen
);
2280 if (passlen
&& pass
) {
2281 bytes
= (uint8_t *)talloc_memdup(state
, pass
, passlen
);
2283 bytes
= talloc_array(state
, uint8_t, 0);
2289 tmp
= talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
2290 cli_state_remote_name(cli
), share
);
2295 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), tmp
, strlen(tmp
)+1,
2300 * Add the devicetype
2302 tmp
= talloc_strdup_upper(talloc_tos(), dev
);
2307 bytes
= smb_bytes_push_str(bytes
, false, tmp
, strlen(tmp
)+1, NULL
);
2310 if (bytes
== NULL
) {
2315 state
->bytes
.iov_base
= (void *)bytes
;
2316 state
->bytes
.iov_len
= talloc_get_size(bytes
);
2318 subreq
= cli_smb_req_create(state
, ev
, cli
, SMBtconX
, 0, 4, vwv
,
2320 if (subreq
== NULL
) {
2324 tevent_req_set_callback(subreq
, cli_tcon_andx_done
, req
);
2329 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
2330 return tevent_req_post(req
, ev
);
2333 struct tevent_req
*cli_tcon_andx_send(TALLOC_CTX
*mem_ctx
,
2334 struct event_context
*ev
,
2335 struct cli_state
*cli
,
2336 const char *share
, const char *dev
,
2337 const char *pass
, int passlen
)
2339 struct tevent_req
*req
, *subreq
;
2342 req
= cli_tcon_andx_create(mem_ctx
, ev
, cli
, share
, dev
, pass
, passlen
,
2347 if (subreq
== NULL
) {
2350 status
= cli_smb_req_send(subreq
);
2351 if (!NT_STATUS_IS_OK(status
)) {
2352 tevent_req_nterror(req
, status
);
2353 return tevent_req_post(req
, ev
);
2358 static void cli_tcon_andx_done(struct tevent_req
*subreq
)
2360 struct tevent_req
*req
= tevent_req_callback_data(
2361 subreq
, struct tevent_req
);
2362 struct cli_tcon_andx_state
*state
= tevent_req_data(
2363 req
, struct cli_tcon_andx_state
);
2364 struct cli_state
*cli
= state
->cli
;
2373 status
= cli_smb_recv(subreq
, state
, &in
, 0, &wct
, &vwv
,
2374 &num_bytes
, &bytes
);
2375 TALLOC_FREE(subreq
);
2376 if (!NT_STATUS_IS_OK(status
)) {
2377 tevent_req_nterror(req
, status
);
2384 if (clistr_pull_talloc(cli
,
2386 SVAL(inbuf
, smb_flg2
),
2390 STR_TERMINATE
|STR_ASCII
) == -1) {
2391 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
2395 cli
->dev
= talloc_strdup(cli
, "");
2396 if (cli
->dev
== NULL
) {
2397 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
2402 if ((cli_state_protocol(cli
) >= PROTOCOL_NT1
) && (num_bytes
== 3)) {
2403 /* almost certainly win95 - enable bug fixes */
2408 * Make sure that we have the optional support 16-bit field. WCT > 2.
2409 * Avoids issues when connecting to Win9x boxes sharing files
2412 cli
->dfsroot
= false;
2414 if ((wct
> 2) && (cli_state_protocol(cli
) >= PROTOCOL_LANMAN2
)) {
2415 cli
->dfsroot
= ((SVAL(vwv
+2, 0) & SMB_SHARE_IN_DFS
) != 0);
2418 cli
->smb1
.tid
= SVAL(inbuf
,smb_tid
);
2419 tevent_req_done(req
);
2422 NTSTATUS
cli_tcon_andx_recv(struct tevent_req
*req
)
2424 return tevent_req_simple_recv_ntstatus(req
);
2427 NTSTATUS
cli_tcon_andx(struct cli_state
*cli
, const char *share
,
2428 const char *dev
, const char *pass
, int passlen
)
2430 TALLOC_CTX
*frame
= talloc_stackframe();
2431 struct event_context
*ev
;
2432 struct tevent_req
*req
;
2433 NTSTATUS status
= NT_STATUS_OK
;
2435 if (cli_has_async_calls(cli
)) {
2437 * Can't use sync call while an async call is in flight
2439 status
= NT_STATUS_INVALID_PARAMETER
;
2443 ev
= event_context_init(frame
);
2445 status
= NT_STATUS_NO_MEMORY
;
2449 req
= cli_tcon_andx_send(frame
, ev
, cli
, share
, dev
, pass
, passlen
);
2451 status
= NT_STATUS_NO_MEMORY
;
2455 if (!tevent_req_poll(req
, ev
)) {
2456 status
= map_nt_error_from_unix(errno
);
2460 status
= cli_tcon_andx_recv(req
);
2466 /****************************************************************************
2467 Send a tree disconnect.
2468 ****************************************************************************/
2470 struct cli_tdis_state
{
2471 struct cli_state
*cli
;
2474 static void cli_tdis_done(struct tevent_req
*subreq
);
2476 struct tevent_req
*cli_tdis_send(TALLOC_CTX
*mem_ctx
,
2477 struct tevent_context
*ev
,
2478 struct cli_state
*cli
)
2480 struct tevent_req
*req
, *subreq
;
2481 struct cli_tdis_state
*state
;
2483 req
= tevent_req_create(mem_ctx
, &state
, struct cli_tdis_state
);
2489 subreq
= cli_smb_send(state
, ev
, cli
, SMBtdis
, 0, 0, NULL
, 0, NULL
);
2490 if (tevent_req_nomem(subreq
, req
)) {
2491 return tevent_req_post(req
, ev
);
2493 tevent_req_set_callback(subreq
, cli_tdis_done
, req
);
2497 static void cli_tdis_done(struct tevent_req
*subreq
)
2499 struct tevent_req
*req
= tevent_req_callback_data(
2500 subreq
, struct tevent_req
);
2501 struct cli_tdis_state
*state
= tevent_req_data(
2502 req
, struct cli_tdis_state
);
2505 status
= cli_smb_recv(subreq
, NULL
, NULL
, 0, NULL
, NULL
, NULL
, NULL
);
2506 TALLOC_FREE(subreq
);
2507 if (!NT_STATUS_IS_OK(status
)) {
2508 tevent_req_nterror(req
, status
);
2511 state
->cli
->smb1
.tid
= UINT16_MAX
;
2512 tevent_req_done(req
);
2515 NTSTATUS
cli_tdis_recv(struct tevent_req
*req
)
2517 return tevent_req_simple_recv_ntstatus(req
);
2520 NTSTATUS
cli_tdis(struct cli_state
*cli
)
2522 struct tevent_context
*ev
;
2523 struct tevent_req
*req
;
2524 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2526 if (cli_has_async_calls(cli
)) {
2527 return NT_STATUS_INVALID_PARAMETER
;
2529 ev
= tevent_context_init(talloc_tos());
2533 req
= cli_tdis_send(ev
, ev
, cli
);
2537 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2540 status
= cli_tdis_recv(req
);
2546 /****************************************************************************
2547 Send a negprot command.
2548 ****************************************************************************/
2550 struct cli_negprot_state
{
2551 struct cli_state
*cli
;
2554 static void cli_negprot_done(struct tevent_req
*subreq
);
2556 struct tevent_req
*cli_negprot_send(TALLOC_CTX
*mem_ctx
,
2557 struct event_context
*ev
,
2558 struct cli_state
*cli
)
2560 struct tevent_req
*req
, *subreq
;
2561 struct cli_negprot_state
*state
;
2562 uint8_t *bytes
= NULL
;
2565 req
= tevent_req_create(mem_ctx
, &state
, struct cli_negprot_state
);
2571 if (cli_state_protocol(cli
) < PROTOCOL_NT1
)
2572 cli
->use_spnego
= False
;
2574 /* setup the protocol strings */
2575 for (numprots
=0; numprots
< ARRAY_SIZE(prots
); numprots
++) {
2577 if (prots
[numprots
].prot
> cli_state_protocol(cli
)) {
2580 bytes
= (uint8_t *)talloc_append_blob(
2581 state
, bytes
, data_blob_const(&c
, sizeof(c
)));
2582 if (tevent_req_nomem(bytes
, req
)) {
2583 return tevent_req_post(req
, ev
);
2585 bytes
= smb_bytes_push_str(bytes
, false,
2586 prots
[numprots
].name
,
2587 strlen(prots
[numprots
].name
)+1,
2589 if (tevent_req_nomem(bytes
, req
)) {
2590 return tevent_req_post(req
, ev
);
2594 subreq
= cli_smb_send(state
, ev
, cli
, SMBnegprot
, 0, 0, NULL
,
2595 talloc_get_size(bytes
), bytes
);
2597 if (tevent_req_nomem(subreq
, req
)) {
2598 return tevent_req_post(req
, ev
);
2600 tevent_req_set_callback(subreq
, cli_negprot_done
, req
);
2604 static void cli_negprot_done(struct tevent_req
*subreq
)
2606 struct tevent_req
*req
= tevent_req_callback_data(
2607 subreq
, struct tevent_req
);
2608 struct cli_negprot_state
*state
= tevent_req_data(
2609 req
, struct cli_negprot_state
);
2610 struct cli_state
*cli
= state
->cli
;
2619 status
= cli_smb_recv(subreq
, state
, &inbuf
, 1, &wct
, &vwv
,
2620 &num_bytes
, &bytes
);
2621 TALLOC_FREE(subreq
);
2622 if (!NT_STATUS_IS_OK(status
)) {
2623 tevent_req_nterror(req
, status
);
2627 protnum
= SVAL(vwv
, 0);
2629 if ((protnum
>= ARRAY_SIZE(prots
))
2630 || (prots
[protnum
].prot
> cli_state_protocol(cli
))) {
2631 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
2635 cli
->protocol
= prots
[protnum
].prot
;
2637 if ((cli_state_protocol(cli
) < PROTOCOL_NT1
) &&
2638 client_is_signing_mandatory(cli
)) {
2639 DEBUG(0,("cli_negprot: SMB signing is mandatory and the selected protocol level doesn't support it.\n"));
2640 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
2644 if (cli_state_protocol(cli
) >= PROTOCOL_NT1
) {
2646 bool negotiated_smb_signing
= false;
2649 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
2654 cli
->sec_mode
= CVAL(vwv
+ 1, 0);
2655 cli
->max_mux
= SVAL(vwv
+ 1, 1);
2656 cli
->max_xmit
= IVAL(vwv
+ 3, 1);
2657 cli
->sesskey
= IVAL(vwv
+ 7, 1);
2658 cli
->serverzone
= SVALS(vwv
+ 15, 1);
2659 cli
->serverzone
*= 60;
2660 /* this time arrives in real GMT */
2661 ts
= interpret_long_date(((char *)(vwv
+11))+1);
2662 cli
->servertime
= ts
.tv_sec
;
2663 cli
->secblob
= data_blob(bytes
, num_bytes
);
2664 cli
->capabilities
= IVAL(vwv
+ 9, 1);
2665 if (cli_state_capabilities(cli
) & CAP_RAW_MODE
) {
2666 cli
->readbraw_supported
= True
;
2667 cli
->writebraw_supported
= True
;
2669 /* work out if they sent us a workgroup */
2670 if (!(cli_state_capabilities(cli
) & CAP_EXTENDED_SECURITY
) &&
2671 smb_buflen(inbuf
) > 8) {
2673 status
= smb_bytes_talloc_string(
2674 cli
, (char *)inbuf
, &cli
->server_domain
,
2675 bytes
+ 8, num_bytes
- 8, &ret
);
2676 if (tevent_req_nterror(req
, status
)) {
2682 * As signing is slow we only turn it on if either the client or
2683 * the server require it. JRA.
2686 if (cli
->sec_mode
& NEGOTIATE_SECURITY_SIGNATURES_REQUIRED
) {
2687 /* Fail if server says signing is mandatory and we don't want to support it. */
2688 if (!client_is_signing_allowed(cli
)) {
2689 DEBUG(0,("cli_negprot: SMB signing is mandatory and we have disabled it.\n"));
2690 tevent_req_nterror(req
,
2691 NT_STATUS_ACCESS_DENIED
);
2694 negotiated_smb_signing
= true;
2695 } else if (client_is_signing_mandatory(cli
) && client_is_signing_allowed(cli
)) {
2696 /* Fail if client says signing is mandatory and the server doesn't support it. */
2697 if (!(cli
->sec_mode
& NEGOTIATE_SECURITY_SIGNATURES_ENABLED
)) {
2698 DEBUG(1,("cli_negprot: SMB signing is mandatory and the server doesn't support it.\n"));
2699 tevent_req_nterror(req
,
2700 NT_STATUS_ACCESS_DENIED
);
2703 negotiated_smb_signing
= true;
2704 } else if (cli
->sec_mode
& NEGOTIATE_SECURITY_SIGNATURES_ENABLED
) {
2705 negotiated_smb_signing
= true;
2708 if (negotiated_smb_signing
) {
2709 cli_set_signing_negotiated(cli
);
2712 } else if (cli_state_protocol(cli
) >= PROTOCOL_LANMAN1
) {
2714 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
2718 cli
->use_spnego
= False
;
2719 cli
->sec_mode
= SVAL(vwv
+ 1, 0);
2720 cli
->max_xmit
= SVAL(vwv
+ 2, 0);
2721 cli
->max_mux
= SVAL(vwv
+ 3, 0);
2722 cli
->sesskey
= IVAL(vwv
+ 6, 0);
2723 cli
->serverzone
= SVALS(vwv
+ 10, 0);
2724 cli
->serverzone
*= 60;
2725 /* this time is converted to GMT by make_unix_date */
2726 cli
->servertime
= make_unix_date(
2727 (char *)(vwv
+ 8), cli
->serverzone
);
2728 cli
->readbraw_supported
= ((SVAL(vwv
+ 5, 0) & 0x1) != 0);
2729 cli
->writebraw_supported
= ((SVAL(vwv
+ 5, 0) & 0x2) != 0);
2730 cli
->secblob
= data_blob(bytes
, num_bytes
);
2732 /* the old core protocol */
2733 cli
->use_spnego
= False
;
2735 cli
->serverzone
= get_time_zone(time(NULL
));
2736 cli
->max_xmit
= 1024;
2740 if (cli
->max_xmit
< 1024) {
2741 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
2745 if (cli
->max_mux
< 1) {
2746 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
2750 cli
->max_xmit
= MIN(cli
->max_xmit
, CLI_BUFFER_SIZE
);
2752 /* a way to force ascii SMB */
2753 if (cli
->force_ascii
) {
2754 cli
->capabilities
&= ~CAP_UNICODE
;
2757 tevent_req_done(req
);
2760 NTSTATUS
cli_negprot_recv(struct tevent_req
*req
)
2762 return tevent_req_simple_recv_ntstatus(req
);
2765 NTSTATUS
cli_negprot(struct cli_state
*cli
)
2767 TALLOC_CTX
*frame
= talloc_stackframe();
2768 struct event_context
*ev
;
2769 struct tevent_req
*req
;
2770 NTSTATUS status
= NT_STATUS_OK
;
2772 if (cli_has_async_calls(cli
)) {
2774 * Can't use sync call while an async call is in flight
2776 status
= NT_STATUS_INVALID_PARAMETER
;
2780 ev
= event_context_init(frame
);
2782 status
= NT_STATUS_NO_MEMORY
;
2786 req
= cli_negprot_send(frame
, ev
, cli
);
2788 status
= NT_STATUS_NO_MEMORY
;
2792 if (!tevent_req_poll(req
, ev
)) {
2793 status
= map_nt_error_from_unix(errno
);
2797 status
= cli_negprot_recv(req
);
2803 static NTSTATUS
cli_connect_sock(const char *host
, int name_type
,
2804 const struct sockaddr_storage
*pss
,
2805 const char *myname
, uint16_t port
,
2806 int sec_timeout
, int *pfd
, uint16_t *pport
)
2808 TALLOC_CTX
*frame
= talloc_stackframe();
2810 unsigned int i
, num_addrs
;
2811 const char **called_names
;
2812 const char **calling_names
;
2817 prog
= getenv("LIBSMB_PROG");
2819 fd
= sock_exec(prog
);
2821 return map_nt_error_from_unix(errno
);
2827 if ((pss
== NULL
) || is_zero_addr(pss
)) {
2828 struct sockaddr_storage
*addrs
;
2829 status
= resolve_name_list(talloc_tos(), host
, name_type
,
2830 &addrs
, &num_addrs
);
2831 if (!NT_STATUS_IS_OK(status
)) {
2839 called_names
= talloc_array(talloc_tos(), const char *, num_addrs
);
2840 if (called_names
== NULL
) {
2841 status
= NT_STATUS_NO_MEMORY
;
2844 called_types
= talloc_array(talloc_tos(), int, num_addrs
);
2845 if (called_types
== NULL
) {
2846 status
= NT_STATUS_NO_MEMORY
;
2849 calling_names
= talloc_array(talloc_tos(), const char *, num_addrs
);
2850 if (calling_names
== NULL
) {
2851 status
= NT_STATUS_NO_MEMORY
;
2854 for (i
=0; i
<num_addrs
; i
++) {
2855 called_names
[i
] = host
;
2856 called_types
[i
] = name_type
;
2857 calling_names
[i
] = myname
;
2859 status
= smbsock_any_connect(pss
, called_names
, called_types
,
2860 calling_names
, NULL
, num_addrs
, port
,
2861 sec_timeout
, &fd
, NULL
, &port
);
2862 if (!NT_STATUS_IS_OK(status
)) {
2865 set_socket_options(fd
, lp_socket_options());
2869 status
= NT_STATUS_OK
;
2875 NTSTATUS
cli_connect_nb(const char *host
, const struct sockaddr_storage
*dest_ss
,
2876 uint16_t port
, int name_type
, const char *myname
,
2877 int signing_state
, int flags
, struct cli_state
**pcli
)
2879 TALLOC_CTX
*frame
= talloc_stackframe();
2880 struct cli_state
*cli
;
2881 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2886 desthost
= talloc_strdup(talloc_tos(), host
);
2887 if (desthost
== NULL
) {
2891 p
= strchr(host
, '#');
2893 name_type
= strtol(p
+1, NULL
, 16);
2894 host
= talloc_strndup(talloc_tos(), host
, p
- host
);
2900 status
= cli_connect_sock(host
, name_type
, dest_ss
, myname
, port
,
2902 if (!NT_STATUS_IS_OK(status
)) {
2906 cli
= cli_state_create(NULL
, fd
, desthost
, NULL
, signing_state
, flags
);
2912 status
= NT_STATUS_OK
;
2919 establishes a connection to after the negprot.
2920 @param output_cli A fully initialised cli structure, non-null only on success
2921 @param dest_host The netbios name of the remote host
2922 @param dest_ss (optional) The the destination IP, NULL for name based lookup
2923 @param port (optional) The destination port (0 for default)
2925 NTSTATUS
cli_start_connection(struct cli_state
**output_cli
,
2926 const char *my_name
,
2927 const char *dest_host
,
2928 const struct sockaddr_storage
*dest_ss
, int port
,
2929 int signing_state
, int flags
)
2932 struct cli_state
*cli
;
2934 nt_status
= cli_connect_nb(dest_host
, dest_ss
, port
, 0x20, my_name
,
2935 signing_state
, flags
, &cli
);
2936 if (!NT_STATUS_IS_OK(nt_status
)) {
2937 DEBUG(10, ("cli_connect_nb failed: %s\n",
2938 nt_errstr(nt_status
)));
2942 nt_status
= cli_negprot(cli
);
2943 if (!NT_STATUS_IS_OK(nt_status
)) {
2944 DEBUG(1, ("failed negprot: %s\n", nt_errstr(nt_status
)));
2950 return NT_STATUS_OK
;
2955 establishes a connection right up to doing tconX, password specified.
2956 @param output_cli A fully initialised cli structure, non-null only on success
2957 @param dest_host The netbios name of the remote host
2958 @param dest_ip (optional) The the destination IP, NULL for name based lookup
2959 @param port (optional) The destination port (0 for default)
2960 @param service (optional) The share to make the connection to. Should be 'unqualified' in any way.
2961 @param service_type The 'type' of serivice.
2962 @param user Username, unix string
2963 @param domain User's domain
2964 @param password User's password, unencrypted unix string.
2967 NTSTATUS
cli_full_connection(struct cli_state
**output_cli
,
2968 const char *my_name
,
2969 const char *dest_host
,
2970 const struct sockaddr_storage
*dest_ss
, int port
,
2971 const char *service
, const char *service_type
,
2972 const char *user
, const char *domain
,
2973 const char *password
, int flags
,
2977 struct cli_state
*cli
= NULL
;
2978 int pw_len
= password
? strlen(password
)+1 : 0;
2982 if (password
== NULL
) {
2986 nt_status
= cli_start_connection(&cli
, my_name
, dest_host
,
2987 dest_ss
, port
, signing_state
,
2990 if (!NT_STATUS_IS_OK(nt_status
)) {
2994 nt_status
= cli_session_setup(cli
, user
, password
, pw_len
, password
,
2996 if (!NT_STATUS_IS_OK(nt_status
)) {
2998 if (!(flags
& CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK
)) {
2999 DEBUG(1,("failed session setup with %s\n",
3000 nt_errstr(nt_status
)));
3005 nt_status
= cli_session_setup(cli
, "", "", 0, "", 0, domain
);
3006 if (!NT_STATUS_IS_OK(nt_status
)) {
3007 DEBUG(1,("anonymous failed session setup with %s\n",
3008 nt_errstr(nt_status
)));
3015 nt_status
= cli_tcon_andx(cli
, service
, service_type
, password
,
3017 if (!NT_STATUS_IS_OK(nt_status
)) {
3018 DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status
)));
3020 if (NT_STATUS_IS_OK(nt_status
)) {
3021 nt_status
= NT_STATUS_UNSUCCESSFUL
;
3027 nt_status
= cli_init_creds(cli
, user
, domain
, password
);
3028 if (!NT_STATUS_IS_OK(nt_status
)) {
3034 return NT_STATUS_OK
;
3037 /****************************************************************************
3038 Send an old style tcon.
3039 ****************************************************************************/
3040 NTSTATUS
cli_raw_tcon(struct cli_state
*cli
,
3041 const char *service
, const char *pass
, const char *dev
,
3042 uint16
*max_xmit
, uint16
*tid
)
3044 struct tevent_req
*req
;
3049 if (!lp_client_plaintext_auth() && (*pass
)) {
3050 DEBUG(1, ("Server requested plaintext password but 'client "
3051 "plaintext auth' is disabled\n"));
3052 return NT_STATUS_ACCESS_DENIED
;
3055 bytes
= talloc_array(talloc_tos(), uint8_t, 0);
3056 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
3057 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
),
3058 service
, strlen(service
)+1, NULL
);
3059 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
3060 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
),
3061 pass
, strlen(pass
)+1, NULL
);
3062 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
3063 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
),
3064 dev
, strlen(dev
)+1, NULL
);
3066 status
= cli_smb(talloc_tos(), cli
, SMBtcon
, 0, 0, NULL
,
3067 talloc_get_size(bytes
), bytes
, &req
,
3068 2, NULL
, &ret_vwv
, NULL
, NULL
);
3069 if (!NT_STATUS_IS_OK(status
)) {
3073 *max_xmit
= SVAL(ret_vwv
+ 0, 0);
3074 *tid
= SVAL(ret_vwv
+ 1, 0);
3076 return NT_STATUS_OK
;
3079 /* Return a cli_state pointing at the IPC$ share for the given server */
3081 struct cli_state
*get_ipc_connect(char *server
,
3082 struct sockaddr_storage
*server_ss
,
3083 const struct user_auth_info
*user_info
)
3085 struct cli_state
*cli
;
3087 uint32_t flags
= CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK
;
3089 if (user_info
->use_kerberos
) {
3090 flags
|= CLI_FULL_CONNECTION_USE_KERBEROS
;
3093 nt_status
= cli_full_connection(&cli
, NULL
, server
, server_ss
, 0, "IPC$", "IPC",
3094 user_info
->username
? user_info
->username
: "",
3096 user_info
->password
? user_info
->password
: "",
3100 if (NT_STATUS_IS_OK(nt_status
)) {
3102 } else if (is_ipaddress(server
)) {
3103 /* windows 9* needs a correct NMB name for connections */
3104 fstring remote_name
;
3106 if (name_status_find("*", 0, 0, server_ss
, remote_name
)) {
3107 cli
= get_ipc_connect(remote_name
, server_ss
, user_info
);
3116 * Given the IP address of a master browser on the network, return its
3117 * workgroup and connect to it.
3119 * This function is provided to allow additional processing beyond what
3120 * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
3121 * browsers and obtain each master browsers' list of domains (in case the
3122 * first master browser is recently on the network and has not yet
3123 * synchronized with other master browsers and therefore does not yet have the
3124 * entire network browse list)
3127 struct cli_state
*get_ipc_connect_master_ip(TALLOC_CTX
*ctx
,
3128 struct sockaddr_storage
*mb_ip
,
3129 const struct user_auth_info
*user_info
,
3130 char **pp_workgroup_out
)
3132 char addr
[INET6_ADDRSTRLEN
];
3134 struct cli_state
*cli
;
3135 struct sockaddr_storage server_ss
;
3137 *pp_workgroup_out
= NULL
;
3139 print_sockaddr(addr
, sizeof(addr
), mb_ip
);
3140 DEBUG(99, ("Looking up name of master browser %s\n",
3144 * Do a name status query to find out the name of the master browser.
3145 * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
3146 * master browser will not respond to a wildcard query (or, at least,
3147 * an NT4 server acting as the domain master browser will not).
3149 * We might be able to use ONLY the query on MSBROWSE, but that's not
3150 * yet been tested with all Windows versions, so until it is, leave
3151 * the original wildcard query as the first choice and fall back to
3152 * MSBROWSE if the wildcard query fails.
3154 if (!name_status_find("*", 0, 0x1d, mb_ip
, name
) &&
3155 !name_status_find(MSBROWSE
, 1, 0x1d, mb_ip
, name
)) {
3157 DEBUG(99, ("Could not retrieve name status for %s\n",
3162 if (!find_master_ip(name
, &server_ss
)) {
3163 DEBUG(99, ("Could not find master ip for %s\n", name
));
3167 *pp_workgroup_out
= talloc_strdup(ctx
, name
);
3169 DEBUG(4, ("found master browser %s, %s\n", name
, addr
));
3171 print_sockaddr(addr
, sizeof(addr
), &server_ss
);
3172 cli
= get_ipc_connect(addr
, &server_ss
, user_info
);
3178 * Return the IP address and workgroup of a master browser on the network, and
3182 struct cli_state
*get_ipc_connect_master_ip_bcast(TALLOC_CTX
*ctx
,
3183 const struct user_auth_info
*user_info
,
3184 char **pp_workgroup_out
)
3186 struct sockaddr_storage
*ip_list
;
3187 struct cli_state
*cli
;
3191 *pp_workgroup_out
= NULL
;
3193 DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
3195 /* Go looking for workgroups by broadcasting on the local network */
3197 status
= name_resolve_bcast(MSBROWSE
, 1, talloc_tos(),
3199 if (!NT_STATUS_IS_OK(status
)) {
3200 DEBUG(99, ("No master browsers responded: %s\n",
3201 nt_errstr(status
)));
3205 for (i
= 0; i
< count
; i
++) {
3206 char addr
[INET6_ADDRSTRLEN
];
3207 print_sockaddr(addr
, sizeof(addr
), &ip_list
[i
]);
3208 DEBUG(99, ("Found master browser %s\n", addr
));
3210 cli
= get_ipc_connect_master_ip(ctx
, &ip_list
[i
],
3211 user_info
, pp_workgroup_out
);