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"
40 {PROTOCOL_CORE
, "PC NETWORK PROGRAM 1.0"},
41 {PROTOCOL_COREPLUS
, "MICROSOFT NETWORKS 1.03"},
42 {PROTOCOL_LANMAN1
, "MICROSOFT NETWORKS 3.0"},
43 {PROTOCOL_LANMAN1
, "LANMAN1.0"},
44 {PROTOCOL_LANMAN2
, "LM1.2X002"},
45 {PROTOCOL_LANMAN2
, "DOS LANMAN2.1"},
46 {PROTOCOL_LANMAN2
, "LANMAN2.1"},
47 {PROTOCOL_LANMAN2
, "Samba"},
48 {PROTOCOL_NT1
, "NT LANMAN 1.0"},
49 {PROTOCOL_NT1
, "NT LM 0.12"},
52 #define STAR_SMBSERVER "*SMBSERVER"
54 /********************************************************
55 Utility function to ensure we always return at least
56 a valid char * pointer to an empty string for the
57 cli->server_os, cli->server_type and cli->server_domain
59 *******************************************************/
61 static NTSTATUS
smb_bytes_talloc_string(struct cli_state
*cli
,
68 *destlen
= clistr_pull_talloc(cli
,
70 SVAL(inbuf
, smb_flg2
),
76 return NT_STATUS_NO_MEMORY
;
80 *dest
= talloc_strdup(cli
, "");
82 return NT_STATUS_NO_MEMORY
;
89 * Set the user session key for a connection
90 * @param cli The cli structure to add it too
91 * @param session_key The session key used. (A copy of this is taken for the cli struct)
95 static void cli_set_session_key (struct cli_state
*cli
, const DATA_BLOB session_key
)
97 cli
->user_session_key
= data_blob(session_key
.data
, session_key
.length
);
100 /****************************************************************************
101 Do an old lanman2 style session setup.
102 ****************************************************************************/
104 struct cli_session_setup_lanman2_state
{
105 struct cli_state
*cli
;
110 static void cli_session_setup_lanman2_done(struct tevent_req
*subreq
);
112 static struct tevent_req
*cli_session_setup_lanman2_send(
113 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
114 struct cli_state
*cli
, const char *user
,
115 const char *pass
, size_t passlen
,
116 const char *workgroup
)
118 struct tevent_req
*req
, *subreq
;
119 struct cli_session_setup_lanman2_state
*state
;
120 DATA_BLOB lm_response
= data_blob_null
;
125 req
= tevent_req_create(mem_ctx
, &state
,
126 struct cli_session_setup_lanman2_state
);
135 * LANMAN servers predate NT status codes and Unicode and
136 * ignore those smb flags so we must disable the corresponding
137 * default capabilities that would otherwise cause the Unicode
138 * and NT Status flags to be set (and even returned by the
142 cli
->capabilities
&= ~(CAP_UNICODE
| CAP_STATUS32
);
145 * if in share level security then don't send a password now
147 if (!(cli
->sec_mode
& NEGOTIATE_SECURITY_USER_LEVEL
)) {
152 && (cli
->sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
)
155 * Encrypted mode needed, and non encrypted password
158 lm_response
= data_blob(NULL
, 24);
159 if (tevent_req_nomem(lm_response
.data
, req
)) {
160 return tevent_req_post(req
, ev
);
163 if (!SMBencrypt(pass
, cli
->secblob
.data
,
164 (uint8_t *)lm_response
.data
)) {
165 DEBUG(1, ("Password is > 14 chars in length, and is "
166 "therefore incompatible with Lanman "
167 "authentication\n"));
168 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
169 return tevent_req_post(req
, ev
);
171 } else if ((cli
->sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
)
174 * Encrypted mode needed, and encrypted password
177 lm_response
= data_blob(pass
, passlen
);
178 if (tevent_req_nomem(lm_response
.data
, req
)) {
179 return tevent_req_post(req
, ev
);
181 } else if (passlen
> 0) {
183 size_t converted_size
;
185 * Plaintext mode needed, assume plaintext supplied.
187 buf
= talloc_array(talloc_tos(), uint8_t, 0);
188 buf
= smb_bytes_push_str(buf
, cli_ucs2(cli
), pass
, passlen
+1,
190 if (tevent_req_nomem(buf
, req
)) {
191 return tevent_req_post(req
, ev
);
193 lm_response
= data_blob(pass
, passlen
);
195 if (tevent_req_nomem(lm_response
.data
, req
)) {
196 return tevent_req_post(req
, ev
);
200 SCVAL(vwv
+0, 0, 0xff);
203 SSVAL(vwv
+2, 0, CLI_BUFFER_SIZE
);
206 SIVAL(vwv
+5, 0, cli
->sesskey
);
207 SSVAL(vwv
+7, 0, lm_response
.length
);
209 bytes
= talloc_array(state
, uint8_t, lm_response
.length
);
210 if (tevent_req_nomem(bytes
, req
)) {
211 return tevent_req_post(req
, ev
);
213 if (lm_response
.length
!= 0) {
214 memcpy(bytes
, lm_response
.data
, lm_response
.length
);
216 data_blob_free(&lm_response
);
218 tmp
= talloc_strdup_upper(talloc_tos(), user
);
219 if (tevent_req_nomem(tmp
, req
)) {
220 return tevent_req_post(req
, ev
);
222 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), tmp
, strlen(tmp
)+1,
226 tmp
= talloc_strdup_upper(talloc_tos(), workgroup
);
227 if (tevent_req_nomem(tmp
, req
)) {
228 return tevent_req_post(req
, ev
);
230 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), tmp
, strlen(tmp
)+1,
232 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), "Unix", 5, NULL
);
233 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), "Samba", 6, NULL
);
235 if (tevent_req_nomem(bytes
, req
)) {
236 return tevent_req_post(req
, ev
);
239 subreq
= cli_smb_send(state
, ev
, cli
, SMBsesssetupX
, 0, 10, vwv
,
240 talloc_get_size(bytes
), bytes
);
241 if (tevent_req_nomem(subreq
, req
)) {
242 return tevent_req_post(req
, ev
);
244 tevent_req_set_callback(subreq
, cli_session_setup_lanman2_done
, req
);
248 static void cli_session_setup_lanman2_done(struct tevent_req
*subreq
)
250 struct tevent_req
*req
= tevent_req_callback_data(
251 subreq
, struct tevent_req
);
252 struct cli_session_setup_lanman2_state
*state
= tevent_req_data(
253 req
, struct cli_session_setup_lanman2_state
);
254 struct cli_state
*cli
= state
->cli
;
265 status
= cli_smb_recv(subreq
, state
, &in
, 3, &wct
, &vwv
,
268 if (!NT_STATUS_IS_OK(status
)) {
269 tevent_req_nterror(req
, status
);
276 cli
->vuid
= SVAL(inbuf
, smb_uid
);
277 cli
->is_guestlogin
= ((SVAL(vwv
+2, 0) & 1) != 0);
279 status
= smb_bytes_talloc_string(cli
,
286 if (!NT_STATUS_IS_OK(status
)) {
287 tevent_req_nterror(req
, status
);
292 status
= smb_bytes_talloc_string(cli
,
299 if (!NT_STATUS_IS_OK(status
)) {
300 tevent_req_nterror(req
, status
);
305 status
= smb_bytes_talloc_string(cli
,
312 if (!NT_STATUS_IS_OK(status
)) {
313 tevent_req_nterror(req
, status
);
318 if (strstr(cli
->server_type
, "Samba")) {
319 cli
->is_samba
= True
;
321 status
= cli_set_username(cli
, state
->user
);
322 if (tevent_req_nterror(req
, status
)) {
325 tevent_req_done(req
);
328 static NTSTATUS
cli_session_setup_lanman2_recv(struct tevent_req
*req
)
330 return tevent_req_simple_recv_ntstatus(req
);
333 static NTSTATUS
cli_session_setup_lanman2(struct cli_state
*cli
, const char *user
,
334 const char *pass
, size_t passlen
,
335 const char *workgroup
)
337 TALLOC_CTX
*frame
= talloc_stackframe();
338 struct event_context
*ev
;
339 struct tevent_req
*req
;
340 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
342 if (cli_has_async_calls(cli
)) {
344 * Can't use sync call while an async call is in flight
346 status
= NT_STATUS_INVALID_PARAMETER
;
349 ev
= event_context_init(frame
);
353 req
= cli_session_setup_lanman2_send(frame
, ev
, cli
, user
, pass
, passlen
,
358 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
361 status
= cli_session_setup_lanman2_recv(req
);
364 if (!NT_STATUS_IS_OK(status
)) {
365 cli_set_error(cli
, status
);
370 /****************************************************************************
371 Work out suitable capabilities to offer the server.
372 ****************************************************************************/
374 static uint32
cli_session_setup_capabilities(struct cli_state
*cli
)
376 uint32 capabilities
= CAP_NT_SMBS
;
378 if (!cli
->force_dos_errors
)
379 capabilities
|= CAP_STATUS32
;
381 if (cli
->use_level_II_oplocks
)
382 capabilities
|= CAP_LEVEL_II_OPLOCKS
;
384 capabilities
|= (cli
->capabilities
& (CAP_UNICODE
|CAP_LARGE_FILES
|CAP_LARGE_READX
|CAP_LARGE_WRITEX
|CAP_DFS
));
388 /****************************************************************************
389 Do a NT1 guest session setup.
390 ****************************************************************************/
392 struct cli_session_setup_guest_state
{
393 struct cli_state
*cli
;
398 static void cli_session_setup_guest_done(struct tevent_req
*subreq
);
400 struct tevent_req
*cli_session_setup_guest_create(TALLOC_CTX
*mem_ctx
,
401 struct event_context
*ev
,
402 struct cli_state
*cli
,
403 struct tevent_req
**psmbreq
)
405 struct tevent_req
*req
, *subreq
;
406 struct cli_session_setup_guest_state
*state
;
410 req
= tevent_req_create(mem_ctx
, &state
,
411 struct cli_session_setup_guest_state
);
418 SCVAL(vwv
+0, 0, 0xFF);
421 SSVAL(vwv
+2, 0, CLI_BUFFER_SIZE
);
423 SSVAL(vwv
+4, 0, cli
->pid
);
424 SIVAL(vwv
+5, 0, cli
->sesskey
);
429 SIVAL(vwv
+11, 0, cli_session_setup_capabilities(cli
));
431 bytes
= talloc_array(state
, uint8_t, 0);
433 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), "", 1, /* username */
435 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), "", 1, /* workgroup */
437 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), "Unix", 5, NULL
);
438 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), "Samba", 6, NULL
);
445 state
->bytes
.iov_base
= (void *)bytes
;
446 state
->bytes
.iov_len
= talloc_get_size(bytes
);
448 subreq
= cli_smb_req_create(state
, ev
, cli
, SMBsesssetupX
, 0, 13, vwv
,
450 if (subreq
== NULL
) {
454 tevent_req_set_callback(subreq
, cli_session_setup_guest_done
, req
);
459 struct tevent_req
*cli_session_setup_guest_send(TALLOC_CTX
*mem_ctx
,
460 struct event_context
*ev
,
461 struct cli_state
*cli
)
463 struct tevent_req
*req
, *subreq
;
466 req
= cli_session_setup_guest_create(mem_ctx
, ev
, cli
, &subreq
);
471 status
= cli_smb_req_send(subreq
);
472 if (NT_STATUS_IS_OK(status
)) {
473 tevent_req_nterror(req
, status
);
474 return tevent_req_post(req
, ev
);
479 static void cli_session_setup_guest_done(struct tevent_req
*subreq
)
481 struct tevent_req
*req
= tevent_req_callback_data(
482 subreq
, struct tevent_req
);
483 struct cli_session_setup_guest_state
*state
= tevent_req_data(
484 req
, struct cli_session_setup_guest_state
);
485 struct cli_state
*cli
= state
->cli
;
496 status
= cli_smb_recv(subreq
, state
, &in
, 3, &wct
, &vwv
,
499 if (!NT_STATUS_IS_OK(status
)) {
500 tevent_req_nterror(req
, status
);
507 cli
->vuid
= SVAL(inbuf
, smb_uid
);
508 cli
->is_guestlogin
= ((SVAL(vwv
+2, 0) & 1) != 0);
510 status
= smb_bytes_talloc_string(cli
,
517 if (!NT_STATUS_IS_OK(status
)) {
518 tevent_req_nterror(req
, status
);
523 status
= smb_bytes_talloc_string(cli
,
530 if (!NT_STATUS_IS_OK(status
)) {
531 tevent_req_nterror(req
, status
);
536 status
= smb_bytes_talloc_string(cli
,
543 if (!NT_STATUS_IS_OK(status
)) {
544 tevent_req_nterror(req
, status
);
549 if (strstr(cli
->server_type
, "Samba")) {
550 cli
->is_samba
= True
;
553 status
= cli_set_username(cli
, "");
554 if (!NT_STATUS_IS_OK(status
)) {
555 tevent_req_nterror(req
, status
);
558 tevent_req_done(req
);
561 NTSTATUS
cli_session_setup_guest_recv(struct tevent_req
*req
)
563 return tevent_req_simple_recv_ntstatus(req
);
566 static NTSTATUS
cli_session_setup_guest(struct cli_state
*cli
)
568 TALLOC_CTX
*frame
= talloc_stackframe();
569 struct event_context
*ev
;
570 struct tevent_req
*req
;
571 NTSTATUS status
= NT_STATUS_OK
;
573 if (cli_has_async_calls(cli
)) {
575 * Can't use sync call while an async call is in flight
577 status
= NT_STATUS_INVALID_PARAMETER
;
581 ev
= event_context_init(frame
);
583 status
= NT_STATUS_NO_MEMORY
;
587 req
= cli_session_setup_guest_send(frame
, ev
, cli
);
589 status
= NT_STATUS_NO_MEMORY
;
593 if (!tevent_req_poll(req
, ev
)) {
594 status
= map_nt_error_from_unix(errno
);
598 status
= cli_session_setup_guest_recv(req
);
601 if (!NT_STATUS_IS_OK(status
)) {
602 cli_set_error(cli
, status
);
607 /****************************************************************************
608 Do a NT1 plaintext session setup.
609 ****************************************************************************/
611 struct cli_session_setup_plain_state
{
612 struct cli_state
*cli
;
617 static void cli_session_setup_plain_done(struct tevent_req
*subreq
);
619 static struct tevent_req
*cli_session_setup_plain_send(
620 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
621 struct cli_state
*cli
,
622 const char *user
, const char *pass
, const char *workgroup
)
624 struct tevent_req
*req
, *subreq
;
625 struct cli_session_setup_plain_state
*state
;
631 req
= tevent_req_create(mem_ctx
, &state
,
632 struct cli_session_setup_plain_state
);
640 SCVAL(vwv
+0, 0, 0xff);
643 SSVAL(vwv
+2, 0, CLI_BUFFER_SIZE
);
645 SSVAL(vwv
+4, 0, cli
->pid
);
646 SIVAL(vwv
+5, 0, cli
->sesskey
);
651 SIVAL(vwv
+11, 0, cli_session_setup_capabilities(cli
));
653 bytes
= talloc_array(state
, uint8_t, 0);
654 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), pass
, strlen(pass
)+1,
656 if (tevent_req_nomem(bytes
, req
)) {
657 return tevent_req_post(req
, ev
);
659 SSVAL(vwv
+ (cli_ucs2(cli
) ? 8 : 7), 0, passlen
);
661 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
),
662 user
, strlen(user
)+1, NULL
);
663 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
),
664 workgroup
, strlen(workgroup
)+1, NULL
);
665 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
),
668 version
= talloc_asprintf(talloc_tos(), "Samba %s",
669 samba_version_string());
670 if (tevent_req_nomem(version
, req
)){
671 return tevent_req_post(req
, ev
);
673 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
),
674 version
, strlen(version
)+1, NULL
);
675 TALLOC_FREE(version
);
677 if (tevent_req_nomem(bytes
, req
)) {
678 return tevent_req_post(req
, ev
);
681 subreq
= cli_smb_send(state
, ev
, cli
, SMBsesssetupX
, 0, 13, vwv
,
682 talloc_get_size(bytes
), bytes
);
683 if (tevent_req_nomem(subreq
, req
)) {
684 return tevent_req_post(req
, ev
);
686 tevent_req_set_callback(subreq
, cli_session_setup_plain_done
, req
);
690 static void cli_session_setup_plain_done(struct tevent_req
*subreq
)
692 struct tevent_req
*req
= tevent_req_callback_data(
693 subreq
, struct tevent_req
);
694 struct cli_session_setup_plain_state
*state
= tevent_req_data(
695 req
, struct cli_session_setup_plain_state
);
696 struct cli_state
*cli
= state
->cli
;
707 status
= cli_smb_recv(subreq
, state
, &in
, 3, &wct
, &vwv
,
710 if (tevent_req_nterror(req
, status
)) {
717 cli
->vuid
= SVAL(inbuf
, smb_uid
);
718 cli
->is_guestlogin
= ((SVAL(vwv
+2, 0) & 1) != 0);
720 status
= smb_bytes_talloc_string(cli
,
727 if (!NT_STATUS_IS_OK(status
)) {
728 tevent_req_nterror(req
, status
);
733 status
= smb_bytes_talloc_string(cli
,
740 if (!NT_STATUS_IS_OK(status
)) {
741 tevent_req_nterror(req
, status
);
746 status
= smb_bytes_talloc_string(cli
,
753 if (!NT_STATUS_IS_OK(status
)) {
754 tevent_req_nterror(req
, status
);
759 status
= cli_set_username(cli
, state
->user
);
760 if (tevent_req_nterror(req
, status
)) {
763 if (strstr(cli
->server_type
, "Samba")) {
764 cli
->is_samba
= True
;
766 tevent_req_done(req
);
769 static NTSTATUS
cli_session_setup_plain_recv(struct tevent_req
*req
)
771 return tevent_req_simple_recv_ntstatus(req
);
774 static NTSTATUS
cli_session_setup_plain(struct cli_state
*cli
,
775 const char *user
, const char *pass
,
776 const char *workgroup
)
778 TALLOC_CTX
*frame
= talloc_stackframe();
779 struct event_context
*ev
;
780 struct tevent_req
*req
;
781 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
783 if (cli_has_async_calls(cli
)) {
785 * Can't use sync call while an async call is in flight
787 status
= NT_STATUS_INVALID_PARAMETER
;
790 ev
= event_context_init(frame
);
794 req
= cli_session_setup_plain_send(frame
, ev
, cli
, user
, pass
,
799 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
802 status
= cli_session_setup_plain_recv(req
);
805 if (!NT_STATUS_IS_OK(status
)) {
806 cli_set_error(cli
, status
);
811 /****************************************************************************
812 do a NT1 NTLM/LM encrypted session setup - for when extended security
814 @param cli client state to create do session setup on
816 @param pass *either* cleartext password (passlen !=24) or LM response.
817 @param ntpass NT response, implies ntpasslen >=24, implies pass is not clear
818 @param workgroup The user's domain.
819 ****************************************************************************/
821 struct cli_session_setup_nt1_state
{
822 struct cli_state
*cli
;
825 DATA_BLOB session_key
;
829 static void cli_session_setup_nt1_done(struct tevent_req
*subreq
);
831 static struct tevent_req
*cli_session_setup_nt1_send(
832 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
833 struct cli_state
*cli
, const char *user
,
834 const char *pass
, size_t passlen
,
835 const char *ntpass
, size_t ntpasslen
,
836 const char *workgroup
)
838 struct tevent_req
*req
, *subreq
;
839 struct cli_session_setup_nt1_state
*state
;
840 DATA_BLOB lm_response
= data_blob_null
;
841 DATA_BLOB nt_response
= data_blob_null
;
842 DATA_BLOB session_key
= data_blob_null
;
845 char *workgroup_upper
;
847 req
= tevent_req_create(mem_ctx
, &state
,
848 struct cli_session_setup_nt1_state
);
857 /* do nothing - guest login */
858 } else if (passlen
!= 24) {
859 if (lp_client_ntlmv2_auth()) {
860 DATA_BLOB server_chal
;
861 DATA_BLOB names_blob
;
863 server_chal
= data_blob(cli
->secblob
.data
,
864 MIN(cli
->secblob
.length
, 8));
865 if (tevent_req_nomem(server_chal
.data
, req
)) {
866 return tevent_req_post(req
, ev
);
870 * note that the 'workgroup' here is a best
871 * guess - we don't know the server's domain
872 * at this point. The 'server name' is also
875 names_blob
= NTLMv2_generate_names_blob(
876 NULL
, cli
->called
.name
, workgroup
);
878 if (tevent_req_nomem(names_blob
.data
, req
)) {
879 return tevent_req_post(req
, ev
);
882 if (!SMBNTLMv2encrypt(NULL
, user
, workgroup
, pass
,
883 &server_chal
, &names_blob
,
884 &lm_response
, &nt_response
,
885 NULL
, &session_key
)) {
886 data_blob_free(&names_blob
);
887 data_blob_free(&server_chal
);
889 req
, NT_STATUS_ACCESS_DENIED
);
890 return tevent_req_post(req
, ev
);
892 data_blob_free(&names_blob
);
893 data_blob_free(&server_chal
);
897 E_md4hash(pass
, nt_hash
);
900 nt_response
= data_blob_null
;
902 nt_response
= data_blob(NULL
, 24);
903 if (tevent_req_nomem(nt_response
.data
, req
)) {
904 return tevent_req_post(req
, ev
);
907 SMBNTencrypt(pass
, cli
->secblob
.data
,
910 /* non encrypted password supplied. Ignore ntpass. */
911 if (lp_client_lanman_auth()) {
913 lm_response
= data_blob(NULL
, 24);
914 if (tevent_req_nomem(lm_response
.data
, req
)) {
915 return tevent_req_post(req
, ev
);
918 if (!SMBencrypt(pass
,cli
->secblob
.data
,
921 * Oops, the LM response is
922 * invalid, just put the NT
923 * response there instead
925 data_blob_free(&lm_response
);
926 lm_response
= data_blob(
932 * LM disabled, place NT# in LM field
935 lm_response
= data_blob(
936 nt_response
.data
, nt_response
.length
);
939 if (tevent_req_nomem(lm_response
.data
, req
)) {
940 return tevent_req_post(req
, ev
);
943 session_key
= data_blob(NULL
, 16);
944 if (tevent_req_nomem(session_key
.data
, req
)) {
945 return tevent_req_post(req
, ev
);
948 E_deshash(pass
, session_key
.data
);
949 memset(&session_key
.data
[8], '\0', 8);
951 SMBsesskeygen_ntv1(nt_hash
, session_key
.data
);
954 cli_temp_set_signing(cli
);
956 /* pre-encrypted password supplied. Only used for
957 security=server, can't do
958 signing because we don't have original key */
960 lm_response
= data_blob(pass
, passlen
);
961 if (tevent_req_nomem(lm_response
.data
, req
)) {
962 return tevent_req_post(req
, ev
);
965 nt_response
= data_blob(ntpass
, ntpasslen
);
966 if (tevent_req_nomem(nt_response
.data
, req
)) {
967 return tevent_req_post(req
, ev
);
972 state
->response
= data_blob_talloc(
973 state
, lm_response
.data
, lm_response
.length
);
975 state
->response
= data_blob_talloc(
976 state
, nt_response
.data
, nt_response
.length
);
978 if (tevent_req_nomem(state
->response
.data
, req
)) {
979 return tevent_req_post(req
, ev
);
982 if (session_key
.data
) {
983 state
->session_key
= data_blob_talloc(
984 state
, session_key
.data
, session_key
.length
);
985 if (tevent_req_nomem(state
->session_key
.data
, req
)) {
986 return tevent_req_post(req
, ev
);
989 data_blob_free(&session_key
);
991 SCVAL(vwv
+0, 0, 0xff);
994 SSVAL(vwv
+2, 0, CLI_BUFFER_SIZE
);
996 SSVAL(vwv
+4, 0, cli
->pid
);
997 SIVAL(vwv
+5, 0, cli
->sesskey
);
998 SSVAL(vwv
+7, 0, lm_response
.length
);
999 SSVAL(vwv
+8, 0, nt_response
.length
);
1001 SSVAL(vwv
+10, 0, 0);
1002 SIVAL(vwv
+11, 0, cli_session_setup_capabilities(cli
));
1004 bytes
= talloc_array(state
, uint8_t,
1005 lm_response
.length
+ nt_response
.length
);
1006 if (tevent_req_nomem(bytes
, req
)) {
1007 return tevent_req_post(req
, ev
);
1009 if (lm_response
.length
!= 0) {
1010 memcpy(bytes
, lm_response
.data
, lm_response
.length
);
1012 if (nt_response
.length
!= 0) {
1013 memcpy(bytes
+ lm_response
.length
,
1014 nt_response
.data
, nt_response
.length
);
1016 data_blob_free(&lm_response
);
1017 data_blob_free(&nt_response
);
1019 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
),
1020 user
, strlen(user
)+1, NULL
);
1023 * Upper case here might help some NTLMv2 implementations
1025 workgroup_upper
= talloc_strdup_upper(talloc_tos(), workgroup
);
1026 if (tevent_req_nomem(workgroup_upper
, req
)) {
1027 return tevent_req_post(req
, ev
);
1029 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
),
1030 workgroup_upper
, strlen(workgroup_upper
)+1,
1032 TALLOC_FREE(workgroup_upper
);
1034 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), "Unix", 5, NULL
);
1035 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), "Samba", 6, NULL
);
1036 if (tevent_req_nomem(bytes
, req
)) {
1037 return tevent_req_post(req
, ev
);
1040 subreq
= cli_smb_send(state
, ev
, cli
, SMBsesssetupX
, 0, 13, vwv
,
1041 talloc_get_size(bytes
), bytes
);
1042 if (tevent_req_nomem(subreq
, req
)) {
1043 return tevent_req_post(req
, ev
);
1045 tevent_req_set_callback(subreq
, cli_session_setup_nt1_done
, req
);
1049 static void cli_session_setup_nt1_done(struct tevent_req
*subreq
)
1051 struct tevent_req
*req
= tevent_req_callback_data(
1052 subreq
, struct tevent_req
);
1053 struct cli_session_setup_nt1_state
*state
= tevent_req_data(
1054 req
, struct cli_session_setup_nt1_state
);
1055 struct cli_state
*cli
= state
->cli
;
1066 status
= cli_smb_recv(subreq
, state
, &in
, 3, &wct
, &vwv
,
1067 &num_bytes
, &bytes
);
1068 TALLOC_FREE(subreq
);
1069 if (!NT_STATUS_IS_OK(status
)) {
1070 tevent_req_nterror(req
, status
);
1077 cli
->vuid
= SVAL(inbuf
, smb_uid
);
1078 cli
->is_guestlogin
= ((SVAL(vwv
+2, 0) & 1) != 0);
1080 status
= smb_bytes_talloc_string(cli
,
1086 if (!NT_STATUS_IS_OK(status
)) {
1087 tevent_req_nterror(req
, status
);
1092 status
= smb_bytes_talloc_string(cli
,
1098 if (!NT_STATUS_IS_OK(status
)) {
1099 tevent_req_nterror(req
, status
);
1104 status
= smb_bytes_talloc_string(cli
,
1106 &cli
->server_domain
,
1110 if (!NT_STATUS_IS_OK(status
)) {
1111 tevent_req_nterror(req
, status
);
1116 if (strstr(cli
->server_type
, "Samba")) {
1117 cli
->is_samba
= True
;
1120 status
= cli_set_username(cli
, state
->user
);
1121 if (tevent_req_nterror(req
, status
)) {
1124 if (cli_simple_set_signing(cli
, state
->session_key
, state
->response
)
1125 && !cli_check_sign_mac(cli
, (char *)in
, 1)) {
1126 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1129 if (state
->session_key
.data
) {
1130 /* Have plaintext orginal */
1131 cli_set_session_key(cli
, state
->session_key
);
1133 tevent_req_done(req
);
1136 static NTSTATUS
cli_session_setup_nt1_recv(struct tevent_req
*req
)
1138 return tevent_req_simple_recv_ntstatus(req
);
1141 static NTSTATUS
cli_session_setup_nt1(struct cli_state
*cli
, const char *user
,
1142 const char *pass
, size_t passlen
,
1143 const char *ntpass
, size_t ntpasslen
,
1144 const char *workgroup
)
1146 TALLOC_CTX
*frame
= talloc_stackframe();
1147 struct event_context
*ev
;
1148 struct tevent_req
*req
;
1149 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
1151 if (cli_has_async_calls(cli
)) {
1153 * Can't use sync call while an async call is in flight
1155 status
= NT_STATUS_INVALID_PARAMETER
;
1158 ev
= event_context_init(frame
);
1162 req
= cli_session_setup_nt1_send(frame
, ev
, cli
, user
, pass
, passlen
,
1163 ntpass
, ntpasslen
, workgroup
);
1167 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
1170 status
= cli_session_setup_nt1_recv(req
);
1173 if (!NT_STATUS_IS_OK(status
)) {
1174 cli_set_error(cli
, status
);
1179 /* The following is calculated from :
1181 * (smb_wcnt * 2) = 24 (smb_wcnt == 12 in cli_session_setup_blob_send() )
1182 * (strlen("Unix") + 1 + strlen("Samba") + 1) * 2 = 22 (unicode strings at
1186 #define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22)
1188 struct cli_sesssetup_blob_state
{
1189 struct tevent_context
*ev
;
1190 struct cli_state
*cli
;
1192 uint16_t max_blob_size
;
1201 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state
*state
,
1202 struct tevent_req
**psubreq
);
1203 static void cli_sesssetup_blob_done(struct tevent_req
*subreq
);
1205 static struct tevent_req
*cli_sesssetup_blob_send(TALLOC_CTX
*mem_ctx
,
1206 struct tevent_context
*ev
,
1207 struct cli_state
*cli
,
1210 struct tevent_req
*req
, *subreq
;
1211 struct cli_sesssetup_blob_state
*state
;
1213 req
= tevent_req_create(mem_ctx
, &state
,
1214 struct cli_sesssetup_blob_state
);
1222 if (cli
->max_xmit
< BASE_SESSSETUP_BLOB_PACKET_SIZE
+ 1) {
1223 DEBUG(1, ("cli_session_setup_blob: cli->max_xmit too small "
1224 "(was %u, need minimum %u)\n",
1225 (unsigned int)cli
->max_xmit
,
1226 BASE_SESSSETUP_BLOB_PACKET_SIZE
));
1227 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1228 return tevent_req_post(req
, ev
);
1230 state
->max_blob_size
=
1231 MIN(cli
->max_xmit
- BASE_SESSSETUP_BLOB_PACKET_SIZE
, 0xFFFF);
1233 if (!cli_sesssetup_blob_next(state
, &subreq
)) {
1234 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
1235 return tevent_req_post(req
, ev
);
1237 tevent_req_set_callback(subreq
, cli_sesssetup_blob_done
, req
);
1241 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state
*state
,
1242 struct tevent_req
**psubreq
)
1244 struct tevent_req
*subreq
;
1247 SCVAL(state
->vwv
+0, 0, 0xFF);
1248 SCVAL(state
->vwv
+0, 1, 0);
1249 SSVAL(state
->vwv
+1, 0, 0);
1250 SSVAL(state
->vwv
+2, 0, CLI_BUFFER_SIZE
);
1251 SSVAL(state
->vwv
+3, 0, 2);
1252 SSVAL(state
->vwv
+4, 0, 1);
1253 SIVAL(state
->vwv
+5, 0, 0);
1255 thistime
= MIN(state
->blob
.length
, state
->max_blob_size
);
1256 SSVAL(state
->vwv
+7, 0, thistime
);
1258 SSVAL(state
->vwv
+8, 0, 0);
1259 SSVAL(state
->vwv
+9, 0, 0);
1260 SIVAL(state
->vwv
+10, 0,
1261 cli_session_setup_capabilities(state
->cli
)
1262 | CAP_EXTENDED_SECURITY
);
1264 state
->buf
= (uint8_t *)talloc_memdup(state
, state
->blob
.data
,
1266 if (state
->buf
== NULL
) {
1269 state
->blob
.data
+= thistime
;
1270 state
->blob
.length
-= thistime
;
1272 state
->buf
= smb_bytes_push_str(state
->buf
, cli_ucs2(state
->cli
),
1274 state
->buf
= smb_bytes_push_str(state
->buf
, cli_ucs2(state
->cli
),
1276 if (state
->buf
== NULL
) {
1279 subreq
= cli_smb_send(state
, state
->ev
, state
->cli
, SMBsesssetupX
, 0,
1281 talloc_get_size(state
->buf
), state
->buf
);
1282 if (subreq
== NULL
) {
1289 static void cli_sesssetup_blob_done(struct tevent_req
*subreq
)
1291 struct tevent_req
*req
= tevent_req_callback_data(
1292 subreq
, struct tevent_req
);
1293 struct cli_sesssetup_blob_state
*state
= tevent_req_data(
1294 req
, struct cli_sesssetup_blob_state
);
1295 struct cli_state
*cli
= state
->cli
;
1302 uint16_t blob_length
;
1306 status
= cli_smb_recv(subreq
, state
, &inbuf
, 4, &wct
, &vwv
,
1307 &num_bytes
, &bytes
);
1308 TALLOC_FREE(subreq
);
1309 if (!NT_STATUS_IS_OK(status
)
1310 && !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1311 tevent_req_nterror(req
, status
);
1315 state
->status
= status
;
1316 TALLOC_FREE(state
->buf
);
1318 state
->inbuf
= (char *)inbuf
;
1319 cli
->vuid
= SVAL(state
->inbuf
, smb_uid
);
1320 cli
->is_guestlogin
= ((SVAL(vwv
+2, 0) & 1) != 0);
1322 blob_length
= SVAL(vwv
+3, 0);
1323 if (blob_length
> num_bytes
) {
1324 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
1327 state
->ret_blob
= data_blob_const(bytes
, blob_length
);
1329 p
= bytes
+ blob_length
;
1331 status
= smb_bytes_talloc_string(cli
,
1338 if (!NT_STATUS_IS_OK(status
)) {
1339 tevent_req_nterror(req
, status
);
1344 status
= smb_bytes_talloc_string(cli
,
1351 if (!NT_STATUS_IS_OK(status
)) {
1352 tevent_req_nterror(req
, status
);
1357 status
= smb_bytes_talloc_string(cli
,
1359 &cli
->server_domain
,
1364 if (!NT_STATUS_IS_OK(status
)) {
1365 tevent_req_nterror(req
, status
);
1370 if (strstr(cli
->server_type
, "Samba")) {
1371 cli
->is_samba
= True
;
1374 if (state
->blob
.length
!= 0) {
1378 if (!cli_sesssetup_blob_next(state
, &subreq
)) {
1379 tevent_req_nomem(NULL
, req
);
1382 tevent_req_set_callback(subreq
, cli_sesssetup_blob_done
, req
);
1385 tevent_req_done(req
);
1388 static NTSTATUS
cli_sesssetup_blob_recv(struct tevent_req
*req
,
1389 TALLOC_CTX
*mem_ctx
,
1393 struct cli_sesssetup_blob_state
*state
= tevent_req_data(
1394 req
, struct cli_sesssetup_blob_state
);
1398 if (tevent_req_is_nterror(req
, &status
)) {
1399 state
->cli
->vuid
= 0;
1403 inbuf
= talloc_move(mem_ctx
, &state
->inbuf
);
1404 if (pblob
!= NULL
) {
1405 *pblob
= state
->ret_blob
;
1407 if (pinbuf
!= NULL
) {
1410 /* could be NT_STATUS_MORE_PROCESSING_REQUIRED */
1411 return state
->status
;
1416 /****************************************************************************
1417 Use in-memory credentials cache
1418 ****************************************************************************/
1420 static void use_in_memory_ccache(void) {
1421 setenv(KRB5_ENV_CCNAME
, "MEMORY:cliconnect", 1);
1424 /****************************************************************************
1425 Do a spnego/kerberos encrypted session setup.
1426 ****************************************************************************/
1428 struct cli_session_setup_kerberos_state
{
1429 struct cli_state
*cli
;
1430 DATA_BLOB negTokenTarg
;
1431 DATA_BLOB session_key_krb5
;
1432 ADS_STATUS ads_status
;
1435 static void cli_session_setup_kerberos_done(struct tevent_req
*subreq
);
1437 static struct tevent_req
*cli_session_setup_kerberos_send(
1438 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
1439 const char *principal
, const char *workgroup
)
1441 struct tevent_req
*req
, *subreq
;
1442 struct cli_session_setup_kerberos_state
*state
;
1445 DEBUG(2,("Doing kerberos session setup\n"));
1447 req
= tevent_req_create(mem_ctx
, &state
,
1448 struct cli_session_setup_kerberos_state
);
1453 state
->ads_status
= ADS_SUCCESS
;
1455 cli_temp_set_signing(cli
);
1458 * Ok, this is cheating: spnego_gen_krb5_negTokenInit can block if
1459 * we have to acquire a ticket. To be fixed later :-)
1461 rc
= spnego_gen_krb5_negTokenInit(state
, principal
, 0, &state
->negTokenTarg
,
1462 &state
->session_key_krb5
, 0, NULL
);
1464 DEBUG(1, ("cli_session_setup_kerberos: "
1465 "spnego_gen_krb5_negTokenInit failed: %s\n",
1466 error_message(rc
)));
1467 state
->ads_status
= ADS_ERROR_KRB5(rc
);
1468 tevent_req_nterror(req
, NT_STATUS_UNSUCCESSFUL
);
1469 return tevent_req_post(req
, ev
);
1473 file_save("negTokenTarg.dat", state
->negTokenTarg
.data
,
1474 state
->negTokenTarg
.length
);
1477 subreq
= cli_sesssetup_blob_send(state
, ev
, cli
, state
->negTokenTarg
);
1478 if (tevent_req_nomem(subreq
, req
)) {
1479 return tevent_req_post(req
, ev
);
1481 tevent_req_set_callback(subreq
, cli_session_setup_kerberos_done
, req
);
1485 static void cli_session_setup_kerberos_done(struct tevent_req
*subreq
)
1487 struct tevent_req
*req
= tevent_req_callback_data(
1488 subreq
, struct tevent_req
);
1489 struct cli_session_setup_kerberos_state
*state
= tevent_req_data(
1490 req
, struct cli_session_setup_kerberos_state
);
1494 status
= cli_sesssetup_blob_recv(subreq
, talloc_tos(), NULL
, &inbuf
);
1495 if (!NT_STATUS_IS_OK(status
)) {
1496 TALLOC_FREE(subreq
);
1497 tevent_req_nterror(req
, status
);
1501 cli_set_session_key(state
->cli
, state
->session_key_krb5
);
1503 if (cli_simple_set_signing(state
->cli
, state
->session_key_krb5
,
1505 && !cli_check_sign_mac(state
->cli
, inbuf
, 1)) {
1506 TALLOC_FREE(subreq
);
1507 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1510 TALLOC_FREE(subreq
);
1511 tevent_req_done(req
);
1514 static ADS_STATUS
cli_session_setup_kerberos_recv(struct tevent_req
*req
)
1516 struct cli_session_setup_kerberos_state
*state
= tevent_req_data(
1517 req
, struct cli_session_setup_kerberos_state
);
1520 if (tevent_req_is_nterror(req
, &status
)) {
1521 return ADS_ERROR_NT(status
);
1523 return state
->ads_status
;
1526 static ADS_STATUS
cli_session_setup_kerberos(struct cli_state
*cli
,
1527 const char *principal
,
1528 const char *workgroup
)
1530 struct tevent_context
*ev
;
1531 struct tevent_req
*req
;
1532 ADS_STATUS status
= ADS_ERROR_NT(NT_STATUS_NO_MEMORY
);
1534 if (cli_has_async_calls(cli
)) {
1535 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
1537 ev
= tevent_context_init(talloc_tos());
1541 req
= cli_session_setup_kerberos_send(ev
, ev
, cli
, principal
,
1546 if (!tevent_req_poll(req
, ev
)) {
1547 status
= ADS_ERROR_SYSTEM(errno
);
1550 status
= cli_session_setup_kerberos_recv(req
);
1555 #endif /* HAVE_KRB5 */
1557 /****************************************************************************
1558 Do a spnego/NTLMSSP encrypted session setup.
1559 ****************************************************************************/
1561 struct cli_session_setup_ntlmssp_state
{
1562 struct tevent_context
*ev
;
1563 struct cli_state
*cli
;
1564 struct ntlmssp_state
*ntlmssp_state
;
1569 static int cli_session_setup_ntlmssp_state_destructor(
1570 struct cli_session_setup_ntlmssp_state
*state
)
1572 if (state
->ntlmssp_state
!= NULL
) {
1573 TALLOC_FREE(state
->ntlmssp_state
);
1578 static void cli_session_setup_ntlmssp_done(struct tevent_req
*req
);
1580 static struct tevent_req
*cli_session_setup_ntlmssp_send(
1581 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
1582 const char *user
, const char *pass
, const char *domain
)
1584 struct tevent_req
*req
, *subreq
;
1585 struct cli_session_setup_ntlmssp_state
*state
;
1588 const char *OIDs_ntlm
[] = {OID_NTLMSSP
, NULL
};
1590 req
= tevent_req_create(mem_ctx
, &state
,
1591 struct cli_session_setup_ntlmssp_state
);
1599 state
->ntlmssp_state
= NULL
;
1600 talloc_set_destructor(
1601 state
, cli_session_setup_ntlmssp_state_destructor
);
1603 cli_temp_set_signing(cli
);
1605 status
= ntlmssp_client_start(state
,
1608 lp_client_ntlmv2_auth(),
1609 &state
->ntlmssp_state
);
1610 if (!NT_STATUS_IS_OK(status
)) {
1613 ntlmssp_want_feature(state
->ntlmssp_state
,
1614 NTLMSSP_FEATURE_SESSION_KEY
);
1615 if (cli
->use_ccache
) {
1616 ntlmssp_want_feature(state
->ntlmssp_state
,
1617 NTLMSSP_FEATURE_CCACHE
);
1619 status
= ntlmssp_set_username(state
->ntlmssp_state
, user
);
1620 if (!NT_STATUS_IS_OK(status
)) {
1623 status
= ntlmssp_set_domain(state
->ntlmssp_state
, domain
);
1624 if (!NT_STATUS_IS_OK(status
)) {
1627 status
= ntlmssp_set_password(state
->ntlmssp_state
, pass
);
1628 if (!NT_STATUS_IS_OK(status
)) {
1631 status
= ntlmssp_update(state
->ntlmssp_state
, data_blob_null
,
1633 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1637 state
->blob_out
= spnego_gen_negTokenInit(state
, OIDs_ntlm
, &blob_out
, NULL
);
1638 data_blob_free(&blob_out
);
1640 subreq
= cli_sesssetup_blob_send(state
, ev
, cli
, state
->blob_out
);
1641 if (tevent_req_nomem(subreq
, req
)) {
1642 return tevent_req_post(req
, ev
);
1644 tevent_req_set_callback(subreq
, cli_session_setup_ntlmssp_done
, req
);
1647 tevent_req_nterror(req
, status
);
1648 return tevent_req_post(req
, ev
);
1651 static void cli_session_setup_ntlmssp_done(struct tevent_req
*subreq
)
1653 struct tevent_req
*req
= tevent_req_callback_data(
1654 subreq
, struct tevent_req
);
1655 struct cli_session_setup_ntlmssp_state
*state
= tevent_req_data(
1656 req
, struct cli_session_setup_ntlmssp_state
);
1657 DATA_BLOB blob_in
, msg_in
, blob_out
;
1662 status
= cli_sesssetup_blob_recv(subreq
, talloc_tos(), &blob_in
,
1664 TALLOC_FREE(subreq
);
1665 data_blob_free(&state
->blob_out
);
1667 if (NT_STATUS_IS_OK(status
)) {
1668 if (state
->cli
->server_domain
[0] == '\0') {
1669 TALLOC_FREE(state
->cli
->server_domain
);
1670 state
->cli
->server_domain
= talloc_strdup(state
->cli
,
1671 state
->ntlmssp_state
->server
.netbios_domain
);
1672 if (state
->cli
->server_domain
== NULL
) {
1673 TALLOC_FREE(subreq
);
1674 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
1678 cli_set_session_key(
1679 state
->cli
, state
->ntlmssp_state
->session_key
);
1681 if (cli_simple_set_signing(
1682 state
->cli
, state
->ntlmssp_state
->session_key
,
1684 && !cli_check_sign_mac(state
->cli
, inbuf
, 1)) {
1685 TALLOC_FREE(subreq
);
1686 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1689 TALLOC_FREE(subreq
);
1690 TALLOC_FREE(state
->ntlmssp_state
);
1691 tevent_req_done(req
);
1694 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1695 tevent_req_nterror(req
, status
);
1699 if (blob_in
.length
== 0) {
1700 tevent_req_nterror(req
, NT_STATUS_UNSUCCESSFUL
);
1704 if ((state
->turn
== 1)
1705 && NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1706 DATA_BLOB tmp_blob
= data_blob_null
;
1707 /* the server might give us back two challenges */
1708 parse_ret
= spnego_parse_challenge(state
, blob_in
, &msg_in
,
1710 data_blob_free(&tmp_blob
);
1712 parse_ret
= spnego_parse_auth_response(state
, blob_in
, status
,
1713 OID_NTLMSSP
, &msg_in
);
1718 DEBUG(3,("Failed to parse auth response\n"));
1719 if (NT_STATUS_IS_OK(status
)
1720 || NT_STATUS_EQUAL(status
,
1721 NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1723 req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
1728 status
= ntlmssp_update(state
->ntlmssp_state
, msg_in
, &blob_out
);
1730 if (!NT_STATUS_IS_OK(status
)
1731 && !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1732 TALLOC_FREE(subreq
);
1733 TALLOC_FREE(state
->ntlmssp_state
);
1734 tevent_req_nterror(req
, status
);
1738 state
->blob_out
= spnego_gen_auth(state
, blob_out
);
1739 TALLOC_FREE(subreq
);
1740 if (tevent_req_nomem(state
->blob_out
.data
, req
)) {
1744 subreq
= cli_sesssetup_blob_send(state
, state
->ev
, state
->cli
,
1746 if (tevent_req_nomem(subreq
, req
)) {
1749 tevent_req_set_callback(subreq
, cli_session_setup_ntlmssp_done
, req
);
1752 static NTSTATUS
cli_session_setup_ntlmssp_recv(struct tevent_req
*req
)
1754 struct cli_session_setup_ntlmssp_state
*state
= tevent_req_data(
1755 req
, struct cli_session_setup_ntlmssp_state
);
1758 if (tevent_req_is_nterror(req
, &status
)) {
1759 state
->cli
->vuid
= 0;
1762 return NT_STATUS_OK
;
1765 static NTSTATUS
cli_session_setup_ntlmssp(struct cli_state
*cli
,
1770 struct tevent_context
*ev
;
1771 struct tevent_req
*req
;
1772 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
1774 if (cli_has_async_calls(cli
)) {
1775 return NT_STATUS_INVALID_PARAMETER
;
1777 ev
= tevent_context_init(talloc_tos());
1781 req
= cli_session_setup_ntlmssp_send(ev
, ev
, cli
, user
, pass
, domain
);
1785 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
1788 status
= cli_session_setup_ntlmssp_recv(req
);
1791 if (!NT_STATUS_IS_OK(status
)) {
1792 cli_set_error(cli
, status
);
1797 /****************************************************************************
1798 Do a spnego encrypted session setup.
1800 user_domain: The shortname of the domain the user/machine is a member of.
1801 dest_realm: The realm we're connecting to, if NULL we use our default realm.
1802 ****************************************************************************/
1804 ADS_STATUS
cli_session_setup_spnego(struct cli_state
*cli
, const char *user
,
1805 const char *pass
, const char *user_domain
,
1806 const char * dest_realm
)
1808 char *principal
= NULL
;
1809 char *OIDs
[ASN1_MAX_OIDS
];
1812 const char *p
= NULL
;
1813 char *account
= NULL
;
1816 DEBUG(3,("Doing spnego session setup (blob length=%lu)\n", (unsigned long)cli
->secblob
.length
));
1818 /* the server might not even do spnego */
1819 if (cli
->secblob
.length
<= 16) {
1820 DEBUG(3,("server didn't supply a full spnego negprot\n"));
1825 file_save("negprot.dat", cli
->secblob
.data
, cli
->secblob
.length
);
1828 /* there is 16 bytes of GUID before the real spnego packet starts */
1829 blob
= data_blob(cli
->secblob
.data
+16, cli
->secblob
.length
-16);
1831 /* The server sent us the first part of the SPNEGO exchange in the
1832 * negprot reply. It is WRONG to depend on the principal sent in the
1833 * negprot reply, but right now we do it. If we don't receive one,
1834 * we try to best guess, then fall back to NTLM. */
1835 if (!spnego_parse_negTokenInit(talloc_tos(), blob
, OIDs
, &principal
, NULL
) ||
1837 data_blob_free(&blob
);
1838 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
1840 data_blob_free(&blob
);
1842 /* make sure the server understands kerberos */
1843 for (i
=0;OIDs
[i
];i
++) {
1845 DEBUG(3,("got OID=%s\n", OIDs
[i
]));
1847 DEBUGADD(3,("got OID=%s\n", OIDs
[i
]));
1848 if (strcmp(OIDs
[i
], OID_KERBEROS5_OLD
) == 0 ||
1849 strcmp(OIDs
[i
], OID_KERBEROS5
) == 0) {
1850 cli
->got_kerberos_mechanism
= True
;
1852 talloc_free(OIDs
[i
]);
1855 DEBUG(3,("got principal=%s\n", principal
? principal
: "<null>"));
1857 status
= cli_set_username(cli
, user
);
1858 if (!NT_STATUS_IS_OK(status
)) {
1859 TALLOC_FREE(principal
);
1860 return ADS_ERROR_NT(status
);
1864 /* If password is set we reauthenticate to kerberos server
1865 * and do not store results */
1867 if (cli
->got_kerberos_mechanism
&& cli
->use_kerberos
) {
1870 if (pass
&& *pass
) {
1873 use_in_memory_ccache();
1874 ret
= kerberos_kinit_password(user
, pass
, 0 /* no time correction for now */, NULL
);
1877 TALLOC_FREE(principal
);
1878 DEBUG(0, ("Kinit failed: %s\n", error_message(ret
)));
1879 if (cli
->fallback_after_kerberos
)
1881 return ADS_ERROR_KRB5(ret
);
1885 /* We may not be allowed to use the server-supplied SPNEGO principal, or it may not have been supplied to us
1887 if (!lp_client_use_spnego_principal() || strequal(principal
, ADS_IGNORE_PRINCIPAL
)) {
1888 TALLOC_FREE(principal
);
1891 if (principal
== NULL
&&
1892 !is_ipaddress(cli
->desthost
) &&
1893 !strequal(STAR_SMBSERVER
,
1897 DEBUG(3,("cli_session_setup_spnego: using target "
1898 "hostname not SPNEGO principal\n"));
1900 host
= strchr_m(cli
->desthost
, '.');
1902 realm
= SMB_STRDUP(dest_realm
);
1904 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY
);
1910 realm
= kerberos_get_realm_from_hostname(cli
->desthost
);
1912 /* NetBIOS name - use our realm. */
1913 realm
= kerberos_get_default_realm_from_ccache();
1917 if (realm
== NULL
|| *realm
== '\0') {
1918 realm
= SMB_STRDUP(lp_realm());
1920 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY
);
1923 DEBUG(3,("cli_session_setup_spnego: cannot "
1924 "get realm from dest_realm %s, "
1925 "desthost %s. Using default "
1926 "smb.conf realm %s\n",
1927 dest_realm
? dest_realm
: "<null>",
1932 principal
= talloc_asprintf(talloc_tos(),
1938 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY
);
1940 DEBUG(3,("cli_session_setup_spnego: guessed "
1941 "server principal=%s\n",
1942 principal
? principal
: "<null>"));
1948 rc
= cli_session_setup_kerberos(cli
, principal
,
1950 if (ADS_ERR_OK(rc
) || !cli
->fallback_after_kerberos
) {
1951 TALLOC_FREE(principal
);
1958 TALLOC_FREE(principal
);
1962 account
= talloc_strdup(talloc_tos(), user
);
1964 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY
);
1967 /* when falling back to ntlmssp while authenticating with a machine
1968 * account strip off the realm - gd */
1970 if ((p
= strchr_m(user
, '@')) != NULL
) {
1971 account
[PTR_DIFF(p
,user
)] = '\0';
1974 return ADS_ERROR_NT(cli_session_setup_ntlmssp(cli
, account
, pass
, user_domain
));
1977 /****************************************************************************
1978 Send a session setup. The username and workgroup is in UNIX character
1979 format and must be converted to DOS codepage format before sending. If the
1980 password is in plaintext, the same should be done.
1981 ****************************************************************************/
1983 NTSTATUS
cli_session_setup(struct cli_state
*cli
,
1985 const char *pass
, int passlen
,
1986 const char *ntpass
, int ntpasslen
,
1987 const char *workgroup
)
1993 user2
= talloc_strdup(talloc_tos(), user
);
1995 user2
= talloc_strdup(talloc_tos(), "");
1997 if (user2
== NULL
) {
1998 return NT_STATUS_NO_MEMORY
;
2005 /* allow for workgroups as part of the username */
2006 if ((p
=strchr_m(user2
,'\\')) || (p
=strchr_m(user2
,'/')) ||
2007 (p
=strchr_m(user2
,*lp_winbind_separator()))) {
2014 if (cli
->protocol
< PROTOCOL_LANMAN1
) {
2015 return NT_STATUS_OK
;
2018 /* now work out what sort of session setup we are going to
2019 do. I have split this into separate functions to make the
2020 flow a bit easier to understand (tridge) */
2022 /* if its an older server then we have to use the older request format */
2024 if (cli
->protocol
< PROTOCOL_NT1
) {
2025 if (!lp_client_lanman_auth() && passlen
!= 24 && (*pass
)) {
2026 DEBUG(1, ("Server requested LM password but 'client lanman auth = no'"
2027 " or 'client ntlmv2 auth = yes'\n"));
2028 return NT_STATUS_ACCESS_DENIED
;
2031 if ((cli
->sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
) == 0 &&
2032 !lp_client_plaintext_auth() && (*pass
)) {
2033 DEBUG(1, ("Server requested LM password but 'client plaintext auth = no'"
2034 " or 'client ntlmv2 auth = yes'\n"));
2035 return NT_STATUS_ACCESS_DENIED
;
2038 return cli_session_setup_lanman2(cli
, user
, pass
, passlen
,
2042 /* if no user is supplied then we have to do an anonymous connection.
2043 passwords are ignored */
2045 if (!user
|| !*user
)
2046 return cli_session_setup_guest(cli
);
2048 /* if the server is share level then send a plaintext null
2049 password at this point. The password is sent in the tree
2052 if ((cli
->sec_mode
& NEGOTIATE_SECURITY_USER_LEVEL
) == 0)
2053 return cli_session_setup_plain(cli
, user
, "", workgroup
);
2055 /* if the server doesn't support encryption then we have to use
2056 plaintext. The second password is ignored */
2058 if ((cli
->sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
) == 0) {
2059 if (!lp_client_plaintext_auth() && (*pass
)) {
2060 DEBUG(1, ("Server requested LM password but 'client plaintext auth = no'"
2061 " or 'client ntlmv2 auth = yes'\n"));
2062 return NT_STATUS_ACCESS_DENIED
;
2064 return cli_session_setup_plain(cli
, user
, pass
, workgroup
);
2067 /* if the server supports extended security then use SPNEGO */
2069 if (cli
->capabilities
& CAP_EXTENDED_SECURITY
) {
2070 ADS_STATUS status
= cli_session_setup_spnego(cli
, user
, pass
,
2072 if (!ADS_ERR_OK(status
)) {
2073 DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status
)));
2074 return ads_ntstatus(status
);
2079 /* otherwise do a NT1 style session setup */
2080 status
= cli_session_setup_nt1(cli
, user
, pass
, passlen
,
2081 ntpass
, ntpasslen
, workgroup
);
2082 if (!NT_STATUS_IS_OK(status
)) {
2083 DEBUG(3,("cli_session_setup: NT1 session setup "
2084 "failed: %s\n", nt_errstr(status
)));
2089 if (strstr(cli
->server_type
, "Samba")) {
2090 cli
->is_samba
= True
;
2093 return NT_STATUS_OK
;
2096 /****************************************************************************
2098 *****************************************************************************/
2100 struct cli_ulogoff_state
{
2101 struct cli_state
*cli
;
2105 static void cli_ulogoff_done(struct tevent_req
*subreq
);
2107 struct tevent_req
*cli_ulogoff_send(TALLOC_CTX
*mem_ctx
,
2108 struct tevent_context
*ev
,
2109 struct cli_state
*cli
)
2111 struct tevent_req
*req
, *subreq
;
2112 struct cli_ulogoff_state
*state
;
2114 req
= tevent_req_create(mem_ctx
, &state
, struct cli_ulogoff_state
);
2120 SCVAL(state
->vwv
+0, 0, 0xFF);
2121 SCVAL(state
->vwv
+1, 0, 0);
2122 SSVAL(state
->vwv
+2, 0, 0);
2124 subreq
= cli_smb_send(state
, ev
, cli
, SMBulogoffX
, 0, 2, state
->vwv
,
2126 if (tevent_req_nomem(subreq
, req
)) {
2127 return tevent_req_post(req
, ev
);
2129 tevent_req_set_callback(subreq
, cli_ulogoff_done
, req
);
2133 static void cli_ulogoff_done(struct tevent_req
*subreq
)
2135 struct tevent_req
*req
= tevent_req_callback_data(
2136 subreq
, struct tevent_req
);
2137 struct cli_ulogoff_state
*state
= tevent_req_data(
2138 req
, struct cli_ulogoff_state
);
2141 status
= cli_smb_recv(subreq
, NULL
, NULL
, 0, NULL
, NULL
, NULL
, NULL
);
2142 if (!NT_STATUS_IS_OK(status
)) {
2143 tevent_req_nterror(req
, status
);
2146 state
->cli
->vuid
= -1;
2147 tevent_req_done(req
);
2150 NTSTATUS
cli_ulogoff_recv(struct tevent_req
*req
)
2152 return tevent_req_simple_recv_ntstatus(req
);
2155 NTSTATUS
cli_ulogoff(struct cli_state
*cli
)
2157 struct tevent_context
*ev
;
2158 struct tevent_req
*req
;
2159 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2161 if (cli_has_async_calls(cli
)) {
2162 return NT_STATUS_INVALID_PARAMETER
;
2164 ev
= tevent_context_init(talloc_tos());
2168 req
= cli_ulogoff_send(ev
, ev
, cli
);
2172 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2175 status
= cli_ulogoff_recv(req
);
2178 if (!NT_STATUS_IS_OK(status
)) {
2179 cli_set_error(cli
, status
);
2184 /****************************************************************************
2186 ****************************************************************************/
2188 struct cli_tcon_andx_state
{
2189 struct cli_state
*cli
;
2194 static void cli_tcon_andx_done(struct tevent_req
*subreq
);
2196 struct tevent_req
*cli_tcon_andx_create(TALLOC_CTX
*mem_ctx
,
2197 struct event_context
*ev
,
2198 struct cli_state
*cli
,
2199 const char *share
, const char *dev
,
2200 const char *pass
, int passlen
,
2201 struct tevent_req
**psmbreq
)
2203 struct tevent_req
*req
, *subreq
;
2204 struct cli_tcon_andx_state
*state
;
2212 req
= tevent_req_create(mem_ctx
, &state
, struct cli_tcon_andx_state
);
2219 cli
->share
= talloc_strdup(cli
, share
);
2224 /* in user level security don't send a password now */
2225 if (cli
->sec_mode
& NEGOTIATE_SECURITY_USER_LEVEL
) {
2228 } else if (pass
== NULL
) {
2229 DEBUG(1, ("Server not using user level security and no "
2230 "password supplied.\n"));
2234 if ((cli
->sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
) &&
2235 *pass
&& passlen
!= 24) {
2236 if (!lp_client_lanman_auth()) {
2237 DEBUG(1, ("Server requested LANMAN password "
2238 "(share-level security) but "
2239 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2244 * Non-encrypted passwords - convert to DOS codepage before
2247 SMBencrypt(pass
, cli
->secblob
.data
, p24
);
2249 pass
= (const char *)p24
;
2251 if((cli
->sec_mode
& (NEGOTIATE_SECURITY_USER_LEVEL
2252 |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
))
2256 if (!lp_client_plaintext_auth() && (*pass
)) {
2257 DEBUG(1, ("Server requested plaintext "
2259 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2264 * Non-encrypted passwords - convert to DOS codepage
2267 tmp_pass
= talloc_array(talloc_tos(), char, 128);
2268 if (tmp_pass
== NULL
) {
2269 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
2270 return tevent_req_post(req
, ev
);
2272 passlen
= clistr_push(cli
,
2275 talloc_get_size(tmp_pass
),
2277 if (passlen
== -1) {
2278 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
2279 return tevent_req_post(req
, ev
);
2285 SCVAL(vwv
+0, 0, 0xFF);
2288 SSVAL(vwv
+2, 0, TCONX_FLAG_EXTENDED_RESPONSE
);
2289 SSVAL(vwv
+3, 0, passlen
);
2291 if (passlen
&& pass
) {
2292 bytes
= (uint8_t *)talloc_memdup(state
, pass
, passlen
);
2294 bytes
= talloc_array(state
, uint8_t, 0);
2300 tmp
= talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
2301 cli
->desthost
, share
);
2306 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
), tmp
, strlen(tmp
)+1,
2311 * Add the devicetype
2313 tmp
= talloc_strdup_upper(talloc_tos(), dev
);
2318 bytes
= smb_bytes_push_str(bytes
, false, tmp
, strlen(tmp
)+1, NULL
);
2321 if (bytes
== NULL
) {
2326 state
->bytes
.iov_base
= (void *)bytes
;
2327 state
->bytes
.iov_len
= talloc_get_size(bytes
);
2329 subreq
= cli_smb_req_create(state
, ev
, cli
, SMBtconX
, 0, 4, vwv
,
2331 if (subreq
== NULL
) {
2335 tevent_req_set_callback(subreq
, cli_tcon_andx_done
, req
);
2340 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
2341 return tevent_req_post(req
, ev
);
2344 struct tevent_req
*cli_tcon_andx_send(TALLOC_CTX
*mem_ctx
,
2345 struct event_context
*ev
,
2346 struct cli_state
*cli
,
2347 const char *share
, const char *dev
,
2348 const char *pass
, int passlen
)
2350 struct tevent_req
*req
, *subreq
;
2353 req
= cli_tcon_andx_create(mem_ctx
, ev
, cli
, share
, dev
, pass
, passlen
,
2358 if (subreq
== NULL
) {
2361 status
= cli_smb_req_send(subreq
);
2362 if (!NT_STATUS_IS_OK(status
)) {
2363 tevent_req_nterror(req
, status
);
2364 return tevent_req_post(req
, ev
);
2369 static void cli_tcon_andx_done(struct tevent_req
*subreq
)
2371 struct tevent_req
*req
= tevent_req_callback_data(
2372 subreq
, struct tevent_req
);
2373 struct cli_tcon_andx_state
*state
= tevent_req_data(
2374 req
, struct cli_tcon_andx_state
);
2375 struct cli_state
*cli
= state
->cli
;
2384 status
= cli_smb_recv(subreq
, state
, &in
, 0, &wct
, &vwv
,
2385 &num_bytes
, &bytes
);
2386 TALLOC_FREE(subreq
);
2387 if (!NT_STATUS_IS_OK(status
)) {
2388 tevent_req_nterror(req
, status
);
2395 if (clistr_pull_talloc(cli
,
2397 SVAL(inbuf
, smb_flg2
),
2401 STR_TERMINATE
|STR_ASCII
) == -1) {
2402 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
2406 cli
->dev
= talloc_strdup(cli
, "");
2407 if (cli
->dev
== NULL
) {
2408 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
2413 if ((cli
->protocol
>= PROTOCOL_NT1
) && (num_bytes
== 3)) {
2414 /* almost certainly win95 - enable bug fixes */
2419 * Make sure that we have the optional support 16-bit field. WCT > 2.
2420 * Avoids issues when connecting to Win9x boxes sharing files
2423 cli
->dfsroot
= false;
2425 if ((wct
> 2) && (cli
->protocol
>= PROTOCOL_LANMAN2
)) {
2426 cli
->dfsroot
= ((SVAL(vwv
+2, 0) & SMB_SHARE_IN_DFS
) != 0);
2429 cli
->cnum
= SVAL(inbuf
,smb_tid
);
2430 tevent_req_done(req
);
2433 NTSTATUS
cli_tcon_andx_recv(struct tevent_req
*req
)
2435 return tevent_req_simple_recv_ntstatus(req
);
2438 NTSTATUS
cli_tcon_andx(struct cli_state
*cli
, const char *share
,
2439 const char *dev
, const char *pass
, int passlen
)
2441 TALLOC_CTX
*frame
= talloc_stackframe();
2442 struct event_context
*ev
;
2443 struct tevent_req
*req
;
2444 NTSTATUS status
= NT_STATUS_OK
;
2446 if (cli_has_async_calls(cli
)) {
2448 * Can't use sync call while an async call is in flight
2450 status
= NT_STATUS_INVALID_PARAMETER
;
2454 ev
= event_context_init(frame
);
2456 status
= NT_STATUS_NO_MEMORY
;
2460 req
= cli_tcon_andx_send(frame
, ev
, cli
, share
, dev
, pass
, passlen
);
2462 status
= NT_STATUS_NO_MEMORY
;
2466 if (!tevent_req_poll(req
, ev
)) {
2467 status
= map_nt_error_from_unix(errno
);
2471 status
= cli_tcon_andx_recv(req
);
2474 if (!NT_STATUS_IS_OK(status
)) {
2475 cli_set_error(cli
, status
);
2480 /****************************************************************************
2481 Send a tree disconnect.
2482 ****************************************************************************/
2484 struct cli_tdis_state
{
2485 struct cli_state
*cli
;
2488 static void cli_tdis_done(struct tevent_req
*subreq
);
2490 struct tevent_req
*cli_tdis_send(TALLOC_CTX
*mem_ctx
,
2491 struct tevent_context
*ev
,
2492 struct cli_state
*cli
)
2494 struct tevent_req
*req
, *subreq
;
2495 struct cli_tdis_state
*state
;
2497 req
= tevent_req_create(mem_ctx
, &state
, struct cli_tdis_state
);
2503 subreq
= cli_smb_send(state
, ev
, cli
, SMBtdis
, 0, 0, NULL
, 0, NULL
);
2504 if (tevent_req_nomem(subreq
, req
)) {
2505 return tevent_req_post(req
, ev
);
2507 tevent_req_set_callback(subreq
, cli_tdis_done
, req
);
2511 static void cli_tdis_done(struct tevent_req
*subreq
)
2513 struct tevent_req
*req
= tevent_req_callback_data(
2514 subreq
, struct tevent_req
);
2515 struct cli_tdis_state
*state
= tevent_req_data(
2516 req
, struct cli_tdis_state
);
2519 status
= cli_smb_recv(subreq
, NULL
, NULL
, 0, NULL
, NULL
, NULL
, NULL
);
2520 TALLOC_FREE(subreq
);
2521 if (!NT_STATUS_IS_OK(status
)) {
2522 tevent_req_nterror(req
, status
);
2525 state
->cli
->cnum
= -1;
2526 tevent_req_done(req
);
2529 NTSTATUS
cli_tdis_recv(struct tevent_req
*req
)
2531 return tevent_req_simple_recv_ntstatus(req
);
2534 NTSTATUS
cli_tdis(struct cli_state
*cli
)
2536 struct tevent_context
*ev
;
2537 struct tevent_req
*req
;
2538 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2540 if (cli_has_async_calls(cli
)) {
2541 return NT_STATUS_INVALID_PARAMETER
;
2543 ev
= tevent_context_init(talloc_tos());
2547 req
= cli_tdis_send(ev
, ev
, cli
);
2551 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2554 status
= cli_tdis_recv(req
);
2557 if (!NT_STATUS_IS_OK(status
)) {
2558 cli_set_error(cli
, status
);
2563 /****************************************************************************
2564 Send a negprot command.
2565 ****************************************************************************/
2567 struct cli_negprot_state
{
2568 struct cli_state
*cli
;
2571 static void cli_negprot_done(struct tevent_req
*subreq
);
2573 struct tevent_req
*cli_negprot_send(TALLOC_CTX
*mem_ctx
,
2574 struct event_context
*ev
,
2575 struct cli_state
*cli
)
2577 struct tevent_req
*req
, *subreq
;
2578 struct cli_negprot_state
*state
;
2579 uint8_t *bytes
= NULL
;
2583 req
= tevent_req_create(mem_ctx
, &state
, struct cli_negprot_state
);
2589 if (cli
->protocol
< PROTOCOL_NT1
)
2590 cli
->use_spnego
= False
;
2592 /* setup the protocol strings */
2593 for (numprots
=0; numprots
< ARRAY_SIZE(prots
); numprots
++) {
2595 if (prots
[numprots
].prot
> cli
->protocol
) {
2598 bytes
= (uint8_t *)talloc_append_blob(
2599 state
, bytes
, data_blob_const(&c
, sizeof(c
)));
2600 if (tevent_req_nomem(bytes
, req
)) {
2601 return tevent_req_post(req
, ev
);
2603 bytes
= smb_bytes_push_str(bytes
, false,
2604 prots
[numprots
].name
,
2605 strlen(prots
[numprots
].name
)+1,
2607 if (tevent_req_nomem(bytes
, req
)) {
2608 return tevent_req_post(req
, ev
);
2615 subreq
= cli_smb_send(state
, ev
, cli
, SMBnegprot
, 0, 0, NULL
,
2616 talloc_get_size(bytes
), bytes
);
2619 if (tevent_req_nomem(subreq
, req
)) {
2620 return tevent_req_post(req
, ev
);
2622 tevent_req_set_callback(subreq
, cli_negprot_done
, req
);
2626 static void cli_negprot_done(struct tevent_req
*subreq
)
2628 struct tevent_req
*req
= tevent_req_callback_data(
2629 subreq
, struct tevent_req
);
2630 struct cli_negprot_state
*state
= tevent_req_data(
2631 req
, struct cli_negprot_state
);
2632 struct cli_state
*cli
= state
->cli
;
2641 status
= cli_smb_recv(subreq
, state
, &inbuf
, 1, &wct
, &vwv
,
2642 &num_bytes
, &bytes
);
2643 TALLOC_FREE(subreq
);
2644 if (!NT_STATUS_IS_OK(status
)) {
2645 tevent_req_nterror(req
, status
);
2649 protnum
= SVAL(vwv
, 0);
2651 if ((protnum
>= ARRAY_SIZE(prots
))
2652 || (prots
[protnum
].prot
> cli
->protocol
)) {
2653 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
2657 cli
->protocol
= prots
[protnum
].prot
;
2659 if ((cli
->protocol
< PROTOCOL_NT1
) &&
2660 client_is_signing_mandatory(cli
)) {
2661 DEBUG(0,("cli_negprot: SMB signing is mandatory and the selected protocol level doesn't support it.\n"));
2662 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
2666 if (cli
->protocol
>= PROTOCOL_NT1
) {
2668 bool negotiated_smb_signing
= false;
2671 cli
->sec_mode
= CVAL(vwv
+ 1, 0);
2672 cli
->max_mux
= SVAL(vwv
+ 1, 1);
2673 cli
->max_xmit
= IVAL(vwv
+ 3, 1);
2674 cli
->sesskey
= IVAL(vwv
+ 7, 1);
2675 cli
->serverzone
= SVALS(vwv
+ 15, 1);
2676 cli
->serverzone
*= 60;
2677 /* this time arrives in real GMT */
2678 ts
= interpret_long_date(((char *)(vwv
+11))+1);
2679 cli
->servertime
= ts
.tv_sec
;
2680 cli
->secblob
= data_blob(bytes
, num_bytes
);
2681 cli
->capabilities
= IVAL(vwv
+ 9, 1);
2682 if (cli
->capabilities
& CAP_RAW_MODE
) {
2683 cli
->readbraw_supported
= True
;
2684 cli
->writebraw_supported
= True
;
2686 /* work out if they sent us a workgroup */
2687 if (!(cli
->capabilities
& CAP_EXTENDED_SECURITY
) &&
2688 smb_buflen(inbuf
) > 8) {
2690 status
= smb_bytes_talloc_string(
2691 cli
, (char *)inbuf
, &cli
->server_domain
,
2692 bytes
+ 8, num_bytes
- 8, &ret
);
2693 if (tevent_req_nterror(req
, status
)) {
2699 * As signing is slow we only turn it on if either the client or
2700 * the server require it. JRA.
2703 if (cli
->sec_mode
& NEGOTIATE_SECURITY_SIGNATURES_REQUIRED
) {
2704 /* Fail if server says signing is mandatory and we don't want to support it. */
2705 if (!client_is_signing_allowed(cli
)) {
2706 DEBUG(0,("cli_negprot: SMB signing is mandatory and we have disabled it.\n"));
2707 tevent_req_nterror(req
,
2708 NT_STATUS_ACCESS_DENIED
);
2711 negotiated_smb_signing
= true;
2712 } else if (client_is_signing_mandatory(cli
) && client_is_signing_allowed(cli
)) {
2713 /* Fail if client says signing is mandatory and the server doesn't support it. */
2714 if (!(cli
->sec_mode
& NEGOTIATE_SECURITY_SIGNATURES_ENABLED
)) {
2715 DEBUG(1,("cli_negprot: SMB signing is mandatory and the server doesn't support it.\n"));
2716 tevent_req_nterror(req
,
2717 NT_STATUS_ACCESS_DENIED
);
2720 negotiated_smb_signing
= true;
2721 } else if (cli
->sec_mode
& NEGOTIATE_SECURITY_SIGNATURES_ENABLED
) {
2722 negotiated_smb_signing
= true;
2725 if (negotiated_smb_signing
) {
2726 cli_set_signing_negotiated(cli
);
2729 if (cli
->capabilities
& (CAP_LARGE_READX
|CAP_LARGE_WRITEX
)) {
2730 SAFE_FREE(cli
->outbuf
);
2731 SAFE_FREE(cli
->inbuf
);
2732 cli
->outbuf
= (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE
+LARGE_WRITEX_HDR_SIZE
+SAFETY_MARGIN
);
2733 cli
->inbuf
= (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE
+LARGE_WRITEX_HDR_SIZE
+SAFETY_MARGIN
);
2734 if (!cli
->outbuf
|| !cli
->inbuf
) {
2735 tevent_req_nterror(req
,
2736 NT_STATUS_NO_MEMORY
);
2739 cli
->bufsize
= CLI_SAMBA_MAX_LARGE_READX_SIZE
+ LARGE_WRITEX_HDR_SIZE
;
2742 } else if (cli
->protocol
>= PROTOCOL_LANMAN1
) {
2743 cli
->use_spnego
= False
;
2744 cli
->sec_mode
= SVAL(vwv
+ 1, 0);
2745 cli
->max_xmit
= SVAL(vwv
+ 2, 0);
2746 cli
->max_mux
= SVAL(vwv
+ 3, 0);
2747 cli
->sesskey
= IVAL(vwv
+ 6, 0);
2748 cli
->serverzone
= SVALS(vwv
+ 10, 0);
2749 cli
->serverzone
*= 60;
2750 /* this time is converted to GMT by make_unix_date */
2751 cli
->servertime
= make_unix_date(
2752 (char *)(vwv
+ 8), cli
->serverzone
);
2753 cli
->readbraw_supported
= ((SVAL(vwv
+ 5, 0) & 0x1) != 0);
2754 cli
->writebraw_supported
= ((SVAL(vwv
+ 5, 0) & 0x2) != 0);
2755 cli
->secblob
= data_blob(bytes
, num_bytes
);
2757 /* the old core protocol */
2758 cli
->use_spnego
= False
;
2760 cli
->serverzone
= get_time_zone(time(NULL
));
2763 cli
->max_xmit
= MIN(cli
->max_xmit
, CLI_BUFFER_SIZE
);
2765 /* a way to force ascii SMB */
2766 if (getenv("CLI_FORCE_ASCII"))
2767 cli
->capabilities
&= ~CAP_UNICODE
;
2769 tevent_req_done(req
);
2772 NTSTATUS
cli_negprot_recv(struct tevent_req
*req
)
2774 return tevent_req_simple_recv_ntstatus(req
);
2777 NTSTATUS
cli_negprot(struct cli_state
*cli
)
2779 TALLOC_CTX
*frame
= talloc_stackframe();
2780 struct event_context
*ev
;
2781 struct tevent_req
*req
;
2782 NTSTATUS status
= NT_STATUS_OK
;
2784 if (cli_has_async_calls(cli
)) {
2786 * Can't use sync call while an async call is in flight
2788 status
= NT_STATUS_INVALID_PARAMETER
;
2792 ev
= event_context_init(frame
);
2794 status
= NT_STATUS_NO_MEMORY
;
2798 req
= cli_negprot_send(frame
, ev
, cli
);
2800 status
= NT_STATUS_NO_MEMORY
;
2804 if (!tevent_req_poll(req
, ev
)) {
2805 status
= map_nt_error_from_unix(errno
);
2809 status
= cli_negprot_recv(req
);
2812 if (!NT_STATUS_IS_OK(status
)) {
2813 cli_set_error(cli
, status
);
2818 /****************************************************************************
2819 Send a session request. See rfc1002.txt 4.3 and 4.3.2.
2820 ****************************************************************************/
2822 bool cli_session_request(struct cli_state
*cli
,
2823 struct nmb_name
*calling
, struct nmb_name
*called
)
2830 /* 445 doesn't have session request */
2831 if (cli
->port
== 445)
2834 memcpy(&(cli
->calling
), calling
, sizeof(*calling
));
2835 memcpy(&(cli
->called
), called
, sizeof(*called
));
2837 /* put in the destination name */
2839 tmp
= name_mangle(talloc_tos(), cli
->called
.name
,
2840 cli
->called
.name_type
);
2845 p
= cli
->outbuf
+len
;
2846 namelen
= name_len((unsigned char *)tmp
, talloc_get_size(tmp
));
2848 memcpy(p
, tmp
, namelen
);
2855 tmp
= name_mangle(talloc_tos(), cli
->calling
.name
,
2856 cli
->calling
.name_type
);
2861 p
= cli
->outbuf
+len
;
2862 namelen
= name_len((unsigned char *)tmp
, talloc_get_size(tmp
));
2864 memcpy(p
, tmp
, namelen
);
2869 /* send a session request (RFC 1002) */
2870 /* setup the packet length
2871 * Remove four bytes from the length count, since the length
2872 * field in the NBT Session Service header counts the number
2873 * of bytes which follow. The cli_send_smb() function knows
2874 * about this and accounts for those four bytes.
2878 _smb_setlen(cli
->outbuf
,len
);
2879 SCVAL(cli
->outbuf
,0,0x81);
2882 DEBUG(5,("Sent session request\n"));
2884 if (!cli_receive_smb(cli
))
2887 if (CVAL(cli
->inbuf
,0) == 0x84) {
2888 /* C. Hoch 9/14/95 Start */
2889 /* For information, here is the response structure.
2890 * We do the byte-twiddling to for portability.
2891 struct RetargetResponse{
2893 unsigned char flags;
2899 uint16_t port
= (CVAL(cli
->inbuf
,8)<<8)+CVAL(cli
->inbuf
,9);
2900 struct in_addr dest_ip
;
2903 /* SESSION RETARGET */
2904 putip((char *)&dest_ip
,cli
->inbuf
+4);
2905 in_addr_to_sockaddr_storage(&cli
->dest_ss
, dest_ip
);
2907 status
= open_socket_out(&cli
->dest_ss
, port
,
2908 LONG_CONNECT_TIMEOUT
, &cli
->fd
);
2909 if (!NT_STATUS_IS_OK(status
)) {
2913 DEBUG(3,("Retargeted\n"));
2915 set_socket_options(cli
->fd
, lp_socket_options());
2922 DEBUG(0,("Retarget recursion - failing\n"));
2926 ret
= cli_session_request(cli
, calling
, called
);
2930 } /* C. Hoch 9/14/95 End */
2932 if (CVAL(cli
->inbuf
,0) != 0x82) {
2933 /* This is the wrong place to put the error... JRA. */
2934 cli
->rap_error
= CVAL(cli
->inbuf
,4);
2944 static void smb_sock_connected(struct tevent_req
*req
)
2946 struct fd_struct
*pfd
= tevent_req_callback_data(
2947 req
, struct fd_struct
);
2951 status
= open_socket_out_defer_recv(req
, &fd
);
2952 if (NT_STATUS_IS_OK(status
)) {
2957 static NTSTATUS
open_smb_socket(const struct sockaddr_storage
*pss
,
2958 uint16_t *port
, int timeout
, int *pfd
)
2960 struct event_context
*ev
;
2961 struct tevent_req
*r139
, *r445
;
2962 struct fd_struct
*fd139
, *fd445
;
2963 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2966 return open_socket_out(pss
, *port
, timeout
, pfd
);
2969 ev
= event_context_init(talloc_tos());
2971 return NT_STATUS_NO_MEMORY
;
2974 fd139
= talloc(ev
, struct fd_struct
);
2975 if (fd139
== NULL
) {
2980 fd445
= talloc(ev
, struct fd_struct
);
2981 if (fd445
== NULL
) {
2986 r445
= open_socket_out_defer_send(ev
, ev
, timeval_set(0, 0),
2988 r139
= open_socket_out_defer_send(ev
, ev
, timeval_set(0, 3000),
2990 if ((r445
== NULL
) || (r139
== NULL
)) {
2993 tevent_req_set_callback(r445
, smb_sock_connected
, fd445
);
2994 tevent_req_set_callback(r139
, smb_sock_connected
, fd139
);
2996 while ((fd445
->fd
== -1) && (fd139
->fd
== -1)
2997 && (tevent_req_is_in_progress(r139
)
2998 || tevent_req_is_in_progress(r445
))) {
2999 event_loop_once(ev
);
3002 if ((fd139
->fd
!= -1) && (fd445
->fd
!= -1)) {
3007 if (fd445
->fd
!= -1) {
3010 status
= NT_STATUS_OK
;
3013 if (fd139
->fd
!= -1) {
3016 status
= NT_STATUS_OK
;
3020 status
= open_socket_out_defer_recv(r445
, &fd445
->fd
);
3026 /****************************************************************************
3027 Open the client sockets.
3028 ****************************************************************************/
3030 NTSTATUS
cli_connect(struct cli_state
*cli
,
3032 struct sockaddr_storage
*dest_ss
)
3035 int name_type
= 0x20;
3036 TALLOC_CTX
*frame
= talloc_stackframe();
3037 unsigned int num_addrs
= 0;
3039 struct sockaddr_storage
*ss_arr
= NULL
;
3042 /* reasonable default hostname */
3044 host
= STAR_SMBSERVER
;
3047 cli
->desthost
= talloc_strdup(cli
, host
);
3048 if (cli
->desthost
== NULL
) {
3049 return NT_STATUS_NO_MEMORY
;
3052 /* allow hostnames of the form NAME#xx and do a netbios lookup */
3053 if ((p
= strchr(cli
->desthost
, '#'))) {
3054 name_type
= strtol(p
+1, NULL
, 16);
3058 if (!dest_ss
|| is_zero_addr(dest_ss
)) {
3059 NTSTATUS status
=resolve_name_list(frame
,
3064 if (!NT_STATUS_IS_OK(status
)) {
3066 return NT_STATUS_BAD_NETWORK_NAME
;
3070 ss_arr
= TALLOC_P(frame
, struct sockaddr_storage
);
3073 return NT_STATUS_NO_MEMORY
;
3078 for (i
= 0; i
< num_addrs
; i
++) {
3079 cli
->dest_ss
= ss_arr
[i
];
3080 if (getenv("LIBSMB_PROG")) {
3081 cli
->fd
= sock_exec(getenv("LIBSMB_PROG"));
3083 uint16_t port
= cli
->port
;
3085 status
= open_smb_socket(&cli
->dest_ss
, &port
,
3086 cli
->timeout
, &cli
->fd
);
3087 if (NT_STATUS_IS_OK(status
)) {
3091 if (cli
->fd
== -1) {
3092 char addr
[INET6_ADDRSTRLEN
];
3093 print_sockaddr(addr
, sizeof(addr
), &ss_arr
[i
]);
3094 DEBUG(2,("Error connecting to %s (%s)\n",
3095 dest_ss
?addr
:host
,strerror(errno
)));
3097 /* Exit from loop on first connection. */
3102 if (cli
->fd
== -1) {
3104 return map_nt_error_from_unix(errno
);
3108 *dest_ss
= cli
->dest_ss
;
3111 set_socket_options(cli
->fd
, lp_socket_options());
3114 return NT_STATUS_OK
;
3118 establishes a connection to after the negprot.
3119 @param output_cli A fully initialised cli structure, non-null only on success
3120 @param dest_host The netbios name of the remote host
3121 @param dest_ss (optional) The the destination IP, NULL for name based lookup
3122 @param port (optional) The destination port (0 for default)
3124 NTSTATUS
cli_start_connection(struct cli_state
**output_cli
,
3125 const char *my_name
,
3126 const char *dest_host
,
3127 struct sockaddr_storage
*dest_ss
, int port
,
3128 int signing_state
, int flags
)
3131 struct nmb_name calling
;
3132 struct nmb_name called
;
3133 struct cli_state
*cli
;
3134 struct sockaddr_storage ss
;
3137 my_name
= global_myname();
3139 if (!(cli
= cli_initialise_ex(signing_state
))) {
3140 return NT_STATUS_NO_MEMORY
;
3143 make_nmb_name(&calling
, my_name
, 0x0);
3144 make_nmb_name(&called
, dest_host
, 0x20);
3146 cli_set_port(cli
, port
);
3147 cli_set_timeout(cli
, 10000); /* 10 seconds. */
3157 DEBUG(3,("Connecting to host=%s\n", dest_host
));
3159 nt_status
= cli_connect(cli
, dest_host
, &ss
);
3160 if (!NT_STATUS_IS_OK(nt_status
)) {
3161 char addr
[INET6_ADDRSTRLEN
];
3162 print_sockaddr(addr
, sizeof(addr
), &ss
);
3163 DEBUG(1,("cli_start_connection: failed to connect to %s (%s). Error %s\n",
3164 nmb_namestr(&called
), addr
, nt_errstr(nt_status
) ));
3169 if (!cli_session_request(cli
, &calling
, &called
)) {
3171 DEBUG(1,("session request to %s failed (%s)\n",
3172 called
.name
, cli_errstr(cli
)));
3173 if ((p
=strchr(called
.name
, '.')) && !is_ipaddress(called
.name
)) {
3177 if (strcmp(called
.name
, STAR_SMBSERVER
)) {
3178 make_nmb_name(&called
, STAR_SMBSERVER
, 0x20);
3181 return NT_STATUS_BAD_NETWORK_NAME
;
3184 if (flags
& CLI_FULL_CONNECTION_DONT_SPNEGO
)
3185 cli
->use_spnego
= False
;
3186 else if (flags
& CLI_FULL_CONNECTION_USE_KERBEROS
)
3187 cli
->use_kerberos
= True
;
3189 if ((flags
& CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS
) &&
3190 cli
->use_kerberos
) {
3191 cli
->fallback_after_kerberos
= true;
3193 if (flags
& CLI_FULL_CONNECTION_USE_CCACHE
) {
3194 cli
->use_ccache
= true;
3197 nt_status
= cli_negprot(cli
);
3198 if (!NT_STATUS_IS_OK(nt_status
)) {
3199 DEBUG(1, ("failed negprot: %s\n", nt_errstr(nt_status
)));
3205 return NT_STATUS_OK
;
3210 establishes a connection right up to doing tconX, password specified.
3211 @param output_cli A fully initialised cli structure, non-null only on success
3212 @param dest_host The netbios name of the remote host
3213 @param dest_ip (optional) The the destination IP, NULL for name based lookup
3214 @param port (optional) The destination port (0 for default)
3215 @param service (optional) The share to make the connection to. Should be 'unqualified' in any way.
3216 @param service_type The 'type' of serivice.
3217 @param user Username, unix string
3218 @param domain User's domain
3219 @param password User's password, unencrypted unix string.
3222 NTSTATUS
cli_full_connection(struct cli_state
**output_cli
,
3223 const char *my_name
,
3224 const char *dest_host
,
3225 struct sockaddr_storage
*dest_ss
, int port
,
3226 const char *service
, const char *service_type
,
3227 const char *user
, const char *domain
,
3228 const char *password
, int flags
,
3232 struct cli_state
*cli
= NULL
;
3233 int pw_len
= password
? strlen(password
)+1 : 0;
3237 if (password
== NULL
) {
3241 nt_status
= cli_start_connection(&cli
, my_name
, dest_host
,
3242 dest_ss
, port
, signing_state
,
3245 if (!NT_STATUS_IS_OK(nt_status
)) {
3249 cli
->use_oplocks
= ((flags
& CLI_FULL_CONNECTION_OPLOCKS
) != 0);
3250 cli
->use_level_II_oplocks
=
3251 ((flags
& CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS
) != 0);
3253 nt_status
= cli_session_setup(cli
, user
, password
, pw_len
, password
,
3255 if (!NT_STATUS_IS_OK(nt_status
)) {
3257 if (!(flags
& CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK
)) {
3258 DEBUG(1,("failed session setup with %s\n",
3259 nt_errstr(nt_status
)));
3264 nt_status
= cli_session_setup(cli
, "", "", 0, "", 0, domain
);
3265 if (!NT_STATUS_IS_OK(nt_status
)) {
3266 DEBUG(1,("anonymous failed session setup with %s\n",
3267 nt_errstr(nt_status
)));
3274 nt_status
= cli_tcon_andx(cli
, service
, service_type
, password
,
3276 if (!NT_STATUS_IS_OK(nt_status
)) {
3277 DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status
)));
3279 if (NT_STATUS_IS_OK(nt_status
)) {
3280 nt_status
= NT_STATUS_UNSUCCESSFUL
;
3286 nt_status
= cli_init_creds(cli
, user
, domain
, password
);
3287 if (!NT_STATUS_IS_OK(nt_status
)) {
3293 return NT_STATUS_OK
;
3296 /****************************************************************************
3297 Attempt a NetBIOS session request, falling back to *SMBSERVER if needed.
3298 ****************************************************************************/
3300 bool attempt_netbios_session_request(struct cli_state
**ppcli
, const char *srchost
, const char *desthost
,
3301 struct sockaddr_storage
*pdest_ss
)
3303 struct nmb_name calling
, called
;
3305 make_nmb_name(&calling
, srchost
, 0x0);
3308 * If the called name is an IP address
3309 * then use *SMBSERVER immediately.
3312 if(is_ipaddress(desthost
)) {
3313 make_nmb_name(&called
, STAR_SMBSERVER
, 0x20);
3315 make_nmb_name(&called
, desthost
, 0x20);
3318 if (!cli_session_request(*ppcli
, &calling
, &called
)) {
3320 struct nmb_name smbservername
;
3322 make_nmb_name(&smbservername
, STAR_SMBSERVER
, 0x20);
3325 * If the name wasn't *SMBSERVER then
3326 * try with *SMBSERVER if the first name fails.
3329 if (nmb_name_equal(&called
, &smbservername
)) {
3332 * The name used was *SMBSERVER, don't bother with another name.
3335 DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER \
3336 with error %s.\n", desthost
, cli_errstr(*ppcli
) ));
3341 cli_shutdown(*ppcli
);
3343 *ppcli
= cli_initialise();
3345 /* Out of memory... */
3349 status
= cli_connect(*ppcli
, desthost
, pdest_ss
);
3350 if (!NT_STATUS_IS_OK(status
) ||
3351 !cli_session_request(*ppcli
, &calling
, &smbservername
)) {
3352 DEBUG(0,("attempt_netbios_session_request: %s rejected the session for \
3353 name *SMBSERVER with error %s\n", desthost
, cli_errstr(*ppcli
) ));
3361 /****************************************************************************
3362 Send an old style tcon.
3363 ****************************************************************************/
3364 NTSTATUS
cli_raw_tcon(struct cli_state
*cli
,
3365 const char *service
, const char *pass
, const char *dev
,
3366 uint16
*max_xmit
, uint16
*tid
)
3368 struct tevent_req
*req
;
3373 if (!lp_client_plaintext_auth() && (*pass
)) {
3374 DEBUG(1, ("Server requested plaintext password but 'client "
3375 "plaintext auth' is disabled\n"));
3376 return NT_STATUS_ACCESS_DENIED
;
3379 bytes
= talloc_array(talloc_tos(), uint8_t, 0);
3380 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
3381 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
),
3382 service
, strlen(service
)+1, NULL
);
3383 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
3384 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
),
3385 pass
, strlen(pass
)+1, NULL
);
3386 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
3387 bytes
= smb_bytes_push_str(bytes
, cli_ucs2(cli
),
3388 dev
, strlen(dev
)+1, NULL
);
3390 status
= cli_smb(talloc_tos(), cli
, SMBtcon
, 0, 0, NULL
,
3391 talloc_get_size(bytes
), bytes
, &req
,
3392 2, NULL
, &ret_vwv
, NULL
, NULL
);
3393 if (!NT_STATUS_IS_OK(status
)) {
3397 *max_xmit
= SVAL(ret_vwv
+ 0, 0);
3398 *tid
= SVAL(ret_vwv
+ 1, 0);
3400 return NT_STATUS_OK
;
3403 /* Return a cli_state pointing at the IPC$ share for the given server */
3405 struct cli_state
*get_ipc_connect(char *server
,
3406 struct sockaddr_storage
*server_ss
,
3407 const struct user_auth_info
*user_info
)
3409 struct cli_state
*cli
;
3411 uint32_t flags
= CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK
;
3413 if (user_info
->use_kerberos
) {
3414 flags
|= CLI_FULL_CONNECTION_USE_KERBEROS
;
3417 nt_status
= cli_full_connection(&cli
, NULL
, server
, server_ss
, 0, "IPC$", "IPC",
3418 user_info
->username
? user_info
->username
: "",
3420 user_info
->password
? user_info
->password
: "",
3424 if (NT_STATUS_IS_OK(nt_status
)) {
3426 } else if (is_ipaddress(server
)) {
3427 /* windows 9* needs a correct NMB name for connections */
3428 fstring remote_name
;
3430 if (name_status_find("*", 0, 0, server_ss
, remote_name
)) {
3431 cli
= get_ipc_connect(remote_name
, server_ss
, user_info
);
3440 * Given the IP address of a master browser on the network, return its
3441 * workgroup and connect to it.
3443 * This function is provided to allow additional processing beyond what
3444 * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
3445 * browsers and obtain each master browsers' list of domains (in case the
3446 * first master browser is recently on the network and has not yet
3447 * synchronized with other master browsers and therefore does not yet have the
3448 * entire network browse list)
3451 struct cli_state
*get_ipc_connect_master_ip(TALLOC_CTX
*ctx
,
3452 struct sockaddr_storage
*mb_ip
,
3453 const struct user_auth_info
*user_info
,
3454 char **pp_workgroup_out
)
3456 char addr
[INET6_ADDRSTRLEN
];
3458 struct cli_state
*cli
;
3459 struct sockaddr_storage server_ss
;
3461 *pp_workgroup_out
= NULL
;
3463 print_sockaddr(addr
, sizeof(addr
), mb_ip
);
3464 DEBUG(99, ("Looking up name of master browser %s\n",
3468 * Do a name status query to find out the name of the master browser.
3469 * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
3470 * master browser will not respond to a wildcard query (or, at least,
3471 * an NT4 server acting as the domain master browser will not).
3473 * We might be able to use ONLY the query on MSBROWSE, but that's not
3474 * yet been tested with all Windows versions, so until it is, leave
3475 * the original wildcard query as the first choice and fall back to
3476 * MSBROWSE if the wildcard query fails.
3478 if (!name_status_find("*", 0, 0x1d, mb_ip
, name
) &&
3479 !name_status_find(MSBROWSE
, 1, 0x1d, mb_ip
, name
)) {
3481 DEBUG(99, ("Could not retrieve name status for %s\n",
3486 if (!find_master_ip(name
, &server_ss
)) {
3487 DEBUG(99, ("Could not find master ip for %s\n", name
));
3491 *pp_workgroup_out
= talloc_strdup(ctx
, name
);
3493 DEBUG(4, ("found master browser %s, %s\n", name
, addr
));
3495 print_sockaddr(addr
, sizeof(addr
), &server_ss
);
3496 cli
= get_ipc_connect(addr
, &server_ss
, user_info
);
3502 * Return the IP address and workgroup of a master browser on the network, and
3506 struct cli_state
*get_ipc_connect_master_ip_bcast(TALLOC_CTX
*ctx
,
3507 const struct user_auth_info
*user_info
,
3508 char **pp_workgroup_out
)
3510 struct sockaddr_storage
*ip_list
;
3511 struct cli_state
*cli
;
3515 *pp_workgroup_out
= NULL
;
3517 DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
3519 /* Go looking for workgroups by broadcasting on the local network */
3521 status
= name_resolve_bcast(MSBROWSE
, 1, talloc_tos(),
3523 if (!NT_STATUS_IS_OK(status
)) {
3524 DEBUG(99, ("No master browsers responded: %s\n",
3525 nt_errstr(status
)));
3529 for (i
= 0; i
< count
; i
++) {
3530 char addr
[INET6_ADDRSTRLEN
];
3531 print_sockaddr(addr
, sizeof(addr
), &ip_list
[i
]);
3532 DEBUG(99, ("Found master browser %s\n", addr
));
3534 cli
= get_ipc_connect_master_ip(ctx
, &ip_list
[i
],
3535 user_info
, pp_workgroup_out
);