2 Unix SMB/CIFS implementation.
3 client connect/disconnect routines
4 Copyright (C) Andrew Tridgell 1994-1998
5 Copyright (C) Andrew Bartlett 2001-2003
6 Copyright (C) Volker Lendecke 2011
7 Copyright (C) Jeremy Allison 2011
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "libsmb/libsmb.h"
25 #include "popt_common.h"
26 #include "../libcli/auth/libcli_auth.h"
27 #include "../libcli/auth/spnego.h"
29 #include "../libcli/auth/ntlmssp.h"
30 #include "libads/kerberos_proto.h"
32 #include "../lib/util/tevent_ntstatus.h"
33 #include "async_smb.h"
34 #include "libsmb/nmblib.h"
36 #include "librpc/ndr/libndr.h"
42 {PROTOCOL_CORE, "PC NETWORK PROGRAM 1.0"},
43 {PROTOCOL_COREPLUS, "MICROSOFT NETWORKS 1.03"},
44 {PROTOCOL_LANMAN1, "MICROSOFT NETWORKS 3.0"},
45 {PROTOCOL_LANMAN1, "LANMAN1.0"},
46 {PROTOCOL_LANMAN2, "LM1.2X002"},
47 {PROTOCOL_LANMAN2, "DOS LANMAN2.1"},
48 {PROTOCOL_LANMAN2, "LANMAN2.1"},
49 {PROTOCOL_LANMAN2, "Samba"},
50 {PROTOCOL_NT1, "NT LANMAN 1.0"},
51 {PROTOCOL_NT1, "NT LM 0.12"},
54 #define STAR_SMBSERVER "*SMBSERVER"
56 /********************************************************
57 Utility function to ensure we always return at least
58 a valid char * pointer to an empty string for the
59 cli->server_os, cli->server_type and cli->server_domain
61 *******************************************************/
63 static NTSTATUS smb_bytes_talloc_string(TALLOC_CTX *mem_ctx,
70 *destlen = clistr_pull_talloc(mem_ctx,
72 SVAL(inbuf, smb_flg2),
78 return NT_STATUS_NO_MEMORY;
82 *dest = talloc_strdup(mem_ctx, "");
84 return NT_STATUS_NO_MEMORY;
91 * Set the user session key for a connection
92 * @param cli The cli structure to add it too
93 * @param session_key The session key used. (A copy of this is taken for the cli struct)
97 static void cli_set_session_key (struct cli_state *cli, const DATA_BLOB session_key)
99 cli->user_session_key = data_blob(session_key.data, session_key.length);
102 /****************************************************************************
103 Do an old lanman2 style session setup.
104 ****************************************************************************/
106 struct cli_session_setup_lanman2_state {
107 struct cli_state *cli;
112 static void cli_session_setup_lanman2_done(struct tevent_req *subreq);
114 static struct tevent_req *cli_session_setup_lanman2_send(
115 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
116 struct cli_state *cli, const char *user,
117 const char *pass, size_t passlen,
118 const char *workgroup)
120 struct tevent_req *req, *subreq;
121 struct cli_session_setup_lanman2_state *state;
122 DATA_BLOB lm_response = data_blob_null;
126 uint16_t sec_mode = cli_state_security_mode(cli);
128 req = tevent_req_create(mem_ctx, &state,
129 struct cli_session_setup_lanman2_state);
138 * if in share level security then don't send a password now
140 if (!(sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) {
145 && (sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)
148 * Encrypted mode needed, and non encrypted password
151 lm_response = data_blob(NULL, 24);
152 if (tevent_req_nomem(lm_response.data, req)) {
153 return tevent_req_post(req, ev);
156 if (!SMBencrypt(pass, cli_state_server_challenge(cli),
157 (uint8_t *)lm_response.data)) {
158 DEBUG(1, ("Password is > 14 chars in length, and is "
159 "therefore incompatible with Lanman "
160 "authentication\n"));
161 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
162 return tevent_req_post(req, ev);
164 } else if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)
167 * Encrypted mode needed, and encrypted password
170 lm_response = data_blob(pass, passlen);
171 if (tevent_req_nomem(lm_response.data, req)) {
172 return tevent_req_post(req, ev);
174 } else if (passlen > 0) {
176 size_t converted_size;
178 * Plaintext mode needed, assume plaintext supplied.
180 buf = talloc_array(talloc_tos(), uint8_t, 0);
181 buf = smb_bytes_push_str(buf, cli_ucs2(cli), pass, passlen+1,
183 if (tevent_req_nomem(buf, req)) {
184 return tevent_req_post(req, ev);
186 lm_response = data_blob(pass, passlen);
188 if (tevent_req_nomem(lm_response.data, req)) {
189 return tevent_req_post(req, ev);
193 SCVAL(vwv+0, 0, 0xff);
196 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
199 SIVAL(vwv+5, 0, cli_state_server_session_key(cli));
200 SSVAL(vwv+7, 0, lm_response.length);
202 bytes = talloc_array(state, uint8_t, lm_response.length);
203 if (tevent_req_nomem(bytes, req)) {
204 return tevent_req_post(req, ev);
206 if (lm_response.length != 0) {
207 memcpy(bytes, lm_response.data, lm_response.length);
209 data_blob_free(&lm_response);
211 tmp = talloc_strdup_upper(talloc_tos(), user);
212 if (tevent_req_nomem(tmp, req)) {
213 return tevent_req_post(req, ev);
215 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), tmp, strlen(tmp)+1,
219 tmp = talloc_strdup_upper(talloc_tos(), workgroup);
220 if (tevent_req_nomem(tmp, req)) {
221 return tevent_req_post(req, ev);
223 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), tmp, strlen(tmp)+1,
225 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Unix", 5, NULL);
226 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Samba", 6, NULL);
228 if (tevent_req_nomem(bytes, req)) {
229 return tevent_req_post(req, ev);
232 subreq = cli_smb_send(state, ev, cli, SMBsesssetupX, 0, 10, vwv,
233 talloc_get_size(bytes), bytes);
234 if (tevent_req_nomem(subreq, req)) {
235 return tevent_req_post(req, ev);
237 tevent_req_set_callback(subreq, cli_session_setup_lanman2_done, req);
241 static void cli_session_setup_lanman2_done(struct tevent_req *subreq)
243 struct tevent_req *req = tevent_req_callback_data(
244 subreq, struct tevent_req);
245 struct cli_session_setup_lanman2_state *state = tevent_req_data(
246 req, struct cli_session_setup_lanman2_state);
247 struct cli_state *cli = state->cli;
258 status = cli_smb_recv(subreq, state, &in, 3, &wct, &vwv,
261 if (!NT_STATUS_IS_OK(status)) {
262 tevent_req_nterror(req, status);
269 cli_state_set_uid(state->cli, SVAL(inbuf, smb_uid));
270 cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0);
272 status = smb_bytes_talloc_string(cli,
279 if (!NT_STATUS_IS_OK(status)) {
280 tevent_req_nterror(req, status);
285 status = smb_bytes_talloc_string(cli,
292 if (!NT_STATUS_IS_OK(status)) {
293 tevent_req_nterror(req, status);
298 status = smb_bytes_talloc_string(cli,
305 if (!NT_STATUS_IS_OK(status)) {
306 tevent_req_nterror(req, status);
311 status = cli_set_username(cli, state->user);
312 if (tevent_req_nterror(req, status)) {
315 tevent_req_done(req);
318 static NTSTATUS cli_session_setup_lanman2_recv(struct tevent_req *req)
320 return tevent_req_simple_recv_ntstatus(req);
323 static NTSTATUS cli_session_setup_lanman2(struct cli_state *cli, const char *user,
324 const char *pass, size_t passlen,
325 const char *workgroup)
327 TALLOC_CTX *frame = talloc_stackframe();
328 struct event_context *ev;
329 struct tevent_req *req;
330 NTSTATUS status = NT_STATUS_NO_MEMORY;
332 if (cli_has_async_calls(cli)) {
334 * Can't use sync call while an async call is in flight
336 status = NT_STATUS_INVALID_PARAMETER;
339 ev = event_context_init(frame);
343 req = cli_session_setup_lanman2_send(frame, ev, cli, user, pass, passlen,
348 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
351 status = cli_session_setup_lanman2_recv(req);
357 /****************************************************************************
358 Work out suitable capabilities to offer the server.
359 ****************************************************************************/
361 static uint32_t cli_session_setup_capabilities(struct cli_state *cli,
362 uint32_t sesssetup_capabilities)
364 uint32_t client_capabilities = cli_state_capabilities(cli);
367 * We only send capabilities based on the mask for:
368 * - client only flags
369 * - flags used in both directions
371 * We do not echo the server only flags.
373 client_capabilities &= (SMB_CAP_BOTH_MASK | SMB_CAP_CLIENT_MASK);
376 * Session Setup specific flags CAP_DYNAMIC_REAUTH
377 * and CAP_EXTENDED_SECURITY are passed by the caller.
378 * We need that in order to do guest logins even if
379 * CAP_EXTENDED_SECURITY is negotiated.
381 client_capabilities &= ~(CAP_DYNAMIC_REAUTH|CAP_EXTENDED_SECURITY);
382 sesssetup_capabilities &= (CAP_DYNAMIC_REAUTH|CAP_EXTENDED_SECURITY);
383 client_capabilities |= sesssetup_capabilities;
385 return client_capabilities;
388 /****************************************************************************
389 Do a NT1 guest session setup.
390 ****************************************************************************/
392 struct cli_session_setup_guest_state {
393 struct cli_state *cli;
398 static void cli_session_setup_guest_done(struct tevent_req *subreq);
400 struct tevent_req *cli_session_setup_guest_create(TALLOC_CTX *mem_ctx,
401 struct event_context *ev,
402 struct cli_state *cli,
403 struct tevent_req **psmbreq)
405 struct tevent_req *req, *subreq;
406 struct cli_session_setup_guest_state *state;
410 req = tevent_req_create(mem_ctx, &state,
411 struct cli_session_setup_guest_state);
418 SCVAL(vwv+0, 0, 0xFF);
421 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
423 SSVAL(vwv+4, 0, cli_state_get_vc_num(cli));
424 SIVAL(vwv+5, 0, cli_state_server_session_key(cli));
429 SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli, 0));
431 bytes = talloc_array(state, uint8_t, 0);
433 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "", 1, /* username */
435 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "", 1, /* workgroup */
437 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Unix", 5, NULL);
438 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Samba", 6, NULL);
445 state->bytes.iov_base = (void *)bytes;
446 state->bytes.iov_len = talloc_get_size(bytes);
448 subreq = cli_smb_req_create(state, ev, cli, SMBsesssetupX, 0, 13, vwv,
450 if (subreq == NULL) {
454 tevent_req_set_callback(subreq, cli_session_setup_guest_done, req);
459 struct tevent_req *cli_session_setup_guest_send(TALLOC_CTX *mem_ctx,
460 struct event_context *ev,
461 struct cli_state *cli)
463 struct tevent_req *req, *subreq;
466 req = cli_session_setup_guest_create(mem_ctx, ev, cli, &subreq);
471 status = cli_smb_req_send(subreq);
472 if (NT_STATUS_IS_OK(status)) {
473 tevent_req_nterror(req, status);
474 return tevent_req_post(req, ev);
479 static void cli_session_setup_guest_done(struct tevent_req *subreq)
481 struct tevent_req *req = tevent_req_callback_data(
482 subreq, struct tevent_req);
483 struct cli_session_setup_guest_state *state = tevent_req_data(
484 req, struct cli_session_setup_guest_state);
485 struct cli_state *cli = state->cli;
496 status = cli_smb_recv(subreq, state, &in, 3, &wct, &vwv,
499 if (!NT_STATUS_IS_OK(status)) {
500 tevent_req_nterror(req, status);
507 cli_state_set_uid(state->cli, SVAL(inbuf, smb_uid));
508 cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0);
510 status = smb_bytes_talloc_string(cli,
517 if (!NT_STATUS_IS_OK(status)) {
518 tevent_req_nterror(req, status);
523 status = smb_bytes_talloc_string(cli,
530 if (!NT_STATUS_IS_OK(status)) {
531 tevent_req_nterror(req, status);
536 status = smb_bytes_talloc_string(cli,
543 if (!NT_STATUS_IS_OK(status)) {
544 tevent_req_nterror(req, status);
549 status = cli_set_username(cli, "");
550 if (!NT_STATUS_IS_OK(status)) {
551 tevent_req_nterror(req, status);
554 tevent_req_done(req);
557 NTSTATUS cli_session_setup_guest_recv(struct tevent_req *req)
559 return tevent_req_simple_recv_ntstatus(req);
562 static NTSTATUS cli_session_setup_guest(struct cli_state *cli)
564 TALLOC_CTX *frame = talloc_stackframe();
565 struct event_context *ev;
566 struct tevent_req *req;
567 NTSTATUS status = NT_STATUS_OK;
569 if (cli_has_async_calls(cli)) {
571 * Can't use sync call while an async call is in flight
573 status = NT_STATUS_INVALID_PARAMETER;
577 ev = event_context_init(frame);
579 status = NT_STATUS_NO_MEMORY;
583 req = cli_session_setup_guest_send(frame, ev, cli);
585 status = NT_STATUS_NO_MEMORY;
589 if (!tevent_req_poll(req, ev)) {
590 status = map_nt_error_from_unix(errno);
594 status = cli_session_setup_guest_recv(req);
600 /****************************************************************************
601 Do a NT1 plaintext session setup.
602 ****************************************************************************/
604 struct cli_session_setup_plain_state {
605 struct cli_state *cli;
610 static void cli_session_setup_plain_done(struct tevent_req *subreq);
612 static struct tevent_req *cli_session_setup_plain_send(
613 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
614 struct cli_state *cli,
615 const char *user, const char *pass, const char *workgroup)
617 struct tevent_req *req, *subreq;
618 struct cli_session_setup_plain_state *state;
624 req = tevent_req_create(mem_ctx, &state,
625 struct cli_session_setup_plain_state);
633 SCVAL(vwv+0, 0, 0xff);
636 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
638 SSVAL(vwv+4, 0, cli_state_get_vc_num(cli));
639 SIVAL(vwv+5, 0, cli_state_server_session_key(cli));
644 SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli, 0));
646 bytes = talloc_array(state, uint8_t, 0);
647 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), pass, strlen(pass)+1,
649 if (tevent_req_nomem(bytes, req)) {
650 return tevent_req_post(req, ev);
652 SSVAL(vwv + (cli_ucs2(cli) ? 8 : 7), 0, passlen);
654 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
655 user, strlen(user)+1, NULL);
656 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
657 workgroup, strlen(workgroup)+1, NULL);
658 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
661 version = talloc_asprintf(talloc_tos(), "Samba %s",
662 samba_version_string());
663 if (tevent_req_nomem(version, req)){
664 return tevent_req_post(req, ev);
666 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
667 version, strlen(version)+1, NULL);
668 TALLOC_FREE(version);
670 if (tevent_req_nomem(bytes, req)) {
671 return tevent_req_post(req, ev);
674 subreq = cli_smb_send(state, ev, cli, SMBsesssetupX, 0, 13, vwv,
675 talloc_get_size(bytes), bytes);
676 if (tevent_req_nomem(subreq, req)) {
677 return tevent_req_post(req, ev);
679 tevent_req_set_callback(subreq, cli_session_setup_plain_done, req);
683 static void cli_session_setup_plain_done(struct tevent_req *subreq)
685 struct tevent_req *req = tevent_req_callback_data(
686 subreq, struct tevent_req);
687 struct cli_session_setup_plain_state *state = tevent_req_data(
688 req, struct cli_session_setup_plain_state);
689 struct cli_state *cli = state->cli;
700 status = cli_smb_recv(subreq, state, &in, 3, &wct, &vwv,
703 if (tevent_req_nterror(req, status)) {
710 cli_state_set_uid(state->cli, SVAL(inbuf, smb_uid));
711 cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0);
713 status = smb_bytes_talloc_string(cli,
720 if (!NT_STATUS_IS_OK(status)) {
721 tevent_req_nterror(req, status);
726 status = smb_bytes_talloc_string(cli,
733 if (!NT_STATUS_IS_OK(status)) {
734 tevent_req_nterror(req, status);
739 status = smb_bytes_talloc_string(cli,
746 if (!NT_STATUS_IS_OK(status)) {
747 tevent_req_nterror(req, status);
752 status = cli_set_username(cli, state->user);
753 if (tevent_req_nterror(req, status)) {
757 tevent_req_done(req);
760 static NTSTATUS cli_session_setup_plain_recv(struct tevent_req *req)
762 return tevent_req_simple_recv_ntstatus(req);
765 static NTSTATUS cli_session_setup_plain(struct cli_state *cli,
766 const char *user, const char *pass,
767 const char *workgroup)
769 TALLOC_CTX *frame = talloc_stackframe();
770 struct event_context *ev;
771 struct tevent_req *req;
772 NTSTATUS status = NT_STATUS_NO_MEMORY;
774 if (cli_has_async_calls(cli)) {
776 * Can't use sync call while an async call is in flight
778 status = NT_STATUS_INVALID_PARAMETER;
781 ev = event_context_init(frame);
785 req = cli_session_setup_plain_send(frame, ev, cli, user, pass,
790 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
793 status = cli_session_setup_plain_recv(req);
799 /****************************************************************************
800 do a NT1 NTLM/LM encrypted session setup - for when extended security
802 @param cli client state to create do session setup on
804 @param pass *either* cleartext password (passlen !=24) or LM response.
805 @param ntpass NT response, implies ntpasslen >=24, implies pass is not clear
806 @param workgroup The user's domain.
807 ****************************************************************************/
809 struct cli_session_setup_nt1_state {
810 struct cli_state *cli;
813 DATA_BLOB session_key;
817 static void cli_session_setup_nt1_done(struct tevent_req *subreq);
819 static struct tevent_req *cli_session_setup_nt1_send(
820 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
821 struct cli_state *cli, const char *user,
822 const char *pass, size_t passlen,
823 const char *ntpass, size_t ntpasslen,
824 const char *workgroup)
826 struct tevent_req *req, *subreq;
827 struct cli_session_setup_nt1_state *state;
828 DATA_BLOB lm_response = data_blob_null;
829 DATA_BLOB nt_response = data_blob_null;
830 DATA_BLOB session_key = data_blob_null;
833 char *workgroup_upper;
835 req = tevent_req_create(mem_ctx, &state,
836 struct cli_session_setup_nt1_state);
845 /* do nothing - guest login */
846 } else if (passlen != 24) {
847 if (lp_client_ntlmv2_auth()) {
848 DATA_BLOB server_chal;
849 DATA_BLOB names_blob;
852 data_blob_const(cli_state_server_challenge(cli),
856 * note that the 'workgroup' here is a best
857 * guess - we don't know the server's domain
858 * at this point. Windows clients also don't
861 names_blob = NTLMv2_generate_names_blob(
862 NULL, NULL, workgroup);
864 if (tevent_req_nomem(names_blob.data, req)) {
865 return tevent_req_post(req, ev);
868 if (!SMBNTLMv2encrypt(NULL, user, workgroup, pass,
869 &server_chal, &names_blob,
870 &lm_response, &nt_response,
871 NULL, &session_key)) {
872 data_blob_free(&names_blob);
874 req, NT_STATUS_ACCESS_DENIED);
875 return tevent_req_post(req, ev);
877 data_blob_free(&names_blob);
881 E_md4hash(pass, nt_hash);
884 nt_response = data_blob_null;
886 nt_response = data_blob(NULL, 24);
887 if (tevent_req_nomem(nt_response.data, req)) {
888 return tevent_req_post(req, ev);
891 SMBNTencrypt(pass, cli_state_server_challenge(cli),
894 /* non encrypted password supplied. Ignore ntpass. */
895 if (lp_client_lanman_auth()) {
897 lm_response = data_blob(NULL, 24);
898 if (tevent_req_nomem(lm_response.data, req)) {
899 return tevent_req_post(req, ev);
902 if (!SMBencrypt(pass,
903 cli_state_server_challenge(cli),
906 * Oops, the LM response is
907 * invalid, just put the NT
908 * response there instead
910 data_blob_free(&lm_response);
911 lm_response = data_blob(
917 * LM disabled, place NT# in LM field
920 lm_response = data_blob(
921 nt_response.data, nt_response.length);
924 if (tevent_req_nomem(lm_response.data, req)) {
925 return tevent_req_post(req, ev);
928 session_key = data_blob(NULL, 16);
929 if (tevent_req_nomem(session_key.data, req)) {
930 return tevent_req_post(req, ev);
933 E_deshash(pass, session_key.data);
934 memset(&session_key.data[8], '\0', 8);
936 SMBsesskeygen_ntv1(nt_hash, session_key.data);
940 /* pre-encrypted password supplied. Only used for
941 security=server, can't do
942 signing because we don't have original key */
944 lm_response = data_blob(pass, passlen);
945 if (tevent_req_nomem(lm_response.data, req)) {
946 return tevent_req_post(req, ev);
949 nt_response = data_blob(ntpass, ntpasslen);
950 if (tevent_req_nomem(nt_response.data, req)) {
951 return tevent_req_post(req, ev);
956 state->response = data_blob_talloc(
957 state, lm_response.data, lm_response.length);
959 state->response = data_blob_talloc(
960 state, nt_response.data, nt_response.length);
962 if (tevent_req_nomem(state->response.data, req)) {
963 return tevent_req_post(req, ev);
966 if (session_key.data) {
967 state->session_key = data_blob_talloc(
968 state, session_key.data, session_key.length);
969 if (tevent_req_nomem(state->session_key.data, req)) {
970 return tevent_req_post(req, ev);
973 data_blob_free(&session_key);
975 SCVAL(vwv+0, 0, 0xff);
978 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
980 SSVAL(vwv+4, 0, cli_state_get_vc_num(cli));
981 SIVAL(vwv+5, 0, cli_state_server_session_key(cli));
982 SSVAL(vwv+7, 0, lm_response.length);
983 SSVAL(vwv+8, 0, nt_response.length);
986 SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli, 0));
988 bytes = talloc_array(state, uint8_t,
989 lm_response.length + nt_response.length);
990 if (tevent_req_nomem(bytes, req)) {
991 return tevent_req_post(req, ev);
993 if (lm_response.length != 0) {
994 memcpy(bytes, lm_response.data, lm_response.length);
996 if (nt_response.length != 0) {
997 memcpy(bytes + lm_response.length,
998 nt_response.data, nt_response.length);
1000 data_blob_free(&lm_response);
1001 data_blob_free(&nt_response);
1003 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
1004 user, strlen(user)+1, NULL);
1007 * Upper case here might help some NTLMv2 implementations
1009 workgroup_upper = talloc_strdup_upper(talloc_tos(), workgroup);
1010 if (tevent_req_nomem(workgroup_upper, req)) {
1011 return tevent_req_post(req, ev);
1013 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
1014 workgroup_upper, strlen(workgroup_upper)+1,
1016 TALLOC_FREE(workgroup_upper);
1018 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Unix", 5, NULL);
1019 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Samba", 6, NULL);
1020 if (tevent_req_nomem(bytes, req)) {
1021 return tevent_req_post(req, ev);
1024 subreq = cli_smb_send(state, ev, cli, SMBsesssetupX, 0, 13, vwv,
1025 talloc_get_size(bytes), bytes);
1026 if (tevent_req_nomem(subreq, req)) {
1027 return tevent_req_post(req, ev);
1029 tevent_req_set_callback(subreq, cli_session_setup_nt1_done, req);
1033 static void cli_session_setup_nt1_done(struct tevent_req *subreq)
1035 struct tevent_req *req = tevent_req_callback_data(
1036 subreq, struct tevent_req);
1037 struct cli_session_setup_nt1_state *state = tevent_req_data(
1038 req, struct cli_session_setup_nt1_state);
1039 struct cli_state *cli = state->cli;
1050 status = cli_smb_recv(subreq, state, &in, 3, &wct, &vwv,
1051 &num_bytes, &bytes);
1052 TALLOC_FREE(subreq);
1053 if (!NT_STATUS_IS_OK(status)) {
1054 tevent_req_nterror(req, status);
1061 cli_state_set_uid(state->cli, SVAL(inbuf, smb_uid));
1062 cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0);
1064 status = smb_bytes_talloc_string(cli,
1070 if (!NT_STATUS_IS_OK(status)) {
1071 tevent_req_nterror(req, status);
1076 status = smb_bytes_talloc_string(cli,
1082 if (!NT_STATUS_IS_OK(status)) {
1083 tevent_req_nterror(req, status);
1088 status = smb_bytes_talloc_string(cli,
1090 &cli->server_domain,
1094 if (!NT_STATUS_IS_OK(status)) {
1095 tevent_req_nterror(req, status);
1100 status = cli_set_username(cli, state->user);
1101 if (tevent_req_nterror(req, status)) {
1104 if (cli_simple_set_signing(cli, state->session_key, state->response)
1105 && !cli_check_sign_mac(cli, (char *)in, 1)) {
1106 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1109 if (state->session_key.data) {
1110 /* Have plaintext orginal */
1111 cli_set_session_key(cli, state->session_key);
1113 tevent_req_done(req);
1116 static NTSTATUS cli_session_setup_nt1_recv(struct tevent_req *req)
1118 return tevent_req_simple_recv_ntstatus(req);
1121 static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user,
1122 const char *pass, size_t passlen,
1123 const char *ntpass, size_t ntpasslen,
1124 const char *workgroup)
1126 TALLOC_CTX *frame = talloc_stackframe();
1127 struct event_context *ev;
1128 struct tevent_req *req;
1129 NTSTATUS status = NT_STATUS_NO_MEMORY;
1131 if (cli_has_async_calls(cli)) {
1133 * Can't use sync call while an async call is in flight
1135 status = NT_STATUS_INVALID_PARAMETER;
1138 ev = event_context_init(frame);
1142 req = cli_session_setup_nt1_send(frame, ev, cli, user, pass, passlen,
1143 ntpass, ntpasslen, workgroup);
1147 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1150 status = cli_session_setup_nt1_recv(req);
1156 /* The following is calculated from :
1158 * (smb_wcnt * 2) = 24 (smb_wcnt == 12 in cli_session_setup_blob_send() )
1159 * (strlen("Unix") + 1 + strlen("Samba") + 1) * 2 = 22 (unicode strings at
1163 #define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22)
1165 struct cli_sesssetup_blob_state {
1166 struct tevent_context *ev;
1167 struct cli_state *cli;
1169 uint16_t max_blob_size;
1178 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state *state,
1179 struct tevent_req **psubreq);
1180 static void cli_sesssetup_blob_done(struct tevent_req *subreq);
1182 static struct tevent_req *cli_sesssetup_blob_send(TALLOC_CTX *mem_ctx,
1183 struct tevent_context *ev,
1184 struct cli_state *cli,
1187 struct tevent_req *req, *subreq;
1188 struct cli_sesssetup_blob_state *state;
1189 uint32_t usable_space;
1191 req = tevent_req_create(mem_ctx, &state,
1192 struct cli_sesssetup_blob_state);
1200 usable_space = cli_state_available_size(cli,
1201 BASE_SESSSETUP_BLOB_PACKET_SIZE);
1203 if (usable_space == 0) {
1204 DEBUG(1, ("cli_session_setup_blob: cli->max_xmit too small "
1205 "(not possible to send %u bytes)\n",
1206 BASE_SESSSETUP_BLOB_PACKET_SIZE + 1));
1207 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1208 return tevent_req_post(req, ev);
1210 state->max_blob_size = MIN(usable_space, 0xFFFF);
1212 if (!cli_sesssetup_blob_next(state, &subreq)) {
1213 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1214 return tevent_req_post(req, ev);
1216 tevent_req_set_callback(subreq, cli_sesssetup_blob_done, req);
1220 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state *state,
1221 struct tevent_req **psubreq)
1223 struct tevent_req *subreq;
1226 SCVAL(state->vwv+0, 0, 0xFF);
1227 SCVAL(state->vwv+0, 1, 0);
1228 SSVAL(state->vwv+1, 0, 0);
1229 SSVAL(state->vwv+2, 0, CLI_BUFFER_SIZE);
1230 SSVAL(state->vwv+3, 0, 2);
1231 SSVAL(state->vwv+4, 0, 1);
1232 SIVAL(state->vwv+5, 0, 0);
1234 thistime = MIN(state->blob.length, state->max_blob_size);
1235 SSVAL(state->vwv+7, 0, thistime);
1237 SSVAL(state->vwv+8, 0, 0);
1238 SSVAL(state->vwv+9, 0, 0);
1239 SIVAL(state->vwv+10, 0,
1240 cli_session_setup_capabilities(state->cli, CAP_EXTENDED_SECURITY));
1242 state->buf = (uint8_t *)talloc_memdup(state, state->blob.data,
1244 if (state->buf == NULL) {
1247 state->blob.data += thistime;
1248 state->blob.length -= thistime;
1250 state->buf = smb_bytes_push_str(state->buf, cli_ucs2(state->cli),
1252 state->buf = smb_bytes_push_str(state->buf, cli_ucs2(state->cli),
1254 if (state->buf == NULL) {
1257 subreq = cli_smb_send(state, state->ev, state->cli, SMBsesssetupX, 0,
1259 talloc_get_size(state->buf), state->buf);
1260 if (subreq == NULL) {
1267 static void cli_sesssetup_blob_done(struct tevent_req *subreq)
1269 struct tevent_req *req = tevent_req_callback_data(
1270 subreq, struct tevent_req);
1271 struct cli_sesssetup_blob_state *state = tevent_req_data(
1272 req, struct cli_sesssetup_blob_state);
1273 struct cli_state *cli = state->cli;
1280 uint16_t blob_length;
1284 status = cli_smb_recv(subreq, state, &inbuf, 4, &wct, &vwv,
1285 &num_bytes, &bytes);
1286 TALLOC_FREE(subreq);
1287 if (!NT_STATUS_IS_OK(status)
1288 && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1289 tevent_req_nterror(req, status);
1293 state->status = status;
1294 TALLOC_FREE(state->buf);
1296 state->inbuf = (char *)inbuf;
1297 cli_state_set_uid(state->cli, SVAL(inbuf, smb_uid));
1298 cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0);
1300 blob_length = SVAL(vwv+3, 0);
1301 if (blob_length > num_bytes) {
1302 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1305 state->ret_blob = data_blob_const(bytes, blob_length);
1307 p = bytes + blob_length;
1309 status = smb_bytes_talloc_string(cli,
1316 if (!NT_STATUS_IS_OK(status)) {
1317 tevent_req_nterror(req, status);
1322 status = smb_bytes_talloc_string(cli,
1329 if (!NT_STATUS_IS_OK(status)) {
1330 tevent_req_nterror(req, status);
1335 status = smb_bytes_talloc_string(cli,
1337 &cli->server_domain,
1342 if (!NT_STATUS_IS_OK(status)) {
1343 tevent_req_nterror(req, status);
1348 if (state->blob.length != 0) {
1352 if (!cli_sesssetup_blob_next(state, &subreq)) {
1353 tevent_req_oom(req);
1356 tevent_req_set_callback(subreq, cli_sesssetup_blob_done, req);
1359 tevent_req_done(req);
1362 static NTSTATUS cli_sesssetup_blob_recv(struct tevent_req *req,
1363 TALLOC_CTX *mem_ctx,
1367 struct cli_sesssetup_blob_state *state = tevent_req_data(
1368 req, struct cli_sesssetup_blob_state);
1372 if (tevent_req_is_nterror(req, &status)) {
1373 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
1377 inbuf = talloc_move(mem_ctx, &state->inbuf);
1378 if (pblob != NULL) {
1379 *pblob = state->ret_blob;
1381 if (pinbuf != NULL) {
1384 /* could be NT_STATUS_MORE_PROCESSING_REQUIRED */
1385 return state->status;
1390 /****************************************************************************
1391 Use in-memory credentials cache
1392 ****************************************************************************/
1394 static void use_in_memory_ccache(void) {
1395 setenv(KRB5_ENV_CCNAME, "MEMORY:cliconnect", 1);
1398 /****************************************************************************
1399 Do a spnego/kerberos encrypted session setup.
1400 ****************************************************************************/
1402 struct cli_session_setup_kerberos_state {
1403 struct cli_state *cli;
1404 DATA_BLOB negTokenTarg;
1405 DATA_BLOB session_key_krb5;
1406 ADS_STATUS ads_status;
1409 static void cli_session_setup_kerberos_done(struct tevent_req *subreq);
1411 static struct tevent_req *cli_session_setup_kerberos_send(
1412 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
1413 const char *principal)
1415 struct tevent_req *req, *subreq;
1416 struct cli_session_setup_kerberos_state *state;
1419 DEBUG(2,("Doing kerberos session setup\n"));
1421 req = tevent_req_create(mem_ctx, &state,
1422 struct cli_session_setup_kerberos_state);
1427 state->ads_status = ADS_SUCCESS;
1430 * Ok, this is cheating: spnego_gen_krb5_negTokenInit can block if
1431 * we have to acquire a ticket. To be fixed later :-)
1433 rc = spnego_gen_krb5_negTokenInit(state, principal, 0, &state->negTokenTarg,
1434 &state->session_key_krb5, 0, NULL);
1436 DEBUG(1, ("cli_session_setup_kerberos: "
1437 "spnego_gen_krb5_negTokenInit failed: %s\n",
1438 error_message(rc)));
1439 state->ads_status = ADS_ERROR_KRB5(rc);
1440 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
1441 return tevent_req_post(req, ev);
1445 file_save("negTokenTarg.dat", state->negTokenTarg.data,
1446 state->negTokenTarg.length);
1449 subreq = cli_sesssetup_blob_send(state, ev, cli, state->negTokenTarg);
1450 if (tevent_req_nomem(subreq, req)) {
1451 return tevent_req_post(req, ev);
1453 tevent_req_set_callback(subreq, cli_session_setup_kerberos_done, req);
1457 static void cli_session_setup_kerberos_done(struct tevent_req *subreq)
1459 struct tevent_req *req = tevent_req_callback_data(
1460 subreq, struct tevent_req);
1461 struct cli_session_setup_kerberos_state *state = tevent_req_data(
1462 req, struct cli_session_setup_kerberos_state);
1466 status = cli_sesssetup_blob_recv(subreq, talloc_tos(), NULL, &inbuf);
1467 TALLOC_FREE(subreq);
1468 if (!NT_STATUS_IS_OK(status)) {
1469 tevent_req_nterror(req, status);
1473 cli_set_session_key(state->cli, state->session_key_krb5);
1475 if (cli_simple_set_signing(state->cli, state->session_key_krb5,
1477 && !cli_check_sign_mac(state->cli, inbuf, 1)) {
1478 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1482 tevent_req_done(req);
1485 static ADS_STATUS cli_session_setup_kerberos_recv(struct tevent_req *req)
1487 struct cli_session_setup_kerberos_state *state = tevent_req_data(
1488 req, struct cli_session_setup_kerberos_state);
1491 if (tevent_req_is_nterror(req, &status)) {
1492 return ADS_ERROR_NT(status);
1494 return state->ads_status;
1497 static ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli,
1498 const char *principal)
1500 struct tevent_context *ev;
1501 struct tevent_req *req;
1502 ADS_STATUS status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1504 if (cli_has_async_calls(cli)) {
1505 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1507 ev = tevent_context_init(talloc_tos());
1511 req = cli_session_setup_kerberos_send(ev, ev, cli, principal);
1515 if (!tevent_req_poll(req, ev)) {
1516 status = ADS_ERROR_SYSTEM(errno);
1519 status = cli_session_setup_kerberos_recv(req);
1524 #endif /* HAVE_KRB5 */
1526 /****************************************************************************
1527 Do a spnego/NTLMSSP encrypted session setup.
1528 ****************************************************************************/
1530 struct cli_session_setup_ntlmssp_state {
1531 struct tevent_context *ev;
1532 struct cli_state *cli;
1533 struct ntlmssp_state *ntlmssp_state;
1538 static int cli_session_setup_ntlmssp_state_destructor(
1539 struct cli_session_setup_ntlmssp_state *state)
1541 if (state->ntlmssp_state != NULL) {
1542 TALLOC_FREE(state->ntlmssp_state);
1547 static void cli_session_setup_ntlmssp_done(struct tevent_req *req);
1549 static struct tevent_req *cli_session_setup_ntlmssp_send(
1550 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
1551 const char *user, const char *pass, const char *domain)
1553 struct tevent_req *req, *subreq;
1554 struct cli_session_setup_ntlmssp_state *state;
1557 const char *OIDs_ntlm[] = {OID_NTLMSSP, NULL};
1559 req = tevent_req_create(mem_ctx, &state,
1560 struct cli_session_setup_ntlmssp_state);
1568 state->ntlmssp_state = NULL;
1569 talloc_set_destructor(
1570 state, cli_session_setup_ntlmssp_state_destructor);
1572 status = ntlmssp_client_start(state,
1575 lp_client_ntlmv2_auth(),
1576 &state->ntlmssp_state);
1577 if (!NT_STATUS_IS_OK(status)) {
1580 ntlmssp_want_feature(state->ntlmssp_state,
1581 NTLMSSP_FEATURE_SESSION_KEY);
1582 if (cli->use_ccache) {
1583 ntlmssp_want_feature(state->ntlmssp_state,
1584 NTLMSSP_FEATURE_CCACHE);
1586 status = ntlmssp_set_username(state->ntlmssp_state, user);
1587 if (!NT_STATUS_IS_OK(status)) {
1590 status = ntlmssp_set_domain(state->ntlmssp_state, domain);
1591 if (!NT_STATUS_IS_OK(status)) {
1594 status = ntlmssp_set_password(state->ntlmssp_state, pass);
1595 if (!NT_STATUS_IS_OK(status)) {
1598 status = ntlmssp_update(state->ntlmssp_state, data_blob_null,
1600 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1604 state->blob_out = spnego_gen_negTokenInit(state, OIDs_ntlm, &blob_out, NULL);
1605 data_blob_free(&blob_out);
1607 subreq = cli_sesssetup_blob_send(state, ev, cli, state->blob_out);
1608 if (tevent_req_nomem(subreq, req)) {
1609 return tevent_req_post(req, ev);
1611 tevent_req_set_callback(subreq, cli_session_setup_ntlmssp_done, req);
1614 tevent_req_nterror(req, status);
1615 return tevent_req_post(req, ev);
1618 static void cli_session_setup_ntlmssp_done(struct tevent_req *subreq)
1620 struct tevent_req *req = tevent_req_callback_data(
1621 subreq, struct tevent_req);
1622 struct cli_session_setup_ntlmssp_state *state = tevent_req_data(
1623 req, struct cli_session_setup_ntlmssp_state);
1624 DATA_BLOB blob_in, msg_in, blob_out;
1629 status = cli_sesssetup_blob_recv(subreq, talloc_tos(), &blob_in,
1631 TALLOC_FREE(subreq);
1632 data_blob_free(&state->blob_out);
1634 if (NT_STATUS_IS_OK(status)) {
1635 if (state->cli->server_domain[0] == '\0') {
1636 TALLOC_FREE(state->cli->server_domain);
1637 state->cli->server_domain = talloc_strdup(state->cli,
1638 state->ntlmssp_state->server.netbios_domain);
1639 if (state->cli->server_domain == NULL) {
1640 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1644 cli_set_session_key(
1645 state->cli, state->ntlmssp_state->session_key);
1647 if (cli_simple_set_signing(
1648 state->cli, state->ntlmssp_state->session_key,
1650 && !cli_check_sign_mac(state->cli, inbuf, 1)) {
1651 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1654 TALLOC_FREE(state->ntlmssp_state);
1655 tevent_req_done(req);
1658 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1659 tevent_req_nterror(req, status);
1663 if (blob_in.length == 0) {
1664 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
1668 if ((state->turn == 1)
1669 && NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1670 DATA_BLOB tmp_blob = data_blob_null;
1671 /* the server might give us back two challenges */
1672 parse_ret = spnego_parse_challenge(state, blob_in, &msg_in,
1674 data_blob_free(&tmp_blob);
1676 parse_ret = spnego_parse_auth_response(state, blob_in, status,
1677 OID_NTLMSSP, &msg_in);
1682 DEBUG(3,("Failed to parse auth response\n"));
1683 if (NT_STATUS_IS_OK(status)
1684 || NT_STATUS_EQUAL(status,
1685 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1687 req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1692 status = ntlmssp_update(state->ntlmssp_state, msg_in, &blob_out);
1694 if (!NT_STATUS_IS_OK(status)
1695 && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1696 TALLOC_FREE(state->ntlmssp_state);
1697 tevent_req_nterror(req, status);
1701 state->blob_out = spnego_gen_auth(state, blob_out);
1702 if (tevent_req_nomem(state->blob_out.data, req)) {
1706 subreq = cli_sesssetup_blob_send(state, state->ev, state->cli,
1708 if (tevent_req_nomem(subreq, req)) {
1711 tevent_req_set_callback(subreq, cli_session_setup_ntlmssp_done, req);
1714 static NTSTATUS cli_session_setup_ntlmssp_recv(struct tevent_req *req)
1716 struct cli_session_setup_ntlmssp_state *state = tevent_req_data(
1717 req, struct cli_session_setup_ntlmssp_state);
1720 if (tevent_req_is_nterror(req, &status)) {
1721 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
1724 return NT_STATUS_OK;
1727 static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli,
1732 struct tevent_context *ev;
1733 struct tevent_req *req;
1734 NTSTATUS status = NT_STATUS_NO_MEMORY;
1736 if (cli_has_async_calls(cli)) {
1737 return NT_STATUS_INVALID_PARAMETER;
1739 ev = tevent_context_init(talloc_tos());
1743 req = cli_session_setup_ntlmssp_send(ev, ev, cli, user, pass, domain);
1747 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1750 status = cli_session_setup_ntlmssp_recv(req);
1756 /****************************************************************************
1757 Do a spnego encrypted session setup.
1759 user_domain: The shortname of the domain the user/machine is a member of.
1760 dest_realm: The realm we're connecting to, if NULL we use our default realm.
1761 ****************************************************************************/
1763 static ADS_STATUS cli_session_setup_spnego(struct cli_state *cli,
1766 const char *user_domain,
1767 const char * dest_realm)
1769 char *principal = NULL;
1770 char *OIDs[ASN1_MAX_OIDS];
1772 const DATA_BLOB *server_blob;
1773 DATA_BLOB blob = data_blob_null;
1774 const char *p = NULL;
1775 char *account = NULL;
1778 server_blob = cli_state_server_gss_blob(cli);
1780 blob = data_blob(server_blob->data, server_blob->length);
1783 DEBUG(3,("Doing spnego session setup (blob length=%lu)\n", (unsigned long)blob.length));
1785 /* the server might not even do spnego */
1786 if (blob.length == 0) {
1787 DEBUG(3,("server didn't supply a full spnego negprot\n"));
1792 file_save("negprot.dat", cli->secblob.data, cli->secblob.length);
1795 /* The server sent us the first part of the SPNEGO exchange in the
1796 * negprot reply. It is WRONG to depend on the principal sent in the
1797 * negprot reply, but right now we do it. If we don't receive one,
1798 * we try to best guess, then fall back to NTLM. */
1799 if (!spnego_parse_negTokenInit(talloc_tos(), blob, OIDs, &principal, NULL) ||
1801 data_blob_free(&blob);
1802 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1804 data_blob_free(&blob);
1806 /* make sure the server understands kerberos */
1807 for (i=0;OIDs[i];i++) {
1809 DEBUG(3,("got OID=%s\n", OIDs[i]));
1811 DEBUGADD(3,("got OID=%s\n", OIDs[i]));
1812 if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0 ||
1813 strcmp(OIDs[i], OID_KERBEROS5) == 0) {
1814 cli->got_kerberos_mechanism = True;
1816 talloc_free(OIDs[i]);
1819 DEBUG(3,("got principal=%s\n", principal ? principal : "<null>"));
1821 status = cli_set_username(cli, user);
1822 if (!NT_STATUS_IS_OK(status)) {
1823 TALLOC_FREE(principal);
1824 return ADS_ERROR_NT(status);
1828 /* If password is set we reauthenticate to kerberos server
1829 * and do not store results */
1831 if (cli->got_kerberos_mechanism && cli->use_kerberos) {
1833 const char *remote_name = cli_state_remote_name(cli);
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 return ADS_ERROR_KRB5(ret);
1850 /* We may not be allowed to use the server-supplied SPNEGO principal, or it may not have been supplied to us
1852 if (!lp_client_use_spnego_principal() || strequal(principal, ADS_IGNORE_PRINCIPAL)) {
1853 TALLOC_FREE(principal);
1856 if (principal == NULL &&
1857 !is_ipaddress(remote_name) &&
1858 !strequal(STAR_SMBSERVER,
1862 DEBUG(3,("cli_session_setup_spnego: using target "
1863 "hostname not SPNEGO principal\n"));
1865 host = strchr_m(remote_name, '.');
1867 realm = SMB_STRDUP(dest_realm);
1869 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1875 realm = kerberos_get_realm_from_hostname(remote_name);
1877 /* NetBIOS name - use our realm. */
1878 realm = kerberos_get_default_realm_from_ccache();
1882 if (realm == NULL || *realm == '\0') {
1883 realm = SMB_STRDUP(lp_realm());
1885 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1888 DEBUG(3,("cli_session_setup_spnego: cannot "
1889 "get realm from dest_realm %s, "
1890 "desthost %s. Using default "
1891 "smb.conf realm %s\n",
1892 dest_realm ? dest_realm : "<null>",
1897 principal = talloc_asprintf(talloc_tos(),
1903 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1905 DEBUG(3,("cli_session_setup_spnego: guessed "
1906 "server principal=%s\n",
1907 principal ? principal : "<null>"));
1913 rc = cli_session_setup_kerberos(cli, principal);
1914 if (ADS_ERR_OK(rc) || !cli->fallback_after_kerberos) {
1915 TALLOC_FREE(principal);
1922 TALLOC_FREE(principal);
1926 account = talloc_strdup(talloc_tos(), user);
1928 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1931 /* when falling back to ntlmssp while authenticating with a machine
1932 * account strip off the realm - gd */
1934 if ((p = strchr_m(user, '@')) != NULL) {
1935 account[PTR_DIFF(p,user)] = '\0';
1938 return ADS_ERROR_NT(cli_session_setup_ntlmssp(cli, account, pass, user_domain));
1941 /****************************************************************************
1942 Send a session setup. The username and workgroup is in UNIX character
1943 format and must be converted to DOS codepage format before sending. If the
1944 password is in plaintext, the same should be done.
1945 ****************************************************************************/
1947 NTSTATUS cli_session_setup(struct cli_state *cli,
1949 const char *pass, int passlen,
1950 const char *ntpass, int ntpasslen,
1951 const char *workgroup)
1955 uint16_t sec_mode = cli_state_security_mode(cli);
1958 user2 = talloc_strdup(talloc_tos(), user);
1960 user2 = talloc_strdup(talloc_tos(), "");
1962 if (user2 == NULL) {
1963 return NT_STATUS_NO_MEMORY;
1970 /* allow for workgroups as part of the username */
1971 if ((p=strchr_m(user2,'\\')) || (p=strchr_m(user2,'/')) ||
1972 (p=strchr_m(user2,*lp_winbind_separator()))) {
1979 if (cli_state_protocol(cli) < PROTOCOL_LANMAN1) {
1981 * Ensure cli->server_domain,
1982 * cli->server_os and cli->server_type
1983 * are valid pointers.
1985 cli->server_domain = talloc_strdup(cli, "");
1986 cli->server_os = talloc_strdup(cli, "");
1987 cli->server_type = talloc_strdup(cli, "");
1988 if (cli->server_domain == NULL ||
1989 cli->server_os == NULL ||
1990 cli->server_type == NULL) {
1991 return NT_STATUS_NO_MEMORY;
1993 return NT_STATUS_OK;
1996 /* now work out what sort of session setup we are going to
1997 do. I have split this into separate functions to make the
1998 flow a bit easier to understand (tridge) */
2000 /* if its an older server then we have to use the older request format */
2002 if (cli_state_protocol(cli) < PROTOCOL_NT1) {
2003 if (!lp_client_lanman_auth() && passlen != 24 && (*pass)) {
2004 DEBUG(1, ("Server requested LM password but 'client lanman auth = no'"
2005 " or 'client ntlmv2 auth = yes'\n"));
2006 return NT_STATUS_ACCESS_DENIED;
2009 if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0 &&
2010 !lp_client_plaintext_auth() && (*pass)) {
2011 DEBUG(1, ("Server requested LM password but 'client plaintext auth = no'"
2012 " or 'client ntlmv2 auth = yes'\n"));
2013 return NT_STATUS_ACCESS_DENIED;
2016 return cli_session_setup_lanman2(cli, user, pass, passlen,
2020 /* if no user is supplied then we have to do an anonymous connection.
2021 passwords are ignored */
2023 if (!user || !*user)
2024 return cli_session_setup_guest(cli);
2026 /* if the server is share level then send a plaintext null
2027 password at this point. The password is sent in the tree
2030 if ((sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0)
2031 return cli_session_setup_plain(cli, user, "", workgroup);
2033 /* if the server doesn't support encryption then we have to use
2034 plaintext. The second password is ignored */
2036 if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) {
2037 if (!lp_client_plaintext_auth() && (*pass)) {
2038 DEBUG(1, ("Server requested LM password but 'client plaintext auth = no'"
2039 " or 'client ntlmv2 auth = yes'\n"));
2040 return NT_STATUS_ACCESS_DENIED;
2042 return cli_session_setup_plain(cli, user, pass, workgroup);
2045 /* if the server supports extended security then use SPNEGO */
2047 if (cli_state_capabilities(cli) & CAP_EXTENDED_SECURITY) {
2048 const char *remote_realm = cli_state_remote_realm(cli);
2049 ADS_STATUS status = cli_session_setup_spnego(cli, user, pass,
2052 if (!ADS_ERR_OK(status)) {
2053 DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status)));
2054 return ads_ntstatus(status);
2059 /* otherwise do a NT1 style session setup */
2060 status = cli_session_setup_nt1(cli, user, pass, passlen,
2061 ntpass, ntpasslen, workgroup);
2062 if (!NT_STATUS_IS_OK(status)) {
2063 DEBUG(3,("cli_session_setup: NT1 session setup "
2064 "failed: %s\n", nt_errstr(status)));
2069 return NT_STATUS_OK;
2072 /****************************************************************************
2074 *****************************************************************************/
2076 struct cli_ulogoff_state {
2077 struct cli_state *cli;
2081 static void cli_ulogoff_done(struct tevent_req *subreq);
2083 struct tevent_req *cli_ulogoff_send(TALLOC_CTX *mem_ctx,
2084 struct tevent_context *ev,
2085 struct cli_state *cli)
2087 struct tevent_req *req, *subreq;
2088 struct cli_ulogoff_state *state;
2090 req = tevent_req_create(mem_ctx, &state, struct cli_ulogoff_state);
2096 SCVAL(state->vwv+0, 0, 0xFF);
2097 SCVAL(state->vwv+1, 0, 0);
2098 SSVAL(state->vwv+2, 0, 0);
2100 subreq = cli_smb_send(state, ev, cli, SMBulogoffX, 0, 2, state->vwv,
2102 if (tevent_req_nomem(subreq, req)) {
2103 return tevent_req_post(req, ev);
2105 tevent_req_set_callback(subreq, cli_ulogoff_done, req);
2109 static void cli_ulogoff_done(struct tevent_req *subreq)
2111 struct tevent_req *req = tevent_req_callback_data(
2112 subreq, struct tevent_req);
2113 struct cli_ulogoff_state *state = tevent_req_data(
2114 req, struct cli_ulogoff_state);
2117 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
2118 if (!NT_STATUS_IS_OK(status)) {
2119 tevent_req_nterror(req, status);
2122 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
2123 tevent_req_done(req);
2126 NTSTATUS cli_ulogoff_recv(struct tevent_req *req)
2128 return tevent_req_simple_recv_ntstatus(req);
2131 NTSTATUS cli_ulogoff(struct cli_state *cli)
2133 struct tevent_context *ev;
2134 struct tevent_req *req;
2135 NTSTATUS status = NT_STATUS_NO_MEMORY;
2137 if (cli_has_async_calls(cli)) {
2138 return NT_STATUS_INVALID_PARAMETER;
2140 ev = tevent_context_init(talloc_tos());
2144 req = cli_ulogoff_send(ev, ev, cli);
2148 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2151 status = cli_ulogoff_recv(req);
2157 /****************************************************************************
2159 ****************************************************************************/
2161 struct cli_tcon_andx_state {
2162 struct cli_state *cli;
2167 static void cli_tcon_andx_done(struct tevent_req *subreq);
2169 struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx,
2170 struct event_context *ev,
2171 struct cli_state *cli,
2172 const char *share, const char *dev,
2173 const char *pass, int passlen,
2174 struct tevent_req **psmbreq)
2176 struct tevent_req *req, *subreq;
2177 struct cli_tcon_andx_state *state;
2182 uint16_t sec_mode = cli_state_security_mode(cli);
2186 req = tevent_req_create(mem_ctx, &state, struct cli_tcon_andx_state);
2193 cli->share = talloc_strdup(cli, share);
2198 /* in user level security don't send a password now */
2199 if (sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {
2202 } else if (pass == NULL) {
2203 DEBUG(1, ("Server not using user level security and no "
2204 "password supplied.\n"));
2208 if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) &&
2209 *pass && passlen != 24) {
2210 if (!lp_client_lanman_auth()) {
2211 DEBUG(1, ("Server requested LANMAN password "
2212 "(share-level security) but "
2213 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2218 * Non-encrypted passwords - convert to DOS codepage before
2221 SMBencrypt(pass, cli_state_server_challenge(cli), p24);
2223 pass = (const char *)p24;
2225 if((sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL
2226 |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE))
2230 if (!lp_client_plaintext_auth() && (*pass)) {
2231 DEBUG(1, ("Server requested plaintext "
2233 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2238 * Non-encrypted passwords - convert to DOS codepage
2241 tmp_pass = talloc_array(talloc_tos(), uint8, 0);
2242 if (tevent_req_nomem(tmp_pass, req)) {
2243 return tevent_req_post(req, ev);
2245 tmp_pass = trans2_bytes_push_str(tmp_pass,
2246 false, /* always DOS */
2250 if (tevent_req_nomem(tmp_pass, req)) {
2251 return tevent_req_post(req, ev);
2253 pass = (const char *)tmp_pass;
2254 passlen = talloc_get_size(tmp_pass);
2258 SCVAL(vwv+0, 0, 0xFF);
2261 SSVAL(vwv+2, 0, TCONX_FLAG_EXTENDED_RESPONSE);
2262 SSVAL(vwv+3, 0, passlen);
2264 if (passlen && pass) {
2265 bytes = (uint8_t *)talloc_memdup(state, pass, passlen);
2267 bytes = talloc_array(state, uint8_t, 0);
2273 tmp = talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
2274 cli_state_remote_name(cli), share);
2279 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), tmp, strlen(tmp)+1,
2284 * Add the devicetype
2286 tmp = talloc_strdup_upper(talloc_tos(), dev);
2291 bytes = smb_bytes_push_str(bytes, false, tmp, strlen(tmp)+1, NULL);
2294 if (bytes == NULL) {
2299 state->bytes.iov_base = (void *)bytes;
2300 state->bytes.iov_len = talloc_get_size(bytes);
2302 subreq = cli_smb_req_create(state, ev, cli, SMBtconX, 0, 4, vwv,
2304 if (subreq == NULL) {
2308 tevent_req_set_callback(subreq, cli_tcon_andx_done, req);
2313 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
2314 return tevent_req_post(req, ev);
2317 struct tevent_req *cli_tcon_andx_send(TALLOC_CTX *mem_ctx,
2318 struct event_context *ev,
2319 struct cli_state *cli,
2320 const char *share, const char *dev,
2321 const char *pass, int passlen)
2323 struct tevent_req *req, *subreq;
2326 req = cli_tcon_andx_create(mem_ctx, ev, cli, share, dev, pass, passlen,
2331 if (subreq == NULL) {
2334 status = cli_smb_req_send(subreq);
2335 if (!NT_STATUS_IS_OK(status)) {
2336 tevent_req_nterror(req, status);
2337 return tevent_req_post(req, ev);
2342 static void cli_tcon_andx_done(struct tevent_req *subreq)
2344 struct tevent_req *req = tevent_req_callback_data(
2345 subreq, struct tevent_req);
2346 struct cli_tcon_andx_state *state = tevent_req_data(
2347 req, struct cli_tcon_andx_state);
2348 struct cli_state *cli = state->cli;
2357 status = cli_smb_recv(subreq, state, &in, 0, &wct, &vwv,
2358 &num_bytes, &bytes);
2359 TALLOC_FREE(subreq);
2360 if (!NT_STATUS_IS_OK(status)) {
2361 tevent_req_nterror(req, status);
2368 if (clistr_pull_talloc(cli,
2370 SVAL(inbuf, smb_flg2),
2374 STR_TERMINATE|STR_ASCII) == -1) {
2375 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2379 cli->dev = talloc_strdup(cli, "");
2380 if (cli->dev == NULL) {
2381 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2386 if ((cli_state_protocol(cli) >= PROTOCOL_NT1) && (num_bytes == 3)) {
2387 /* almost certainly win95 - enable bug fixes */
2392 * Make sure that we have the optional support 16-bit field. WCT > 2.
2393 * Avoids issues when connecting to Win9x boxes sharing files
2396 cli->dfsroot = false;
2398 if ((wct > 2) && (cli_state_protocol(cli) >= PROTOCOL_LANMAN2)) {
2399 cli->dfsroot = ((SVAL(vwv+2, 0) & SMB_SHARE_IN_DFS) != 0);
2402 cli->smb1.tid = SVAL(inbuf,smb_tid);
2403 tevent_req_done(req);
2406 NTSTATUS cli_tcon_andx_recv(struct tevent_req *req)
2408 return tevent_req_simple_recv_ntstatus(req);
2411 NTSTATUS cli_tcon_andx(struct cli_state *cli, const char *share,
2412 const char *dev, const char *pass, int passlen)
2414 TALLOC_CTX *frame = talloc_stackframe();
2415 struct event_context *ev;
2416 struct tevent_req *req;
2417 NTSTATUS status = NT_STATUS_OK;
2419 if (cli_has_async_calls(cli)) {
2421 * Can't use sync call while an async call is in flight
2423 status = NT_STATUS_INVALID_PARAMETER;
2427 ev = event_context_init(frame);
2429 status = NT_STATUS_NO_MEMORY;
2433 req = cli_tcon_andx_send(frame, ev, cli, share, dev, pass, passlen);
2435 status = NT_STATUS_NO_MEMORY;
2439 if (!tevent_req_poll(req, ev)) {
2440 status = map_nt_error_from_unix(errno);
2444 status = cli_tcon_andx_recv(req);
2450 /****************************************************************************
2451 Send a tree disconnect.
2452 ****************************************************************************/
2454 struct cli_tdis_state {
2455 struct cli_state *cli;
2458 static void cli_tdis_done(struct tevent_req *subreq);
2460 struct tevent_req *cli_tdis_send(TALLOC_CTX *mem_ctx,
2461 struct tevent_context *ev,
2462 struct cli_state *cli)
2464 struct tevent_req *req, *subreq;
2465 struct cli_tdis_state *state;
2467 req = tevent_req_create(mem_ctx, &state, struct cli_tdis_state);
2473 subreq = cli_smb_send(state, ev, cli, SMBtdis, 0, 0, NULL, 0, NULL);
2474 if (tevent_req_nomem(subreq, req)) {
2475 return tevent_req_post(req, ev);
2477 tevent_req_set_callback(subreq, cli_tdis_done, req);
2481 static void cli_tdis_done(struct tevent_req *subreq)
2483 struct tevent_req *req = tevent_req_callback_data(
2484 subreq, struct tevent_req);
2485 struct cli_tdis_state *state = tevent_req_data(
2486 req, struct cli_tdis_state);
2489 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
2490 TALLOC_FREE(subreq);
2491 if (!NT_STATUS_IS_OK(status)) {
2492 tevent_req_nterror(req, status);
2495 state->cli->smb1.tid = UINT16_MAX;
2496 tevent_req_done(req);
2499 NTSTATUS cli_tdis_recv(struct tevent_req *req)
2501 return tevent_req_simple_recv_ntstatus(req);
2504 NTSTATUS cli_tdis(struct cli_state *cli)
2506 struct tevent_context *ev;
2507 struct tevent_req *req;
2508 NTSTATUS status = NT_STATUS_NO_MEMORY;
2510 if (cli_has_async_calls(cli)) {
2511 return NT_STATUS_INVALID_PARAMETER;
2513 ev = tevent_context_init(talloc_tos());
2517 req = cli_tdis_send(ev, ev, cli);
2521 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2524 status = cli_tdis_recv(req);
2530 /****************************************************************************
2531 Send a negprot command.
2532 ****************************************************************************/
2534 struct cli_negprot_state {
2535 struct cli_state *cli;
2536 enum protocol_types max_protocol;
2539 static void cli_negprot_done(struct tevent_req *subreq);
2541 struct tevent_req *cli_negprot_send(TALLOC_CTX *mem_ctx,
2542 struct event_context *ev,
2543 struct cli_state *cli,
2544 enum protocol_types max_protocol)
2546 struct tevent_req *req, *subreq;
2547 struct cli_negprot_state *state;
2548 uint8_t *bytes = NULL;
2550 enum protocol_types tmp_protocol;
2552 req = tevent_req_create(mem_ctx, &state, struct cli_negprot_state);
2557 state->max_protocol = max_protocol;
2559 /* setup the protocol strings */
2560 for (numprots=0; numprots < ARRAY_SIZE(prots); numprots++) {
2562 if (prots[numprots].prot > state->max_protocol) {
2565 bytes = (uint8_t *)talloc_append_blob(
2566 state, bytes, data_blob_const(&c, sizeof(c)));
2567 if (tevent_req_nomem(bytes, req)) {
2568 return tevent_req_post(req, ev);
2570 bytes = smb_bytes_push_str(bytes, false,
2571 prots[numprots].name,
2572 strlen(prots[numprots].name)+1,
2574 if (tevent_req_nomem(bytes, req)) {
2575 return tevent_req_post(req, ev);
2579 tmp_protocol = cli->conn.protocol;
2580 cli->conn.protocol = state->max_protocol;
2581 subreq = cli_smb_send(state, ev, cli, SMBnegprot, 0, 0, NULL,
2582 talloc_get_size(bytes), bytes);
2583 cli->conn.protocol = tmp_protocol;
2584 if (tevent_req_nomem(subreq, req)) {
2585 return tevent_req_post(req, ev);
2587 tevent_req_set_callback(subreq, cli_negprot_done, req);
2591 static void cli_negprot_done(struct tevent_req *subreq)
2593 struct tevent_req *req = tevent_req_callback_data(
2594 subreq, struct tevent_req);
2595 struct cli_negprot_state *state = tevent_req_data(
2596 req, struct cli_negprot_state);
2597 struct cli_state *cli = state->cli;
2606 uint32_t client_capabilities = cli->conn.smb1.client.capabilities;
2607 uint32_t both_capabilities;
2608 uint32_t server_capabilities = 0;
2609 uint32_t capabilities;
2610 uint32_t client_max_xmit = cli->conn.smb1.client.max_xmit;
2611 uint32_t server_max_xmit = 0;
2613 uint32_t server_max_mux = 0;
2614 uint16_t server_security_mode = 0;
2615 uint32_t server_session_key = 0;
2616 bool server_readbraw = false;
2617 bool server_writebraw = false;
2618 bool server_lockread = false;
2619 bool server_writeunlock = false;
2620 struct GUID server_guid = GUID_zero();
2621 DATA_BLOB server_gss_blob = data_blob_null;
2622 uint8_t server_challenge[8];
2623 char *server_workgroup = NULL;
2624 int server_time_zone = 0;
2625 time_t server_system_time = 0;
2626 enum protocol_types protocol;
2628 ZERO_STRUCT(server_challenge);
2630 status = cli_smb_recv(subreq, state, &inbuf, 1, &wct, &vwv,
2631 &num_bytes, &bytes);
2632 TALLOC_FREE(subreq);
2633 if (!NT_STATUS_IS_OK(status)) {
2634 tevent_req_nterror(req, status);
2638 flags = CVAL(inbuf, smb_flg);
2640 protnum = SVAL(vwv, 0);
2642 if ((protnum >= ARRAY_SIZE(prots))
2643 || (prots[protnum].prot > state->max_protocol)) {
2644 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2648 protocol = prots[protnum].prot;
2650 if ((protocol < PROTOCOL_NT1) &&
2651 client_is_signing_mandatory(cli)) {
2652 DEBUG(0,("cli_negprot: SMB signing is mandatory and the selected protocol level doesn't support it.\n"));
2653 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
2657 if (flags & FLAG_SUPPORT_LOCKREAD) {
2658 server_lockread = true;
2659 server_writeunlock = true;
2662 if (protocol >= PROTOCOL_NT1) {
2664 const char *client_signing = NULL;
2665 bool server_mandatory;
2666 bool server_allowed;
2667 const char *server_signing = NULL;
2672 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2677 server_security_mode = CVAL(vwv + 1, 0);
2678 server_max_mux = SVAL(vwv + 1, 1);
2679 server_max_xmit = IVAL(vwv + 3, 1);
2680 server_session_key = IVAL(vwv + 7, 1);
2681 server_time_zone = SVALS(vwv + 15, 1);
2682 server_time_zone *= 60;
2683 /* this time arrives in real GMT */
2684 ts = interpret_long_date(((char *)(vwv+11))+1);
2685 server_system_time = ts.tv_sec;
2686 server_capabilities = IVAL(vwv + 9, 1);
2688 key_len = CVAL(vwv + 16, 1);
2690 if (server_capabilities & CAP_RAW_MODE) {
2691 server_readbraw = true;
2692 server_writebraw = true;
2694 if (server_capabilities & CAP_LOCK_AND_READ) {
2695 server_lockread = true;
2698 if (server_capabilities & CAP_EXTENDED_SECURITY) {
2699 DATA_BLOB blob1, blob2;
2701 if (num_bytes < 16) {
2702 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2706 blob1 = data_blob_const(bytes, 16);
2707 GUID_from_data_blob(&blob1, &server_guid);
2709 blob1 = data_blob_const(bytes+16, num_bytes-16);
2710 blob2 = data_blob_dup_talloc(state, blob1);
2711 if (blob1.length > 0 &&
2712 tevent_req_nomem(blob2.data, req)) {
2715 server_gss_blob = blob2;
2720 if (num_bytes < key_len) {
2721 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2725 if (key_len != 0 && key_len != 8) {
2726 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2731 memcpy(server_challenge, bytes, 8);
2734 blob1 = data_blob_const(bytes+key_len, num_bytes-key_len);
2735 if (blob1.length > 0) {
2736 ret = pull_string_talloc(state,
2738 SVAL(inbuf, smb_flg2),
2740 blob1.data, blob1.length,
2743 tevent_req_oom(req);
2749 client_signing = "disabled";
2750 if (client_is_signing_allowed(cli)) {
2751 client_signing = "allowed";
2753 if (client_is_signing_mandatory(cli)) {
2754 client_signing = "required";
2757 server_signing = "not supported";
2759 server_allowed = false;
2760 if (server_security_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) {
2761 server_signing = "supported";
2762 server_allowed = true;
2765 server_mandatory = false;
2766 if (server_security_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) {
2767 server_signing = "required";
2768 server_mandatory = true;
2771 ok = cli_set_signing_negotiated(cli,
2775 DEBUG(1,("cli_negprot: SMB signing is required, "
2776 "but client[%s] and server[%s] mismatch\n",
2777 client_signing, server_signing));
2778 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
2782 } else if (protocol >= PROTOCOL_LANMAN1) {
2784 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2788 server_security_mode = SVAL(vwv + 1, 0);
2789 server_max_xmit = SVAL(vwv + 2, 0);
2790 server_max_mux = SVAL(vwv + 3, 0);
2791 server_session_key = IVAL(vwv + 6, 0);
2792 server_time_zone = SVALS(vwv + 10, 0);
2793 server_time_zone *= 60;
2794 /* this time is converted to GMT by make_unix_date */
2795 server_system_time = make_unix_date(
2796 (char *)(vwv + 8), server_time_zone);
2797 server_readbraw = ((SVAL(vwv + 5, 0) & 0x1) != 0);
2798 server_writebraw = ((SVAL(vwv + 5, 0) & 0x2) != 0);
2800 if (num_bytes != 0 && num_bytes != 8) {
2801 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2805 if (num_bytes == 8) {
2806 memcpy(server_challenge, bytes, 8);
2809 /* the old core protocol */
2810 server_time_zone = get_time_zone(time(NULL));
2811 server_system_time = 0;
2812 server_max_xmit = 1024;
2814 server_security_mode = 0;
2817 if (server_max_xmit < 1024) {
2818 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2822 if (server_max_mux < 1) {
2823 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2828 * Now calculate the negotiated capabilities
2829 * based on the mask for:
2830 * - client only flags
2831 * - flags used in both directions
2832 * - server only flags
2834 both_capabilities = client_capabilities & server_capabilities;
2835 capabilities = client_capabilities & SMB_CAP_CLIENT_MASK;
2836 capabilities |= both_capabilities & SMB_CAP_BOTH_MASK;
2837 capabilities |= server_capabilities & SMB_CAP_SERVER_MASK;
2839 max_xmit = MIN(client_max_xmit, server_max_xmit);
2841 if (server_workgroup) {
2842 cli->server_domain = talloc_strdup(cli, server_workgroup);
2843 if (tevent_req_nomem(cli->server_domain, req)) {
2848 cli->conn.protocol = protocol;
2850 cli->conn.smb1.server.capabilities = server_capabilities;
2851 cli->conn.smb1.capabilities = capabilities;
2853 cli->conn.smb1.server.max_xmit = server_max_xmit;
2854 cli->conn.smb1.max_xmit = max_xmit;
2856 cli->conn.smb1.server.max_mux = server_max_mux;
2858 cli->conn.smb1.server.security_mode = server_security_mode;
2860 cli->conn.smb1.server.readbraw = server_readbraw;
2861 cli->conn.smb1.server.writebraw = server_writebraw;
2862 cli->conn.smb1.server.lockread = server_lockread;
2863 cli->conn.smb1.server.writeunlock = server_writeunlock;
2865 cli->conn.smb1.server.session_key = server_session_key;
2867 talloc_steal(cli, server_gss_blob.data);
2868 cli->conn.smb1.server.gss_blob = server_gss_blob;
2869 cli->conn.smb1.server.guid = server_guid;
2870 memcpy(cli->conn.smb1.server.challenge, server_challenge, 8);
2871 cli->conn.smb1.server.workgroup = talloc_move(cli, &server_workgroup);
2873 cli->conn.smb1.server.time_zone = server_time_zone;
2874 cli->conn.smb1.server.system_time = server_system_time;
2876 tevent_req_done(req);
2879 NTSTATUS cli_negprot_recv(struct tevent_req *req)
2881 return tevent_req_simple_recv_ntstatus(req);
2884 NTSTATUS cli_negprot(struct cli_state *cli, enum protocol_types max_protocol)
2886 TALLOC_CTX *frame = talloc_stackframe();
2887 struct event_context *ev;
2888 struct tevent_req *req;
2889 NTSTATUS status = NT_STATUS_OK;
2891 if (cli_has_async_calls(cli)) {
2893 * Can't use sync call while an async call is in flight
2895 status = NT_STATUS_INVALID_PARAMETER;
2899 ev = event_context_init(frame);
2901 status = NT_STATUS_NO_MEMORY;
2905 req = cli_negprot_send(frame, ev, cli, max_protocol);
2907 status = NT_STATUS_NO_MEMORY;
2911 if (!tevent_req_poll(req, ev)) {
2912 status = map_nt_error_from_unix(errno);
2916 status = cli_negprot_recv(req);
2922 static NTSTATUS cli_connect_sock(const char *host, int name_type,
2923 const struct sockaddr_storage *pss,
2924 const char *myname, uint16_t port,
2925 int sec_timeout, int *pfd, uint16_t *pport)
2927 TALLOC_CTX *frame = talloc_stackframe();
2929 unsigned int i, num_addrs;
2930 const char **called_names;
2931 const char **calling_names;
2936 prog = getenv("LIBSMB_PROG");
2938 fd = sock_exec(prog);
2940 return map_nt_error_from_unix(errno);
2946 if ((pss == NULL) || is_zero_addr(pss)) {
2947 struct sockaddr_storage *addrs;
2948 status = resolve_name_list(talloc_tos(), host, name_type,
2949 &addrs, &num_addrs);
2950 if (!NT_STATUS_IS_OK(status)) {
2958 called_names = talloc_array(talloc_tos(), const char *, num_addrs);
2959 if (called_names == NULL) {
2960 status = NT_STATUS_NO_MEMORY;
2963 called_types = talloc_array(talloc_tos(), int, num_addrs);
2964 if (called_types == NULL) {
2965 status = NT_STATUS_NO_MEMORY;
2968 calling_names = talloc_array(talloc_tos(), const char *, num_addrs);
2969 if (calling_names == NULL) {
2970 status = NT_STATUS_NO_MEMORY;
2973 for (i=0; i<num_addrs; i++) {
2974 called_names[i] = host;
2975 called_types[i] = name_type;
2976 calling_names[i] = myname;
2978 status = smbsock_any_connect(pss, called_names, called_types,
2979 calling_names, NULL, num_addrs, port,
2980 sec_timeout, &fd, NULL, &port);
2981 if (!NT_STATUS_IS_OK(status)) {
2984 set_socket_options(fd, lp_socket_options());
2988 status = NT_STATUS_OK;
2994 NTSTATUS cli_connect_nb(const char *host, const struct sockaddr_storage *dest_ss,
2995 uint16_t port, int name_type, const char *myname,
2996 int signing_state, int flags, struct cli_state **pcli)
2998 TALLOC_CTX *frame = talloc_stackframe();
2999 struct cli_state *cli;
3000 NTSTATUS status = NT_STATUS_NO_MEMORY;
3005 desthost = talloc_strdup(talloc_tos(), host);
3006 if (desthost == NULL) {
3010 p = strchr(host, '#');
3012 name_type = strtol(p+1, NULL, 16);
3013 host = talloc_strndup(talloc_tos(), host, p - host);
3019 status = cli_connect_sock(host, name_type, dest_ss, myname, port,
3021 if (!NT_STATUS_IS_OK(status)) {
3025 cli = cli_state_create(NULL, fd, desthost, NULL, signing_state, flags);
3031 status = NT_STATUS_OK;
3038 establishes a connection to after the negprot.
3039 @param output_cli A fully initialised cli structure, non-null only on success
3040 @param dest_host The netbios name of the remote host
3041 @param dest_ss (optional) The the destination IP, NULL for name based lookup
3042 @param port (optional) The destination port (0 for default)
3044 NTSTATUS cli_start_connection(struct cli_state **output_cli,
3045 const char *my_name,
3046 const char *dest_host,
3047 const struct sockaddr_storage *dest_ss, int port,
3048 int signing_state, int flags)
3051 struct cli_state *cli;
3053 nt_status = cli_connect_nb(dest_host, dest_ss, port, 0x20, my_name,
3054 signing_state, flags, &cli);
3055 if (!NT_STATUS_IS_OK(nt_status)) {
3056 DEBUG(10, ("cli_connect_nb failed: %s\n",
3057 nt_errstr(nt_status)));
3061 nt_status = cli_negprot(cli, PROTOCOL_NT1);
3062 if (!NT_STATUS_IS_OK(nt_status)) {
3063 DEBUG(1, ("failed negprot: %s\n", nt_errstr(nt_status)));
3069 return NT_STATUS_OK;
3074 establishes a connection right up to doing tconX, password specified.
3075 @param output_cli A fully initialised cli structure, non-null only on success
3076 @param dest_host The netbios name of the remote host
3077 @param dest_ip (optional) The the destination IP, NULL for name based lookup
3078 @param port (optional) The destination port (0 for default)
3079 @param service (optional) The share to make the connection to. Should be 'unqualified' in any way.
3080 @param service_type The 'type' of serivice.
3081 @param user Username, unix string
3082 @param domain User's domain
3083 @param password User's password, unencrypted unix string.
3086 NTSTATUS cli_full_connection(struct cli_state **output_cli,
3087 const char *my_name,
3088 const char *dest_host,
3089 const struct sockaddr_storage *dest_ss, int port,
3090 const char *service, const char *service_type,
3091 const char *user, const char *domain,
3092 const char *password, int flags,
3096 struct cli_state *cli = NULL;
3097 int pw_len = password ? strlen(password)+1 : 0;
3101 if (password == NULL) {
3105 nt_status = cli_start_connection(&cli, my_name, dest_host,
3106 dest_ss, port, signing_state,
3109 if (!NT_STATUS_IS_OK(nt_status)) {
3113 nt_status = cli_session_setup(cli, user, password, pw_len, password,
3115 if (!NT_STATUS_IS_OK(nt_status)) {
3117 if (!(flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)) {
3118 DEBUG(1,("failed session setup with %s\n",
3119 nt_errstr(nt_status)));
3124 nt_status = cli_session_setup(cli, "", "", 0, "", 0, domain);
3125 if (!NT_STATUS_IS_OK(nt_status)) {
3126 DEBUG(1,("anonymous failed session setup with %s\n",
3127 nt_errstr(nt_status)));
3134 nt_status = cli_tcon_andx(cli, service, service_type, password,
3136 if (!NT_STATUS_IS_OK(nt_status)) {
3137 DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status)));
3139 if (NT_STATUS_IS_OK(nt_status)) {
3140 nt_status = NT_STATUS_UNSUCCESSFUL;
3146 nt_status = cli_init_creds(cli, user, domain, password);
3147 if (!NT_STATUS_IS_OK(nt_status)) {
3153 return NT_STATUS_OK;
3156 /****************************************************************************
3157 Send an old style tcon.
3158 ****************************************************************************/
3159 NTSTATUS cli_raw_tcon(struct cli_state *cli,
3160 const char *service, const char *pass, const char *dev,
3161 uint16 *max_xmit, uint16 *tid)
3163 struct tevent_req *req;
3168 if (!lp_client_plaintext_auth() && (*pass)) {
3169 DEBUG(1, ("Server requested plaintext password but 'client "
3170 "plaintext auth' is disabled\n"));
3171 return NT_STATUS_ACCESS_DENIED;
3174 bytes = talloc_array(talloc_tos(), uint8_t, 0);
3175 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3176 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
3177 service, strlen(service)+1, NULL);
3178 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3179 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
3180 pass, strlen(pass)+1, NULL);
3181 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3182 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
3183 dev, strlen(dev)+1, NULL);
3185 status = cli_smb(talloc_tos(), cli, SMBtcon, 0, 0, NULL,
3186 talloc_get_size(bytes), bytes, &req,
3187 2, NULL, &ret_vwv, NULL, NULL);
3188 if (!NT_STATUS_IS_OK(status)) {
3192 *max_xmit = SVAL(ret_vwv + 0, 0);
3193 *tid = SVAL(ret_vwv + 1, 0);
3195 return NT_STATUS_OK;
3198 /* Return a cli_state pointing at the IPC$ share for the given server */
3200 struct cli_state *get_ipc_connect(char *server,
3201 struct sockaddr_storage *server_ss,
3202 const struct user_auth_info *user_info)
3204 struct cli_state *cli;
3206 uint32_t flags = CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
3208 if (user_info->use_kerberos) {
3209 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
3212 nt_status = cli_full_connection(&cli, NULL, server, server_ss, 0, "IPC$", "IPC",
3213 user_info->username ? user_info->username : "",
3215 user_info->password ? user_info->password : "",
3219 if (NT_STATUS_IS_OK(nt_status)) {
3221 } else if (is_ipaddress(server)) {
3222 /* windows 9* needs a correct NMB name for connections */
3223 fstring remote_name;
3225 if (name_status_find("*", 0, 0, server_ss, remote_name)) {
3226 cli = get_ipc_connect(remote_name, server_ss, user_info);
3235 * Given the IP address of a master browser on the network, return its
3236 * workgroup and connect to it.
3238 * This function is provided to allow additional processing beyond what
3239 * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
3240 * browsers and obtain each master browsers' list of domains (in case the
3241 * first master browser is recently on the network and has not yet
3242 * synchronized with other master browsers and therefore does not yet have the
3243 * entire network browse list)
3246 struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx,
3247 struct sockaddr_storage *mb_ip,
3248 const struct user_auth_info *user_info,
3249 char **pp_workgroup_out)
3251 char addr[INET6_ADDRSTRLEN];
3253 struct cli_state *cli;
3254 struct sockaddr_storage server_ss;
3256 *pp_workgroup_out = NULL;
3258 print_sockaddr(addr, sizeof(addr), mb_ip);
3259 DEBUG(99, ("Looking up name of master browser %s\n",
3263 * Do a name status query to find out the name of the master browser.
3264 * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
3265 * master browser will not respond to a wildcard query (or, at least,
3266 * an NT4 server acting as the domain master browser will not).
3268 * We might be able to use ONLY the query on MSBROWSE, but that's not
3269 * yet been tested with all Windows versions, so until it is, leave
3270 * the original wildcard query as the first choice and fall back to
3271 * MSBROWSE if the wildcard query fails.
3273 if (!name_status_find("*", 0, 0x1d, mb_ip, name) &&
3274 !name_status_find(MSBROWSE, 1, 0x1d, mb_ip, name)) {
3276 DEBUG(99, ("Could not retrieve name status for %s\n",
3281 if (!find_master_ip(name, &server_ss)) {
3282 DEBUG(99, ("Could not find master ip for %s\n", name));
3286 *pp_workgroup_out = talloc_strdup(ctx, name);
3288 DEBUG(4, ("found master browser %s, %s\n", name, addr));
3290 print_sockaddr(addr, sizeof(addr), &server_ss);
3291 cli = get_ipc_connect(addr, &server_ss, user_info);
3297 * Return the IP address and workgroup of a master browser on the network, and
3301 struct cli_state *get_ipc_connect_master_ip_bcast(TALLOC_CTX *ctx,
3302 const struct user_auth_info *user_info,
3303 char **pp_workgroup_out)
3305 struct sockaddr_storage *ip_list;
3306 struct cli_state *cli;
3310 *pp_workgroup_out = NULL;
3312 DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
3314 /* Go looking for workgroups by broadcasting on the local network */
3316 status = name_resolve_bcast(MSBROWSE, 1, talloc_tos(),
3318 if (!NT_STATUS_IS_OK(status)) {
3319 DEBUG(99, ("No master browsers responded: %s\n",
3320 nt_errstr(status)));
3324 for (i = 0; i < count; i++) {
3325 char addr[INET6_ADDRSTRLEN];
3326 print_sockaddr(addr, sizeof(addr), &ip_list[i]);
3327 DEBUG(99, ("Found master browser %s\n", addr));
3329 cli = get_ipc_connect_master_ip(ctx, &ip_list[i],
3330 user_info, pp_workgroup_out);