2 Unix SMB/CIFS implementation.
3 client connect/disconnect routines
4 Copyright (C) Andrew Tridgell 1994-1998
5 Copyright (C) Andrew Bartlett 2001-2003
6 Copyright (C) Volker Lendecke 2011
7 Copyright (C) Jeremy Allison 2011
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "libsmb/libsmb.h"
25 #include "auth_info.h"
26 #include "../libcli/auth/libcli_auth.h"
27 #include "../libcli/auth/spnego.h"
29 #include "../auth/ntlmssp/ntlmssp.h"
30 #include "libads/kerberos_proto.h"
32 #include "../lib/util/tevent_ntstatus.h"
33 #include "async_smb.h"
34 #include "libsmb/nmblib.h"
35 #include "librpc/ndr/libndr.h"
36 #include "../libcli/smb/smbXcli_base.h"
39 #define STAR_SMBSERVER "*SMBSERVER"
41 /********************************************************
42 Utility function to ensure we always return at least
43 a valid char * pointer to an empty string for the
44 cli->server_os, cli->server_type and cli->server_domain
46 *******************************************************/
48 static NTSTATUS smb_bytes_talloc_string(TALLOC_CTX *mem_ctx,
55 *destlen = clistr_pull_talloc(mem_ctx,
63 return NT_STATUS_NO_MEMORY;
67 *dest = talloc_strdup(mem_ctx, "");
69 return NT_STATUS_NO_MEMORY;
75 /****************************************************************************
76 Do an old lanman2 style session setup.
77 ****************************************************************************/
79 struct cli_session_setup_lanman2_state {
80 struct cli_state *cli;
85 static void cli_session_setup_lanman2_done(struct tevent_req *subreq);
87 static struct tevent_req *cli_session_setup_lanman2_send(
88 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
89 struct cli_state *cli, const char *user,
90 const char *pass, size_t passlen,
91 const char *workgroup)
93 struct tevent_req *req, *subreq;
94 struct cli_session_setup_lanman2_state *state;
95 DATA_BLOB lm_response = data_blob_null;
99 uint16_t sec_mode = smb1cli_conn_server_security_mode(cli->conn);
101 req = tevent_req_create(mem_ctx, &state,
102 struct cli_session_setup_lanman2_state);
111 * if in share level security then don't send a password now
113 if (!(sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) {
118 && (sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)
121 * Encrypted mode needed, and non encrypted password
124 lm_response = data_blob(NULL, 24);
125 if (tevent_req_nomem(lm_response.data, req)) {
126 return tevent_req_post(req, ev);
129 if (!SMBencrypt(pass, smb1cli_conn_server_challenge(cli->conn),
130 (uint8_t *)lm_response.data)) {
131 DEBUG(1, ("Password is > 14 chars in length, and is "
132 "therefore incompatible with Lanman "
133 "authentication\n"));
134 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
135 return tevent_req_post(req, ev);
137 } else if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)
140 * Encrypted mode needed, and encrypted password
143 lm_response = data_blob(pass, passlen);
144 if (tevent_req_nomem(lm_response.data, req)) {
145 return tevent_req_post(req, ev);
147 } else if (passlen > 0) {
149 size_t converted_size;
151 * Plaintext mode needed, assume plaintext supplied.
153 buf = talloc_array(talloc_tos(), uint8_t, 0);
154 buf = smb_bytes_push_str(buf, smbXcli_conn_use_unicode(cli->conn), pass, passlen+1,
156 if (tevent_req_nomem(buf, req)) {
157 return tevent_req_post(req, ev);
159 lm_response = data_blob(pass, passlen);
161 if (tevent_req_nomem(lm_response.data, req)) {
162 return tevent_req_post(req, ev);
166 SCVAL(vwv+0, 0, 0xff);
169 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
172 SIVAL(vwv+5, 0, smb1cli_conn_server_session_key(cli->conn));
173 SSVAL(vwv+7, 0, lm_response.length);
175 bytes = talloc_array(state, uint8_t, lm_response.length);
176 if (tevent_req_nomem(bytes, req)) {
177 return tevent_req_post(req, ev);
179 if (lm_response.length != 0) {
180 memcpy(bytes, lm_response.data, lm_response.length);
182 data_blob_free(&lm_response);
184 tmp = talloc_strdup_upper(talloc_tos(), user);
185 if (tevent_req_nomem(tmp, req)) {
186 return tevent_req_post(req, ev);
188 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), tmp, strlen(tmp)+1,
192 tmp = talloc_strdup_upper(talloc_tos(), workgroup);
193 if (tevent_req_nomem(tmp, req)) {
194 return tevent_req_post(req, ev);
196 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), tmp, strlen(tmp)+1,
198 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "Unix", 5, NULL);
199 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "Samba", 6, NULL);
201 if (tevent_req_nomem(bytes, req)) {
202 return tevent_req_post(req, ev);
205 subreq = cli_smb_send(state, ev, cli, SMBsesssetupX, 0, 10, vwv,
206 talloc_get_size(bytes), bytes);
207 if (tevent_req_nomem(subreq, req)) {
208 return tevent_req_post(req, ev);
210 tevent_req_set_callback(subreq, cli_session_setup_lanman2_done, req);
214 static void cli_session_setup_lanman2_done(struct tevent_req *subreq)
216 struct tevent_req *req = tevent_req_callback_data(
217 subreq, struct tevent_req);
218 struct cli_session_setup_lanman2_state *state = tevent_req_data(
219 req, struct cli_session_setup_lanman2_state);
220 struct cli_state *cli = state->cli;
231 status = cli_smb_recv(subreq, state, &in, 3, &wct, &vwv,
234 if (!NT_STATUS_IS_OK(status)) {
235 tevent_req_nterror(req, status);
239 inhdr = in + NBT_HDR_SIZE;
242 cli_state_set_uid(state->cli, SVAL(inhdr, HDR_UID));
243 cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0);
245 status = smb_bytes_talloc_string(cli,
252 if (!NT_STATUS_IS_OK(status)) {
253 tevent_req_nterror(req, status);
258 status = smb_bytes_talloc_string(cli,
265 if (!NT_STATUS_IS_OK(status)) {
266 tevent_req_nterror(req, status);
271 status = smb_bytes_talloc_string(cli,
278 if (!NT_STATUS_IS_OK(status)) {
279 tevent_req_nterror(req, status);
284 status = cli_set_username(cli, state->user);
285 if (tevent_req_nterror(req, status)) {
288 tevent_req_done(req);
291 static NTSTATUS cli_session_setup_lanman2_recv(struct tevent_req *req)
293 return tevent_req_simple_recv_ntstatus(req);
296 static NTSTATUS cli_session_setup_lanman2(struct cli_state *cli, const char *user,
297 const char *pass, size_t passlen,
298 const char *workgroup)
300 TALLOC_CTX *frame = talloc_stackframe();
301 struct tevent_context *ev;
302 struct tevent_req *req;
303 NTSTATUS status = NT_STATUS_NO_MEMORY;
305 if (smbXcli_conn_has_async_calls(cli->conn)) {
307 * Can't use sync call while an async call is in flight
309 status = NT_STATUS_INVALID_PARAMETER;
312 ev = samba_tevent_context_init(frame);
316 req = cli_session_setup_lanman2_send(frame, ev, cli, user, pass, passlen,
321 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
324 status = cli_session_setup_lanman2_recv(req);
330 /****************************************************************************
331 Work out suitable capabilities to offer the server.
332 ****************************************************************************/
334 static uint32_t cli_session_setup_capabilities(struct cli_state *cli,
335 uint32_t sesssetup_capabilities)
337 uint32_t client_capabilities = smb1cli_conn_capabilities(cli->conn);
340 * We only send capabilities based on the mask for:
341 * - client only flags
342 * - flags used in both directions
344 * We do not echo the server only flags, except some legacy flags.
346 * SMB_CAP_LEGACY_CLIENT_MASK contains CAP_LARGE_READX and
347 * CAP_LARGE_WRITEX in order to allow us to do large reads
348 * against old Samba releases (<= 3.6.x).
350 client_capabilities &= (SMB_CAP_BOTH_MASK | SMB_CAP_LEGACY_CLIENT_MASK);
353 * Session Setup specific flags CAP_DYNAMIC_REAUTH
354 * and CAP_EXTENDED_SECURITY are passed by the caller.
355 * We need that in order to do guest logins even if
356 * CAP_EXTENDED_SECURITY is negotiated.
358 client_capabilities &= ~(CAP_DYNAMIC_REAUTH|CAP_EXTENDED_SECURITY);
359 sesssetup_capabilities &= (CAP_DYNAMIC_REAUTH|CAP_EXTENDED_SECURITY);
360 client_capabilities |= sesssetup_capabilities;
362 return client_capabilities;
365 /****************************************************************************
366 Do a NT1 guest session setup.
367 ****************************************************************************/
369 struct cli_session_setup_guest_state {
370 struct cli_state *cli;
375 static void cli_session_setup_guest_done(struct tevent_req *subreq);
377 struct tevent_req *cli_session_setup_guest_create(TALLOC_CTX *mem_ctx,
378 struct tevent_context *ev,
379 struct cli_state *cli,
380 struct tevent_req **psmbreq)
382 struct tevent_req *req, *subreq;
383 struct cli_session_setup_guest_state *state;
387 req = tevent_req_create(mem_ctx, &state,
388 struct cli_session_setup_guest_state);
395 SCVAL(vwv+0, 0, 0xFF);
398 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
400 SSVAL(vwv+4, 0, cli_state_get_vc_num(cli));
401 SIVAL(vwv+5, 0, smb1cli_conn_server_session_key(cli->conn));
406 SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli, 0));
408 bytes = talloc_array(state, uint8_t, 0);
410 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "", 1, /* username */
412 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "", 1, /* workgroup */
414 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "Unix", 5, NULL);
415 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "Samba", 6, NULL);
422 state->bytes.iov_base = (void *)bytes;
423 state->bytes.iov_len = talloc_get_size(bytes);
425 subreq = cli_smb_req_create(state, ev, cli, SMBsesssetupX, 0, 13, vwv,
427 if (subreq == NULL) {
431 tevent_req_set_callback(subreq, cli_session_setup_guest_done, req);
436 struct tevent_req *cli_session_setup_guest_send(TALLOC_CTX *mem_ctx,
437 struct tevent_context *ev,
438 struct cli_state *cli)
440 struct tevent_req *req, *subreq;
443 req = cli_session_setup_guest_create(mem_ctx, ev, cli, &subreq);
448 status = smb1cli_req_chain_submit(&subreq, 1);
449 if (!NT_STATUS_IS_OK(status)) {
450 tevent_req_nterror(req, status);
451 return tevent_req_post(req, ev);
456 static void cli_session_setup_guest_done(struct tevent_req *subreq)
458 struct tevent_req *req = tevent_req_callback_data(
459 subreq, struct tevent_req);
460 struct cli_session_setup_guest_state *state = tevent_req_data(
461 req, struct cli_session_setup_guest_state);
462 struct cli_state *cli = state->cli;
473 status = cli_smb_recv(subreq, state, &in, 3, &wct, &vwv,
476 if (!NT_STATUS_IS_OK(status)) {
477 tevent_req_nterror(req, status);
481 inhdr = in + NBT_HDR_SIZE;
484 cli_state_set_uid(state->cli, SVAL(inhdr, HDR_UID));
485 cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0);
487 status = smb_bytes_talloc_string(cli,
494 if (!NT_STATUS_IS_OK(status)) {
495 tevent_req_nterror(req, status);
500 status = smb_bytes_talloc_string(cli,
507 if (!NT_STATUS_IS_OK(status)) {
508 tevent_req_nterror(req, status);
513 status = smb_bytes_talloc_string(cli,
520 if (!NT_STATUS_IS_OK(status)) {
521 tevent_req_nterror(req, status);
526 status = cli_set_username(cli, "");
527 if (!NT_STATUS_IS_OK(status)) {
528 tevent_req_nterror(req, status);
531 tevent_req_done(req);
534 NTSTATUS cli_session_setup_guest_recv(struct tevent_req *req)
536 return tevent_req_simple_recv_ntstatus(req);
539 static NTSTATUS cli_session_setup_guest(struct cli_state *cli)
541 TALLOC_CTX *frame = talloc_stackframe();
542 struct tevent_context *ev;
543 struct tevent_req *req;
544 NTSTATUS status = NT_STATUS_OK;
546 if (smbXcli_conn_has_async_calls(cli->conn)) {
548 * Can't use sync call while an async call is in flight
550 status = NT_STATUS_INVALID_PARAMETER;
554 ev = samba_tevent_context_init(frame);
556 status = NT_STATUS_NO_MEMORY;
560 req = cli_session_setup_guest_send(frame, ev, cli);
562 status = NT_STATUS_NO_MEMORY;
566 if (!tevent_req_poll(req, ev)) {
567 status = map_nt_error_from_unix(errno);
571 status = cli_session_setup_guest_recv(req);
577 /****************************************************************************
578 Do a NT1 plaintext session setup.
579 ****************************************************************************/
581 struct cli_session_setup_plain_state {
582 struct cli_state *cli;
587 static void cli_session_setup_plain_done(struct tevent_req *subreq);
589 static struct tevent_req *cli_session_setup_plain_send(
590 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
591 struct cli_state *cli,
592 const char *user, const char *pass, const char *workgroup)
594 struct tevent_req *req, *subreq;
595 struct cli_session_setup_plain_state *state;
601 req = tevent_req_create(mem_ctx, &state,
602 struct cli_session_setup_plain_state);
610 SCVAL(vwv+0, 0, 0xff);
613 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
615 SSVAL(vwv+4, 0, cli_state_get_vc_num(cli));
616 SIVAL(vwv+5, 0, smb1cli_conn_server_session_key(cli->conn));
621 SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli, 0));
623 bytes = talloc_array(state, uint8_t, 0);
624 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), pass, strlen(pass)+1,
626 if (tevent_req_nomem(bytes, req)) {
627 return tevent_req_post(req, ev);
629 SSVAL(vwv + (smbXcli_conn_use_unicode(cli->conn) ? 8 : 7), 0, passlen);
631 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
632 user, strlen(user)+1, NULL);
633 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
634 workgroup, strlen(workgroup)+1, NULL);
635 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
638 version = talloc_asprintf(talloc_tos(), "Samba %s",
639 samba_version_string());
640 if (tevent_req_nomem(version, req)){
641 return tevent_req_post(req, ev);
643 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
644 version, strlen(version)+1, NULL);
645 TALLOC_FREE(version);
647 if (tevent_req_nomem(bytes, req)) {
648 return tevent_req_post(req, ev);
651 subreq = cli_smb_send(state, ev, cli, SMBsesssetupX, 0, 13, vwv,
652 talloc_get_size(bytes), bytes);
653 if (tevent_req_nomem(subreq, req)) {
654 return tevent_req_post(req, ev);
656 tevent_req_set_callback(subreq, cli_session_setup_plain_done, req);
660 static void cli_session_setup_plain_done(struct tevent_req *subreq)
662 struct tevent_req *req = tevent_req_callback_data(
663 subreq, struct tevent_req);
664 struct cli_session_setup_plain_state *state = tevent_req_data(
665 req, struct cli_session_setup_plain_state);
666 struct cli_state *cli = state->cli;
677 status = cli_smb_recv(subreq, state, &in, 3, &wct, &vwv,
680 if (tevent_req_nterror(req, status)) {
684 inhdr = in + NBT_HDR_SIZE;
687 cli_state_set_uid(state->cli, SVAL(inhdr, HDR_UID));
688 cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0);
690 status = smb_bytes_talloc_string(cli,
697 if (!NT_STATUS_IS_OK(status)) {
698 tevent_req_nterror(req, status);
703 status = smb_bytes_talloc_string(cli,
710 if (!NT_STATUS_IS_OK(status)) {
711 tevent_req_nterror(req, status);
716 status = smb_bytes_talloc_string(cli,
723 if (!NT_STATUS_IS_OK(status)) {
724 tevent_req_nterror(req, status);
729 status = cli_set_username(cli, state->user);
730 if (tevent_req_nterror(req, status)) {
734 tevent_req_done(req);
737 static NTSTATUS cli_session_setup_plain_recv(struct tevent_req *req)
739 return tevent_req_simple_recv_ntstatus(req);
742 static NTSTATUS cli_session_setup_plain(struct cli_state *cli,
743 const char *user, const char *pass,
744 const char *workgroup)
746 TALLOC_CTX *frame = talloc_stackframe();
747 struct tevent_context *ev;
748 struct tevent_req *req;
749 NTSTATUS status = NT_STATUS_NO_MEMORY;
751 if (smbXcli_conn_has_async_calls(cli->conn)) {
753 * Can't use sync call while an async call is in flight
755 status = NT_STATUS_INVALID_PARAMETER;
758 ev = samba_tevent_context_init(frame);
762 req = cli_session_setup_plain_send(frame, ev, cli, user, pass,
767 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
770 status = cli_session_setup_plain_recv(req);
776 /****************************************************************************
777 do a NT1 NTLM/LM encrypted session setup - for when extended security
779 @param cli client state to create do session setup on
781 @param pass *either* cleartext password (passlen !=24) or LM response.
782 @param ntpass NT response, implies ntpasslen >=24, implies pass is not clear
783 @param workgroup The user's domain.
784 ****************************************************************************/
786 struct cli_session_setup_nt1_state {
787 struct cli_state *cli;
790 DATA_BLOB session_key;
794 static void cli_session_setup_nt1_done(struct tevent_req *subreq);
796 static struct tevent_req *cli_session_setup_nt1_send(
797 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
798 struct cli_state *cli, const char *user,
799 const char *pass, size_t passlen,
800 const char *ntpass, size_t ntpasslen,
801 const char *workgroup)
803 struct tevent_req *req, *subreq;
804 struct cli_session_setup_nt1_state *state;
805 DATA_BLOB lm_response = data_blob_null;
806 DATA_BLOB nt_response = data_blob_null;
807 DATA_BLOB session_key = data_blob_null;
810 char *workgroup_upper;
812 req = tevent_req_create(mem_ctx, &state,
813 struct cli_session_setup_nt1_state);
822 /* do nothing - guest login */
823 } else if (passlen != 24) {
824 if (lp_client_ntlmv2_auth()) {
825 DATA_BLOB server_chal;
826 DATA_BLOB names_blob;
829 data_blob_const(smb1cli_conn_server_challenge(cli->conn),
833 * note that the 'workgroup' here is a best
834 * guess - we don't know the server's domain
835 * at this point. Windows clients also don't
838 names_blob = NTLMv2_generate_names_blob(
839 NULL, NULL, workgroup);
841 if (tevent_req_nomem(names_blob.data, req)) {
842 return tevent_req_post(req, ev);
845 if (!SMBNTLMv2encrypt(NULL, user, workgroup, pass,
846 &server_chal, &names_blob,
847 &lm_response, &nt_response,
848 NULL, &session_key)) {
849 data_blob_free(&names_blob);
851 req, NT_STATUS_ACCESS_DENIED);
852 return tevent_req_post(req, ev);
854 data_blob_free(&names_blob);
858 E_md4hash(pass, nt_hash);
861 nt_response = data_blob_null;
863 nt_response = data_blob(NULL, 24);
864 if (tevent_req_nomem(nt_response.data, req)) {
865 return tevent_req_post(req, ev);
868 SMBNTencrypt(pass, smb1cli_conn_server_challenge(cli->conn),
871 /* non encrypted password supplied. Ignore ntpass. */
872 if (lp_client_lanman_auth()) {
874 lm_response = data_blob(NULL, 24);
875 if (tevent_req_nomem(lm_response.data, req)) {
876 return tevent_req_post(req, ev);
879 if (!SMBencrypt(pass,
880 smb1cli_conn_server_challenge(cli->conn),
883 * Oops, the LM response is
884 * invalid, just put the NT
885 * response there instead
887 data_blob_free(&lm_response);
888 lm_response = data_blob(
894 * LM disabled, place NT# in LM field
897 lm_response = data_blob(
898 nt_response.data, nt_response.length);
901 if (tevent_req_nomem(lm_response.data, req)) {
902 return tevent_req_post(req, ev);
905 session_key = data_blob(NULL, 16);
906 if (tevent_req_nomem(session_key.data, req)) {
907 return tevent_req_post(req, ev);
910 E_deshash(pass, session_key.data);
911 memset(&session_key.data[8], '\0', 8);
913 SMBsesskeygen_ntv1(nt_hash, session_key.data);
917 /* pre-encrypted password supplied. Only used for
918 security=server, can't do
919 signing because we don't have original key */
921 lm_response = data_blob(pass, passlen);
922 if (tevent_req_nomem(lm_response.data, req)) {
923 return tevent_req_post(req, ev);
926 nt_response = data_blob(ntpass, ntpasslen);
927 if (tevent_req_nomem(nt_response.data, req)) {
928 return tevent_req_post(req, ev);
933 state->response = data_blob_talloc(
934 state, lm_response.data, lm_response.length);
936 state->response = data_blob_talloc(
937 state, nt_response.data, nt_response.length);
939 if (tevent_req_nomem(state->response.data, req)) {
940 return tevent_req_post(req, ev);
943 if (session_key.data) {
944 state->session_key = data_blob_talloc(
945 state, session_key.data, session_key.length);
946 if (tevent_req_nomem(state->session_key.data, req)) {
947 return tevent_req_post(req, ev);
950 data_blob_free(&session_key);
952 SCVAL(vwv+0, 0, 0xff);
955 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
957 SSVAL(vwv+4, 0, cli_state_get_vc_num(cli));
958 SIVAL(vwv+5, 0, smb1cli_conn_server_session_key(cli->conn));
959 SSVAL(vwv+7, 0, lm_response.length);
960 SSVAL(vwv+8, 0, nt_response.length);
963 SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli, 0));
965 bytes = talloc_array(state, uint8_t,
966 lm_response.length + nt_response.length);
967 if (tevent_req_nomem(bytes, req)) {
968 return tevent_req_post(req, ev);
970 if (lm_response.length != 0) {
971 memcpy(bytes, lm_response.data, lm_response.length);
973 if (nt_response.length != 0) {
974 memcpy(bytes + lm_response.length,
975 nt_response.data, nt_response.length);
977 data_blob_free(&lm_response);
978 data_blob_free(&nt_response);
980 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
981 user, strlen(user)+1, NULL);
984 * Upper case here might help some NTLMv2 implementations
986 workgroup_upper = talloc_strdup_upper(talloc_tos(), workgroup);
987 if (tevent_req_nomem(workgroup_upper, req)) {
988 return tevent_req_post(req, ev);
990 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
991 workgroup_upper, strlen(workgroup_upper)+1,
993 TALLOC_FREE(workgroup_upper);
995 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "Unix", 5, NULL);
996 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "Samba", 6, NULL);
997 if (tevent_req_nomem(bytes, req)) {
998 return tevent_req_post(req, ev);
1001 subreq = cli_smb_send(state, ev, cli, SMBsesssetupX, 0, 13, vwv,
1002 talloc_get_size(bytes), bytes);
1003 if (tevent_req_nomem(subreq, req)) {
1004 return tevent_req_post(req, ev);
1006 tevent_req_set_callback(subreq, cli_session_setup_nt1_done, req);
1010 static void cli_session_setup_nt1_done(struct tevent_req *subreq)
1012 struct tevent_req *req = tevent_req_callback_data(
1013 subreq, struct tevent_req);
1014 struct cli_session_setup_nt1_state *state = tevent_req_data(
1015 req, struct cli_session_setup_nt1_state);
1016 struct cli_state *cli = state->cli;
1027 status = cli_smb_recv(subreq, state, &in, 3, &wct, &vwv,
1028 &num_bytes, &bytes);
1029 TALLOC_FREE(subreq);
1030 if (!NT_STATUS_IS_OK(status)) {
1031 tevent_req_nterror(req, status);
1035 inhdr = in + NBT_HDR_SIZE;
1038 cli_state_set_uid(state->cli, SVAL(inhdr, HDR_UID));
1039 cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0);
1041 status = smb_bytes_talloc_string(cli,
1047 if (!NT_STATUS_IS_OK(status)) {
1048 tevent_req_nterror(req, status);
1053 status = smb_bytes_talloc_string(cli,
1059 if (!NT_STATUS_IS_OK(status)) {
1060 tevent_req_nterror(req, status);
1065 status = smb_bytes_talloc_string(cli,
1067 &cli->server_domain,
1071 if (!NT_STATUS_IS_OK(status)) {
1072 tevent_req_nterror(req, status);
1077 status = cli_set_username(cli, state->user);
1078 if (tevent_req_nterror(req, status)) {
1081 if (smb1cli_conn_activate_signing(cli->conn, state->session_key, state->response)
1082 && !smb1cli_conn_check_signing(cli->conn, (uint8_t *)in, 1)) {
1083 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1086 if (state->session_key.data) {
1087 struct smbXcli_session *session = state->cli->smb1.session;
1089 status = smb1cli_session_set_session_key(session,
1090 state->session_key);
1091 if (tevent_req_nterror(req, status)) {
1095 tevent_req_done(req);
1098 static NTSTATUS cli_session_setup_nt1_recv(struct tevent_req *req)
1100 return tevent_req_simple_recv_ntstatus(req);
1103 static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user,
1104 const char *pass, size_t passlen,
1105 const char *ntpass, size_t ntpasslen,
1106 const char *workgroup)
1108 TALLOC_CTX *frame = talloc_stackframe();
1109 struct tevent_context *ev;
1110 struct tevent_req *req;
1111 NTSTATUS status = NT_STATUS_NO_MEMORY;
1113 if (smbXcli_conn_has_async_calls(cli->conn)) {
1115 * Can't use sync call while an async call is in flight
1117 status = NT_STATUS_INVALID_PARAMETER;
1120 ev = samba_tevent_context_init(frame);
1124 req = cli_session_setup_nt1_send(frame, ev, cli, user, pass, passlen,
1125 ntpass, ntpasslen, workgroup);
1129 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1132 status = cli_session_setup_nt1_recv(req);
1138 /* The following is calculated from :
1140 * (smb_wcnt * 2) = 24 (smb_wcnt == 12 in cli_session_setup_blob_send() )
1141 * (strlen("Unix") + 1 + strlen("Samba") + 1) * 2 = 22 (unicode strings at
1145 #define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22)
1147 struct cli_sesssetup_blob_state {
1148 struct tevent_context *ev;
1149 struct cli_state *cli;
1151 uint16_t max_blob_size;
1155 DATA_BLOB smb2_blob;
1156 struct iovec *recv_iov;
1163 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state *state,
1164 struct tevent_req **psubreq);
1165 static void cli_sesssetup_blob_done(struct tevent_req *subreq);
1167 static struct tevent_req *cli_sesssetup_blob_send(TALLOC_CTX *mem_ctx,
1168 struct tevent_context *ev,
1169 struct cli_state *cli,
1172 struct tevent_req *req, *subreq;
1173 struct cli_sesssetup_blob_state *state;
1174 uint32_t usable_space;
1176 req = tevent_req_create(mem_ctx, &state,
1177 struct cli_sesssetup_blob_state);
1185 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
1186 usable_space = UINT16_MAX;
1188 usable_space = cli_state_available_size(cli,
1189 BASE_SESSSETUP_BLOB_PACKET_SIZE);
1192 if (usable_space == 0) {
1193 DEBUG(1, ("cli_session_setup_blob: cli->max_xmit too small "
1194 "(not possible to send %u bytes)\n",
1195 BASE_SESSSETUP_BLOB_PACKET_SIZE + 1));
1196 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1197 return tevent_req_post(req, ev);
1199 state->max_blob_size = MIN(usable_space, 0xFFFF);
1201 if (!cli_sesssetup_blob_next(state, &subreq)) {
1202 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1203 return tevent_req_post(req, ev);
1205 tevent_req_set_callback(subreq, cli_sesssetup_blob_done, req);
1209 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state *state,
1210 struct tevent_req **psubreq)
1212 struct tevent_req *subreq;
1215 thistime = MIN(state->blob.length, state->max_blob_size);
1217 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
1219 state->smb2_blob.data = state->blob.data;
1220 state->smb2_blob.length = thistime;
1222 state->blob.data += thistime;
1223 state->blob.length -= thistime;
1225 subreq = smb2cli_session_setup_send(state, state->ev,
1227 state->cli->timeout,
1228 state->cli->smb2.session,
1230 SMB2_CAP_DFS, /* in_capabilities */
1232 0, /* in_previous_session_id */
1234 if (subreq == NULL) {
1241 SCVAL(state->vwv+0, 0, 0xFF);
1242 SCVAL(state->vwv+0, 1, 0);
1243 SSVAL(state->vwv+1, 0, 0);
1244 SSVAL(state->vwv+2, 0, CLI_BUFFER_SIZE);
1245 SSVAL(state->vwv+3, 0, 2);
1246 SSVAL(state->vwv+4, 0, 1);
1247 SIVAL(state->vwv+5, 0, 0);
1249 SSVAL(state->vwv+7, 0, thistime);
1251 SSVAL(state->vwv+8, 0, 0);
1252 SSVAL(state->vwv+9, 0, 0);
1253 SIVAL(state->vwv+10, 0,
1254 cli_session_setup_capabilities(state->cli, CAP_EXTENDED_SECURITY));
1256 state->buf = (uint8_t *)talloc_memdup(state, state->blob.data,
1258 if (state->buf == NULL) {
1261 state->blob.data += thistime;
1262 state->blob.length -= thistime;
1264 state->buf = smb_bytes_push_str(state->buf, smbXcli_conn_use_unicode(state->cli->conn),
1266 state->buf = smb_bytes_push_str(state->buf, smbXcli_conn_use_unicode(state->cli->conn),
1268 if (state->buf == NULL) {
1271 subreq = cli_smb_send(state, state->ev, state->cli, SMBsesssetupX, 0,
1273 talloc_get_size(state->buf), state->buf);
1274 if (subreq == NULL) {
1281 static void cli_sesssetup_blob_done(struct tevent_req *subreq)
1283 struct tevent_req *req = tevent_req_callback_data(
1284 subreq, struct tevent_req);
1285 struct cli_sesssetup_blob_state *state = tevent_req_data(
1286 req, struct cli_sesssetup_blob_state);
1287 struct cli_state *cli = state->cli;
1294 uint16_t blob_length;
1299 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
1300 status = smb2cli_session_setup_recv(subreq, state,
1304 status = cli_smb_recv(subreq, state, &in, 4, &wct, &vwv,
1305 &num_bytes, &bytes);
1306 TALLOC_FREE(state->buf);
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;
1317 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
1322 inhdr = in + NBT_HDR_SIZE;
1323 cli_state_set_uid(state->cli, SVAL(inhdr, HDR_UID));
1324 cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0);
1326 blob_length = SVAL(vwv+3, 0);
1327 if (blob_length > num_bytes) {
1328 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1331 state->ret_blob = data_blob_const(bytes, blob_length);
1333 p = bytes + blob_length;
1335 status = smb_bytes_talloc_string(cli,
1342 if (!NT_STATUS_IS_OK(status)) {
1343 tevent_req_nterror(req, status);
1348 status = smb_bytes_talloc_string(cli,
1355 if (!NT_STATUS_IS_OK(status)) {
1356 tevent_req_nterror(req, status);
1361 status = smb_bytes_talloc_string(cli,
1363 &cli->server_domain,
1368 if (!NT_STATUS_IS_OK(status)) {
1369 tevent_req_nterror(req, status);
1375 if (state->blob.length != 0) {
1379 if (!cli_sesssetup_blob_next(state, &subreq)) {
1380 tevent_req_oom(req);
1383 tevent_req_set_callback(subreq, cli_sesssetup_blob_done, req);
1386 tevent_req_done(req);
1389 static NTSTATUS cli_sesssetup_blob_recv(struct tevent_req *req,
1390 TALLOC_CTX *mem_ctx,
1393 struct iovec **precv_iov)
1395 struct cli_sesssetup_blob_state *state = tevent_req_data(
1396 req, struct cli_sesssetup_blob_state);
1399 struct iovec *recv_iov;
1401 if (tevent_req_is_nterror(req, &status)) {
1402 TALLOC_FREE(state->cli->smb2.session);
1403 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
1407 inbuf = talloc_move(mem_ctx, &state->inbuf);
1408 recv_iov = talloc_move(mem_ctx, &state->recv_iov);
1409 if (pblob != NULL) {
1410 *pblob = state->ret_blob;
1412 if (pinbuf != NULL) {
1415 if (precv_iov != NULL) {
1416 *precv_iov = recv_iov;
1418 /* could be NT_STATUS_MORE_PROCESSING_REQUIRED */
1419 return state->status;
1424 /****************************************************************************
1425 Use in-memory credentials cache
1426 ****************************************************************************/
1428 static void use_in_memory_ccache(void) {
1429 setenv(KRB5_ENV_CCNAME, "MEMORY:cliconnect", 1);
1432 /****************************************************************************
1433 Do a spnego/kerberos encrypted session setup.
1434 ****************************************************************************/
1436 struct cli_session_setup_kerberos_state {
1437 struct cli_state *cli;
1438 DATA_BLOB negTokenTarg;
1439 DATA_BLOB session_key_krb5;
1440 ADS_STATUS ads_status;
1443 static void cli_session_setup_kerberos_done(struct tevent_req *subreq);
1445 static struct tevent_req *cli_session_setup_kerberos_send(
1446 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
1447 const char *principal)
1449 struct tevent_req *req, *subreq;
1450 struct cli_session_setup_kerberos_state *state;
1453 DEBUG(2,("Doing kerberos session setup\n"));
1455 req = tevent_req_create(mem_ctx, &state,
1456 struct cli_session_setup_kerberos_state);
1461 state->ads_status = ADS_SUCCESS;
1464 * Ok, this is cheating: spnego_gen_krb5_negTokenInit can block if
1465 * we have to acquire a ticket. To be fixed later :-)
1467 rc = spnego_gen_krb5_negTokenInit(state, principal, 0, &state->negTokenTarg,
1468 &state->session_key_krb5, 0, NULL, NULL);
1470 DEBUG(1, ("cli_session_setup_kerberos: "
1471 "spnego_gen_krb5_negTokenInit failed: %s\n",
1472 error_message(rc)));
1473 state->ads_status = ADS_ERROR_KRB5(rc);
1474 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
1475 return tevent_req_post(req, ev);
1479 file_save("negTokenTarg.dat", state->negTokenTarg.data,
1480 state->negTokenTarg.length);
1483 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
1484 state->cli->smb2.session = smbXcli_session_create(cli,
1486 if (tevent_req_nomem(state->cli->smb2.session, req)) {
1487 return tevent_req_post(req, ev);
1491 subreq = cli_sesssetup_blob_send(state, ev, cli, state->negTokenTarg);
1492 if (tevent_req_nomem(subreq, req)) {
1493 return tevent_req_post(req, ev);
1495 tevent_req_set_callback(subreq, cli_session_setup_kerberos_done, req);
1499 static void cli_session_setup_kerberos_done(struct tevent_req *subreq)
1501 struct tevent_req *req = tevent_req_callback_data(
1502 subreq, struct tevent_req);
1503 struct cli_session_setup_kerberos_state *state = tevent_req_data(
1504 req, struct cli_session_setup_kerberos_state);
1505 uint8_t *inbuf = NULL;
1506 struct iovec *recv_iov = NULL;
1509 status = cli_sesssetup_blob_recv(subreq, state,
1510 NULL, &inbuf, &recv_iov);
1511 TALLOC_FREE(subreq);
1512 if (!NT_STATUS_IS_OK(status)) {
1513 tevent_req_nterror(req, status);
1517 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
1518 struct smbXcli_session *session = state->cli->smb2.session;
1519 status = smb2cli_session_set_session_key(session,
1520 state->session_key_krb5,
1522 if (tevent_req_nterror(req, status)) {
1526 struct smbXcli_session *session = state->cli->smb1.session;
1528 status = smb1cli_session_set_session_key(session,
1529 state->session_key_krb5);
1530 if (tevent_req_nterror(req, status)) {
1534 if (smb1cli_conn_activate_signing(state->cli->conn, state->session_key_krb5,
1536 && !smb1cli_conn_check_signing(state->cli->conn, inbuf, 1)) {
1537 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1542 tevent_req_done(req);
1545 static ADS_STATUS cli_session_setup_kerberos_recv(struct tevent_req *req)
1547 struct cli_session_setup_kerberos_state *state = tevent_req_data(
1548 req, struct cli_session_setup_kerberos_state);
1551 if (tevent_req_is_nterror(req, &status)) {
1552 return ADS_ERROR_NT(status);
1554 return state->ads_status;
1557 static ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli,
1558 const char *principal)
1560 struct tevent_context *ev;
1561 struct tevent_req *req;
1562 ADS_STATUS status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1564 if (smbXcli_conn_has_async_calls(cli->conn)) {
1565 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1567 ev = samba_tevent_context_init(talloc_tos());
1571 req = cli_session_setup_kerberos_send(ev, ev, cli, principal);
1575 if (!tevent_req_poll(req, ev)) {
1576 status = ADS_ERROR_SYSTEM(errno);
1579 status = cli_session_setup_kerberos_recv(req);
1584 #endif /* HAVE_KRB5 */
1586 /****************************************************************************
1587 Do a spnego/NTLMSSP encrypted session setup.
1588 ****************************************************************************/
1590 struct cli_session_setup_ntlmssp_state {
1591 struct tevent_context *ev;
1592 struct cli_state *cli;
1593 struct ntlmssp_state *ntlmssp_state;
1598 static int cli_session_setup_ntlmssp_state_destructor(
1599 struct cli_session_setup_ntlmssp_state *state)
1601 if (state->ntlmssp_state != NULL) {
1602 TALLOC_FREE(state->ntlmssp_state);
1607 static void cli_session_setup_ntlmssp_done(struct tevent_req *req);
1609 static struct tevent_req *cli_session_setup_ntlmssp_send(
1610 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
1611 const char *user, const char *pass, const char *domain)
1613 struct tevent_req *req, *subreq;
1614 struct cli_session_setup_ntlmssp_state *state;
1617 const char *OIDs_ntlm[] = {OID_NTLMSSP, NULL};
1619 req = tevent_req_create(mem_ctx, &state,
1620 struct cli_session_setup_ntlmssp_state);
1628 state->ntlmssp_state = NULL;
1629 talloc_set_destructor(
1630 state, cli_session_setup_ntlmssp_state_destructor);
1632 status = ntlmssp_client_start(state,
1635 lp_client_ntlmv2_auth(),
1636 &state->ntlmssp_state);
1637 if (!NT_STATUS_IS_OK(status)) {
1640 ntlmssp_want_feature(state->ntlmssp_state,
1641 NTLMSSP_FEATURE_SESSION_KEY);
1642 if (cli->use_ccache) {
1643 ntlmssp_want_feature(state->ntlmssp_state,
1644 NTLMSSP_FEATURE_CCACHE);
1646 status = ntlmssp_set_username(state->ntlmssp_state, user);
1647 if (!NT_STATUS_IS_OK(status)) {
1650 status = ntlmssp_set_domain(state->ntlmssp_state, domain);
1651 if (!NT_STATUS_IS_OK(status)) {
1654 if (cli->pw_nt_hash) {
1655 status = ntlmssp_set_password_hash(state->ntlmssp_state, pass);
1657 status = ntlmssp_set_password(state->ntlmssp_state, pass);
1659 if (!NT_STATUS_IS_OK(status)) {
1662 status = ntlmssp_update(state->ntlmssp_state, data_blob_null,
1664 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1668 state->blob_out = spnego_gen_negTokenInit(state, OIDs_ntlm, &blob_out, NULL);
1669 data_blob_free(&blob_out);
1671 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
1672 state->cli->smb2.session = smbXcli_session_create(cli,
1674 if (tevent_req_nomem(state->cli->smb2.session, req)) {
1675 return tevent_req_post(req, ev);
1679 subreq = cli_sesssetup_blob_send(state, ev, cli, state->blob_out);
1680 if (tevent_req_nomem(subreq, req)) {
1681 return tevent_req_post(req, ev);
1683 tevent_req_set_callback(subreq, cli_session_setup_ntlmssp_done, req);
1686 tevent_req_nterror(req, status);
1687 return tevent_req_post(req, ev);
1690 static void cli_session_setup_ntlmssp_done(struct tevent_req *subreq)
1692 struct tevent_req *req = tevent_req_callback_data(
1693 subreq, struct tevent_req);
1694 struct cli_session_setup_ntlmssp_state *state = tevent_req_data(
1695 req, struct cli_session_setup_ntlmssp_state);
1696 DATA_BLOB blob_in, msg_in, blob_out;
1697 uint8_t *inbuf = NULL;
1698 struct iovec *recv_iov = NULL;
1702 status = cli_sesssetup_blob_recv(subreq, talloc_tos(), &blob_in,
1704 TALLOC_FREE(subreq);
1705 data_blob_free(&state->blob_out);
1707 if (NT_STATUS_IS_OK(status)) {
1708 if (state->cli->server_domain[0] == '\0') {
1709 TALLOC_FREE(state->cli->server_domain);
1710 state->cli->server_domain = talloc_strdup(state->cli,
1711 state->ntlmssp_state->server.netbios_domain);
1712 if (state->cli->server_domain == NULL) {
1713 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1718 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
1719 struct smbXcli_session *session = state->cli->smb2.session;
1721 if (ntlmssp_is_anonymous(state->ntlmssp_state)) {
1723 * Windows server does not set the
1724 * SMB2_SESSION_FLAG_IS_GUEST nor
1725 * SMB2_SESSION_FLAG_IS_NULL flag.
1727 * This fix makes sure we do not try
1728 * to verify a signature on the final
1729 * session setup response.
1731 TALLOC_FREE(state->ntlmssp_state);
1732 tevent_req_done(req);
1736 status = smb2cli_session_set_session_key(session,
1737 state->ntlmssp_state->session_key,
1739 if (tevent_req_nterror(req, status)) {
1743 struct smbXcli_session *session = state->cli->smb1.session;
1745 status = smb1cli_session_set_session_key(session,
1746 state->ntlmssp_state->session_key);
1747 if (tevent_req_nterror(req, status)) {
1751 if (smb1cli_conn_activate_signing(
1752 state->cli->conn, state->ntlmssp_state->session_key,
1754 && !smb1cli_conn_check_signing(state->cli->conn, inbuf, 1)) {
1755 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1759 TALLOC_FREE(state->ntlmssp_state);
1760 tevent_req_done(req);
1763 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1764 tevent_req_nterror(req, status);
1768 if (blob_in.length == 0) {
1769 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
1773 if ((state->turn == 1)
1774 && NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1775 DATA_BLOB tmp_blob = data_blob_null;
1776 /* the server might give us back two challenges */
1777 parse_ret = spnego_parse_challenge(state, blob_in, &msg_in,
1779 data_blob_free(&tmp_blob);
1781 parse_ret = spnego_parse_auth_response(state, blob_in, status,
1782 OID_NTLMSSP, &msg_in);
1787 DEBUG(3,("Failed to parse auth response\n"));
1788 if (NT_STATUS_IS_OK(status)
1789 || NT_STATUS_EQUAL(status,
1790 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1792 req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1797 status = ntlmssp_update(state->ntlmssp_state, msg_in, &blob_out);
1799 if (!NT_STATUS_IS_OK(status)
1800 && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1801 TALLOC_FREE(state->ntlmssp_state);
1802 tevent_req_nterror(req, status);
1806 state->blob_out = spnego_gen_auth(state, blob_out);
1807 if (tevent_req_nomem(state->blob_out.data, req)) {
1811 subreq = cli_sesssetup_blob_send(state, state->ev, state->cli,
1813 if (tevent_req_nomem(subreq, req)) {
1816 tevent_req_set_callback(subreq, cli_session_setup_ntlmssp_done, req);
1819 static NTSTATUS cli_session_setup_ntlmssp_recv(struct tevent_req *req)
1821 struct cli_session_setup_ntlmssp_state *state = tevent_req_data(
1822 req, struct cli_session_setup_ntlmssp_state);
1825 if (tevent_req_is_nterror(req, &status)) {
1826 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
1829 return NT_STATUS_OK;
1834 static char *cli_session_setup_get_principal(
1835 TALLOC_CTX *mem_ctx, const char *spnego_principal,
1836 const char *remote_name, const char *dest_realm)
1838 char *principal = NULL;
1840 if (!lp_client_use_spnego_principal() ||
1841 strequal(principal, ADS_IGNORE_PRINCIPAL)) {
1842 spnego_principal = NULL;
1844 if (spnego_principal != NULL) {
1845 DEBUG(3, ("cli_session_setup_spnego: using spnego provided "
1846 "principal %s\n", spnego_principal));
1847 return talloc_strdup(mem_ctx, spnego_principal);
1849 if (is_ipaddress(remote_name) ||
1850 strequal(remote_name, STAR_SMBSERVER)) {
1854 DEBUG(3, ("cli_session_setup_spnego: using target "
1855 "hostname not SPNEGO principal\n"));
1858 char *realm = strupper_talloc(talloc_tos(), dest_realm);
1859 if (realm == NULL) {
1862 principal = talloc_asprintf(talloc_tos(), "cifs/%s@%s",
1863 remote_name, realm);
1866 principal = kerberos_get_principal_from_service_hostname(
1867 talloc_tos(), "cifs", remote_name, lp_realm());
1869 DEBUG(3, ("cli_session_setup_spnego: guessed server principal=%s\n",
1870 principal ? principal : "<null>"));
1876 static char *cli_session_setup_get_account(TALLOC_CTX *mem_ctx,
1877 const char *principal)
1881 account = talloc_strdup(mem_ctx, principal);
1882 if (account == NULL) {
1885 p = strchr_m(account, '@');
1892 /****************************************************************************
1893 Do a spnego encrypted session setup.
1895 user_domain: The shortname of the domain the user/machine is a member of.
1896 dest_realm: The realm we're connecting to, if NULL we use our default realm.
1897 ****************************************************************************/
1899 struct cli_session_setup_spnego_state {
1900 struct tevent_context *ev;
1901 struct cli_state *cli;
1903 const char *account;
1905 const char *user_domain;
1906 const char *dest_realm;
1911 static void cli_session_setup_spnego_done_krb(struct tevent_req *subreq);
1914 static void cli_session_setup_spnego_done_ntlmssp(struct tevent_req *subreq);
1916 static struct tevent_req *cli_session_setup_spnego_send(
1917 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
1918 const char *user, const char *pass, const char *user_domain,
1919 const char *dest_realm)
1921 struct tevent_req *req, *subreq;
1922 struct cli_session_setup_spnego_state *state;
1923 char *principal = NULL;
1924 char *OIDs[ASN1_MAX_OIDS];
1926 const DATA_BLOB *server_blob;
1929 req = tevent_req_create(mem_ctx, &state,
1930 struct cli_session_setup_spnego_state);
1938 state->user_domain = user_domain;
1939 state->dest_realm = dest_realm;
1941 state->account = cli_session_setup_get_account(state, user);
1942 if (tevent_req_nomem(state->account, req)) {
1943 return tevent_req_post(req, ev);
1946 server_blob = smbXcli_conn_server_gss_blob(cli->conn);
1948 DEBUG(3,("Doing spnego session setup (blob length=%lu)\n",
1949 (unsigned long)server_blob->length));
1951 /* the server might not even do spnego */
1952 if (server_blob->length == 0) {
1953 DEBUG(3,("server didn't supply a full spnego negprot\n"));
1958 file_save("negprot.dat", cli->secblob.data, cli->secblob.length);
1961 /* The server sent us the first part of the SPNEGO exchange in the
1962 * negprot reply. It is WRONG to depend on the principal sent in the
1963 * negprot reply, but right now we do it. If we don't receive one,
1964 * we try to best guess, then fall back to NTLM. */
1965 if (!spnego_parse_negTokenInit(state, *server_blob, OIDs,
1966 &principal, NULL) ||
1968 state->result = ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1969 tevent_req_done(req);
1970 return tevent_req_post(req, ev);
1973 /* make sure the server understands kerberos */
1974 for (i=0;OIDs[i];i++) {
1976 DEBUG(3,("got OID=%s\n", OIDs[i]));
1978 DEBUGADD(3,("got OID=%s\n", OIDs[i]));
1979 if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0 ||
1980 strcmp(OIDs[i], OID_KERBEROS5) == 0) {
1981 cli->got_kerberos_mechanism = True;
1983 talloc_free(OIDs[i]);
1986 DEBUG(3,("got principal=%s\n", principal ? principal : "<null>"));
1988 status = cli_set_username(cli, user);
1989 if (!NT_STATUS_IS_OK(status)) {
1990 state->result = ADS_ERROR_NT(status);
1991 tevent_req_done(req);
1992 return tevent_req_post(req, ev);
1996 /* If password is set we reauthenticate to kerberos server
1997 * and do not store results */
1999 if (user && *user && cli->got_kerberos_mechanism && cli->use_kerberos) {
2000 const char *remote_name = smbXcli_conn_remote_name(cli->conn);
2003 if (pass && *pass) {
2006 use_in_memory_ccache();
2007 ret = kerberos_kinit_password(user, pass, 0 /* no time correction for now */, NULL);
2010 TALLOC_FREE(principal);
2011 DEBUG(0, ("Kinit failed: %s\n", error_message(ret)));
2012 if (cli->fallback_after_kerberos)
2014 state->result = ADS_ERROR_KRB5(ret);
2015 tevent_req_done(req);
2016 return tevent_req_post(req, ev);
2020 tmp = cli_session_setup_get_principal(
2021 talloc_tos(), principal, remote_name, dest_realm);
2022 TALLOC_FREE(principal);
2026 subreq = cli_session_setup_kerberos_send(
2027 state, ev, cli, principal);
2028 if (tevent_req_nomem(subreq, req)) {
2029 return tevent_req_post(req, ev);
2031 tevent_req_set_callback(
2032 subreq, cli_session_setup_spnego_done_krb,
2040 subreq = cli_session_setup_ntlmssp_send(
2041 state, ev, cli, state->account, pass, user_domain);
2042 if (tevent_req_nomem(subreq, req)) {
2043 return tevent_req_post(req, ev);
2045 tevent_req_set_callback(
2046 subreq, cli_session_setup_spnego_done_ntlmssp, req);
2051 static void cli_session_setup_spnego_done_krb(struct tevent_req *subreq)
2053 struct tevent_req *req = tevent_req_callback_data(
2054 subreq, struct tevent_req);
2055 struct cli_session_setup_spnego_state *state = tevent_req_data(
2056 req, struct cli_session_setup_spnego_state);
2058 state->result = cli_session_setup_kerberos_recv(subreq);
2059 TALLOC_FREE(subreq);
2061 if (ADS_ERR_OK(state->result) ||
2062 !state->cli->fallback_after_kerberos) {
2063 tevent_req_done(req);
2067 subreq = cli_session_setup_ntlmssp_send(
2068 state, state->ev, state->cli, state->account, state->pass,
2069 state->user_domain);
2070 if (tevent_req_nomem(subreq, req)) {
2073 tevent_req_set_callback(subreq, cli_session_setup_spnego_done_ntlmssp,
2078 static void cli_session_setup_spnego_done_ntlmssp(struct tevent_req *subreq)
2080 struct tevent_req *req = tevent_req_callback_data(
2081 subreq, struct tevent_req);
2082 struct cli_session_setup_spnego_state *state = tevent_req_data(
2083 req, struct cli_session_setup_spnego_state);
2086 status = cli_session_setup_ntlmssp_recv(subreq);
2087 TALLOC_FREE(subreq);
2088 state->result = ADS_ERROR_NT(status);
2089 tevent_req_done(req);
2092 static ADS_STATUS cli_session_setup_spnego_recv(struct tevent_req *req)
2094 struct cli_session_setup_spnego_state *state = tevent_req_data(
2095 req, struct cli_session_setup_spnego_state);
2097 return state->result;
2100 static ADS_STATUS cli_session_setup_spnego(struct cli_state *cli,
2103 const char *user_domain,
2104 const char * dest_realm)
2106 struct tevent_context *ev;
2107 struct tevent_req *req;
2108 ADS_STATUS result = ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
2111 if (smbXcli_conn_has_async_calls(cli->conn)) {
2112 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2114 ev = samba_tevent_context_init(talloc_tos());
2118 req = cli_session_setup_spnego_send(ev, ev, cli, user, pass,
2119 user_domain, dest_realm);
2123 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2124 result = ADS_ERROR_NT(status);
2127 result = cli_session_setup_spnego_recv(req);
2133 /****************************************************************************
2134 Send a session setup. The username and workgroup is in UNIX character
2135 format and must be converted to DOS codepage format before sending. If the
2136 password is in plaintext, the same should be done.
2137 ****************************************************************************/
2139 NTSTATUS cli_session_setup(struct cli_state *cli,
2141 const char *pass, int passlen,
2142 const char *ntpass, int ntpasslen,
2143 const char *workgroup)
2147 uint16_t sec_mode = smb1cli_conn_server_security_mode(cli->conn);
2150 user2 = talloc_strdup(talloc_tos(), user);
2152 user2 = talloc_strdup(talloc_tos(), "");
2154 if (user2 == NULL) {
2155 return NT_STATUS_NO_MEMORY;
2162 /* allow for workgroups as part of the username */
2163 if ((p=strchr_m(user2,'\\')) || (p=strchr_m(user2,'/')) ||
2164 (p=strchr_m(user2,*lp_winbind_separator()))) {
2167 if (!strupper_m(user2)) {
2168 return NT_STATUS_INVALID_PARAMETER;
2173 if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_LANMAN1) {
2174 return NT_STATUS_OK;
2177 /* now work out what sort of session setup we are going to
2178 do. I have split this into separate functions to make the
2179 flow a bit easier to understand (tridge) */
2181 /* if its an older server then we have to use the older request format */
2183 if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_NT1) {
2184 if (!lp_client_lanman_auth() && passlen != 24 && (*pass)) {
2185 DEBUG(1, ("Server requested LM password but 'client lanman auth = no'"
2186 " or 'client ntlmv2 auth = yes'\n"));
2187 return NT_STATUS_ACCESS_DENIED;
2190 if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0 &&
2191 !lp_client_plaintext_auth() && (*pass)) {
2192 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
2193 " or 'client ntlmv2 auth = yes'\n"));
2194 return NT_STATUS_ACCESS_DENIED;
2197 return cli_session_setup_lanman2(cli, user, pass, passlen,
2201 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
2202 const char *remote_realm = cli_state_remote_realm(cli);
2203 ADS_STATUS status = cli_session_setup_spnego(cli, user, pass,
2206 if (!ADS_ERR_OK(status)) {
2207 DEBUG(3, ("SMB2-SPNEGO login failed: %s\n", ads_errstr(status)));
2208 return ads_ntstatus(status);
2210 return NT_STATUS_OK;
2213 /* if no user is supplied then we have to do an anonymous connection.
2214 passwords are ignored */
2216 if (!user || !*user)
2217 return cli_session_setup_guest(cli);
2219 /* if the server is share level then send a plaintext null
2220 password at this point. The password is sent in the tree
2223 if ((sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0)
2224 return cli_session_setup_plain(cli, user, "", workgroup);
2226 /* if the server doesn't support encryption then we have to use
2227 plaintext. The second password is ignored */
2229 if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) {
2230 if (!lp_client_plaintext_auth() && (*pass)) {
2231 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
2232 " or 'client ntlmv2 auth = yes'\n"));
2233 return NT_STATUS_ACCESS_DENIED;
2235 return cli_session_setup_plain(cli, user, pass, workgroup);
2238 /* if the server supports extended security then use SPNEGO */
2240 if (smb1cli_conn_capabilities(cli->conn) & CAP_EXTENDED_SECURITY) {
2241 const char *remote_realm = cli_state_remote_realm(cli);
2242 ADS_STATUS status = cli_session_setup_spnego(cli, user, pass,
2245 if (!ADS_ERR_OK(status)) {
2246 DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status)));
2247 return ads_ntstatus(status);
2252 /* otherwise do a NT1 style session setup */
2253 status = cli_session_setup_nt1(cli, user, pass, passlen,
2254 ntpass, ntpasslen, workgroup);
2255 if (!NT_STATUS_IS_OK(status)) {
2256 DEBUG(3,("cli_session_setup: NT1 session setup "
2257 "failed: %s\n", nt_errstr(status)));
2262 return NT_STATUS_OK;
2265 /****************************************************************************
2267 *****************************************************************************/
2269 struct cli_ulogoff_state {
2270 struct cli_state *cli;
2274 static void cli_ulogoff_done(struct tevent_req *subreq);
2276 struct tevent_req *cli_ulogoff_send(TALLOC_CTX *mem_ctx,
2277 struct tevent_context *ev,
2278 struct cli_state *cli)
2280 struct tevent_req *req, *subreq;
2281 struct cli_ulogoff_state *state;
2283 req = tevent_req_create(mem_ctx, &state, struct cli_ulogoff_state);
2289 SCVAL(state->vwv+0, 0, 0xFF);
2290 SCVAL(state->vwv+1, 0, 0);
2291 SSVAL(state->vwv+2, 0, 0);
2293 subreq = cli_smb_send(state, ev, cli, SMBulogoffX, 0, 2, state->vwv,
2295 if (tevent_req_nomem(subreq, req)) {
2296 return tevent_req_post(req, ev);
2298 tevent_req_set_callback(subreq, cli_ulogoff_done, req);
2302 static void cli_ulogoff_done(struct tevent_req *subreq)
2304 struct tevent_req *req = tevent_req_callback_data(
2305 subreq, struct tevent_req);
2306 struct cli_ulogoff_state *state = tevent_req_data(
2307 req, struct cli_ulogoff_state);
2310 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
2311 if (!NT_STATUS_IS_OK(status)) {
2312 tevent_req_nterror(req, status);
2315 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
2316 tevent_req_done(req);
2319 NTSTATUS cli_ulogoff_recv(struct tevent_req *req)
2321 return tevent_req_simple_recv_ntstatus(req);
2324 NTSTATUS cli_ulogoff(struct cli_state *cli)
2326 struct tevent_context *ev;
2327 struct tevent_req *req;
2328 NTSTATUS status = NT_STATUS_NO_MEMORY;
2330 if (smbXcli_conn_has_async_calls(cli->conn)) {
2331 return NT_STATUS_INVALID_PARAMETER;
2333 ev = samba_tevent_context_init(talloc_tos());
2337 req = cli_ulogoff_send(ev, ev, cli);
2341 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2344 status = cli_ulogoff_recv(req);
2350 /****************************************************************************
2352 ****************************************************************************/
2354 struct cli_tcon_andx_state {
2355 struct cli_state *cli;
2360 static void cli_tcon_andx_done(struct tevent_req *subreq);
2362 struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx,
2363 struct tevent_context *ev,
2364 struct cli_state *cli,
2365 const char *share, const char *dev,
2366 const char *pass, int passlen,
2367 struct tevent_req **psmbreq)
2369 struct tevent_req *req, *subreq;
2370 struct cli_tcon_andx_state *state;
2375 uint16_t sec_mode = smb1cli_conn_server_security_mode(cli->conn);
2376 uint16_t tcon_flags = 0;
2380 req = tevent_req_create(mem_ctx, &state, struct cli_tcon_andx_state);
2387 cli->share = talloc_strdup(cli, share);
2392 /* in user level security don't send a password now */
2393 if (sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {
2396 } else if (pass == NULL) {
2397 DEBUG(1, ("Server not using user level security and no "
2398 "password supplied.\n"));
2402 if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) &&
2403 *pass && passlen != 24) {
2404 if (!lp_client_lanman_auth()) {
2405 DEBUG(1, ("Server requested LANMAN password "
2406 "(share-level security) but "
2407 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2412 * Non-encrypted passwords - convert to DOS codepage before
2415 SMBencrypt(pass, smb1cli_conn_server_challenge(cli->conn), p24);
2417 pass = (const char *)p24;
2419 if((sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL
2420 |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE))
2424 if (!lp_client_plaintext_auth() && (*pass)) {
2425 DEBUG(1, ("Server requested PLAINTEXT "
2427 "'client plaintext auth = no' or 'client ntlmv2 auth = yes'\n"));
2432 * Non-encrypted passwords - convert to DOS codepage
2435 tmp_pass = talloc_array(talloc_tos(), uint8, 0);
2436 if (tevent_req_nomem(tmp_pass, req)) {
2437 return tevent_req_post(req, ev);
2439 tmp_pass = trans2_bytes_push_str(tmp_pass,
2440 false, /* always DOS */
2444 if (tevent_req_nomem(tmp_pass, req)) {
2445 return tevent_req_post(req, ev);
2447 pass = (const char *)tmp_pass;
2448 passlen = talloc_get_size(tmp_pass);
2452 tcon_flags |= TCONX_FLAG_EXTENDED_RESPONSE;
2453 tcon_flags |= TCONX_FLAG_EXTENDED_SIGNATURES;
2455 SCVAL(vwv+0, 0, 0xFF);
2458 SSVAL(vwv+2, 0, tcon_flags);
2459 SSVAL(vwv+3, 0, passlen);
2461 if (passlen && pass) {
2462 bytes = (uint8_t *)talloc_memdup(state, pass, passlen);
2464 bytes = talloc_array(state, uint8_t, 0);
2470 tmp = talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
2471 smbXcli_conn_remote_name(cli->conn), share);
2476 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), tmp, strlen(tmp)+1,
2481 * Add the devicetype
2483 tmp = talloc_strdup_upper(talloc_tos(), dev);
2488 bytes = smb_bytes_push_str(bytes, false, tmp, strlen(tmp)+1, NULL);
2491 if (bytes == NULL) {
2496 state->bytes.iov_base = (void *)bytes;
2497 state->bytes.iov_len = talloc_get_size(bytes);
2499 subreq = cli_smb_req_create(state, ev, cli, SMBtconX, 0, 4, vwv,
2501 if (subreq == NULL) {
2505 tevent_req_set_callback(subreq, cli_tcon_andx_done, req);
2510 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
2511 return tevent_req_post(req, ev);
2514 struct tevent_req *cli_tcon_andx_send(TALLOC_CTX *mem_ctx,
2515 struct tevent_context *ev,
2516 struct cli_state *cli,
2517 const char *share, const char *dev,
2518 const char *pass, int passlen)
2520 struct tevent_req *req, *subreq;
2523 req = cli_tcon_andx_create(mem_ctx, ev, cli, share, dev, pass, passlen,
2528 if (subreq == NULL) {
2531 status = smb1cli_req_chain_submit(&subreq, 1);
2532 if (!NT_STATUS_IS_OK(status)) {
2533 tevent_req_nterror(req, status);
2534 return tevent_req_post(req, ev);
2539 static void cli_tcon_andx_done(struct tevent_req *subreq)
2541 struct tevent_req *req = tevent_req_callback_data(
2542 subreq, struct tevent_req);
2543 struct cli_tcon_andx_state *state = tevent_req_data(
2544 req, struct cli_tcon_andx_state);
2545 struct cli_state *cli = state->cli;
2553 uint16_t optional_support = 0;
2555 status = cli_smb_recv(subreq, state, &in, 0, &wct, &vwv,
2556 &num_bytes, &bytes);
2557 TALLOC_FREE(subreq);
2558 if (!NT_STATUS_IS_OK(status)) {
2559 tevent_req_nterror(req, status);
2563 inhdr = in + NBT_HDR_SIZE;
2566 if (clistr_pull_talloc(cli,
2567 (const char *)inhdr,
2568 SVAL(inhdr, HDR_FLG2),
2572 STR_TERMINATE|STR_ASCII) == -1) {
2573 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2577 cli->dev = talloc_strdup(cli, "");
2578 if (cli->dev == NULL) {
2579 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2584 if ((smbXcli_conn_protocol(cli->conn) >= PROTOCOL_NT1) && (num_bytes == 3)) {
2585 /* almost certainly win95 - enable bug fixes */
2590 * Make sure that we have the optional support 16-bit field. WCT > 2.
2591 * Avoids issues when connecting to Win9x boxes sharing files
2594 cli->dfsroot = false;
2596 if ((wct > 2) && (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_LANMAN2)) {
2597 optional_support = SVAL(vwv+2, 0);
2600 if (optional_support & SMB_SHARE_IN_DFS) {
2601 cli->dfsroot = true;
2604 if (optional_support & SMB_EXTENDED_SIGNATURES) {
2605 smb1cli_session_protect_session_key(cli->smb1.session);
2608 cli_state_set_tid(cli, SVAL(inhdr, HDR_TID));
2609 tevent_req_done(req);
2612 NTSTATUS cli_tcon_andx_recv(struct tevent_req *req)
2614 return tevent_req_simple_recv_ntstatus(req);
2617 NTSTATUS cli_tcon_andx(struct cli_state *cli, const char *share,
2618 const char *dev, const char *pass, int passlen)
2620 TALLOC_CTX *frame = talloc_stackframe();
2621 struct tevent_context *ev;
2622 struct tevent_req *req;
2623 NTSTATUS status = NT_STATUS_OK;
2625 if (smbXcli_conn_has_async_calls(cli->conn)) {
2627 * Can't use sync call while an async call is in flight
2629 status = NT_STATUS_INVALID_PARAMETER;
2633 ev = samba_tevent_context_init(frame);
2635 status = NT_STATUS_NO_MEMORY;
2639 req = cli_tcon_andx_send(frame, ev, cli, share, dev, pass, passlen);
2641 status = NT_STATUS_NO_MEMORY;
2645 if (!tevent_req_poll(req, ev)) {
2646 status = map_nt_error_from_unix(errno);
2650 status = cli_tcon_andx_recv(req);
2656 NTSTATUS cli_tree_connect(struct cli_state *cli, const char *share,
2657 const char *dev, const char *pass, int passlen)
2660 uint16_t max_xmit = 0;
2663 cli->share = talloc_strdup(cli, share);
2665 return NT_STATUS_NO_MEMORY;
2668 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
2669 return smb2cli_tcon(cli, share);
2672 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_LANMAN1) {
2673 return cli_tcon_andx(cli, share, dev, pass, passlen);
2676 status = cli_raw_tcon(cli, share, pass, dev, &max_xmit, &tid);
2677 if (!NT_STATUS_IS_OK(status)) {
2681 cli_state_set_tid(cli, tid);
2683 return NT_STATUS_OK;
2686 /****************************************************************************
2687 Send a tree disconnect.
2688 ****************************************************************************/
2690 struct cli_tdis_state {
2691 struct cli_state *cli;
2694 static void cli_tdis_done(struct tevent_req *subreq);
2696 struct tevent_req *cli_tdis_send(TALLOC_CTX *mem_ctx,
2697 struct tevent_context *ev,
2698 struct cli_state *cli)
2700 struct tevent_req *req, *subreq;
2701 struct cli_tdis_state *state;
2703 req = tevent_req_create(mem_ctx, &state, struct cli_tdis_state);
2709 subreq = cli_smb_send(state, ev, cli, SMBtdis, 0, 0, NULL, 0, NULL);
2710 if (tevent_req_nomem(subreq, req)) {
2711 return tevent_req_post(req, ev);
2713 tevent_req_set_callback(subreq, cli_tdis_done, req);
2717 static void cli_tdis_done(struct tevent_req *subreq)
2719 struct tevent_req *req = tevent_req_callback_data(
2720 subreq, struct tevent_req);
2721 struct cli_tdis_state *state = tevent_req_data(
2722 req, struct cli_tdis_state);
2725 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
2726 TALLOC_FREE(subreq);
2727 if (!NT_STATUS_IS_OK(status)) {
2728 tevent_req_nterror(req, status);
2731 cli_state_set_tid(state->cli, UINT16_MAX);
2732 tevent_req_done(req);
2735 NTSTATUS cli_tdis_recv(struct tevent_req *req)
2737 return tevent_req_simple_recv_ntstatus(req);
2740 NTSTATUS cli_tdis(struct cli_state *cli)
2742 struct tevent_context *ev;
2743 struct tevent_req *req;
2744 NTSTATUS status = NT_STATUS_NO_MEMORY;
2746 if (smbXcli_conn_has_async_calls(cli->conn)) {
2747 return NT_STATUS_INVALID_PARAMETER;
2749 ev = samba_tevent_context_init(talloc_tos());
2753 req = cli_tdis_send(ev, ev, cli);
2757 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2760 status = cli_tdis_recv(req);
2766 static NTSTATUS cli_connect_sock(const char *host, int name_type,
2767 const struct sockaddr_storage *pss,
2768 const char *myname, uint16_t port,
2769 int sec_timeout, int *pfd, uint16_t *pport)
2771 TALLOC_CTX *frame = talloc_stackframe();
2773 unsigned int i, num_addrs;
2774 const char **called_names;
2775 const char **calling_names;
2780 prog = getenv("LIBSMB_PROG");
2782 fd = sock_exec(prog);
2784 return map_nt_error_from_unix(errno);
2790 if ((pss == NULL) || is_zero_addr(pss)) {
2791 struct sockaddr_storage *addrs;
2792 status = resolve_name_list(talloc_tos(), host, name_type,
2793 &addrs, &num_addrs);
2794 if (!NT_STATUS_IS_OK(status)) {
2802 called_names = talloc_array(talloc_tos(), const char *, num_addrs);
2803 if (called_names == NULL) {
2804 status = NT_STATUS_NO_MEMORY;
2807 called_types = talloc_array(talloc_tos(), int, num_addrs);
2808 if (called_types == NULL) {
2809 status = NT_STATUS_NO_MEMORY;
2812 calling_names = talloc_array(talloc_tos(), const char *, num_addrs);
2813 if (calling_names == NULL) {
2814 status = NT_STATUS_NO_MEMORY;
2817 for (i=0; i<num_addrs; i++) {
2818 called_names[i] = host;
2819 called_types[i] = name_type;
2820 calling_names[i] = myname;
2822 status = smbsock_any_connect(pss, called_names, called_types,
2823 calling_names, NULL, num_addrs, port,
2824 sec_timeout, &fd, NULL, &port);
2825 if (!NT_STATUS_IS_OK(status)) {
2828 set_socket_options(fd, lp_socket_options());
2832 status = NT_STATUS_OK;
2838 NTSTATUS cli_connect_nb(const char *host, const struct sockaddr_storage *dest_ss,
2839 uint16_t port, int name_type, const char *myname,
2840 int signing_state, int flags, struct cli_state **pcli)
2842 TALLOC_CTX *frame = talloc_stackframe();
2843 struct cli_state *cli;
2844 NTSTATUS status = NT_STATUS_NO_MEMORY;
2849 desthost = talloc_strdup(talloc_tos(), host);
2850 if (desthost == NULL) {
2854 p = strchr(host, '#');
2856 name_type = strtol(p+1, NULL, 16);
2857 host = talloc_strndup(talloc_tos(), host, p - host);
2863 status = cli_connect_sock(host, name_type, dest_ss, myname, port,
2865 if (!NT_STATUS_IS_OK(status)) {
2869 cli = cli_state_create(NULL, fd, desthost, NULL, signing_state, flags);
2877 status = NT_STATUS_OK;
2884 establishes a connection to after the negprot.
2885 @param output_cli A fully initialised cli structure, non-null only on success
2886 @param dest_host The netbios name of the remote host
2887 @param dest_ss (optional) The the destination IP, NULL for name based lookup
2888 @param port (optional) The destination port (0 for default)
2890 NTSTATUS cli_start_connection(struct cli_state **output_cli,
2891 const char *my_name,
2892 const char *dest_host,
2893 const struct sockaddr_storage *dest_ss, int port,
2894 int signing_state, int flags)
2897 struct cli_state *cli;
2899 nt_status = cli_connect_nb(dest_host, dest_ss, port, 0x20, my_name,
2900 signing_state, flags, &cli);
2901 if (!NT_STATUS_IS_OK(nt_status)) {
2902 DEBUG(10, ("cli_connect_nb failed: %s\n",
2903 nt_errstr(nt_status)));
2907 nt_status = smbXcli_negprot(cli->conn, cli->timeout, PROTOCOL_CORE,
2909 if (!NT_STATUS_IS_OK(nt_status)) {
2910 DEBUG(1, ("failed negprot: %s\n", nt_errstr(nt_status)));
2916 return NT_STATUS_OK;
2921 establishes a connection right up to doing tconX, password specified.
2922 @param output_cli A fully initialised cli structure, non-null only on success
2923 @param dest_host The netbios name of the remote host
2924 @param dest_ip (optional) The the destination IP, NULL for name based lookup
2925 @param port (optional) The destination port (0 for default)
2926 @param service (optional) The share to make the connection to. Should be 'unqualified' in any way.
2927 @param service_type The 'type' of serivice.
2928 @param user Username, unix string
2929 @param domain User's domain
2930 @param password User's password, unencrypted unix string.
2933 NTSTATUS cli_full_connection(struct cli_state **output_cli,
2934 const char *my_name,
2935 const char *dest_host,
2936 const struct sockaddr_storage *dest_ss, int port,
2937 const char *service, const char *service_type,
2938 const char *user, const char *domain,
2939 const char *password, int flags,
2943 struct cli_state *cli = NULL;
2944 int pw_len = password ? strlen(password)+1 : 0;
2948 if (password == NULL) {
2952 nt_status = cli_start_connection(&cli, my_name, dest_host,
2953 dest_ss, port, signing_state,
2956 if (!NT_STATUS_IS_OK(nt_status)) {
2960 nt_status = cli_session_setup(cli, user, password, pw_len, password,
2962 if (!NT_STATUS_IS_OK(nt_status)) {
2964 if (!(flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)) {
2965 DEBUG(1,("failed session setup with %s\n",
2966 nt_errstr(nt_status)));
2971 nt_status = cli_session_setup(cli, "", "", 0, "", 0, domain);
2972 if (!NT_STATUS_IS_OK(nt_status)) {
2973 DEBUG(1,("anonymous failed session setup with %s\n",
2974 nt_errstr(nt_status)));
2981 nt_status = cli_tree_connect(cli, service, service_type,
2983 if (!NT_STATUS_IS_OK(nt_status)) {
2984 DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status)));
2986 if (NT_STATUS_IS_OK(nt_status)) {
2987 nt_status = NT_STATUS_UNSUCCESSFUL;
2993 nt_status = cli_init_creds(cli, user, domain, password);
2994 if (!NT_STATUS_IS_OK(nt_status)) {
3000 return NT_STATUS_OK;
3003 /****************************************************************************
3004 Send an old style tcon.
3005 ****************************************************************************/
3006 NTSTATUS cli_raw_tcon(struct cli_state *cli,
3007 const char *service, const char *pass, const char *dev,
3008 uint16 *max_xmit, uint16 *tid)
3010 struct tevent_req *req;
3015 if (!lp_client_plaintext_auth() && (*pass)) {
3016 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
3017 " or 'client ntlmv2 auth = yes'\n"));
3018 return NT_STATUS_ACCESS_DENIED;
3021 bytes = talloc_array(talloc_tos(), uint8_t, 0);
3022 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3023 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3024 service, strlen(service)+1, NULL);
3025 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3026 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3027 pass, strlen(pass)+1, NULL);
3028 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3029 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
3030 dev, strlen(dev)+1, NULL);
3032 status = cli_smb(talloc_tos(), cli, SMBtcon, 0, 0, NULL,
3033 talloc_get_size(bytes), bytes, &req,
3034 2, NULL, &ret_vwv, NULL, NULL);
3035 if (!NT_STATUS_IS_OK(status)) {
3039 *max_xmit = SVAL(ret_vwv + 0, 0);
3040 *tid = SVAL(ret_vwv + 1, 0);
3042 return NT_STATUS_OK;
3045 /* Return a cli_state pointing at the IPC$ share for the given server */
3047 struct cli_state *get_ipc_connect(char *server,
3048 struct sockaddr_storage *server_ss,
3049 const struct user_auth_info *user_info)
3051 struct cli_state *cli;
3053 uint32_t flags = CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
3055 if (user_info->use_kerberos) {
3056 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
3059 nt_status = cli_full_connection(&cli, NULL, server, server_ss, 0, "IPC$", "IPC",
3060 user_info->username ? user_info->username : "",
3062 user_info->password ? user_info->password : "",
3064 SMB_SIGNING_DEFAULT);
3066 if (NT_STATUS_IS_OK(nt_status)) {
3068 } else if (is_ipaddress(server)) {
3069 /* windows 9* needs a correct NMB name for connections */
3070 fstring remote_name;
3072 if (name_status_find("*", 0, 0, server_ss, remote_name)) {
3073 cli = get_ipc_connect(remote_name, server_ss, user_info);
3082 * Given the IP address of a master browser on the network, return its
3083 * workgroup and connect to it.
3085 * This function is provided to allow additional processing beyond what
3086 * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
3087 * browsers and obtain each master browsers' list of domains (in case the
3088 * first master browser is recently on the network and has not yet
3089 * synchronized with other master browsers and therefore does not yet have the
3090 * entire network browse list)
3093 struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx,
3094 struct sockaddr_storage *mb_ip,
3095 const struct user_auth_info *user_info,
3096 char **pp_workgroup_out)
3098 char addr[INET6_ADDRSTRLEN];
3100 struct cli_state *cli;
3101 struct sockaddr_storage server_ss;
3103 *pp_workgroup_out = NULL;
3105 print_sockaddr(addr, sizeof(addr), mb_ip);
3106 DEBUG(99, ("Looking up name of master browser %s\n",
3110 * Do a name status query to find out the name of the master browser.
3111 * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
3112 * master browser will not respond to a wildcard query (or, at least,
3113 * an NT4 server acting as the domain master browser will not).
3115 * We might be able to use ONLY the query on MSBROWSE, but that's not
3116 * yet been tested with all Windows versions, so until it is, leave
3117 * the original wildcard query as the first choice and fall back to
3118 * MSBROWSE if the wildcard query fails.
3120 if (!name_status_find("*", 0, 0x1d, mb_ip, name) &&
3121 !name_status_find(MSBROWSE, 1, 0x1d, mb_ip, name)) {
3123 DEBUG(99, ("Could not retrieve name status for %s\n",
3128 if (!find_master_ip(name, &server_ss)) {
3129 DEBUG(99, ("Could not find master ip for %s\n", name));
3133 *pp_workgroup_out = talloc_strdup(ctx, name);
3135 DEBUG(4, ("found master browser %s, %s\n", name, addr));
3137 print_sockaddr(addr, sizeof(addr), &server_ss);
3138 cli = get_ipc_connect(addr, &server_ss, user_info);
3144 * Return the IP address and workgroup of a master browser on the network, and
3148 struct cli_state *get_ipc_connect_master_ip_bcast(TALLOC_CTX *ctx,
3149 const struct user_auth_info *user_info,
3150 char **pp_workgroup_out)
3152 struct sockaddr_storage *ip_list;
3153 struct cli_state *cli;
3157 *pp_workgroup_out = NULL;
3159 DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
3161 /* Go looking for workgroups by broadcasting on the local network */
3163 status = name_resolve_bcast(MSBROWSE, 1, talloc_tos(),
3165 if (!NT_STATUS_IS_OK(status)) {
3166 DEBUG(99, ("No master browsers responded: %s\n",
3167 nt_errstr(status)));
3171 for (i = 0; i < count; i++) {
3172 char addr[INET6_ADDRSTRLEN];
3173 print_sockaddr(addr, sizeof(addr), &ip_list[i]);
3174 DEBUG(99, ("Found master browser %s\n", addr));
3176 cli = get_ipc_connect_master_ip(ctx, &ip_list[i],
3177 user_info, pp_workgroup_out);