2 Unix SMB/CIFS implementation.
3 client connect/disconnect routines
4 Copyright (C) Andrew Tridgell 1994-1998
5 Copyright (C) Andrew Bartlett 2001-2003
6 Copyright (C) Volker Lendecke 2011
7 Copyright (C) Jeremy Allison 2011
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "libsmb/libsmb.h"
25 #include "auth_info.h"
26 #include "../libcli/auth/libcli_auth.h"
27 #include "../libcli/auth/spnego.h"
29 #include "../auth/ntlmssp/ntlmssp.h"
30 #include "libads/kerberos_proto.h"
32 #include "../lib/util/tevent_ntstatus.h"
33 #include "async_smb.h"
34 #include "libsmb/nmblib.h"
35 #include "librpc/ndr/libndr.h"
36 #include "../libcli/smb/smbXcli_base.h"
39 #define STAR_SMBSERVER "*SMBSERVER"
41 /********************************************************
42 Utility function to ensure we always return at least
43 a valid char * pointer to an empty string for the
44 cli->server_os, cli->server_type and cli->server_domain
46 *******************************************************/
48 static NTSTATUS
smb_bytes_talloc_string(TALLOC_CTX
*mem_ctx
,
55 *destlen
= clistr_pull_talloc(mem_ctx
,
63 return NT_STATUS_NO_MEMORY
;
67 *dest
= talloc_strdup(mem_ctx
, "");
69 return NT_STATUS_NO_MEMORY
;
75 /****************************************************************************
76 Do an old lanman2 style session setup.
77 ****************************************************************************/
79 struct cli_session_setup_lanman2_state
{
80 struct cli_state
*cli
;
85 static void cli_session_setup_lanman2_done(struct tevent_req
*subreq
);
87 static struct tevent_req
*cli_session_setup_lanman2_send(
88 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
89 struct cli_state
*cli
, const char *user
,
90 const char *pass
, size_t passlen
,
91 const char *workgroup
)
93 struct tevent_req
*req
, *subreq
;
94 struct cli_session_setup_lanman2_state
*state
;
95 DATA_BLOB lm_response
= data_blob_null
;
99 uint16_t sec_mode
= smb1cli_conn_server_security_mode(cli
->conn
);
101 req
= tevent_req_create(mem_ctx
, &state
,
102 struct cli_session_setup_lanman2_state
);
111 * if in share level security then don't send a password now
113 if (!(sec_mode
& NEGOTIATE_SECURITY_USER_LEVEL
)) {
118 && (sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
)
121 * Encrypted mode needed, and non encrypted password
124 lm_response
= data_blob(NULL
, 24);
125 if (tevent_req_nomem(lm_response
.data
, req
)) {
126 return tevent_req_post(req
, ev
);
129 if (!SMBencrypt(pass
, smb1cli_conn_server_challenge(cli
->conn
),
130 (uint8_t *)lm_response
.data
)) {
131 DEBUG(1, ("Password is > 14 chars in length, and is "
132 "therefore incompatible with Lanman "
133 "authentication\n"));
134 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
135 return tevent_req_post(req
, ev
);
137 } else if ((sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
)
140 * Encrypted mode needed, and encrypted password
143 lm_response
= data_blob(pass
, passlen
);
144 if (tevent_req_nomem(lm_response
.data
, req
)) {
145 return tevent_req_post(req
, ev
);
147 } else if (passlen
> 0) {
149 size_t converted_size
;
151 * Plaintext mode needed, assume plaintext supplied.
153 buf
= talloc_array(talloc_tos(), uint8_t, 0);
154 buf
= smb_bytes_push_str(buf
, smbXcli_conn_use_unicode(cli
->conn
), pass
, passlen
+1,
156 if (tevent_req_nomem(buf
, req
)) {
157 return tevent_req_post(req
, ev
);
159 lm_response
= data_blob(pass
, passlen
);
161 if (tevent_req_nomem(lm_response
.data
, req
)) {
162 return tevent_req_post(req
, ev
);
166 SCVAL(vwv
+0, 0, 0xff);
169 SSVAL(vwv
+2, 0, CLI_BUFFER_SIZE
);
172 SIVAL(vwv
+5, 0, smb1cli_conn_server_session_key(cli
->conn
));
173 SSVAL(vwv
+7, 0, lm_response
.length
);
175 bytes
= talloc_array(state
, uint8_t, lm_response
.length
);
176 if (tevent_req_nomem(bytes
, req
)) {
177 return tevent_req_post(req
, ev
);
179 if (lm_response
.length
!= 0) {
180 memcpy(bytes
, lm_response
.data
, lm_response
.length
);
182 data_blob_free(&lm_response
);
184 tmp
= talloc_strdup_upper(talloc_tos(), user
);
185 if (tevent_req_nomem(tmp
, req
)) {
186 return tevent_req_post(req
, ev
);
188 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), tmp
, strlen(tmp
)+1,
192 tmp
= talloc_strdup_upper(talloc_tos(), workgroup
);
193 if (tevent_req_nomem(tmp
, req
)) {
194 return tevent_req_post(req
, ev
);
196 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), tmp
, strlen(tmp
)+1,
198 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "Unix", 5, NULL
);
199 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "Samba", 6, NULL
);
201 if (tevent_req_nomem(bytes
, req
)) {
202 return tevent_req_post(req
, ev
);
205 subreq
= cli_smb_send(state
, ev
, cli
, SMBsesssetupX
, 0, 10, vwv
,
206 talloc_get_size(bytes
), bytes
);
207 if (tevent_req_nomem(subreq
, req
)) {
208 return tevent_req_post(req
, ev
);
210 tevent_req_set_callback(subreq
, cli_session_setup_lanman2_done
, req
);
214 static void cli_session_setup_lanman2_done(struct tevent_req
*subreq
)
216 struct tevent_req
*req
= tevent_req_callback_data(
217 subreq
, struct tevent_req
);
218 struct cli_session_setup_lanman2_state
*state
= tevent_req_data(
219 req
, struct cli_session_setup_lanman2_state
);
220 struct cli_state
*cli
= state
->cli
;
231 status
= cli_smb_recv(subreq
, state
, &in
, 3, &wct
, &vwv
,
234 if (!NT_STATUS_IS_OK(status
)) {
235 tevent_req_nterror(req
, status
);
239 inhdr
= in
+ NBT_HDR_SIZE
;
242 cli_state_set_uid(state
->cli
, SVAL(inhdr
, HDR_UID
));
243 cli
->is_guestlogin
= ((SVAL(vwv
+2, 0) & 1) != 0);
245 status
= smb_bytes_talloc_string(cli
,
252 if (!NT_STATUS_IS_OK(status
)) {
253 tevent_req_nterror(req
, status
);
258 status
= smb_bytes_talloc_string(cli
,
265 if (!NT_STATUS_IS_OK(status
)) {
266 tevent_req_nterror(req
, status
);
271 status
= smb_bytes_talloc_string(cli
,
278 if (!NT_STATUS_IS_OK(status
)) {
279 tevent_req_nterror(req
, status
);
284 status
= cli_set_username(cli
, state
->user
);
285 if (tevent_req_nterror(req
, status
)) {
288 tevent_req_done(req
);
291 static NTSTATUS
cli_session_setup_lanman2_recv(struct tevent_req
*req
)
293 return tevent_req_simple_recv_ntstatus(req
);
296 /****************************************************************************
297 Work out suitable capabilities to offer the server.
298 ****************************************************************************/
300 static uint32_t cli_session_setup_capabilities(struct cli_state
*cli
,
301 uint32_t sesssetup_capabilities
)
303 uint32_t client_capabilities
= smb1cli_conn_capabilities(cli
->conn
);
306 * We only send capabilities based on the mask for:
307 * - client only flags
308 * - flags used in both directions
310 * We do not echo the server only flags, except some legacy flags.
312 * SMB_CAP_LEGACY_CLIENT_MASK contains CAP_LARGE_READX and
313 * CAP_LARGE_WRITEX in order to allow us to do large reads
314 * against old Samba releases (<= 3.6.x).
316 client_capabilities
&= (SMB_CAP_BOTH_MASK
| SMB_CAP_LEGACY_CLIENT_MASK
);
319 * Session Setup specific flags CAP_DYNAMIC_REAUTH
320 * and CAP_EXTENDED_SECURITY are passed by the caller.
321 * We need that in order to do guest logins even if
322 * CAP_EXTENDED_SECURITY is negotiated.
324 client_capabilities
&= ~(CAP_DYNAMIC_REAUTH
|CAP_EXTENDED_SECURITY
);
325 sesssetup_capabilities
&= (CAP_DYNAMIC_REAUTH
|CAP_EXTENDED_SECURITY
);
326 client_capabilities
|= sesssetup_capabilities
;
328 return client_capabilities
;
331 /****************************************************************************
332 Do a NT1 guest session setup.
333 ****************************************************************************/
335 struct cli_session_setup_guest_state
{
336 struct cli_state
*cli
;
341 static void cli_session_setup_guest_done(struct tevent_req
*subreq
);
343 struct tevent_req
*cli_session_setup_guest_create(TALLOC_CTX
*mem_ctx
,
344 struct tevent_context
*ev
,
345 struct cli_state
*cli
,
346 struct tevent_req
**psmbreq
)
348 struct tevent_req
*req
, *subreq
;
349 struct cli_session_setup_guest_state
*state
;
353 req
= tevent_req_create(mem_ctx
, &state
,
354 struct cli_session_setup_guest_state
);
361 SCVAL(vwv
+0, 0, 0xFF);
364 SSVAL(vwv
+2, 0, CLI_BUFFER_SIZE
);
366 SSVAL(vwv
+4, 0, cli_state_get_vc_num(cli
));
367 SIVAL(vwv
+5, 0, smb1cli_conn_server_session_key(cli
->conn
));
372 SIVAL(vwv
+11, 0, cli_session_setup_capabilities(cli
, 0));
374 bytes
= talloc_array(state
, uint8_t, 0);
376 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "", 1, /* username */
378 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "", 1, /* workgroup */
380 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "Unix", 5, NULL
);
381 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "Samba", 6, NULL
);
388 state
->bytes
.iov_base
= (void *)bytes
;
389 state
->bytes
.iov_len
= talloc_get_size(bytes
);
391 subreq
= cli_smb_req_create(state
, ev
, cli
, SMBsesssetupX
, 0, 13, vwv
,
393 if (subreq
== NULL
) {
397 tevent_req_set_callback(subreq
, cli_session_setup_guest_done
, req
);
402 struct tevent_req
*cli_session_setup_guest_send(TALLOC_CTX
*mem_ctx
,
403 struct tevent_context
*ev
,
404 struct cli_state
*cli
)
406 struct tevent_req
*req
, *subreq
;
409 req
= cli_session_setup_guest_create(mem_ctx
, ev
, cli
, &subreq
);
414 status
= smb1cli_req_chain_submit(&subreq
, 1);
415 if (!NT_STATUS_IS_OK(status
)) {
416 tevent_req_nterror(req
, status
);
417 return tevent_req_post(req
, ev
);
422 static void cli_session_setup_guest_done(struct tevent_req
*subreq
)
424 struct tevent_req
*req
= tevent_req_callback_data(
425 subreq
, struct tevent_req
);
426 struct cli_session_setup_guest_state
*state
= tevent_req_data(
427 req
, struct cli_session_setup_guest_state
);
428 struct cli_state
*cli
= state
->cli
;
439 status
= cli_smb_recv(subreq
, state
, &in
, 3, &wct
, &vwv
,
442 if (!NT_STATUS_IS_OK(status
)) {
443 tevent_req_nterror(req
, status
);
447 inhdr
= in
+ NBT_HDR_SIZE
;
450 cli_state_set_uid(state
->cli
, SVAL(inhdr
, HDR_UID
));
451 cli
->is_guestlogin
= ((SVAL(vwv
+2, 0) & 1) != 0);
453 status
= smb_bytes_talloc_string(cli
,
460 if (!NT_STATUS_IS_OK(status
)) {
461 tevent_req_nterror(req
, status
);
466 status
= smb_bytes_talloc_string(cli
,
473 if (!NT_STATUS_IS_OK(status
)) {
474 tevent_req_nterror(req
, status
);
479 status
= smb_bytes_talloc_string(cli
,
486 if (!NT_STATUS_IS_OK(status
)) {
487 tevent_req_nterror(req
, status
);
492 status
= cli_set_username(cli
, "");
493 if (!NT_STATUS_IS_OK(status
)) {
494 tevent_req_nterror(req
, status
);
497 tevent_req_done(req
);
500 NTSTATUS
cli_session_setup_guest_recv(struct tevent_req
*req
)
502 return tevent_req_simple_recv_ntstatus(req
);
505 /****************************************************************************
506 Do a NT1 plaintext session setup.
507 ****************************************************************************/
509 struct cli_session_setup_plain_state
{
510 struct cli_state
*cli
;
515 static void cli_session_setup_plain_done(struct tevent_req
*subreq
);
517 static struct tevent_req
*cli_session_setup_plain_send(
518 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
519 struct cli_state
*cli
,
520 const char *user
, const char *pass
, const char *workgroup
)
522 struct tevent_req
*req
, *subreq
;
523 struct cli_session_setup_plain_state
*state
;
529 req
= tevent_req_create(mem_ctx
, &state
,
530 struct cli_session_setup_plain_state
);
538 SCVAL(vwv
+0, 0, 0xff);
541 SSVAL(vwv
+2, 0, CLI_BUFFER_SIZE
);
543 SSVAL(vwv
+4, 0, cli_state_get_vc_num(cli
));
544 SIVAL(vwv
+5, 0, smb1cli_conn_server_session_key(cli
->conn
));
549 SIVAL(vwv
+11, 0, cli_session_setup_capabilities(cli
, 0));
551 bytes
= talloc_array(state
, uint8_t, 0);
552 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), pass
, strlen(pass
)+1,
554 if (tevent_req_nomem(bytes
, req
)) {
555 return tevent_req_post(req
, ev
);
557 SSVAL(vwv
+ (smbXcli_conn_use_unicode(cli
->conn
) ? 8 : 7), 0, passlen
);
559 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
560 user
, strlen(user
)+1, NULL
);
561 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
562 workgroup
, strlen(workgroup
)+1, NULL
);
563 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
566 version
= talloc_asprintf(talloc_tos(), "Samba %s",
567 samba_version_string());
568 if (tevent_req_nomem(version
, req
)){
569 return tevent_req_post(req
, ev
);
571 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
572 version
, strlen(version
)+1, NULL
);
573 TALLOC_FREE(version
);
575 if (tevent_req_nomem(bytes
, req
)) {
576 return tevent_req_post(req
, ev
);
579 subreq
= cli_smb_send(state
, ev
, cli
, SMBsesssetupX
, 0, 13, vwv
,
580 talloc_get_size(bytes
), bytes
);
581 if (tevent_req_nomem(subreq
, req
)) {
582 return tevent_req_post(req
, ev
);
584 tevent_req_set_callback(subreq
, cli_session_setup_plain_done
, req
);
588 static void cli_session_setup_plain_done(struct tevent_req
*subreq
)
590 struct tevent_req
*req
= tevent_req_callback_data(
591 subreq
, struct tevent_req
);
592 struct cli_session_setup_plain_state
*state
= tevent_req_data(
593 req
, struct cli_session_setup_plain_state
);
594 struct cli_state
*cli
= state
->cli
;
605 status
= cli_smb_recv(subreq
, state
, &in
, 3, &wct
, &vwv
,
608 if (tevent_req_nterror(req
, status
)) {
612 inhdr
= in
+ NBT_HDR_SIZE
;
615 cli_state_set_uid(state
->cli
, SVAL(inhdr
, HDR_UID
));
616 cli
->is_guestlogin
= ((SVAL(vwv
+2, 0) & 1) != 0);
618 status
= smb_bytes_talloc_string(cli
,
625 if (!NT_STATUS_IS_OK(status
)) {
626 tevent_req_nterror(req
, status
);
631 status
= smb_bytes_talloc_string(cli
,
638 if (!NT_STATUS_IS_OK(status
)) {
639 tevent_req_nterror(req
, status
);
644 status
= smb_bytes_talloc_string(cli
,
651 if (!NT_STATUS_IS_OK(status
)) {
652 tevent_req_nterror(req
, status
);
657 status
= cli_set_username(cli
, state
->user
);
658 if (tevent_req_nterror(req
, status
)) {
662 tevent_req_done(req
);
665 static NTSTATUS
cli_session_setup_plain_recv(struct tevent_req
*req
)
667 return tevent_req_simple_recv_ntstatus(req
);
670 /****************************************************************************
671 do a NT1 NTLM/LM encrypted session setup - for when extended security
673 @param cli client state to create do session setup on
675 @param pass *either* cleartext password (passlen !=24) or LM response.
676 @param ntpass NT response, implies ntpasslen >=24, implies pass is not clear
677 @param workgroup The user's domain.
678 ****************************************************************************/
680 struct cli_session_setup_nt1_state
{
681 struct cli_state
*cli
;
684 DATA_BLOB session_key
;
688 static void cli_session_setup_nt1_done(struct tevent_req
*subreq
);
690 static struct tevent_req
*cli_session_setup_nt1_send(
691 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
692 struct cli_state
*cli
, const char *user
,
693 const char *pass
, size_t passlen
,
694 const char *ntpass
, size_t ntpasslen
,
695 const char *workgroup
)
697 struct tevent_req
*req
, *subreq
;
698 struct cli_session_setup_nt1_state
*state
;
699 DATA_BLOB lm_response
= data_blob_null
;
700 DATA_BLOB nt_response
= data_blob_null
;
701 DATA_BLOB session_key
= data_blob_null
;
704 char *workgroup_upper
;
706 req
= tevent_req_create(mem_ctx
, &state
,
707 struct cli_session_setup_nt1_state
);
716 /* do nothing - guest login */
717 } else if (passlen
!= 24) {
718 if (lp_client_ntlmv2_auth()) {
719 DATA_BLOB server_chal
;
720 DATA_BLOB names_blob
;
723 data_blob_const(smb1cli_conn_server_challenge(cli
->conn
),
727 * note that the 'workgroup' here is a best
728 * guess - we don't know the server's domain
729 * at this point. Windows clients also don't
732 names_blob
= NTLMv2_generate_names_blob(
733 NULL
, NULL
, workgroup
);
735 if (tevent_req_nomem(names_blob
.data
, req
)) {
736 return tevent_req_post(req
, ev
);
739 if (!SMBNTLMv2encrypt(NULL
, user
, workgroup
, pass
,
740 &server_chal
, &names_blob
,
741 &lm_response
, &nt_response
,
742 NULL
, &session_key
)) {
743 data_blob_free(&names_blob
);
745 req
, NT_STATUS_ACCESS_DENIED
);
746 return tevent_req_post(req
, ev
);
748 data_blob_free(&names_blob
);
752 E_md4hash(pass
, nt_hash
);
755 nt_response
= data_blob_null
;
757 nt_response
= data_blob(NULL
, 24);
758 if (tevent_req_nomem(nt_response
.data
, req
)) {
759 return tevent_req_post(req
, ev
);
762 SMBNTencrypt(pass
, smb1cli_conn_server_challenge(cli
->conn
),
765 /* non encrypted password supplied. Ignore ntpass. */
766 if (lp_client_lanman_auth()) {
768 lm_response
= data_blob(NULL
, 24);
769 if (tevent_req_nomem(lm_response
.data
, req
)) {
770 return tevent_req_post(req
, ev
);
773 if (!SMBencrypt(pass
,
774 smb1cli_conn_server_challenge(cli
->conn
),
777 * Oops, the LM response is
778 * invalid, just put the NT
779 * response there instead
781 data_blob_free(&lm_response
);
782 lm_response
= data_blob(
788 * LM disabled, place NT# in LM field
791 lm_response
= data_blob(
792 nt_response
.data
, nt_response
.length
);
795 if (tevent_req_nomem(lm_response
.data
, req
)) {
796 return tevent_req_post(req
, ev
);
799 session_key
= data_blob(NULL
, 16);
800 if (tevent_req_nomem(session_key
.data
, req
)) {
801 return tevent_req_post(req
, ev
);
804 E_deshash(pass
, session_key
.data
);
805 memset(&session_key
.data
[8], '\0', 8);
807 SMBsesskeygen_ntv1(nt_hash
, session_key
.data
);
811 /* pre-encrypted password supplied. Only used for
812 security=server, can't do
813 signing because we don't have original key */
815 lm_response
= data_blob(pass
, passlen
);
816 if (tevent_req_nomem(lm_response
.data
, req
)) {
817 return tevent_req_post(req
, ev
);
820 nt_response
= data_blob(ntpass
, ntpasslen
);
821 if (tevent_req_nomem(nt_response
.data
, req
)) {
822 return tevent_req_post(req
, ev
);
827 state
->response
= data_blob_talloc(
828 state
, lm_response
.data
, lm_response
.length
);
830 state
->response
= data_blob_talloc(
831 state
, nt_response
.data
, nt_response
.length
);
833 if (tevent_req_nomem(state
->response
.data
, req
)) {
834 return tevent_req_post(req
, ev
);
837 if (session_key
.data
) {
838 state
->session_key
= data_blob_talloc(
839 state
, session_key
.data
, session_key
.length
);
840 if (tevent_req_nomem(state
->session_key
.data
, req
)) {
841 return tevent_req_post(req
, ev
);
844 data_blob_free(&session_key
);
846 SCVAL(vwv
+0, 0, 0xff);
849 SSVAL(vwv
+2, 0, CLI_BUFFER_SIZE
);
851 SSVAL(vwv
+4, 0, cli_state_get_vc_num(cli
));
852 SIVAL(vwv
+5, 0, smb1cli_conn_server_session_key(cli
->conn
));
853 SSVAL(vwv
+7, 0, lm_response
.length
);
854 SSVAL(vwv
+8, 0, nt_response
.length
);
857 SIVAL(vwv
+11, 0, cli_session_setup_capabilities(cli
, 0));
859 bytes
= talloc_array(state
, uint8_t,
860 lm_response
.length
+ nt_response
.length
);
861 if (tevent_req_nomem(bytes
, req
)) {
862 return tevent_req_post(req
, ev
);
864 if (lm_response
.length
!= 0) {
865 memcpy(bytes
, lm_response
.data
, lm_response
.length
);
867 if (nt_response
.length
!= 0) {
868 memcpy(bytes
+ lm_response
.length
,
869 nt_response
.data
, nt_response
.length
);
871 data_blob_free(&lm_response
);
872 data_blob_free(&nt_response
);
874 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
875 user
, strlen(user
)+1, NULL
);
878 * Upper case here might help some NTLMv2 implementations
880 workgroup_upper
= talloc_strdup_upper(talloc_tos(), workgroup
);
881 if (tevent_req_nomem(workgroup_upper
, req
)) {
882 return tevent_req_post(req
, ev
);
884 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
885 workgroup_upper
, strlen(workgroup_upper
)+1,
887 TALLOC_FREE(workgroup_upper
);
889 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "Unix", 5, NULL
);
890 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), "Samba", 6, NULL
);
891 if (tevent_req_nomem(bytes
, req
)) {
892 return tevent_req_post(req
, ev
);
895 subreq
= cli_smb_send(state
, ev
, cli
, SMBsesssetupX
, 0, 13, vwv
,
896 talloc_get_size(bytes
), bytes
);
897 if (tevent_req_nomem(subreq
, req
)) {
898 return tevent_req_post(req
, ev
);
900 tevent_req_set_callback(subreq
, cli_session_setup_nt1_done
, req
);
904 static void cli_session_setup_nt1_done(struct tevent_req
*subreq
)
906 struct tevent_req
*req
= tevent_req_callback_data(
907 subreq
, struct tevent_req
);
908 struct cli_session_setup_nt1_state
*state
= tevent_req_data(
909 req
, struct cli_session_setup_nt1_state
);
910 struct cli_state
*cli
= state
->cli
;
921 status
= cli_smb_recv(subreq
, state
, &in
, 3, &wct
, &vwv
,
924 if (!NT_STATUS_IS_OK(status
)) {
925 tevent_req_nterror(req
, status
);
929 inhdr
= in
+ NBT_HDR_SIZE
;
932 cli_state_set_uid(state
->cli
, SVAL(inhdr
, HDR_UID
));
933 cli
->is_guestlogin
= ((SVAL(vwv
+2, 0) & 1) != 0);
935 status
= smb_bytes_talloc_string(cli
,
941 if (!NT_STATUS_IS_OK(status
)) {
942 tevent_req_nterror(req
, status
);
947 status
= smb_bytes_talloc_string(cli
,
953 if (!NT_STATUS_IS_OK(status
)) {
954 tevent_req_nterror(req
, status
);
959 status
= smb_bytes_talloc_string(cli
,
965 if (!NT_STATUS_IS_OK(status
)) {
966 tevent_req_nterror(req
, status
);
971 status
= cli_set_username(cli
, state
->user
);
972 if (tevent_req_nterror(req
, status
)) {
975 if (smb1cli_conn_activate_signing(cli
->conn
, state
->session_key
, state
->response
)
976 && !smb1cli_conn_check_signing(cli
->conn
, (uint8_t *)in
, 1)) {
977 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
980 if (state
->session_key
.data
) {
981 struct smbXcli_session
*session
= state
->cli
->smb1
.session
;
983 status
= smb1cli_session_set_session_key(session
,
985 if (tevent_req_nterror(req
, status
)) {
989 tevent_req_done(req
);
992 static NTSTATUS
cli_session_setup_nt1_recv(struct tevent_req
*req
)
994 return tevent_req_simple_recv_ntstatus(req
);
997 /* The following is calculated from :
999 * (smb_wcnt * 2) = 24 (smb_wcnt == 12 in cli_session_setup_blob_send() )
1000 * (strlen("Unix") + 1 + strlen("Samba") + 1) * 2 = 22 (unicode strings at
1004 #define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22)
1006 struct cli_sesssetup_blob_state
{
1007 struct tevent_context
*ev
;
1008 struct cli_state
*cli
;
1010 uint16_t max_blob_size
;
1014 DATA_BLOB smb2_blob
;
1015 struct iovec
*recv_iov
;
1022 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state
*state
,
1023 struct tevent_req
**psubreq
);
1024 static void cli_sesssetup_blob_done(struct tevent_req
*subreq
);
1026 static struct tevent_req
*cli_sesssetup_blob_send(TALLOC_CTX
*mem_ctx
,
1027 struct tevent_context
*ev
,
1028 struct cli_state
*cli
,
1031 struct tevent_req
*req
, *subreq
;
1032 struct cli_sesssetup_blob_state
*state
;
1033 uint32_t usable_space
;
1035 req
= tevent_req_create(mem_ctx
, &state
,
1036 struct cli_sesssetup_blob_state
);
1044 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
1045 usable_space
= UINT16_MAX
;
1047 usable_space
= cli_state_available_size(cli
,
1048 BASE_SESSSETUP_BLOB_PACKET_SIZE
);
1051 if (usable_space
== 0) {
1052 DEBUG(1, ("cli_session_setup_blob: cli->max_xmit too small "
1053 "(not possible to send %u bytes)\n",
1054 BASE_SESSSETUP_BLOB_PACKET_SIZE
+ 1));
1055 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1056 return tevent_req_post(req
, ev
);
1058 state
->max_blob_size
= MIN(usable_space
, 0xFFFF);
1060 if (!cli_sesssetup_blob_next(state
, &subreq
)) {
1061 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
1062 return tevent_req_post(req
, ev
);
1064 tevent_req_set_callback(subreq
, cli_sesssetup_blob_done
, req
);
1068 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state
*state
,
1069 struct tevent_req
**psubreq
)
1071 struct tevent_req
*subreq
;
1074 thistime
= MIN(state
->blob
.length
, state
->max_blob_size
);
1076 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
1078 state
->smb2_blob
.data
= state
->blob
.data
;
1079 state
->smb2_blob
.length
= thistime
;
1081 state
->blob
.data
+= thistime
;
1082 state
->blob
.length
-= thistime
;
1084 subreq
= smb2cli_session_setup_send(state
, state
->ev
,
1086 state
->cli
->timeout
,
1087 state
->cli
->smb2
.session
,
1089 SMB2_CAP_DFS
, /* in_capabilities */
1091 0, /* in_previous_session_id */
1093 if (subreq
== NULL
) {
1100 SCVAL(state
->vwv
+0, 0, 0xFF);
1101 SCVAL(state
->vwv
+0, 1, 0);
1102 SSVAL(state
->vwv
+1, 0, 0);
1103 SSVAL(state
->vwv
+2, 0, CLI_BUFFER_SIZE
);
1104 SSVAL(state
->vwv
+3, 0, 2);
1105 SSVAL(state
->vwv
+4, 0, 1);
1106 SIVAL(state
->vwv
+5, 0, 0);
1108 SSVAL(state
->vwv
+7, 0, thistime
);
1110 SSVAL(state
->vwv
+8, 0, 0);
1111 SSVAL(state
->vwv
+9, 0, 0);
1112 SIVAL(state
->vwv
+10, 0,
1113 cli_session_setup_capabilities(state
->cli
, CAP_EXTENDED_SECURITY
));
1115 state
->buf
= (uint8_t *)talloc_memdup(state
, state
->blob
.data
,
1117 if (state
->buf
== NULL
) {
1120 state
->blob
.data
+= thistime
;
1121 state
->blob
.length
-= thistime
;
1123 state
->buf
= smb_bytes_push_str(state
->buf
, smbXcli_conn_use_unicode(state
->cli
->conn
),
1125 state
->buf
= smb_bytes_push_str(state
->buf
, smbXcli_conn_use_unicode(state
->cli
->conn
),
1127 if (state
->buf
== NULL
) {
1130 subreq
= cli_smb_send(state
, state
->ev
, state
->cli
, SMBsesssetupX
, 0,
1132 talloc_get_size(state
->buf
), state
->buf
);
1133 if (subreq
== NULL
) {
1140 static void cli_sesssetup_blob_done(struct tevent_req
*subreq
)
1142 struct tevent_req
*req
= tevent_req_callback_data(
1143 subreq
, struct tevent_req
);
1144 struct cli_sesssetup_blob_state
*state
= tevent_req_data(
1145 req
, struct cli_sesssetup_blob_state
);
1146 struct cli_state
*cli
= state
->cli
;
1153 uint16_t blob_length
;
1158 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
1159 status
= smb2cli_session_setup_recv(subreq
, state
,
1163 status
= cli_smb_recv(subreq
, state
, &in
, 4, &wct
, &vwv
,
1164 &num_bytes
, &bytes
);
1165 TALLOC_FREE(state
->buf
);
1167 TALLOC_FREE(subreq
);
1168 if (!NT_STATUS_IS_OK(status
)
1169 && !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1170 tevent_req_nterror(req
, status
);
1174 state
->status
= status
;
1176 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
1181 inhdr
= in
+ NBT_HDR_SIZE
;
1182 cli_state_set_uid(state
->cli
, SVAL(inhdr
, HDR_UID
));
1183 cli
->is_guestlogin
= ((SVAL(vwv
+2, 0) & 1) != 0);
1185 blob_length
= SVAL(vwv
+3, 0);
1186 if (blob_length
> num_bytes
) {
1187 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
1190 state
->ret_blob
= data_blob_const(bytes
, blob_length
);
1192 p
= bytes
+ blob_length
;
1194 status
= smb_bytes_talloc_string(cli
,
1201 if (!NT_STATUS_IS_OK(status
)) {
1202 tevent_req_nterror(req
, status
);
1207 status
= smb_bytes_talloc_string(cli
,
1214 if (!NT_STATUS_IS_OK(status
)) {
1215 tevent_req_nterror(req
, status
);
1220 status
= smb_bytes_talloc_string(cli
,
1222 &cli
->server_domain
,
1227 if (!NT_STATUS_IS_OK(status
)) {
1228 tevent_req_nterror(req
, status
);
1234 if (state
->blob
.length
!= 0) {
1238 if (!cli_sesssetup_blob_next(state
, &subreq
)) {
1239 tevent_req_oom(req
);
1242 tevent_req_set_callback(subreq
, cli_sesssetup_blob_done
, req
);
1245 tevent_req_done(req
);
1248 static NTSTATUS
cli_sesssetup_blob_recv(struct tevent_req
*req
,
1249 TALLOC_CTX
*mem_ctx
,
1252 struct iovec
**precv_iov
)
1254 struct cli_sesssetup_blob_state
*state
= tevent_req_data(
1255 req
, struct cli_sesssetup_blob_state
);
1258 struct iovec
*recv_iov
;
1260 if (tevent_req_is_nterror(req
, &status
)) {
1261 TALLOC_FREE(state
->cli
->smb2
.session
);
1262 cli_state_set_uid(state
->cli
, UID_FIELD_INVALID
);
1266 inbuf
= talloc_move(mem_ctx
, &state
->inbuf
);
1267 recv_iov
= talloc_move(mem_ctx
, &state
->recv_iov
);
1268 if (pblob
!= NULL
) {
1269 *pblob
= state
->ret_blob
;
1271 if (pinbuf
!= NULL
) {
1274 if (precv_iov
!= NULL
) {
1275 *precv_iov
= recv_iov
;
1277 /* could be NT_STATUS_MORE_PROCESSING_REQUIRED */
1278 return state
->status
;
1283 /****************************************************************************
1284 Use in-memory credentials cache
1285 ****************************************************************************/
1287 static void use_in_memory_ccache(void) {
1288 setenv(KRB5_ENV_CCNAME
, "MEMORY:cliconnect", 1);
1291 /****************************************************************************
1292 Do a spnego/kerberos encrypted session setup.
1293 ****************************************************************************/
1295 struct cli_session_setup_kerberos_state
{
1296 struct cli_state
*cli
;
1297 DATA_BLOB negTokenTarg
;
1298 DATA_BLOB session_key_krb5
;
1299 ADS_STATUS ads_status
;
1302 static void cli_session_setup_kerberos_done(struct tevent_req
*subreq
);
1304 static struct tevent_req
*cli_session_setup_kerberos_send(
1305 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
1306 const char *principal
)
1308 struct tevent_req
*req
, *subreq
;
1309 struct cli_session_setup_kerberos_state
*state
;
1312 DEBUG(2,("Doing kerberos session setup\n"));
1314 req
= tevent_req_create(mem_ctx
, &state
,
1315 struct cli_session_setup_kerberos_state
);
1320 state
->ads_status
= ADS_SUCCESS
;
1323 * Ok, this is cheating: spnego_gen_krb5_negTokenInit can block if
1324 * we have to acquire a ticket. To be fixed later :-)
1326 rc
= spnego_gen_krb5_negTokenInit(state
, principal
, 0, &state
->negTokenTarg
,
1327 &state
->session_key_krb5
, 0, NULL
, NULL
);
1329 DEBUG(1, ("cli_session_setup_kerberos: "
1330 "spnego_gen_krb5_negTokenInit failed: %s\n",
1331 error_message(rc
)));
1332 state
->ads_status
= ADS_ERROR_KRB5(rc
);
1333 tevent_req_nterror(req
, NT_STATUS_UNSUCCESSFUL
);
1334 return tevent_req_post(req
, ev
);
1338 file_save("negTokenTarg.dat", state
->negTokenTarg
.data
,
1339 state
->negTokenTarg
.length
);
1342 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
1343 state
->cli
->smb2
.session
= smbXcli_session_create(cli
,
1345 if (tevent_req_nomem(state
->cli
->smb2
.session
, req
)) {
1346 return tevent_req_post(req
, ev
);
1350 subreq
= cli_sesssetup_blob_send(state
, ev
, cli
, state
->negTokenTarg
);
1351 if (tevent_req_nomem(subreq
, req
)) {
1352 return tevent_req_post(req
, ev
);
1354 tevent_req_set_callback(subreq
, cli_session_setup_kerberos_done
, req
);
1358 static void cli_session_setup_kerberos_done(struct tevent_req
*subreq
)
1360 struct tevent_req
*req
= tevent_req_callback_data(
1361 subreq
, struct tevent_req
);
1362 struct cli_session_setup_kerberos_state
*state
= tevent_req_data(
1363 req
, struct cli_session_setup_kerberos_state
);
1364 uint8_t *inbuf
= NULL
;
1365 struct iovec
*recv_iov
= NULL
;
1368 status
= cli_sesssetup_blob_recv(subreq
, state
,
1369 NULL
, &inbuf
, &recv_iov
);
1370 TALLOC_FREE(subreq
);
1371 if (!NT_STATUS_IS_OK(status
)) {
1372 tevent_req_nterror(req
, status
);
1376 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
1377 struct smbXcli_session
*session
= state
->cli
->smb2
.session
;
1378 status
= smb2cli_session_set_session_key(session
,
1379 state
->session_key_krb5
,
1381 if (tevent_req_nterror(req
, status
)) {
1385 struct smbXcli_session
*session
= state
->cli
->smb1
.session
;
1387 status
= smb1cli_session_set_session_key(session
,
1388 state
->session_key_krb5
);
1389 if (tevent_req_nterror(req
, status
)) {
1393 if (smb1cli_conn_activate_signing(state
->cli
->conn
, state
->session_key_krb5
,
1395 && !smb1cli_conn_check_signing(state
->cli
->conn
, inbuf
, 1)) {
1396 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1401 tevent_req_done(req
);
1404 static ADS_STATUS
cli_session_setup_kerberos_recv(struct tevent_req
*req
)
1406 struct cli_session_setup_kerberos_state
*state
= tevent_req_data(
1407 req
, struct cli_session_setup_kerberos_state
);
1410 if (tevent_req_is_nterror(req
, &status
)) {
1411 return ADS_ERROR_NT(status
);
1413 return state
->ads_status
;
1416 #endif /* HAVE_KRB5 */
1418 /****************************************************************************
1419 Do a spnego/NTLMSSP encrypted session setup.
1420 ****************************************************************************/
1422 struct cli_session_setup_ntlmssp_state
{
1423 struct tevent_context
*ev
;
1424 struct cli_state
*cli
;
1425 struct ntlmssp_state
*ntlmssp_state
;
1430 static int cli_session_setup_ntlmssp_state_destructor(
1431 struct cli_session_setup_ntlmssp_state
*state
)
1433 if (state
->ntlmssp_state
!= NULL
) {
1434 TALLOC_FREE(state
->ntlmssp_state
);
1439 static void cli_session_setup_ntlmssp_done(struct tevent_req
*req
);
1441 static struct tevent_req
*cli_session_setup_ntlmssp_send(
1442 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
1443 const char *user
, const char *pass
, const char *domain
)
1445 struct tevent_req
*req
, *subreq
;
1446 struct cli_session_setup_ntlmssp_state
*state
;
1449 const char *OIDs_ntlm
[] = {OID_NTLMSSP
, NULL
};
1451 req
= tevent_req_create(mem_ctx
, &state
,
1452 struct cli_session_setup_ntlmssp_state
);
1460 state
->ntlmssp_state
= NULL
;
1461 talloc_set_destructor(
1462 state
, cli_session_setup_ntlmssp_state_destructor
);
1464 status
= ntlmssp_client_start(state
,
1467 lp_client_ntlmv2_auth(),
1468 &state
->ntlmssp_state
);
1469 if (!NT_STATUS_IS_OK(status
)) {
1472 ntlmssp_want_feature(state
->ntlmssp_state
,
1473 NTLMSSP_FEATURE_SESSION_KEY
);
1474 if (cli
->use_ccache
) {
1475 ntlmssp_want_feature(state
->ntlmssp_state
,
1476 NTLMSSP_FEATURE_CCACHE
);
1478 status
= ntlmssp_set_username(state
->ntlmssp_state
, user
);
1479 if (!NT_STATUS_IS_OK(status
)) {
1482 status
= ntlmssp_set_domain(state
->ntlmssp_state
, domain
);
1483 if (!NT_STATUS_IS_OK(status
)) {
1486 if (cli
->pw_nt_hash
) {
1487 status
= ntlmssp_set_password_hash(state
->ntlmssp_state
, pass
);
1489 status
= ntlmssp_set_password(state
->ntlmssp_state
, pass
);
1491 if (!NT_STATUS_IS_OK(status
)) {
1494 status
= ntlmssp_update(state
->ntlmssp_state
, data_blob_null
,
1496 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1500 state
->blob_out
= spnego_gen_negTokenInit(state
, OIDs_ntlm
, &blob_out
, NULL
);
1501 data_blob_free(&blob_out
);
1503 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
1504 state
->cli
->smb2
.session
= smbXcli_session_create(cli
,
1506 if (tevent_req_nomem(state
->cli
->smb2
.session
, req
)) {
1507 return tevent_req_post(req
, ev
);
1511 subreq
= cli_sesssetup_blob_send(state
, ev
, cli
, state
->blob_out
);
1512 if (tevent_req_nomem(subreq
, req
)) {
1513 return tevent_req_post(req
, ev
);
1515 tevent_req_set_callback(subreq
, cli_session_setup_ntlmssp_done
, req
);
1518 tevent_req_nterror(req
, status
);
1519 return tevent_req_post(req
, ev
);
1522 static void cli_session_setup_ntlmssp_done(struct tevent_req
*subreq
)
1524 struct tevent_req
*req
= tevent_req_callback_data(
1525 subreq
, struct tevent_req
);
1526 struct cli_session_setup_ntlmssp_state
*state
= tevent_req_data(
1527 req
, struct cli_session_setup_ntlmssp_state
);
1528 DATA_BLOB blob_in
, msg_in
, blob_out
;
1529 uint8_t *inbuf
= NULL
;
1530 struct iovec
*recv_iov
= NULL
;
1534 status
= cli_sesssetup_blob_recv(subreq
, talloc_tos(), &blob_in
,
1536 TALLOC_FREE(subreq
);
1537 data_blob_free(&state
->blob_out
);
1539 if (NT_STATUS_IS_OK(status
)) {
1540 if (state
->cli
->server_domain
[0] == '\0') {
1541 TALLOC_FREE(state
->cli
->server_domain
);
1542 state
->cli
->server_domain
= talloc_strdup(state
->cli
,
1543 state
->ntlmssp_state
->server
.netbios_domain
);
1544 if (state
->cli
->server_domain
== NULL
) {
1545 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
1550 if (smbXcli_conn_protocol(state
->cli
->conn
) >= PROTOCOL_SMB2_02
) {
1551 struct smbXcli_session
*session
= state
->cli
->smb2
.session
;
1553 if (ntlmssp_is_anonymous(state
->ntlmssp_state
)) {
1555 * Windows server does not set the
1556 * SMB2_SESSION_FLAG_IS_GUEST nor
1557 * SMB2_SESSION_FLAG_IS_NULL flag.
1559 * This fix makes sure we do not try
1560 * to verify a signature on the final
1561 * session setup response.
1563 TALLOC_FREE(state
->ntlmssp_state
);
1564 tevent_req_done(req
);
1568 status
= smb2cli_session_set_session_key(session
,
1569 state
->ntlmssp_state
->session_key
,
1571 if (tevent_req_nterror(req
, status
)) {
1575 struct smbXcli_session
*session
= state
->cli
->smb1
.session
;
1577 status
= smb1cli_session_set_session_key(session
,
1578 state
->ntlmssp_state
->session_key
);
1579 if (tevent_req_nterror(req
, status
)) {
1583 if (smb1cli_conn_activate_signing(
1584 state
->cli
->conn
, state
->ntlmssp_state
->session_key
,
1586 && !smb1cli_conn_check_signing(state
->cli
->conn
, inbuf
, 1)) {
1587 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1591 TALLOC_FREE(state
->ntlmssp_state
);
1592 tevent_req_done(req
);
1595 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1596 tevent_req_nterror(req
, status
);
1600 if (blob_in
.length
== 0) {
1601 tevent_req_nterror(req
, NT_STATUS_UNSUCCESSFUL
);
1605 if ((state
->turn
== 1)
1606 && NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1607 DATA_BLOB tmp_blob
= data_blob_null
;
1608 /* the server might give us back two challenges */
1609 parse_ret
= spnego_parse_challenge(state
, blob_in
, &msg_in
,
1611 data_blob_free(&tmp_blob
);
1613 parse_ret
= spnego_parse_auth_response(state
, blob_in
, status
,
1614 OID_NTLMSSP
, &msg_in
);
1619 DEBUG(3,("Failed to parse auth response\n"));
1620 if (NT_STATUS_IS_OK(status
)
1621 || NT_STATUS_EQUAL(status
,
1622 NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1624 req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
1629 status
= ntlmssp_update(state
->ntlmssp_state
, msg_in
, &blob_out
);
1631 if (!NT_STATUS_IS_OK(status
)
1632 && !NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
1633 TALLOC_FREE(state
->ntlmssp_state
);
1634 tevent_req_nterror(req
, status
);
1638 state
->blob_out
= spnego_gen_auth(state
, blob_out
);
1639 if (tevent_req_nomem(state
->blob_out
.data
, req
)) {
1643 subreq
= cli_sesssetup_blob_send(state
, state
->ev
, state
->cli
,
1645 if (tevent_req_nomem(subreq
, req
)) {
1648 tevent_req_set_callback(subreq
, cli_session_setup_ntlmssp_done
, req
);
1651 static NTSTATUS
cli_session_setup_ntlmssp_recv(struct tevent_req
*req
)
1653 struct cli_session_setup_ntlmssp_state
*state
= tevent_req_data(
1654 req
, struct cli_session_setup_ntlmssp_state
);
1657 if (tevent_req_is_nterror(req
, &status
)) {
1658 cli_state_set_uid(state
->cli
, UID_FIELD_INVALID
);
1661 return NT_STATUS_OK
;
1666 static char *cli_session_setup_get_principal(
1667 TALLOC_CTX
*mem_ctx
, const char *spnego_principal
,
1668 const char *remote_name
, const char *dest_realm
)
1670 char *principal
= NULL
;
1672 if (!lp_client_use_spnego_principal() ||
1673 strequal(principal
, ADS_IGNORE_PRINCIPAL
)) {
1674 spnego_principal
= NULL
;
1676 if (spnego_principal
!= NULL
) {
1677 DEBUG(3, ("cli_session_setup_spnego: using spnego provided "
1678 "principal %s\n", spnego_principal
));
1679 return talloc_strdup(mem_ctx
, spnego_principal
);
1681 if (is_ipaddress(remote_name
) ||
1682 strequal(remote_name
, STAR_SMBSERVER
)) {
1686 DEBUG(3, ("cli_session_setup_spnego: using target "
1687 "hostname not SPNEGO principal\n"));
1690 char *realm
= strupper_talloc(talloc_tos(), dest_realm
);
1691 if (realm
== NULL
) {
1694 principal
= talloc_asprintf(talloc_tos(), "cifs/%s@%s",
1695 remote_name
, realm
);
1698 principal
= kerberos_get_principal_from_service_hostname(
1699 talloc_tos(), "cifs", remote_name
, lp_realm());
1701 DEBUG(3, ("cli_session_setup_spnego: guessed server principal=%s\n",
1702 principal
? principal
: "<null>"));
1708 static char *cli_session_setup_get_account(TALLOC_CTX
*mem_ctx
,
1709 const char *principal
)
1713 account
= talloc_strdup(mem_ctx
, principal
);
1714 if (account
== NULL
) {
1717 p
= strchr_m(account
, '@');
1724 /****************************************************************************
1725 Do a spnego encrypted session setup.
1727 user_domain: The shortname of the domain the user/machine is a member of.
1728 dest_realm: The realm we're connecting to, if NULL we use our default realm.
1729 ****************************************************************************/
1731 struct cli_session_setup_spnego_state
{
1732 struct tevent_context
*ev
;
1733 struct cli_state
*cli
;
1735 const char *account
;
1737 const char *user_domain
;
1738 const char *dest_realm
;
1743 static void cli_session_setup_spnego_done_krb(struct tevent_req
*subreq
);
1746 static void cli_session_setup_spnego_done_ntlmssp(struct tevent_req
*subreq
);
1748 static struct tevent_req
*cli_session_setup_spnego_send(
1749 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, struct cli_state
*cli
,
1750 const char *user
, const char *pass
, const char *user_domain
,
1751 const char *dest_realm
)
1753 struct tevent_req
*req
, *subreq
;
1754 struct cli_session_setup_spnego_state
*state
;
1755 char *principal
= NULL
;
1756 char *OIDs
[ASN1_MAX_OIDS
];
1758 const DATA_BLOB
*server_blob
;
1761 req
= tevent_req_create(mem_ctx
, &state
,
1762 struct cli_session_setup_spnego_state
);
1770 state
->user_domain
= user_domain
;
1771 state
->dest_realm
= dest_realm
;
1773 state
->account
= cli_session_setup_get_account(state
, user
);
1774 if (tevent_req_nomem(state
->account
, req
)) {
1775 return tevent_req_post(req
, ev
);
1778 server_blob
= smbXcli_conn_server_gss_blob(cli
->conn
);
1780 DEBUG(3,("Doing spnego session setup (blob length=%lu)\n",
1781 (unsigned long)server_blob
->length
));
1783 /* the server might not even do spnego */
1784 if (server_blob
->length
== 0) {
1785 DEBUG(3,("server didn't supply a full spnego negprot\n"));
1790 file_save("negprot.dat", cli
->secblob
.data
, cli
->secblob
.length
);
1793 /* The server sent us the first part of the SPNEGO exchange in the
1794 * negprot reply. It is WRONG to depend on the principal sent in the
1795 * negprot reply, but right now we do it. If we don't receive one,
1796 * we try to best guess, then fall back to NTLM. */
1797 if (!spnego_parse_negTokenInit(state
, *server_blob
, OIDs
,
1798 &principal
, NULL
) ||
1800 state
->result
= ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
1801 tevent_req_done(req
);
1802 return tevent_req_post(req
, ev
);
1805 /* make sure the server understands kerberos */
1806 for (i
=0;OIDs
[i
];i
++) {
1808 DEBUG(3,("got OID=%s\n", OIDs
[i
]));
1810 DEBUGADD(3,("got OID=%s\n", OIDs
[i
]));
1811 if (strcmp(OIDs
[i
], OID_KERBEROS5_OLD
) == 0 ||
1812 strcmp(OIDs
[i
], OID_KERBEROS5
) == 0) {
1813 cli
->got_kerberos_mechanism
= True
;
1815 talloc_free(OIDs
[i
]);
1818 DEBUG(3,("got principal=%s\n", principal
? principal
: "<null>"));
1820 status
= cli_set_username(cli
, user
);
1821 if (!NT_STATUS_IS_OK(status
)) {
1822 state
->result
= ADS_ERROR_NT(status
);
1823 tevent_req_done(req
);
1824 return tevent_req_post(req
, ev
);
1828 /* If password is set we reauthenticate to kerberos server
1829 * and do not store results */
1831 if (user
&& *user
&& cli
->got_kerberos_mechanism
&& cli
->use_kerberos
) {
1832 const char *remote_name
= smbXcli_conn_remote_name(cli
->conn
);
1835 if (pass
&& *pass
) {
1838 use_in_memory_ccache();
1839 ret
= kerberos_kinit_password(user
, pass
, 0 /* no time correction for now */, NULL
);
1842 TALLOC_FREE(principal
);
1843 DEBUG(0, ("Kinit failed: %s\n", error_message(ret
)));
1844 if (cli
->fallback_after_kerberos
)
1846 state
->result
= ADS_ERROR_KRB5(ret
);
1847 tevent_req_done(req
);
1848 return tevent_req_post(req
, ev
);
1852 tmp
= cli_session_setup_get_principal(
1853 talloc_tos(), principal
, remote_name
, dest_realm
);
1854 TALLOC_FREE(principal
);
1858 subreq
= cli_session_setup_kerberos_send(
1859 state
, ev
, cli
, principal
);
1860 if (tevent_req_nomem(subreq
, req
)) {
1861 return tevent_req_post(req
, ev
);
1863 tevent_req_set_callback(
1864 subreq
, cli_session_setup_spnego_done_krb
,
1872 subreq
= cli_session_setup_ntlmssp_send(
1873 state
, ev
, cli
, state
->account
, pass
, user_domain
);
1874 if (tevent_req_nomem(subreq
, req
)) {
1875 return tevent_req_post(req
, ev
);
1877 tevent_req_set_callback(
1878 subreq
, cli_session_setup_spnego_done_ntlmssp
, req
);
1883 static void cli_session_setup_spnego_done_krb(struct tevent_req
*subreq
)
1885 struct tevent_req
*req
= tevent_req_callback_data(
1886 subreq
, struct tevent_req
);
1887 struct cli_session_setup_spnego_state
*state
= tevent_req_data(
1888 req
, struct cli_session_setup_spnego_state
);
1890 state
->result
= cli_session_setup_kerberos_recv(subreq
);
1891 TALLOC_FREE(subreq
);
1893 if (ADS_ERR_OK(state
->result
) ||
1894 !state
->cli
->fallback_after_kerberos
) {
1895 tevent_req_done(req
);
1899 subreq
= cli_session_setup_ntlmssp_send(
1900 state
, state
->ev
, state
->cli
, state
->account
, state
->pass
,
1901 state
->user_domain
);
1902 if (tevent_req_nomem(subreq
, req
)) {
1905 tevent_req_set_callback(subreq
, cli_session_setup_spnego_done_ntlmssp
,
1910 static void cli_session_setup_spnego_done_ntlmssp(struct tevent_req
*subreq
)
1912 struct tevent_req
*req
= tevent_req_callback_data(
1913 subreq
, struct tevent_req
);
1914 struct cli_session_setup_spnego_state
*state
= tevent_req_data(
1915 req
, struct cli_session_setup_spnego_state
);
1918 status
= cli_session_setup_ntlmssp_recv(subreq
);
1919 TALLOC_FREE(subreq
);
1920 state
->result
= ADS_ERROR_NT(status
);
1921 tevent_req_done(req
);
1924 static ADS_STATUS
cli_session_setup_spnego_recv(struct tevent_req
*req
)
1926 struct cli_session_setup_spnego_state
*state
= tevent_req_data(
1927 req
, struct cli_session_setup_spnego_state
);
1929 return state
->result
;
1932 struct cli_session_setup_state
{
1936 static void cli_session_setup_done_lanman2(struct tevent_req
*subreq
);
1937 static void cli_session_setup_done_spnego(struct tevent_req
*subreq
);
1938 static void cli_session_setup_done_guest(struct tevent_req
*subreq
);
1939 static void cli_session_setup_done_plain(struct tevent_req
*subreq
);
1940 static void cli_session_setup_done_nt1(struct tevent_req
*subreq
);
1942 /****************************************************************************
1943 Send a session setup. The username and workgroup is in UNIX character
1944 format and must be converted to DOS codepage format before sending. If the
1945 password is in plaintext, the same should be done.
1946 ****************************************************************************/
1948 struct tevent_req
*cli_session_setup_send(TALLOC_CTX
*mem_ctx
,
1949 struct tevent_context
*ev
,
1950 struct cli_state
*cli
,
1952 const char *pass
, int passlen
,
1953 const char *ntpass
, int ntpasslen
,
1954 const char *workgroup
)
1956 struct tevent_req
*req
, *subreq
;
1957 struct cli_session_setup_state
*state
;
1960 uint16_t sec_mode
= smb1cli_conn_server_security_mode(cli
->conn
);
1962 req
= tevent_req_create(mem_ctx
, &state
,
1963 struct cli_session_setup_state
);
1969 user2
= talloc_strdup(state
, user
);
1971 user2
= talloc_strdup(state
, "");
1973 if (user2
== NULL
) {
1974 tevent_req_oom(req
);
1975 return tevent_req_post(req
, ev
);
1982 /* allow for workgroups as part of the username */
1983 if ((p
=strchr_m(user2
,'\\')) || (p
=strchr_m(user2
,'/')) ||
1984 (p
=strchr_m(user2
,*lp_winbind_separator()))) {
1987 if (!strupper_m(user2
)) {
1988 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1989 return tevent_req_post(req
, ev
);
1994 if (smbXcli_conn_protocol(cli
->conn
) < PROTOCOL_LANMAN1
) {
1995 tevent_req_done(req
);
1996 return tevent_req_post(req
, ev
);
1999 /* now work out what sort of session setup we are going to
2000 do. I have split this into separate functions to make the
2001 flow a bit easier to understand (tridge) */
2003 /* if its an older server then we have to use the older request format */
2005 if (smbXcli_conn_protocol(cli
->conn
) < PROTOCOL_NT1
) {
2006 if (!lp_client_lanman_auth() && passlen
!= 24 && (*pass
)) {
2007 DEBUG(1, ("Server requested LM password but 'client lanman auth = no'"
2008 " or 'client ntlmv2 auth = yes'\n"));
2009 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
2010 return tevent_req_post(req
, ev
);
2013 if ((sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
) == 0 &&
2014 !lp_client_plaintext_auth() && (*pass
)) {
2015 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
2016 " or 'client ntlmv2 auth = yes'\n"));
2017 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
2018 return tevent_req_post(req
, ev
);
2021 subreq
= cli_session_setup_lanman2_send(
2022 state
, ev
, cli
, user
, pass
, passlen
, workgroup
);
2023 if (tevent_req_nomem(subreq
, req
)) {
2024 return tevent_req_post(req
, ev
);
2026 tevent_req_set_callback(subreq
, cli_session_setup_done_lanman2
,
2031 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
2032 const char *remote_realm
= cli_state_remote_realm(cli
);
2034 subreq
= cli_session_setup_spnego_send(
2035 state
, ev
, cli
, user
, pass
, workgroup
, remote_realm
);
2036 if (tevent_req_nomem(subreq
, req
)) {
2037 return tevent_req_post(req
, ev
);
2039 tevent_req_set_callback(subreq
, cli_session_setup_done_spnego
,
2044 /* if no user is supplied then we have to do an anonymous connection.
2045 passwords are ignored */
2047 if (!user
|| !*user
) {
2048 subreq
= cli_session_setup_guest_send(state
, ev
, cli
);
2049 if (tevent_req_nomem(subreq
, req
)) {
2050 return tevent_req_post(req
, ev
);
2052 tevent_req_set_callback(subreq
, cli_session_setup_done_guest
,
2057 /* if the server is share level then send a plaintext null
2058 password at this point. The password is sent in the tree
2061 if ((sec_mode
& NEGOTIATE_SECURITY_USER_LEVEL
) == 0) {
2062 subreq
= cli_session_setup_plain_send(
2063 state
, ev
, cli
, user
, "", workgroup
);
2064 if (tevent_req_nomem(subreq
, req
)) {
2065 return tevent_req_post(req
, ev
);
2067 tevent_req_set_callback(subreq
, cli_session_setup_done_plain
,
2072 /* if the server doesn't support encryption then we have to use
2073 plaintext. The second password is ignored */
2075 if ((sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
) == 0) {
2076 if (!lp_client_plaintext_auth() && (*pass
)) {
2077 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
2078 " or 'client ntlmv2 auth = yes'\n"));
2079 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
2080 return tevent_req_post(req
, ev
);
2082 subreq
= cli_session_setup_plain_send(
2083 state
, ev
, cli
, user
, pass
, workgroup
);
2084 if (tevent_req_nomem(subreq
, req
)) {
2085 return tevent_req_post(req
, ev
);
2087 tevent_req_set_callback(subreq
, cli_session_setup_done_plain
,
2092 /* if the server supports extended security then use SPNEGO */
2094 if (smb1cli_conn_capabilities(cli
->conn
) & CAP_EXTENDED_SECURITY
) {
2095 const char *remote_realm
= cli_state_remote_realm(cli
);
2097 subreq
= cli_session_setup_spnego_send(
2098 state
, ev
, cli
, user
, pass
, workgroup
, remote_realm
);
2099 if (tevent_req_nomem(subreq
, req
)) {
2100 return tevent_req_post(req
, ev
);
2102 tevent_req_set_callback(subreq
, cli_session_setup_done_spnego
,
2106 /* otherwise do a NT1 style session setup */
2108 subreq
= cli_session_setup_nt1_send(
2109 state
, ev
, cli
, user
, pass
, passlen
, ntpass
, ntpasslen
,
2111 if (tevent_req_nomem(subreq
, req
)) {
2112 return tevent_req_post(req
, ev
);
2114 tevent_req_set_callback(subreq
, cli_session_setup_done_nt1
,
2119 tevent_req_done(req
);
2120 return tevent_req_post(req
, ev
);
2123 static void cli_session_setup_done_lanman2(struct tevent_req
*subreq
)
2125 struct tevent_req
*req
= tevent_req_callback_data(
2126 subreq
, struct tevent_req
);
2129 status
= cli_session_setup_lanman2_recv(subreq
);
2130 TALLOC_FREE(subreq
);
2131 if (!NT_STATUS_IS_OK(status
)) {
2132 tevent_req_nterror(req
, status
);
2135 tevent_req_done(req
);
2138 static void cli_session_setup_done_spnego(struct tevent_req
*subreq
)
2140 struct tevent_req
*req
= tevent_req_callback_data(
2141 subreq
, struct tevent_req
);
2144 status
= cli_session_setup_spnego_recv(subreq
);
2145 TALLOC_FREE(subreq
);
2146 if (!ADS_ERR_OK(status
)) {
2147 DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status
)));
2148 tevent_req_nterror(req
, ads_ntstatus(status
));
2151 tevent_req_done(req
);
2154 static void cli_session_setup_done_guest(struct tevent_req
*subreq
)
2156 struct tevent_req
*req
= tevent_req_callback_data(
2157 subreq
, struct tevent_req
);
2160 status
= cli_session_setup_guest_recv(subreq
);
2161 TALLOC_FREE(subreq
);
2162 if (!NT_STATUS_IS_OK(status
)) {
2163 tevent_req_nterror(req
, status
);
2166 tevent_req_done(req
);
2169 static void cli_session_setup_done_plain(struct tevent_req
*subreq
)
2171 struct tevent_req
*req
= tevent_req_callback_data(
2172 subreq
, struct tevent_req
);
2175 status
= cli_session_setup_plain_recv(subreq
);
2176 TALLOC_FREE(subreq
);
2177 if (!NT_STATUS_IS_OK(status
)) {
2178 tevent_req_nterror(req
, status
);
2181 tevent_req_done(req
);
2184 static void cli_session_setup_done_nt1(struct tevent_req
*subreq
)
2186 struct tevent_req
*req
= tevent_req_callback_data(
2187 subreq
, struct tevent_req
);
2190 status
= cli_session_setup_nt1_recv(subreq
);
2191 TALLOC_FREE(subreq
);
2192 if (!NT_STATUS_IS_OK(status
)) {
2193 DEBUG(3, ("cli_session_setup: NT1 session setup "
2194 "failed: %s\n", nt_errstr(status
)));
2195 tevent_req_nterror(req
, status
);
2198 tevent_req_done(req
);
2201 NTSTATUS
cli_session_setup_recv(struct tevent_req
*req
)
2203 return tevent_req_simple_recv_ntstatus(req
);
2206 NTSTATUS
cli_session_setup(struct cli_state
*cli
,
2208 const char *pass
, int passlen
,
2209 const char *ntpass
, int ntpasslen
,
2210 const char *workgroup
)
2212 struct tevent_context
*ev
;
2213 struct tevent_req
*req
;
2214 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2216 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
2217 return NT_STATUS_INVALID_PARAMETER
;
2219 ev
= samba_tevent_context_init(talloc_tos());
2223 req
= cli_session_setup_send(ev
, ev
, cli
, user
, pass
, passlen
,
2224 ntpass
, ntpasslen
, workgroup
);
2228 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2231 status
= cli_session_setup_recv(req
);
2237 /****************************************************************************
2239 *****************************************************************************/
2241 struct cli_ulogoff_state
{
2242 struct cli_state
*cli
;
2246 static void cli_ulogoff_done(struct tevent_req
*subreq
);
2248 struct tevent_req
*cli_ulogoff_send(TALLOC_CTX
*mem_ctx
,
2249 struct tevent_context
*ev
,
2250 struct cli_state
*cli
)
2252 struct tevent_req
*req
, *subreq
;
2253 struct cli_ulogoff_state
*state
;
2255 req
= tevent_req_create(mem_ctx
, &state
, struct cli_ulogoff_state
);
2261 SCVAL(state
->vwv
+0, 0, 0xFF);
2262 SCVAL(state
->vwv
+1, 0, 0);
2263 SSVAL(state
->vwv
+2, 0, 0);
2265 subreq
= cli_smb_send(state
, ev
, cli
, SMBulogoffX
, 0, 2, state
->vwv
,
2267 if (tevent_req_nomem(subreq
, req
)) {
2268 return tevent_req_post(req
, ev
);
2270 tevent_req_set_callback(subreq
, cli_ulogoff_done
, req
);
2274 static void cli_ulogoff_done(struct tevent_req
*subreq
)
2276 struct tevent_req
*req
= tevent_req_callback_data(
2277 subreq
, struct tevent_req
);
2278 struct cli_ulogoff_state
*state
= tevent_req_data(
2279 req
, struct cli_ulogoff_state
);
2282 status
= cli_smb_recv(subreq
, NULL
, NULL
, 0, NULL
, NULL
, NULL
, NULL
);
2283 if (!NT_STATUS_IS_OK(status
)) {
2284 tevent_req_nterror(req
, status
);
2287 cli_state_set_uid(state
->cli
, UID_FIELD_INVALID
);
2288 tevent_req_done(req
);
2291 NTSTATUS
cli_ulogoff_recv(struct tevent_req
*req
)
2293 return tevent_req_simple_recv_ntstatus(req
);
2296 NTSTATUS
cli_ulogoff(struct cli_state
*cli
)
2298 struct tevent_context
*ev
;
2299 struct tevent_req
*req
;
2300 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2302 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
2303 return NT_STATUS_INVALID_PARAMETER
;
2305 ev
= samba_tevent_context_init(talloc_tos());
2309 req
= cli_ulogoff_send(ev
, ev
, cli
);
2313 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2316 status
= cli_ulogoff_recv(req
);
2322 /****************************************************************************
2324 ****************************************************************************/
2326 struct cli_tcon_andx_state
{
2327 struct cli_state
*cli
;
2332 static void cli_tcon_andx_done(struct tevent_req
*subreq
);
2334 struct tevent_req
*cli_tcon_andx_create(TALLOC_CTX
*mem_ctx
,
2335 struct tevent_context
*ev
,
2336 struct cli_state
*cli
,
2337 const char *share
, const char *dev
,
2338 const char *pass
, int passlen
,
2339 struct tevent_req
**psmbreq
)
2341 struct tevent_req
*req
, *subreq
;
2342 struct cli_tcon_andx_state
*state
;
2347 uint16_t sec_mode
= smb1cli_conn_server_security_mode(cli
->conn
);
2348 uint16_t tcon_flags
= 0;
2352 req
= tevent_req_create(mem_ctx
, &state
, struct cli_tcon_andx_state
);
2359 cli
->share
= talloc_strdup(cli
, share
);
2364 /* in user level security don't send a password now */
2365 if (sec_mode
& NEGOTIATE_SECURITY_USER_LEVEL
) {
2368 } else if (pass
== NULL
) {
2369 DEBUG(1, ("Server not using user level security and no "
2370 "password supplied.\n"));
2374 if ((sec_mode
& NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
) &&
2375 *pass
&& passlen
!= 24) {
2376 if (!lp_client_lanman_auth()) {
2377 DEBUG(1, ("Server requested LANMAN password "
2378 "(share-level security) but "
2379 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2384 * Non-encrypted passwords - convert to DOS codepage before
2387 SMBencrypt(pass
, smb1cli_conn_server_challenge(cli
->conn
), p24
);
2389 pass
= (const char *)p24
;
2391 if((sec_mode
& (NEGOTIATE_SECURITY_USER_LEVEL
2392 |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
))
2396 if (!lp_client_plaintext_auth() && (*pass
)) {
2397 DEBUG(1, ("Server requested PLAINTEXT "
2399 "'client plaintext auth = no' or 'client ntlmv2 auth = yes'\n"));
2404 * Non-encrypted passwords - convert to DOS codepage
2407 tmp_pass
= talloc_array(talloc_tos(), uint8
, 0);
2408 if (tevent_req_nomem(tmp_pass
, req
)) {
2409 return tevent_req_post(req
, ev
);
2411 tmp_pass
= trans2_bytes_push_str(tmp_pass
,
2412 false, /* always DOS */
2416 if (tevent_req_nomem(tmp_pass
, req
)) {
2417 return tevent_req_post(req
, ev
);
2419 pass
= (const char *)tmp_pass
;
2420 passlen
= talloc_get_size(tmp_pass
);
2424 tcon_flags
|= TCONX_FLAG_EXTENDED_RESPONSE
;
2425 tcon_flags
|= TCONX_FLAG_EXTENDED_SIGNATURES
;
2427 SCVAL(vwv
+0, 0, 0xFF);
2430 SSVAL(vwv
+2, 0, tcon_flags
);
2431 SSVAL(vwv
+3, 0, passlen
);
2433 if (passlen
&& pass
) {
2434 bytes
= (uint8_t *)talloc_memdup(state
, pass
, passlen
);
2436 bytes
= talloc_array(state
, uint8_t, 0);
2442 tmp
= talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
2443 smbXcli_conn_remote_name(cli
->conn
), share
);
2448 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
), tmp
, strlen(tmp
)+1,
2453 * Add the devicetype
2455 tmp
= talloc_strdup_upper(talloc_tos(), dev
);
2460 bytes
= smb_bytes_push_str(bytes
, false, tmp
, strlen(tmp
)+1, NULL
);
2463 if (bytes
== NULL
) {
2468 state
->bytes
.iov_base
= (void *)bytes
;
2469 state
->bytes
.iov_len
= talloc_get_size(bytes
);
2471 subreq
= cli_smb_req_create(state
, ev
, cli
, SMBtconX
, 0, 4, vwv
,
2473 if (subreq
== NULL
) {
2477 tevent_req_set_callback(subreq
, cli_tcon_andx_done
, req
);
2482 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
2483 return tevent_req_post(req
, ev
);
2486 struct tevent_req
*cli_tcon_andx_send(TALLOC_CTX
*mem_ctx
,
2487 struct tevent_context
*ev
,
2488 struct cli_state
*cli
,
2489 const char *share
, const char *dev
,
2490 const char *pass
, int passlen
)
2492 struct tevent_req
*req
, *subreq
;
2495 req
= cli_tcon_andx_create(mem_ctx
, ev
, cli
, share
, dev
, pass
, passlen
,
2500 if (subreq
== NULL
) {
2503 status
= smb1cli_req_chain_submit(&subreq
, 1);
2504 if (!NT_STATUS_IS_OK(status
)) {
2505 tevent_req_nterror(req
, status
);
2506 return tevent_req_post(req
, ev
);
2511 static void cli_tcon_andx_done(struct tevent_req
*subreq
)
2513 struct tevent_req
*req
= tevent_req_callback_data(
2514 subreq
, struct tevent_req
);
2515 struct cli_tcon_andx_state
*state
= tevent_req_data(
2516 req
, struct cli_tcon_andx_state
);
2517 struct cli_state
*cli
= state
->cli
;
2525 uint16_t optional_support
= 0;
2527 status
= cli_smb_recv(subreq
, state
, &in
, 0, &wct
, &vwv
,
2528 &num_bytes
, &bytes
);
2529 TALLOC_FREE(subreq
);
2530 if (!NT_STATUS_IS_OK(status
)) {
2531 tevent_req_nterror(req
, status
);
2535 inhdr
= in
+ NBT_HDR_SIZE
;
2538 if (clistr_pull_talloc(cli
,
2539 (const char *)inhdr
,
2540 SVAL(inhdr
, HDR_FLG2
),
2544 STR_TERMINATE
|STR_ASCII
) == -1) {
2545 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
2549 cli
->dev
= talloc_strdup(cli
, "");
2550 if (cli
->dev
== NULL
) {
2551 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
2556 if ((smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_NT1
) && (num_bytes
== 3)) {
2557 /* almost certainly win95 - enable bug fixes */
2562 * Make sure that we have the optional support 16-bit field. WCT > 2.
2563 * Avoids issues when connecting to Win9x boxes sharing files
2566 cli
->dfsroot
= false;
2568 if ((wct
> 2) && (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_LANMAN2
)) {
2569 optional_support
= SVAL(vwv
+2, 0);
2572 if (optional_support
& SMB_SHARE_IN_DFS
) {
2573 cli
->dfsroot
= true;
2576 if (optional_support
& SMB_EXTENDED_SIGNATURES
) {
2577 smb1cli_session_protect_session_key(cli
->smb1
.session
);
2580 cli_state_set_tid(cli
, SVAL(inhdr
, HDR_TID
));
2581 tevent_req_done(req
);
2584 NTSTATUS
cli_tcon_andx_recv(struct tevent_req
*req
)
2586 return tevent_req_simple_recv_ntstatus(req
);
2589 NTSTATUS
cli_tcon_andx(struct cli_state
*cli
, const char *share
,
2590 const char *dev
, const char *pass
, int passlen
)
2592 TALLOC_CTX
*frame
= talloc_stackframe();
2593 struct tevent_context
*ev
;
2594 struct tevent_req
*req
;
2595 NTSTATUS status
= NT_STATUS_OK
;
2597 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
2599 * Can't use sync call while an async call is in flight
2601 status
= NT_STATUS_INVALID_PARAMETER
;
2605 ev
= samba_tevent_context_init(frame
);
2607 status
= NT_STATUS_NO_MEMORY
;
2611 req
= cli_tcon_andx_send(frame
, ev
, cli
, share
, dev
, pass
, passlen
);
2613 status
= NT_STATUS_NO_MEMORY
;
2617 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2621 status
= cli_tcon_andx_recv(req
);
2627 NTSTATUS
cli_tree_connect(struct cli_state
*cli
, const char *share
,
2628 const char *dev
, const char *pass
, int passlen
)
2631 uint16_t max_xmit
= 0;
2634 cli
->share
= talloc_strdup(cli
, share
);
2636 return NT_STATUS_NO_MEMORY
;
2639 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
2640 return smb2cli_tcon(cli
, share
);
2643 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_LANMAN1
) {
2644 return cli_tcon_andx(cli
, share
, dev
, pass
, passlen
);
2647 status
= cli_raw_tcon(cli
, share
, pass
, dev
, &max_xmit
, &tid
);
2648 if (!NT_STATUS_IS_OK(status
)) {
2652 cli_state_set_tid(cli
, tid
);
2654 return NT_STATUS_OK
;
2657 /****************************************************************************
2658 Send a tree disconnect.
2659 ****************************************************************************/
2661 struct cli_tdis_state
{
2662 struct cli_state
*cli
;
2665 static void cli_tdis_done(struct tevent_req
*subreq
);
2667 struct tevent_req
*cli_tdis_send(TALLOC_CTX
*mem_ctx
,
2668 struct tevent_context
*ev
,
2669 struct cli_state
*cli
)
2671 struct tevent_req
*req
, *subreq
;
2672 struct cli_tdis_state
*state
;
2674 req
= tevent_req_create(mem_ctx
, &state
, struct cli_tdis_state
);
2680 subreq
= cli_smb_send(state
, ev
, cli
, SMBtdis
, 0, 0, NULL
, 0, NULL
);
2681 if (tevent_req_nomem(subreq
, req
)) {
2682 return tevent_req_post(req
, ev
);
2684 tevent_req_set_callback(subreq
, cli_tdis_done
, req
);
2688 static void cli_tdis_done(struct tevent_req
*subreq
)
2690 struct tevent_req
*req
= tevent_req_callback_data(
2691 subreq
, struct tevent_req
);
2692 struct cli_tdis_state
*state
= tevent_req_data(
2693 req
, struct cli_tdis_state
);
2696 status
= cli_smb_recv(subreq
, NULL
, NULL
, 0, NULL
, NULL
, NULL
, NULL
);
2697 TALLOC_FREE(subreq
);
2698 if (!NT_STATUS_IS_OK(status
)) {
2699 tevent_req_nterror(req
, status
);
2702 cli_state_set_tid(state
->cli
, UINT16_MAX
);
2703 tevent_req_done(req
);
2706 NTSTATUS
cli_tdis_recv(struct tevent_req
*req
)
2708 return tevent_req_simple_recv_ntstatus(req
);
2711 NTSTATUS
cli_tdis(struct cli_state
*cli
)
2713 struct tevent_context
*ev
;
2714 struct tevent_req
*req
;
2715 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2717 if (smbXcli_conn_has_async_calls(cli
->conn
)) {
2718 return NT_STATUS_INVALID_PARAMETER
;
2720 ev
= samba_tevent_context_init(talloc_tos());
2724 req
= cli_tdis_send(ev
, ev
, cli
);
2728 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2731 status
= cli_tdis_recv(req
);
2737 struct cli_connect_sock_state
{
2738 const char **called_names
;
2739 const char **calling_names
;
2745 static void cli_connect_sock_done(struct tevent_req
*subreq
);
2748 * Async only if we don't have to look up the name, i.e. "pss" is set with a
2752 static struct tevent_req
*cli_connect_sock_send(
2753 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
2754 const char *host
, int name_type
, const struct sockaddr_storage
*pss
,
2755 const char *myname
, uint16_t port
)
2757 struct tevent_req
*req
, *subreq
;
2758 struct cli_connect_sock_state
*state
;
2760 unsigned i
, num_addrs
;
2763 req
= tevent_req_create(mem_ctx
, &state
,
2764 struct cli_connect_sock_state
);
2769 prog
= getenv("LIBSMB_PROG");
2771 state
->fd
= sock_exec(prog
);
2772 if (state
->fd
== -1) {
2773 status
= map_nt_error_from_unix(errno
);
2774 tevent_req_nterror(req
, status
);
2777 tevent_req_done(req
);
2779 return tevent_req_post(req
, ev
);
2782 if ((pss
== NULL
) || is_zero_addr(pss
)) {
2783 struct sockaddr_storage
*addrs
;
2786 * Here we cheat. resolve_name_list is not async at all. So
2787 * this call will only be really async if the name lookup has
2788 * been done externally.
2791 status
= resolve_name_list(state
, host
, name_type
,
2792 &addrs
, &num_addrs
);
2793 if (!NT_STATUS_IS_OK(status
)) {
2794 tevent_req_nterror(req
, status
);
2795 return tevent_req_post(req
, ev
);
2802 state
->called_names
= talloc_array(state
, const char *, num_addrs
);
2803 if (tevent_req_nomem(state
->called_names
, req
)) {
2804 return tevent_req_post(req
, ev
);
2806 state
->called_types
= talloc_array(state
, int, num_addrs
);
2807 if (tevent_req_nomem(state
->called_types
, req
)) {
2808 return tevent_req_post(req
, ev
);
2810 state
->calling_names
= talloc_array(state
, const char *, num_addrs
);
2811 if (tevent_req_nomem(state
->calling_names
, req
)) {
2812 return tevent_req_post(req
, ev
);
2814 for (i
=0; i
<num_addrs
; i
++) {
2815 state
->called_names
[i
] = host
;
2816 state
->called_types
[i
] = name_type
;
2817 state
->calling_names
[i
] = myname
;
2820 subreq
= smbsock_any_connect_send(
2821 state
, ev
, pss
, state
->called_names
, state
->called_types
,
2822 state
->calling_names
, NULL
, num_addrs
, port
);
2823 if (tevent_req_nomem(subreq
, req
)) {
2824 return tevent_req_post(req
, ev
);
2826 tevent_req_set_callback(subreq
, cli_connect_sock_done
, req
);
2830 static void cli_connect_sock_done(struct tevent_req
*subreq
)
2832 struct tevent_req
*req
= tevent_req_callback_data(
2833 subreq
, struct tevent_req
);
2834 struct cli_connect_sock_state
*state
= tevent_req_data(
2835 req
, struct cli_connect_sock_state
);
2838 status
= smbsock_any_connect_recv(subreq
, &state
->fd
, NULL
,
2840 TALLOC_FREE(subreq
);
2841 if (tevent_req_nterror(req
, status
)) {
2844 set_socket_options(state
->fd
, lp_socket_options());
2845 tevent_req_done(req
);
2848 static NTSTATUS
cli_connect_sock_recv(struct tevent_req
*req
,
2849 int *pfd
, uint16_t *pport
)
2851 struct cli_connect_sock_state
*state
= tevent_req_data(
2852 req
, struct cli_connect_sock_state
);
2855 if (tevent_req_is_nterror(req
, &status
)) {
2859 *pport
= state
->port
;
2860 return NT_STATUS_OK
;
2863 struct cli_connect_nb_state
{
2864 const char *desthost
;
2867 struct cli_state
*cli
;
2870 static void cli_connect_nb_done(struct tevent_req
*subreq
);
2872 static struct tevent_req
*cli_connect_nb_send(
2873 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
2874 const char *host
, const struct sockaddr_storage
*dest_ss
,
2875 uint16_t port
, int name_type
, const char *myname
,
2876 int signing_state
, int flags
)
2878 struct tevent_req
*req
, *subreq
;
2879 struct cli_connect_nb_state
*state
;
2882 req
= tevent_req_create(mem_ctx
, &state
, struct cli_connect_nb_state
);
2886 state
->desthost
= host
;
2887 state
->signing_state
= signing_state
;
2888 state
->flags
= flags
;
2890 p
= strchr(host
, '#');
2892 name_type
= strtol(p
+1, NULL
, 16);
2893 host
= talloc_strndup(state
, host
, p
- host
);
2894 if (tevent_req_nomem(host
, req
)) {
2895 return tevent_req_post(req
, ev
);
2899 subreq
= cli_connect_sock_send(state
, ev
, host
, name_type
, dest_ss
,
2901 if (tevent_req_nomem(subreq
, req
)) {
2902 return tevent_req_post(req
, ev
);
2904 tevent_req_set_callback(subreq
, cli_connect_nb_done
, req
);
2908 static void cli_connect_nb_done(struct tevent_req
*subreq
)
2910 struct tevent_req
*req
= tevent_req_callback_data(
2911 subreq
, struct tevent_req
);
2912 struct cli_connect_nb_state
*state
= tevent_req_data(
2913 req
, struct cli_connect_nb_state
);
2918 status
= cli_connect_sock_recv(subreq
, &fd
, &port
);
2919 TALLOC_FREE(subreq
);
2920 if (tevent_req_nterror(req
, status
)) {
2924 state
->cli
= cli_state_create(state
, fd
, state
->desthost
, NULL
,
2925 state
->signing_state
, state
->flags
);
2926 if (tevent_req_nomem(state
->cli
, req
)) {
2930 tevent_req_done(req
);
2933 static NTSTATUS
cli_connect_nb_recv(struct tevent_req
*req
,
2934 struct cli_state
**pcli
)
2936 struct cli_connect_nb_state
*state
= tevent_req_data(
2937 req
, struct cli_connect_nb_state
);
2940 if (tevent_req_is_nterror(req
, &status
)) {
2943 *pcli
= talloc_move(NULL
, &state
->cli
);
2944 return NT_STATUS_OK
;
2947 NTSTATUS
cli_connect_nb(const char *host
, const struct sockaddr_storage
*dest_ss
,
2948 uint16_t port
, int name_type
, const char *myname
,
2949 int signing_state
, int flags
, struct cli_state
**pcli
)
2951 struct tevent_context
*ev
;
2952 struct tevent_req
*req
;
2953 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
2955 ev
= samba_tevent_context_init(talloc_tos());
2959 req
= cli_connect_nb_send(ev
, ev
, host
, dest_ss
, port
, name_type
,
2960 myname
, signing_state
, flags
);
2964 if (!tevent_req_set_endtime(req
, ev
, timeval_current_ofs(20, 0))) {
2967 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
2970 status
= cli_connect_nb_recv(req
, pcli
);
2976 struct cli_start_connection_state
{
2977 struct tevent_context
*ev
;
2978 struct cli_state
*cli
;
2981 static void cli_start_connection_connected(struct tevent_req
*subreq
);
2982 static void cli_start_connection_done(struct tevent_req
*subreq
);
2985 establishes a connection to after the negprot.
2986 @param output_cli A fully initialised cli structure, non-null only on success
2987 @param dest_host The netbios name of the remote host
2988 @param dest_ss (optional) The the destination IP, NULL for name based lookup
2989 @param port (optional) The destination port (0 for default)
2992 static struct tevent_req
*cli_start_connection_send(
2993 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
2994 const char *my_name
, const char *dest_host
,
2995 const struct sockaddr_storage
*dest_ss
, int port
,
2996 int signing_state
, int flags
)
2998 struct tevent_req
*req
, *subreq
;
2999 struct cli_start_connection_state
*state
;
3001 req
= tevent_req_create(mem_ctx
, &state
,
3002 struct cli_start_connection_state
);
3008 subreq
= cli_connect_nb_send(state
, ev
, dest_host
, dest_ss
, port
,
3009 0x20, my_name
, signing_state
, flags
);
3010 if (tevent_req_nomem(subreq
, req
)) {
3011 return tevent_req_post(req
, ev
);
3013 tevent_req_set_callback(subreq
, cli_start_connection_connected
, req
);
3017 static void cli_start_connection_connected(struct tevent_req
*subreq
)
3019 struct tevent_req
*req
= tevent_req_callback_data(
3020 subreq
, struct tevent_req
);
3021 struct cli_start_connection_state
*state
= tevent_req_data(
3022 req
, struct cli_start_connection_state
);
3025 status
= cli_connect_nb_recv(subreq
, &state
->cli
);
3026 TALLOC_FREE(subreq
);
3027 if (tevent_req_nterror(req
, status
)) {
3031 subreq
= smbXcli_negprot_send(state
, state
->ev
, state
->cli
->conn
,
3032 state
->cli
->timeout
,
3033 PROTOCOL_CORE
, PROTOCOL_NT1
);
3034 if (tevent_req_nomem(subreq
, req
)) {
3037 tevent_req_set_callback(subreq
, cli_start_connection_done
, req
);
3040 static void cli_start_connection_done(struct tevent_req
*subreq
)
3042 struct tevent_req
*req
= tevent_req_callback_data(
3043 subreq
, struct tevent_req
);
3046 status
= smbXcli_negprot_recv(subreq
);
3047 TALLOC_FREE(subreq
);
3048 if (tevent_req_nterror(req
, status
)) {
3051 tevent_req_done(req
);
3054 static NTSTATUS
cli_start_connection_recv(struct tevent_req
*req
,
3055 struct cli_state
**output_cli
)
3057 struct cli_start_connection_state
*state
= tevent_req_data(
3058 req
, struct cli_start_connection_state
);
3061 if (tevent_req_is_nterror(req
, &status
)) {
3064 *output_cli
= state
->cli
;
3065 return NT_STATUS_OK
;
3068 NTSTATUS
cli_start_connection(struct cli_state
**output_cli
,
3069 const char *my_name
,
3070 const char *dest_host
,
3071 const struct sockaddr_storage
*dest_ss
, int port
,
3072 int signing_state
, int flags
)
3074 struct tevent_context
*ev
;
3075 struct tevent_req
*req
;
3076 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
3078 ev
= samba_tevent_context_init(talloc_tos());
3082 req
= cli_start_connection_send(ev
, ev
, my_name
, dest_host
, dest_ss
,
3083 port
, signing_state
, flags
);
3087 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
3090 status
= cli_start_connection_recv(req
, output_cli
);
3098 establishes a connection right up to doing tconX, password specified.
3099 @param output_cli A fully initialised cli structure, non-null only on success
3100 @param dest_host The netbios name of the remote host
3101 @param dest_ip (optional) The the destination IP, NULL for name based lookup
3102 @param port (optional) The destination port (0 for default)
3103 @param service (optional) The share to make the connection to. Should be 'unqualified' in any way.
3104 @param service_type The 'type' of serivice.
3105 @param user Username, unix string
3106 @param domain User's domain
3107 @param password User's password, unencrypted unix string.
3110 NTSTATUS
cli_full_connection(struct cli_state
**output_cli
,
3111 const char *my_name
,
3112 const char *dest_host
,
3113 const struct sockaddr_storage
*dest_ss
, int port
,
3114 const char *service
, const char *service_type
,
3115 const char *user
, const char *domain
,
3116 const char *password
, int flags
,
3120 struct cli_state
*cli
= NULL
;
3121 int pw_len
= password
? strlen(password
)+1 : 0;
3125 if (password
== NULL
) {
3129 nt_status
= cli_start_connection(&cli
, my_name
, dest_host
,
3130 dest_ss
, port
, signing_state
,
3133 if (!NT_STATUS_IS_OK(nt_status
)) {
3137 nt_status
= cli_session_setup(cli
, user
, password
, pw_len
, password
,
3139 if (!NT_STATUS_IS_OK(nt_status
)) {
3141 if (!(flags
& CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK
)) {
3142 DEBUG(1,("failed session setup with %s\n",
3143 nt_errstr(nt_status
)));
3148 nt_status
= cli_session_setup(cli
, "", "", 0, "", 0, domain
);
3149 if (!NT_STATUS_IS_OK(nt_status
)) {
3150 DEBUG(1,("anonymous failed session setup with %s\n",
3151 nt_errstr(nt_status
)));
3158 nt_status
= cli_tree_connect(cli
, service
, service_type
,
3160 if (!NT_STATUS_IS_OK(nt_status
)) {
3161 DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status
)));
3163 if (NT_STATUS_IS_OK(nt_status
)) {
3164 nt_status
= NT_STATUS_UNSUCCESSFUL
;
3170 nt_status
= cli_init_creds(cli
, user
, domain
, password
);
3171 if (!NT_STATUS_IS_OK(nt_status
)) {
3177 return NT_STATUS_OK
;
3180 /****************************************************************************
3181 Send an old style tcon.
3182 ****************************************************************************/
3183 NTSTATUS
cli_raw_tcon(struct cli_state
*cli
,
3184 const char *service
, const char *pass
, const char *dev
,
3185 uint16
*max_xmit
, uint16
*tid
)
3187 struct tevent_req
*req
;
3192 if (!lp_client_plaintext_auth() && (*pass
)) {
3193 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
3194 " or 'client ntlmv2 auth = yes'\n"));
3195 return NT_STATUS_ACCESS_DENIED
;
3198 bytes
= talloc_array(talloc_tos(), uint8_t, 0);
3199 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
3200 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
3201 service
, strlen(service
)+1, NULL
);
3202 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
3203 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
3204 pass
, strlen(pass
)+1, NULL
);
3205 bytes
= smb_bytes_push_bytes(bytes
, 4, NULL
, 0);
3206 bytes
= smb_bytes_push_str(bytes
, smbXcli_conn_use_unicode(cli
->conn
),
3207 dev
, strlen(dev
)+1, NULL
);
3209 status
= cli_smb(talloc_tos(), cli
, SMBtcon
, 0, 0, NULL
,
3210 talloc_get_size(bytes
), bytes
, &req
,
3211 2, NULL
, &ret_vwv
, NULL
, NULL
);
3212 if (!NT_STATUS_IS_OK(status
)) {
3216 *max_xmit
= SVAL(ret_vwv
+ 0, 0);
3217 *tid
= SVAL(ret_vwv
+ 1, 0);
3219 return NT_STATUS_OK
;
3222 /* Return a cli_state pointing at the IPC$ share for the given server */
3224 struct cli_state
*get_ipc_connect(char *server
,
3225 struct sockaddr_storage
*server_ss
,
3226 const struct user_auth_info
*user_info
)
3228 struct cli_state
*cli
;
3230 uint32_t flags
= CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK
;
3232 if (user_info
->use_kerberos
) {
3233 flags
|= CLI_FULL_CONNECTION_USE_KERBEROS
;
3236 nt_status
= cli_full_connection(&cli
, NULL
, server
, server_ss
, 0, "IPC$", "IPC",
3237 user_info
->username
? user_info
->username
: "",
3239 user_info
->password
? user_info
->password
: "",
3241 SMB_SIGNING_DEFAULT
);
3243 if (NT_STATUS_IS_OK(nt_status
)) {
3245 } else if (is_ipaddress(server
)) {
3246 /* windows 9* needs a correct NMB name for connections */
3247 fstring remote_name
;
3249 if (name_status_find("*", 0, 0, server_ss
, remote_name
)) {
3250 cli
= get_ipc_connect(remote_name
, server_ss
, user_info
);
3259 * Given the IP address of a master browser on the network, return its
3260 * workgroup and connect to it.
3262 * This function is provided to allow additional processing beyond what
3263 * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
3264 * browsers and obtain each master browsers' list of domains (in case the
3265 * first master browser is recently on the network and has not yet
3266 * synchronized with other master browsers and therefore does not yet have the
3267 * entire network browse list)
3270 struct cli_state
*get_ipc_connect_master_ip(TALLOC_CTX
*ctx
,
3271 struct sockaddr_storage
*mb_ip
,
3272 const struct user_auth_info
*user_info
,
3273 char **pp_workgroup_out
)
3275 char addr
[INET6_ADDRSTRLEN
];
3277 struct cli_state
*cli
;
3278 struct sockaddr_storage server_ss
;
3280 *pp_workgroup_out
= NULL
;
3282 print_sockaddr(addr
, sizeof(addr
), mb_ip
);
3283 DEBUG(99, ("Looking up name of master browser %s\n",
3287 * Do a name status query to find out the name of the master browser.
3288 * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
3289 * master browser will not respond to a wildcard query (or, at least,
3290 * an NT4 server acting as the domain master browser will not).
3292 * We might be able to use ONLY the query on MSBROWSE, but that's not
3293 * yet been tested with all Windows versions, so until it is, leave
3294 * the original wildcard query as the first choice and fall back to
3295 * MSBROWSE if the wildcard query fails.
3297 if (!name_status_find("*", 0, 0x1d, mb_ip
, name
) &&
3298 !name_status_find(MSBROWSE
, 1, 0x1d, mb_ip
, name
)) {
3300 DEBUG(99, ("Could not retrieve name status for %s\n",
3305 if (!find_master_ip(name
, &server_ss
)) {
3306 DEBUG(99, ("Could not find master ip for %s\n", name
));
3310 *pp_workgroup_out
= talloc_strdup(ctx
, name
);
3312 DEBUG(4, ("found master browser %s, %s\n", name
, addr
));
3314 print_sockaddr(addr
, sizeof(addr
), &server_ss
);
3315 cli
= get_ipc_connect(addr
, &server_ss
, user_info
);
3321 * Return the IP address and workgroup of a master browser on the network, and
3325 struct cli_state
*get_ipc_connect_master_ip_bcast(TALLOC_CTX
*ctx
,
3326 const struct user_auth_info
*user_info
,
3327 char **pp_workgroup_out
)
3329 struct sockaddr_storage
*ip_list
;
3330 struct cli_state
*cli
;
3334 *pp_workgroup_out
= NULL
;
3336 DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
3338 /* Go looking for workgroups by broadcasting on the local network */
3340 status
= name_resolve_bcast(MSBROWSE
, 1, talloc_tos(),
3342 if (!NT_STATUS_IS_OK(status
)) {
3343 DEBUG(99, ("No master browsers responded: %s\n",
3344 nt_errstr(status
)));
3348 for (i
= 0; i
< count
; i
++) {
3349 char addr
[INET6_ADDRSTRLEN
];
3350 print_sockaddr(addr
, sizeof(addr
), &ip_list
[i
]);
3351 DEBUG(99, ("Found master browser %s\n", addr
));
3353 cli
= get_ipc_connect_master_ip(ctx
, &ip_list
[i
],
3354 user_info
, pp_workgroup_out
);