2 Unix SMB/CIFS implementation.
3 client connect/disconnect routines
4 Copyright (C) Andrew Tridgell 1994-1998
5 Copyright (C) Andrew Bartlett 2001-2003
6 Copyright (C) Volker Lendecke 2011
7 Copyright (C) Jeremy Allison 2011
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "libsmb/libsmb.h"
25 #include "popt_common.h"
26 #include "../libcli/auth/libcli_auth.h"
27 #include "../libcli/auth/spnego.h"
29 #include "../libcli/auth/ntlmssp.h"
30 #include "libads/kerberos_proto.h"
32 #include "../lib/util/tevent_ntstatus.h"
33 #include "async_smb.h"
34 #include "libsmb/nmblib.h"
41 {PROTOCOL_CORE, "PC NETWORK PROGRAM 1.0"},
42 {PROTOCOL_COREPLUS, "MICROSOFT NETWORKS 1.03"},
43 {PROTOCOL_LANMAN1, "MICROSOFT NETWORKS 3.0"},
44 {PROTOCOL_LANMAN1, "LANMAN1.0"},
45 {PROTOCOL_LANMAN2, "LM1.2X002"},
46 {PROTOCOL_LANMAN2, "DOS LANMAN2.1"},
47 {PROTOCOL_LANMAN2, "LANMAN2.1"},
48 {PROTOCOL_LANMAN2, "Samba"},
49 {PROTOCOL_NT1, "NT LANMAN 1.0"},
50 {PROTOCOL_NT1, "NT LM 0.12"},
53 #define STAR_SMBSERVER "*SMBSERVER"
55 /********************************************************
56 Utility function to ensure we always return at least
57 a valid char * pointer to an empty string for the
58 cli->server_os, cli->server_type and cli->server_domain
60 *******************************************************/
62 static NTSTATUS smb_bytes_talloc_string(TALLOC_CTX *mem_ctx,
69 *destlen = clistr_pull_talloc(mem_ctx,
71 SVAL(inbuf, smb_flg2),
77 return NT_STATUS_NO_MEMORY;
81 *dest = talloc_strdup(mem_ctx, "");
83 return NT_STATUS_NO_MEMORY;
90 * Set the user session key for a connection
91 * @param cli The cli structure to add it too
92 * @param session_key The session key used. (A copy of this is taken for the cli struct)
96 static void cli_set_session_key (struct cli_state *cli, const DATA_BLOB session_key)
98 cli->user_session_key = data_blob(session_key.data, session_key.length);
101 /****************************************************************************
102 Do an old lanman2 style session setup.
103 ****************************************************************************/
105 struct cli_session_setup_lanman2_state {
106 struct cli_state *cli;
111 static void cli_session_setup_lanman2_done(struct tevent_req *subreq);
113 static struct tevent_req *cli_session_setup_lanman2_send(
114 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
115 struct cli_state *cli, const char *user,
116 const char *pass, size_t passlen,
117 const char *workgroup)
119 struct tevent_req *req, *subreq;
120 struct cli_session_setup_lanman2_state *state;
121 DATA_BLOB lm_response = data_blob_null;
126 req = tevent_req_create(mem_ctx, &state,
127 struct cli_session_setup_lanman2_state);
136 * LANMAN servers predate NT status codes and Unicode and
137 * ignore those smb flags so we must disable the corresponding
138 * default capabilities that would otherwise cause the Unicode
139 * and NT Status flags to be set (and even returned by the
143 cli->capabilities &= ~(CAP_UNICODE | CAP_STATUS32);
146 * if in share level security then don't send a password now
148 if (!(cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) {
153 && (cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)
156 * Encrypted mode needed, and non encrypted password
159 lm_response = data_blob(NULL, 24);
160 if (tevent_req_nomem(lm_response.data, req)) {
161 return tevent_req_post(req, ev);
164 if (!SMBencrypt(pass, cli->secblob.data,
165 (uint8_t *)lm_response.data)) {
166 DEBUG(1, ("Password is > 14 chars in length, and is "
167 "therefore incompatible with Lanman "
168 "authentication\n"));
169 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
170 return tevent_req_post(req, ev);
172 } else if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)
175 * Encrypted mode needed, and encrypted password
178 lm_response = data_blob(pass, passlen);
179 if (tevent_req_nomem(lm_response.data, req)) {
180 return tevent_req_post(req, ev);
182 } else if (passlen > 0) {
184 size_t converted_size;
186 * Plaintext mode needed, assume plaintext supplied.
188 buf = talloc_array(talloc_tos(), uint8_t, 0);
189 buf = smb_bytes_push_str(buf, cli_ucs2(cli), pass, passlen+1,
191 if (tevent_req_nomem(buf, req)) {
192 return tevent_req_post(req, ev);
194 lm_response = data_blob(pass, passlen);
196 if (tevent_req_nomem(lm_response.data, req)) {
197 return tevent_req_post(req, ev);
201 SCVAL(vwv+0, 0, 0xff);
204 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
207 SIVAL(vwv+5, 0, cli->sesskey);
208 SSVAL(vwv+7, 0, lm_response.length);
210 bytes = talloc_array(state, uint8_t, lm_response.length);
211 if (tevent_req_nomem(bytes, req)) {
212 return tevent_req_post(req, ev);
214 if (lm_response.length != 0) {
215 memcpy(bytes, lm_response.data, lm_response.length);
217 data_blob_free(&lm_response);
219 tmp = talloc_strdup_upper(talloc_tos(), user);
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,
227 tmp = talloc_strdup_upper(talloc_tos(), workgroup);
228 if (tevent_req_nomem(tmp, req)) {
229 return tevent_req_post(req, ev);
231 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), tmp, strlen(tmp)+1,
233 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Unix", 5, NULL);
234 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Samba", 6, NULL);
236 if (tevent_req_nomem(bytes, req)) {
237 return tevent_req_post(req, ev);
240 subreq = cli_smb_send(state, ev, cli, SMBsesssetupX, 0, 10, vwv,
241 talloc_get_size(bytes), bytes);
242 if (tevent_req_nomem(subreq, req)) {
243 return tevent_req_post(req, ev);
245 tevent_req_set_callback(subreq, cli_session_setup_lanman2_done, req);
249 static void cli_session_setup_lanman2_done(struct tevent_req *subreq)
251 struct tevent_req *req = tevent_req_callback_data(
252 subreq, struct tevent_req);
253 struct cli_session_setup_lanman2_state *state = tevent_req_data(
254 req, struct cli_session_setup_lanman2_state);
255 struct cli_state *cli = state->cli;
266 status = cli_smb_recv(subreq, state, &in, 3, &wct, &vwv,
269 if (!NT_STATUS_IS_OK(status)) {
270 tevent_req_nterror(req, status);
277 cli_state_set_uid(state->cli, SVAL(inbuf, smb_uid));
278 cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0);
280 status = smb_bytes_talloc_string(cli,
287 if (!NT_STATUS_IS_OK(status)) {
288 tevent_req_nterror(req, status);
293 status = smb_bytes_talloc_string(cli,
300 if (!NT_STATUS_IS_OK(status)) {
301 tevent_req_nterror(req, status);
306 status = smb_bytes_talloc_string(cli,
313 if (!NT_STATUS_IS_OK(status)) {
314 tevent_req_nterror(req, status);
319 if (strstr(cli->server_type, "Samba")) {
320 cli->is_samba = True;
322 status = cli_set_username(cli, state->user);
323 if (tevent_req_nterror(req, status)) {
326 tevent_req_done(req);
329 static NTSTATUS cli_session_setup_lanman2_recv(struct tevent_req *req)
331 return tevent_req_simple_recv_ntstatus(req);
334 static NTSTATUS cli_session_setup_lanman2(struct cli_state *cli, const char *user,
335 const char *pass, size_t passlen,
336 const char *workgroup)
338 TALLOC_CTX *frame = talloc_stackframe();
339 struct event_context *ev;
340 struct tevent_req *req;
341 NTSTATUS status = NT_STATUS_NO_MEMORY;
343 if (cli_has_async_calls(cli)) {
345 * Can't use sync call while an async call is in flight
347 status = NT_STATUS_INVALID_PARAMETER;
350 ev = event_context_init(frame);
354 req = cli_session_setup_lanman2_send(frame, ev, cli, user, pass, passlen,
359 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
362 status = cli_session_setup_lanman2_recv(req);
368 /****************************************************************************
369 Work out suitable capabilities to offer the server.
370 ****************************************************************************/
372 static uint32 cli_session_setup_capabilities(struct cli_state *cli)
374 uint32 capabilities = CAP_NT_SMBS;
376 if (!cli->force_dos_errors)
377 capabilities |= CAP_STATUS32;
379 if (cli->use_level_II_oplocks)
380 capabilities |= CAP_LEVEL_II_OPLOCKS;
382 capabilities |= (cli_state_capabilities(cli) & (CAP_UNICODE|CAP_LARGE_FILES|CAP_LARGE_READX|CAP_LARGE_WRITEX|CAP_DFS));
386 /****************************************************************************
387 Do a NT1 guest session setup.
388 ****************************************************************************/
390 struct cli_session_setup_guest_state {
391 struct cli_state *cli;
396 static void cli_session_setup_guest_done(struct tevent_req *subreq);
398 struct tevent_req *cli_session_setup_guest_create(TALLOC_CTX *mem_ctx,
399 struct event_context *ev,
400 struct cli_state *cli,
401 struct tevent_req **psmbreq)
403 struct tevent_req *req, *subreq;
404 struct cli_session_setup_guest_state *state;
408 req = tevent_req_create(mem_ctx, &state,
409 struct cli_session_setup_guest_state);
416 SCVAL(vwv+0, 0, 0xFF);
419 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
421 SSVAL(vwv+4, 0, cli_state_get_vc_num(cli));
422 SIVAL(vwv+5, 0, cli->sesskey);
427 SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli));
429 bytes = talloc_array(state, uint8_t, 0);
431 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "", 1, /* username */
433 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "", 1, /* workgroup */
435 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Unix", 5, NULL);
436 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Samba", 6, NULL);
443 state->bytes.iov_base = (void *)bytes;
444 state->bytes.iov_len = talloc_get_size(bytes);
446 subreq = cli_smb_req_create(state, ev, cli, SMBsesssetupX, 0, 13, vwv,
448 if (subreq == NULL) {
452 tevent_req_set_callback(subreq, cli_session_setup_guest_done, req);
457 struct tevent_req *cli_session_setup_guest_send(TALLOC_CTX *mem_ctx,
458 struct event_context *ev,
459 struct cli_state *cli)
461 struct tevent_req *req, *subreq;
464 req = cli_session_setup_guest_create(mem_ctx, ev, cli, &subreq);
469 status = cli_smb_req_send(subreq);
470 if (NT_STATUS_IS_OK(status)) {
471 tevent_req_nterror(req, status);
472 return tevent_req_post(req, ev);
477 static void cli_session_setup_guest_done(struct tevent_req *subreq)
479 struct tevent_req *req = tevent_req_callback_data(
480 subreq, struct tevent_req);
481 struct cli_session_setup_guest_state *state = tevent_req_data(
482 req, struct cli_session_setup_guest_state);
483 struct cli_state *cli = state->cli;
494 status = cli_smb_recv(subreq, state, &in, 3, &wct, &vwv,
497 if (!NT_STATUS_IS_OK(status)) {
498 tevent_req_nterror(req, status);
505 cli_state_set_uid(state->cli, SVAL(inbuf, smb_uid));
506 cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0);
508 status = smb_bytes_talloc_string(cli,
515 if (!NT_STATUS_IS_OK(status)) {
516 tevent_req_nterror(req, status);
521 status = smb_bytes_talloc_string(cli,
528 if (!NT_STATUS_IS_OK(status)) {
529 tevent_req_nterror(req, status);
534 status = smb_bytes_talloc_string(cli,
541 if (!NT_STATUS_IS_OK(status)) {
542 tevent_req_nterror(req, status);
547 if (strstr(cli->server_type, "Samba")) {
548 cli->is_samba = True;
551 status = cli_set_username(cli, "");
552 if (!NT_STATUS_IS_OK(status)) {
553 tevent_req_nterror(req, status);
556 tevent_req_done(req);
559 NTSTATUS cli_session_setup_guest_recv(struct tevent_req *req)
561 return tevent_req_simple_recv_ntstatus(req);
564 static NTSTATUS cli_session_setup_guest(struct cli_state *cli)
566 TALLOC_CTX *frame = talloc_stackframe();
567 struct event_context *ev;
568 struct tevent_req *req;
569 NTSTATUS status = NT_STATUS_OK;
571 if (cli_has_async_calls(cli)) {
573 * Can't use sync call while an async call is in flight
575 status = NT_STATUS_INVALID_PARAMETER;
579 ev = event_context_init(frame);
581 status = NT_STATUS_NO_MEMORY;
585 req = cli_session_setup_guest_send(frame, ev, cli);
587 status = NT_STATUS_NO_MEMORY;
591 if (!tevent_req_poll(req, ev)) {
592 status = map_nt_error_from_unix(errno);
596 status = cli_session_setup_guest_recv(req);
602 /****************************************************************************
603 Do a NT1 plaintext session setup.
604 ****************************************************************************/
606 struct cli_session_setup_plain_state {
607 struct cli_state *cli;
612 static void cli_session_setup_plain_done(struct tevent_req *subreq);
614 static struct tevent_req *cli_session_setup_plain_send(
615 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
616 struct cli_state *cli,
617 const char *user, const char *pass, const char *workgroup)
619 struct tevent_req *req, *subreq;
620 struct cli_session_setup_plain_state *state;
626 req = tevent_req_create(mem_ctx, &state,
627 struct cli_session_setup_plain_state);
635 SCVAL(vwv+0, 0, 0xff);
638 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
640 SSVAL(vwv+4, 0, cli_state_get_vc_num(cli));
641 SIVAL(vwv+5, 0, cli->sesskey);
646 SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli));
648 bytes = talloc_array(state, uint8_t, 0);
649 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), pass, strlen(pass)+1,
651 if (tevent_req_nomem(bytes, req)) {
652 return tevent_req_post(req, ev);
654 SSVAL(vwv + (cli_ucs2(cli) ? 8 : 7), 0, passlen);
656 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
657 user, strlen(user)+1, NULL);
658 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
659 workgroup, strlen(workgroup)+1, NULL);
660 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
663 version = talloc_asprintf(talloc_tos(), "Samba %s",
664 samba_version_string());
665 if (tevent_req_nomem(version, req)){
666 return tevent_req_post(req, ev);
668 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
669 version, strlen(version)+1, NULL);
670 TALLOC_FREE(version);
672 if (tevent_req_nomem(bytes, req)) {
673 return tevent_req_post(req, ev);
676 subreq = cli_smb_send(state, ev, cli, SMBsesssetupX, 0, 13, vwv,
677 talloc_get_size(bytes), bytes);
678 if (tevent_req_nomem(subreq, req)) {
679 return tevent_req_post(req, ev);
681 tevent_req_set_callback(subreq, cli_session_setup_plain_done, req);
685 static void cli_session_setup_plain_done(struct tevent_req *subreq)
687 struct tevent_req *req = tevent_req_callback_data(
688 subreq, struct tevent_req);
689 struct cli_session_setup_plain_state *state = tevent_req_data(
690 req, struct cli_session_setup_plain_state);
691 struct cli_state *cli = state->cli;
702 status = cli_smb_recv(subreq, state, &in, 3, &wct, &vwv,
705 if (tevent_req_nterror(req, status)) {
712 cli_state_set_uid(state->cli, SVAL(inbuf, smb_uid));
713 cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0);
715 status = smb_bytes_talloc_string(cli,
722 if (!NT_STATUS_IS_OK(status)) {
723 tevent_req_nterror(req, status);
728 status = smb_bytes_talloc_string(cli,
735 if (!NT_STATUS_IS_OK(status)) {
736 tevent_req_nterror(req, status);
741 status = smb_bytes_talloc_string(cli,
748 if (!NT_STATUS_IS_OK(status)) {
749 tevent_req_nterror(req, status);
754 status = cli_set_username(cli, state->user);
755 if (tevent_req_nterror(req, status)) {
758 if (strstr(cli->server_type, "Samba")) {
759 cli->is_samba = True;
761 tevent_req_done(req);
764 static NTSTATUS cli_session_setup_plain_recv(struct tevent_req *req)
766 return tevent_req_simple_recv_ntstatus(req);
769 static NTSTATUS cli_session_setup_plain(struct cli_state *cli,
770 const char *user, const char *pass,
771 const char *workgroup)
773 TALLOC_CTX *frame = talloc_stackframe();
774 struct event_context *ev;
775 struct tevent_req *req;
776 NTSTATUS status = NT_STATUS_NO_MEMORY;
778 if (cli_has_async_calls(cli)) {
780 * Can't use sync call while an async call is in flight
782 status = NT_STATUS_INVALID_PARAMETER;
785 ev = event_context_init(frame);
789 req = cli_session_setup_plain_send(frame, ev, cli, user, pass,
794 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
797 status = cli_session_setup_plain_recv(req);
803 /****************************************************************************
804 do a NT1 NTLM/LM encrypted session setup - for when extended security
806 @param cli client state to create do session setup on
808 @param pass *either* cleartext password (passlen !=24) or LM response.
809 @param ntpass NT response, implies ntpasslen >=24, implies pass is not clear
810 @param workgroup The user's domain.
811 ****************************************************************************/
813 struct cli_session_setup_nt1_state {
814 struct cli_state *cli;
817 DATA_BLOB session_key;
821 static void cli_session_setup_nt1_done(struct tevent_req *subreq);
823 static struct tevent_req *cli_session_setup_nt1_send(
824 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
825 struct cli_state *cli, const char *user,
826 const char *pass, size_t passlen,
827 const char *ntpass, size_t ntpasslen,
828 const char *workgroup)
830 struct tevent_req *req, *subreq;
831 struct cli_session_setup_nt1_state *state;
832 DATA_BLOB lm_response = data_blob_null;
833 DATA_BLOB nt_response = data_blob_null;
834 DATA_BLOB session_key = data_blob_null;
837 char *workgroup_upper;
839 req = tevent_req_create(mem_ctx, &state,
840 struct cli_session_setup_nt1_state);
849 /* do nothing - guest login */
850 } else if (passlen != 24) {
851 if (lp_client_ntlmv2_auth()) {
852 DATA_BLOB server_chal;
853 DATA_BLOB names_blob;
855 server_chal = data_blob(cli->secblob.data,
856 MIN(cli->secblob.length, 8));
857 if (tevent_req_nomem(server_chal.data, req)) {
858 return tevent_req_post(req, ev);
862 * note that the 'workgroup' here is a best
863 * guess - we don't know the server's domain
864 * at this point. Windows clients also don't
867 names_blob = NTLMv2_generate_names_blob(
868 NULL, NULL, workgroup);
870 if (tevent_req_nomem(names_blob.data, req)) {
871 return tevent_req_post(req, ev);
874 if (!SMBNTLMv2encrypt(NULL, user, workgroup, pass,
875 &server_chal, &names_blob,
876 &lm_response, &nt_response,
877 NULL, &session_key)) {
878 data_blob_free(&names_blob);
879 data_blob_free(&server_chal);
881 req, NT_STATUS_ACCESS_DENIED);
882 return tevent_req_post(req, ev);
884 data_blob_free(&names_blob);
885 data_blob_free(&server_chal);
889 E_md4hash(pass, nt_hash);
892 nt_response = data_blob_null;
894 nt_response = data_blob(NULL, 24);
895 if (tevent_req_nomem(nt_response.data, req)) {
896 return tevent_req_post(req, ev);
899 SMBNTencrypt(pass, cli->secblob.data,
902 /* non encrypted password supplied. Ignore ntpass. */
903 if (lp_client_lanman_auth()) {
905 lm_response = data_blob(NULL, 24);
906 if (tevent_req_nomem(lm_response.data, req)) {
907 return tevent_req_post(req, ev);
910 if (!SMBencrypt(pass,cli->secblob.data,
913 * Oops, the LM response is
914 * invalid, just put the NT
915 * response there instead
917 data_blob_free(&lm_response);
918 lm_response = data_blob(
924 * LM disabled, place NT# in LM field
927 lm_response = data_blob(
928 nt_response.data, nt_response.length);
931 if (tevent_req_nomem(lm_response.data, req)) {
932 return tevent_req_post(req, ev);
935 session_key = data_blob(NULL, 16);
936 if (tevent_req_nomem(session_key.data, req)) {
937 return tevent_req_post(req, ev);
940 E_deshash(pass, session_key.data);
941 memset(&session_key.data[8], '\0', 8);
943 SMBsesskeygen_ntv1(nt_hash, session_key.data);
946 cli_temp_set_signing(cli);
948 /* pre-encrypted password supplied. Only used for
949 security=server, can't do
950 signing because we don't have original key */
952 lm_response = data_blob(pass, passlen);
953 if (tevent_req_nomem(lm_response.data, req)) {
954 return tevent_req_post(req, ev);
957 nt_response = data_blob(ntpass, ntpasslen);
958 if (tevent_req_nomem(nt_response.data, req)) {
959 return tevent_req_post(req, ev);
964 state->response = data_blob_talloc(
965 state, lm_response.data, lm_response.length);
967 state->response = data_blob_talloc(
968 state, nt_response.data, nt_response.length);
970 if (tevent_req_nomem(state->response.data, req)) {
971 return tevent_req_post(req, ev);
974 if (session_key.data) {
975 state->session_key = data_blob_talloc(
976 state, session_key.data, session_key.length);
977 if (tevent_req_nomem(state->session_key.data, req)) {
978 return tevent_req_post(req, ev);
981 data_blob_free(&session_key);
983 SCVAL(vwv+0, 0, 0xff);
986 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
988 SSVAL(vwv+4, 0, cli_state_get_vc_num(cli));
989 SIVAL(vwv+5, 0, cli->sesskey);
990 SSVAL(vwv+7, 0, lm_response.length);
991 SSVAL(vwv+8, 0, nt_response.length);
994 SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli));
996 bytes = talloc_array(state, uint8_t,
997 lm_response.length + nt_response.length);
998 if (tevent_req_nomem(bytes, req)) {
999 return tevent_req_post(req, ev);
1001 if (lm_response.length != 0) {
1002 memcpy(bytes, lm_response.data, lm_response.length);
1004 if (nt_response.length != 0) {
1005 memcpy(bytes + lm_response.length,
1006 nt_response.data, nt_response.length);
1008 data_blob_free(&lm_response);
1009 data_blob_free(&nt_response);
1011 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
1012 user, strlen(user)+1, NULL);
1015 * Upper case here might help some NTLMv2 implementations
1017 workgroup_upper = talloc_strdup_upper(talloc_tos(), workgroup);
1018 if (tevent_req_nomem(workgroup_upper, req)) {
1019 return tevent_req_post(req, ev);
1021 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
1022 workgroup_upper, strlen(workgroup_upper)+1,
1024 TALLOC_FREE(workgroup_upper);
1026 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Unix", 5, NULL);
1027 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Samba", 6, NULL);
1028 if (tevent_req_nomem(bytes, req)) {
1029 return tevent_req_post(req, ev);
1032 subreq = cli_smb_send(state, ev, cli, SMBsesssetupX, 0, 13, vwv,
1033 talloc_get_size(bytes), bytes);
1034 if (tevent_req_nomem(subreq, req)) {
1035 return tevent_req_post(req, ev);
1037 tevent_req_set_callback(subreq, cli_session_setup_nt1_done, req);
1041 static void cli_session_setup_nt1_done(struct tevent_req *subreq)
1043 struct tevent_req *req = tevent_req_callback_data(
1044 subreq, struct tevent_req);
1045 struct cli_session_setup_nt1_state *state = tevent_req_data(
1046 req, struct cli_session_setup_nt1_state);
1047 struct cli_state *cli = state->cli;
1058 status = cli_smb_recv(subreq, state, &in, 3, &wct, &vwv,
1059 &num_bytes, &bytes);
1060 TALLOC_FREE(subreq);
1061 if (!NT_STATUS_IS_OK(status)) {
1062 tevent_req_nterror(req, status);
1069 cli_state_set_uid(state->cli, SVAL(inbuf, smb_uid));
1070 cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0);
1072 status = smb_bytes_talloc_string(cli,
1078 if (!NT_STATUS_IS_OK(status)) {
1079 tevent_req_nterror(req, status);
1084 status = smb_bytes_talloc_string(cli,
1090 if (!NT_STATUS_IS_OK(status)) {
1091 tevent_req_nterror(req, status);
1096 status = smb_bytes_talloc_string(cli,
1098 &cli->server_domain,
1102 if (!NT_STATUS_IS_OK(status)) {
1103 tevent_req_nterror(req, status);
1108 if (strstr(cli->server_type, "Samba")) {
1109 cli->is_samba = True;
1112 status = cli_set_username(cli, state->user);
1113 if (tevent_req_nterror(req, status)) {
1116 if (cli_simple_set_signing(cli, state->session_key, state->response)
1117 && !cli_check_sign_mac(cli, (char *)in, 1)) {
1118 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1121 if (state->session_key.data) {
1122 /* Have plaintext orginal */
1123 cli_set_session_key(cli, state->session_key);
1125 tevent_req_done(req);
1128 static NTSTATUS cli_session_setup_nt1_recv(struct tevent_req *req)
1130 return tevent_req_simple_recv_ntstatus(req);
1133 static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user,
1134 const char *pass, size_t passlen,
1135 const char *ntpass, size_t ntpasslen,
1136 const char *workgroup)
1138 TALLOC_CTX *frame = talloc_stackframe();
1139 struct event_context *ev;
1140 struct tevent_req *req;
1141 NTSTATUS status = NT_STATUS_NO_MEMORY;
1143 if (cli_has_async_calls(cli)) {
1145 * Can't use sync call while an async call is in flight
1147 status = NT_STATUS_INVALID_PARAMETER;
1150 ev = event_context_init(frame);
1154 req = cli_session_setup_nt1_send(frame, ev, cli, user, pass, passlen,
1155 ntpass, ntpasslen, workgroup);
1159 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1162 status = cli_session_setup_nt1_recv(req);
1168 /* The following is calculated from :
1170 * (smb_wcnt * 2) = 24 (smb_wcnt == 12 in cli_session_setup_blob_send() )
1171 * (strlen("Unix") + 1 + strlen("Samba") + 1) * 2 = 22 (unicode strings at
1175 #define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22)
1177 struct cli_sesssetup_blob_state {
1178 struct tevent_context *ev;
1179 struct cli_state *cli;
1181 uint16_t max_blob_size;
1190 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state *state,
1191 struct tevent_req **psubreq);
1192 static void cli_sesssetup_blob_done(struct tevent_req *subreq);
1194 static struct tevent_req *cli_sesssetup_blob_send(TALLOC_CTX *mem_ctx,
1195 struct tevent_context *ev,
1196 struct cli_state *cli,
1199 struct tevent_req *req, *subreq;
1200 struct cli_sesssetup_blob_state *state;
1201 uint32_t usable_space;
1203 req = tevent_req_create(mem_ctx, &state,
1204 struct cli_sesssetup_blob_state);
1212 usable_space = cli_state_available_size(cli,
1213 BASE_SESSSETUP_BLOB_PACKET_SIZE);
1215 if (usable_space == 0) {
1216 DEBUG(1, ("cli_session_setup_blob: cli->max_xmit too small "
1217 "(not possible to send %u bytes)\n",
1218 BASE_SESSSETUP_BLOB_PACKET_SIZE + 1));
1219 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1220 return tevent_req_post(req, ev);
1222 state->max_blob_size = MIN(usable_space, 0xFFFF);
1224 if (!cli_sesssetup_blob_next(state, &subreq)) {
1225 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1226 return tevent_req_post(req, ev);
1228 tevent_req_set_callback(subreq, cli_sesssetup_blob_done, req);
1232 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state *state,
1233 struct tevent_req **psubreq)
1235 struct tevent_req *subreq;
1238 SCVAL(state->vwv+0, 0, 0xFF);
1239 SCVAL(state->vwv+0, 1, 0);
1240 SSVAL(state->vwv+1, 0, 0);
1241 SSVAL(state->vwv+2, 0, CLI_BUFFER_SIZE);
1242 SSVAL(state->vwv+3, 0, 2);
1243 SSVAL(state->vwv+4, 0, 1);
1244 SIVAL(state->vwv+5, 0, 0);
1246 thistime = MIN(state->blob.length, state->max_blob_size);
1247 SSVAL(state->vwv+7, 0, thistime);
1249 SSVAL(state->vwv+8, 0, 0);
1250 SSVAL(state->vwv+9, 0, 0);
1251 SIVAL(state->vwv+10, 0,
1252 cli_session_setup_capabilities(state->cli)
1253 | CAP_EXTENDED_SECURITY);
1255 state->buf = (uint8_t *)talloc_memdup(state, state->blob.data,
1257 if (state->buf == NULL) {
1260 state->blob.data += thistime;
1261 state->blob.length -= thistime;
1263 state->buf = smb_bytes_push_str(state->buf, cli_ucs2(state->cli),
1265 state->buf = smb_bytes_push_str(state->buf, cli_ucs2(state->cli),
1267 if (state->buf == NULL) {
1270 subreq = cli_smb_send(state, state->ev, state->cli, SMBsesssetupX, 0,
1272 talloc_get_size(state->buf), state->buf);
1273 if (subreq == NULL) {
1280 static void cli_sesssetup_blob_done(struct tevent_req *subreq)
1282 struct tevent_req *req = tevent_req_callback_data(
1283 subreq, struct tevent_req);
1284 struct cli_sesssetup_blob_state *state = tevent_req_data(
1285 req, struct cli_sesssetup_blob_state);
1286 struct cli_state *cli = state->cli;
1293 uint16_t blob_length;
1297 status = cli_smb_recv(subreq, state, &inbuf, 4, &wct, &vwv,
1298 &num_bytes, &bytes);
1299 TALLOC_FREE(subreq);
1300 if (!NT_STATUS_IS_OK(status)
1301 && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1302 tevent_req_nterror(req, status);
1306 state->status = status;
1307 TALLOC_FREE(state->buf);
1309 state->inbuf = (char *)inbuf;
1310 cli_state_set_uid(state->cli, SVAL(inbuf, smb_uid));
1311 cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0);
1313 blob_length = SVAL(vwv+3, 0);
1314 if (blob_length > num_bytes) {
1315 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1318 state->ret_blob = data_blob_const(bytes, blob_length);
1320 p = bytes + blob_length;
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,
1342 if (!NT_STATUS_IS_OK(status)) {
1343 tevent_req_nterror(req, status);
1348 status = smb_bytes_talloc_string(cli,
1350 &cli->server_domain,
1355 if (!NT_STATUS_IS_OK(status)) {
1356 tevent_req_nterror(req, status);
1361 if (strstr(cli->server_type, "Samba")) {
1362 cli->is_samba = True;
1365 if (state->blob.length != 0) {
1369 if (!cli_sesssetup_blob_next(state, &subreq)) {
1370 tevent_req_oom(req);
1373 tevent_req_set_callback(subreq, cli_sesssetup_blob_done, req);
1376 tevent_req_done(req);
1379 static NTSTATUS cli_sesssetup_blob_recv(struct tevent_req *req,
1380 TALLOC_CTX *mem_ctx,
1384 struct cli_sesssetup_blob_state *state = tevent_req_data(
1385 req, struct cli_sesssetup_blob_state);
1389 if (tevent_req_is_nterror(req, &status)) {
1390 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
1394 inbuf = talloc_move(mem_ctx, &state->inbuf);
1395 if (pblob != NULL) {
1396 *pblob = state->ret_blob;
1398 if (pinbuf != NULL) {
1401 /* could be NT_STATUS_MORE_PROCESSING_REQUIRED */
1402 return state->status;
1407 /****************************************************************************
1408 Use in-memory credentials cache
1409 ****************************************************************************/
1411 static void use_in_memory_ccache(void) {
1412 setenv(KRB5_ENV_CCNAME, "MEMORY:cliconnect", 1);
1415 /****************************************************************************
1416 Do a spnego/kerberos encrypted session setup.
1417 ****************************************************************************/
1419 struct cli_session_setup_kerberos_state {
1420 struct cli_state *cli;
1421 DATA_BLOB negTokenTarg;
1422 DATA_BLOB session_key_krb5;
1423 ADS_STATUS ads_status;
1426 static void cli_session_setup_kerberos_done(struct tevent_req *subreq);
1428 static struct tevent_req *cli_session_setup_kerberos_send(
1429 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
1430 const char *principal)
1432 struct tevent_req *req, *subreq;
1433 struct cli_session_setup_kerberos_state *state;
1436 DEBUG(2,("Doing kerberos session setup\n"));
1438 req = tevent_req_create(mem_ctx, &state,
1439 struct cli_session_setup_kerberos_state);
1444 state->ads_status = ADS_SUCCESS;
1446 cli_temp_set_signing(cli);
1449 * Ok, this is cheating: spnego_gen_krb5_negTokenInit can block if
1450 * we have to acquire a ticket. To be fixed later :-)
1452 rc = spnego_gen_krb5_negTokenInit(state, principal, 0, &state->negTokenTarg,
1453 &state->session_key_krb5, 0, NULL);
1455 DEBUG(1, ("cli_session_setup_kerberos: "
1456 "spnego_gen_krb5_negTokenInit failed: %s\n",
1457 error_message(rc)));
1458 state->ads_status = ADS_ERROR_KRB5(rc);
1459 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
1460 return tevent_req_post(req, ev);
1464 file_save("negTokenTarg.dat", state->negTokenTarg.data,
1465 state->negTokenTarg.length);
1468 subreq = cli_sesssetup_blob_send(state, ev, cli, state->negTokenTarg);
1469 if (tevent_req_nomem(subreq, req)) {
1470 return tevent_req_post(req, ev);
1472 tevent_req_set_callback(subreq, cli_session_setup_kerberos_done, req);
1476 static void cli_session_setup_kerberos_done(struct tevent_req *subreq)
1478 struct tevent_req *req = tevent_req_callback_data(
1479 subreq, struct tevent_req);
1480 struct cli_session_setup_kerberos_state *state = tevent_req_data(
1481 req, struct cli_session_setup_kerberos_state);
1485 status = cli_sesssetup_blob_recv(subreq, talloc_tos(), NULL, &inbuf);
1486 if (!NT_STATUS_IS_OK(status)) {
1487 TALLOC_FREE(subreq);
1488 tevent_req_nterror(req, status);
1492 cli_set_session_key(state->cli, state->session_key_krb5);
1494 if (cli_simple_set_signing(state->cli, state->session_key_krb5,
1496 && !cli_check_sign_mac(state->cli, inbuf, 1)) {
1497 TALLOC_FREE(subreq);
1498 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1501 TALLOC_FREE(subreq);
1502 tevent_req_done(req);
1505 static ADS_STATUS cli_session_setup_kerberos_recv(struct tevent_req *req)
1507 struct cli_session_setup_kerberos_state *state = tevent_req_data(
1508 req, struct cli_session_setup_kerberos_state);
1511 if (tevent_req_is_nterror(req, &status)) {
1512 return ADS_ERROR_NT(status);
1514 return state->ads_status;
1517 static ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli,
1518 const char *principal)
1520 struct tevent_context *ev;
1521 struct tevent_req *req;
1522 ADS_STATUS status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1524 if (cli_has_async_calls(cli)) {
1525 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1527 ev = tevent_context_init(talloc_tos());
1531 req = cli_session_setup_kerberos_send(ev, ev, cli, principal);
1535 if (!tevent_req_poll(req, ev)) {
1536 status = ADS_ERROR_SYSTEM(errno);
1539 status = cli_session_setup_kerberos_recv(req);
1544 #endif /* HAVE_KRB5 */
1546 /****************************************************************************
1547 Do a spnego/NTLMSSP encrypted session setup.
1548 ****************************************************************************/
1550 struct cli_session_setup_ntlmssp_state {
1551 struct tevent_context *ev;
1552 struct cli_state *cli;
1553 struct ntlmssp_state *ntlmssp_state;
1558 static int cli_session_setup_ntlmssp_state_destructor(
1559 struct cli_session_setup_ntlmssp_state *state)
1561 if (state->ntlmssp_state != NULL) {
1562 TALLOC_FREE(state->ntlmssp_state);
1567 static void cli_session_setup_ntlmssp_done(struct tevent_req *req);
1569 static struct tevent_req *cli_session_setup_ntlmssp_send(
1570 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
1571 const char *user, const char *pass, const char *domain)
1573 struct tevent_req *req, *subreq;
1574 struct cli_session_setup_ntlmssp_state *state;
1577 const char *OIDs_ntlm[] = {OID_NTLMSSP, NULL};
1579 req = tevent_req_create(mem_ctx, &state,
1580 struct cli_session_setup_ntlmssp_state);
1588 state->ntlmssp_state = NULL;
1589 talloc_set_destructor(
1590 state, cli_session_setup_ntlmssp_state_destructor);
1592 cli_temp_set_signing(cli);
1594 status = ntlmssp_client_start(state,
1597 lp_client_ntlmv2_auth(),
1598 &state->ntlmssp_state);
1599 if (!NT_STATUS_IS_OK(status)) {
1602 ntlmssp_want_feature(state->ntlmssp_state,
1603 NTLMSSP_FEATURE_SESSION_KEY);
1604 if (cli->use_ccache) {
1605 ntlmssp_want_feature(state->ntlmssp_state,
1606 NTLMSSP_FEATURE_CCACHE);
1608 status = ntlmssp_set_username(state->ntlmssp_state, user);
1609 if (!NT_STATUS_IS_OK(status)) {
1612 status = ntlmssp_set_domain(state->ntlmssp_state, domain);
1613 if (!NT_STATUS_IS_OK(status)) {
1616 status = ntlmssp_set_password(state->ntlmssp_state, pass);
1617 if (!NT_STATUS_IS_OK(status)) {
1620 status = ntlmssp_update(state->ntlmssp_state, data_blob_null,
1622 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1626 state->blob_out = spnego_gen_negTokenInit(state, OIDs_ntlm, &blob_out, NULL);
1627 data_blob_free(&blob_out);
1629 subreq = cli_sesssetup_blob_send(state, ev, cli, state->blob_out);
1630 if (tevent_req_nomem(subreq, req)) {
1631 return tevent_req_post(req, ev);
1633 tevent_req_set_callback(subreq, cli_session_setup_ntlmssp_done, req);
1636 tevent_req_nterror(req, status);
1637 return tevent_req_post(req, ev);
1640 static void cli_session_setup_ntlmssp_done(struct tevent_req *subreq)
1642 struct tevent_req *req = tevent_req_callback_data(
1643 subreq, struct tevent_req);
1644 struct cli_session_setup_ntlmssp_state *state = tevent_req_data(
1645 req, struct cli_session_setup_ntlmssp_state);
1646 DATA_BLOB blob_in, msg_in, blob_out;
1651 status = cli_sesssetup_blob_recv(subreq, talloc_tos(), &blob_in,
1653 TALLOC_FREE(subreq);
1654 data_blob_free(&state->blob_out);
1656 if (NT_STATUS_IS_OK(status)) {
1657 if (state->cli->server_domain[0] == '\0') {
1658 TALLOC_FREE(state->cli->server_domain);
1659 state->cli->server_domain = talloc_strdup(state->cli,
1660 state->ntlmssp_state->server.netbios_domain);
1661 if (state->cli->server_domain == NULL) {
1662 TALLOC_FREE(subreq);
1663 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1667 cli_set_session_key(
1668 state->cli, state->ntlmssp_state->session_key);
1670 if (cli_simple_set_signing(
1671 state->cli, state->ntlmssp_state->session_key,
1673 && !cli_check_sign_mac(state->cli, inbuf, 1)) {
1674 TALLOC_FREE(subreq);
1675 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1678 TALLOC_FREE(subreq);
1679 TALLOC_FREE(state->ntlmssp_state);
1680 tevent_req_done(req);
1683 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1684 tevent_req_nterror(req, status);
1688 if (blob_in.length == 0) {
1689 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
1693 if ((state->turn == 1)
1694 && NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1695 DATA_BLOB tmp_blob = data_blob_null;
1696 /* the server might give us back two challenges */
1697 parse_ret = spnego_parse_challenge(state, blob_in, &msg_in,
1699 data_blob_free(&tmp_blob);
1701 parse_ret = spnego_parse_auth_response(state, blob_in, status,
1702 OID_NTLMSSP, &msg_in);
1707 DEBUG(3,("Failed to parse auth response\n"));
1708 if (NT_STATUS_IS_OK(status)
1709 || NT_STATUS_EQUAL(status,
1710 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1712 req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1717 status = ntlmssp_update(state->ntlmssp_state, msg_in, &blob_out);
1719 if (!NT_STATUS_IS_OK(status)
1720 && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1721 TALLOC_FREE(subreq);
1722 TALLOC_FREE(state->ntlmssp_state);
1723 tevent_req_nterror(req, status);
1727 state->blob_out = spnego_gen_auth(state, blob_out);
1728 TALLOC_FREE(subreq);
1729 if (tevent_req_nomem(state->blob_out.data, req)) {
1733 subreq = cli_sesssetup_blob_send(state, state->ev, state->cli,
1735 if (tevent_req_nomem(subreq, req)) {
1738 tevent_req_set_callback(subreq, cli_session_setup_ntlmssp_done, req);
1741 static NTSTATUS cli_session_setup_ntlmssp_recv(struct tevent_req *req)
1743 struct cli_session_setup_ntlmssp_state *state = tevent_req_data(
1744 req, struct cli_session_setup_ntlmssp_state);
1747 if (tevent_req_is_nterror(req, &status)) {
1748 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
1751 return NT_STATUS_OK;
1754 static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli,
1759 struct tevent_context *ev;
1760 struct tevent_req *req;
1761 NTSTATUS status = NT_STATUS_NO_MEMORY;
1763 if (cli_has_async_calls(cli)) {
1764 return NT_STATUS_INVALID_PARAMETER;
1766 ev = tevent_context_init(talloc_tos());
1770 req = cli_session_setup_ntlmssp_send(ev, ev, cli, user, pass, domain);
1774 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1777 status = cli_session_setup_ntlmssp_recv(req);
1783 /****************************************************************************
1784 Do a spnego encrypted session setup.
1786 user_domain: The shortname of the domain the user/machine is a member of.
1787 dest_realm: The realm we're connecting to, if NULL we use our default realm.
1788 ****************************************************************************/
1790 static ADS_STATUS cli_session_setup_spnego(struct cli_state *cli,
1793 const char *user_domain,
1794 const char * dest_realm)
1796 char *principal = NULL;
1797 char *OIDs[ASN1_MAX_OIDS];
1800 const char *p = NULL;
1801 char *account = NULL;
1804 DEBUG(3,("Doing spnego session setup (blob length=%lu)\n", (unsigned long)cli->secblob.length));
1806 /* the server might not even do spnego */
1807 if (cli->secblob.length <= 16) {
1808 DEBUG(3,("server didn't supply a full spnego negprot\n"));
1813 file_save("negprot.dat", cli->secblob.data, cli->secblob.length);
1816 /* there is 16 bytes of GUID before the real spnego packet starts */
1817 blob = data_blob(cli->secblob.data+16, cli->secblob.length-16);
1819 /* The server sent us the first part of the SPNEGO exchange in the
1820 * negprot reply. It is WRONG to depend on the principal sent in the
1821 * negprot reply, but right now we do it. If we don't receive one,
1822 * we try to best guess, then fall back to NTLM. */
1823 if (!spnego_parse_negTokenInit(talloc_tos(), blob, OIDs, &principal, NULL) ||
1825 data_blob_free(&blob);
1826 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1828 data_blob_free(&blob);
1830 /* make sure the server understands kerberos */
1831 for (i=0;OIDs[i];i++) {
1833 DEBUG(3,("got OID=%s\n", OIDs[i]));
1835 DEBUGADD(3,("got OID=%s\n", OIDs[i]));
1836 if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0 ||
1837 strcmp(OIDs[i], OID_KERBEROS5) == 0) {
1838 cli->got_kerberos_mechanism = True;
1840 talloc_free(OIDs[i]);
1843 DEBUG(3,("got principal=%s\n", principal ? principal : "<null>"));
1845 status = cli_set_username(cli, user);
1846 if (!NT_STATUS_IS_OK(status)) {
1847 TALLOC_FREE(principal);
1848 return ADS_ERROR_NT(status);
1852 /* If password is set we reauthenticate to kerberos server
1853 * and do not store results */
1855 if (cli->got_kerberos_mechanism && cli->use_kerberos) {
1857 const char *remote_name = cli_state_remote_name(cli);
1859 if (pass && *pass) {
1862 use_in_memory_ccache();
1863 ret = kerberos_kinit_password(user, pass, 0 /* no time correction for now */, NULL);
1866 TALLOC_FREE(principal);
1867 DEBUG(0, ("Kinit failed: %s\n", error_message(ret)));
1868 if (cli->fallback_after_kerberos)
1870 return ADS_ERROR_KRB5(ret);
1874 /* We may not be allowed to use the server-supplied SPNEGO principal, or it may not have been supplied to us
1876 if (!lp_client_use_spnego_principal() || strequal(principal, ADS_IGNORE_PRINCIPAL)) {
1877 TALLOC_FREE(principal);
1880 if (principal == NULL &&
1881 !is_ipaddress(remote_name) &&
1882 !strequal(STAR_SMBSERVER,
1886 DEBUG(3,("cli_session_setup_spnego: using target "
1887 "hostname not SPNEGO principal\n"));
1889 host = strchr_m(remote_name, '.');
1891 realm = SMB_STRDUP(dest_realm);
1893 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1899 realm = kerberos_get_realm_from_hostname(remote_name);
1901 /* NetBIOS name - use our realm. */
1902 realm = kerberos_get_default_realm_from_ccache();
1906 if (realm == NULL || *realm == '\0') {
1907 realm = SMB_STRDUP(lp_realm());
1909 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1912 DEBUG(3,("cli_session_setup_spnego: cannot "
1913 "get realm from dest_realm %s, "
1914 "desthost %s. Using default "
1915 "smb.conf realm %s\n",
1916 dest_realm ? dest_realm : "<null>",
1921 principal = talloc_asprintf(talloc_tos(),
1927 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1929 DEBUG(3,("cli_session_setup_spnego: guessed "
1930 "server principal=%s\n",
1931 principal ? principal : "<null>"));
1937 rc = cli_session_setup_kerberos(cli, principal);
1938 if (ADS_ERR_OK(rc) || !cli->fallback_after_kerberos) {
1939 TALLOC_FREE(principal);
1946 TALLOC_FREE(principal);
1950 account = talloc_strdup(talloc_tos(), user);
1952 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1955 /* when falling back to ntlmssp while authenticating with a machine
1956 * account strip off the realm - gd */
1958 if ((p = strchr_m(user, '@')) != NULL) {
1959 account[PTR_DIFF(p,user)] = '\0';
1962 return ADS_ERROR_NT(cli_session_setup_ntlmssp(cli, account, pass, user_domain));
1965 /****************************************************************************
1966 Send a session setup. The username and workgroup is in UNIX character
1967 format and must be converted to DOS codepage format before sending. If the
1968 password is in plaintext, the same should be done.
1969 ****************************************************************************/
1971 NTSTATUS cli_session_setup(struct cli_state *cli,
1973 const char *pass, int passlen,
1974 const char *ntpass, int ntpasslen,
1975 const char *workgroup)
1981 user2 = talloc_strdup(talloc_tos(), user);
1983 user2 = talloc_strdup(talloc_tos(), "");
1985 if (user2 == NULL) {
1986 return NT_STATUS_NO_MEMORY;
1993 /* allow for workgroups as part of the username */
1994 if ((p=strchr_m(user2,'\\')) || (p=strchr_m(user2,'/')) ||
1995 (p=strchr_m(user2,*lp_winbind_separator()))) {
2002 if (cli_state_protocol(cli) < PROTOCOL_LANMAN1) {
2003 return NT_STATUS_OK;
2006 /* now work out what sort of session setup we are going to
2007 do. I have split this into separate functions to make the
2008 flow a bit easier to understand (tridge) */
2010 /* if its an older server then we have to use the older request format */
2012 if (cli_state_protocol(cli) < PROTOCOL_NT1) {
2013 if (!lp_client_lanman_auth() && passlen != 24 && (*pass)) {
2014 DEBUG(1, ("Server requested LM password but 'client lanman auth = no'"
2015 " or 'client ntlmv2 auth = yes'\n"));
2016 return NT_STATUS_ACCESS_DENIED;
2019 if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0 &&
2020 !lp_client_plaintext_auth() && (*pass)) {
2021 DEBUG(1, ("Server requested LM password but 'client plaintext auth = no'"
2022 " or 'client ntlmv2 auth = yes'\n"));
2023 return NT_STATUS_ACCESS_DENIED;
2026 return cli_session_setup_lanman2(cli, user, pass, passlen,
2030 /* if no user is supplied then we have to do an anonymous connection.
2031 passwords are ignored */
2033 if (!user || !*user)
2034 return cli_session_setup_guest(cli);
2036 /* if the server is share level then send a plaintext null
2037 password at this point. The password is sent in the tree
2040 if ((cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0)
2041 return cli_session_setup_plain(cli, user, "", workgroup);
2043 /* if the server doesn't support encryption then we have to use
2044 plaintext. The second password is ignored */
2046 if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) {
2047 if (!lp_client_plaintext_auth() && (*pass)) {
2048 DEBUG(1, ("Server requested LM password but 'client plaintext auth = no'"
2049 " or 'client ntlmv2 auth = yes'\n"));
2050 return NT_STATUS_ACCESS_DENIED;
2052 return cli_session_setup_plain(cli, user, pass, workgroup);
2055 /* if the server supports extended security then use SPNEGO */
2057 if (cli_state_capabilities(cli) & CAP_EXTENDED_SECURITY) {
2058 const char *remote_realm = cli_state_remote_realm(cli);
2059 ADS_STATUS status = cli_session_setup_spnego(cli, user, pass,
2062 if (!ADS_ERR_OK(status)) {
2063 DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status)));
2064 return ads_ntstatus(status);
2069 /* otherwise do a NT1 style session setup */
2070 status = cli_session_setup_nt1(cli, user, pass, passlen,
2071 ntpass, ntpasslen, workgroup);
2072 if (!NT_STATUS_IS_OK(status)) {
2073 DEBUG(3,("cli_session_setup: NT1 session setup "
2074 "failed: %s\n", nt_errstr(status)));
2079 if (strstr(cli->server_type, "Samba")) {
2080 cli->is_samba = True;
2083 return NT_STATUS_OK;
2086 /****************************************************************************
2088 *****************************************************************************/
2090 struct cli_ulogoff_state {
2091 struct cli_state *cli;
2095 static void cli_ulogoff_done(struct tevent_req *subreq);
2097 struct tevent_req *cli_ulogoff_send(TALLOC_CTX *mem_ctx,
2098 struct tevent_context *ev,
2099 struct cli_state *cli)
2101 struct tevent_req *req, *subreq;
2102 struct cli_ulogoff_state *state;
2104 req = tevent_req_create(mem_ctx, &state, struct cli_ulogoff_state);
2110 SCVAL(state->vwv+0, 0, 0xFF);
2111 SCVAL(state->vwv+1, 0, 0);
2112 SSVAL(state->vwv+2, 0, 0);
2114 subreq = cli_smb_send(state, ev, cli, SMBulogoffX, 0, 2, state->vwv,
2116 if (tevent_req_nomem(subreq, req)) {
2117 return tevent_req_post(req, ev);
2119 tevent_req_set_callback(subreq, cli_ulogoff_done, req);
2123 static void cli_ulogoff_done(struct tevent_req *subreq)
2125 struct tevent_req *req = tevent_req_callback_data(
2126 subreq, struct tevent_req);
2127 struct cli_ulogoff_state *state = tevent_req_data(
2128 req, struct cli_ulogoff_state);
2131 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
2132 if (!NT_STATUS_IS_OK(status)) {
2133 tevent_req_nterror(req, status);
2136 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
2137 tevent_req_done(req);
2140 NTSTATUS cli_ulogoff_recv(struct tevent_req *req)
2142 return tevent_req_simple_recv_ntstatus(req);
2145 NTSTATUS cli_ulogoff(struct cli_state *cli)
2147 struct tevent_context *ev;
2148 struct tevent_req *req;
2149 NTSTATUS status = NT_STATUS_NO_MEMORY;
2151 if (cli_has_async_calls(cli)) {
2152 return NT_STATUS_INVALID_PARAMETER;
2154 ev = tevent_context_init(talloc_tos());
2158 req = cli_ulogoff_send(ev, ev, cli);
2162 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2165 status = cli_ulogoff_recv(req);
2171 /****************************************************************************
2173 ****************************************************************************/
2175 struct cli_tcon_andx_state {
2176 struct cli_state *cli;
2181 static void cli_tcon_andx_done(struct tevent_req *subreq);
2183 struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx,
2184 struct event_context *ev,
2185 struct cli_state *cli,
2186 const char *share, const char *dev,
2187 const char *pass, int passlen,
2188 struct tevent_req **psmbreq)
2190 struct tevent_req *req, *subreq;
2191 struct cli_tcon_andx_state *state;
2199 req = tevent_req_create(mem_ctx, &state, struct cli_tcon_andx_state);
2206 cli->share = talloc_strdup(cli, share);
2211 /* in user level security don't send a password now */
2212 if (cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {
2215 } else if (pass == NULL) {
2216 DEBUG(1, ("Server not using user level security and no "
2217 "password supplied.\n"));
2221 if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) &&
2222 *pass && passlen != 24) {
2223 if (!lp_client_lanman_auth()) {
2224 DEBUG(1, ("Server requested LANMAN password "
2225 "(share-level security) but "
2226 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2231 * Non-encrypted passwords - convert to DOS codepage before
2234 SMBencrypt(pass, cli->secblob.data, p24);
2236 pass = (const char *)p24;
2238 if((cli->sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL
2239 |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE))
2243 if (!lp_client_plaintext_auth() && (*pass)) {
2244 DEBUG(1, ("Server requested plaintext "
2246 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2251 * Non-encrypted passwords - convert to DOS codepage
2254 tmp_pass = talloc_array(talloc_tos(), uint8, 0);
2255 if (tevent_req_nomem(tmp_pass, req)) {
2256 return tevent_req_post(req, ev);
2258 tmp_pass = trans2_bytes_push_str(tmp_pass,
2259 false, /* always DOS */
2263 if (tevent_req_nomem(tmp_pass, req)) {
2264 return tevent_req_post(req, ev);
2266 pass = (const char *)tmp_pass;
2267 passlen = talloc_get_size(tmp_pass);
2271 SCVAL(vwv+0, 0, 0xFF);
2274 SSVAL(vwv+2, 0, TCONX_FLAG_EXTENDED_RESPONSE);
2275 SSVAL(vwv+3, 0, passlen);
2277 if (passlen && pass) {
2278 bytes = (uint8_t *)talloc_memdup(state, pass, passlen);
2280 bytes = talloc_array(state, uint8_t, 0);
2286 tmp = talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
2287 cli_state_remote_name(cli), share);
2292 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), tmp, strlen(tmp)+1,
2297 * Add the devicetype
2299 tmp = talloc_strdup_upper(talloc_tos(), dev);
2304 bytes = smb_bytes_push_str(bytes, false, tmp, strlen(tmp)+1, NULL);
2307 if (bytes == NULL) {
2312 state->bytes.iov_base = (void *)bytes;
2313 state->bytes.iov_len = talloc_get_size(bytes);
2315 subreq = cli_smb_req_create(state, ev, cli, SMBtconX, 0, 4, vwv,
2317 if (subreq == NULL) {
2321 tevent_req_set_callback(subreq, cli_tcon_andx_done, req);
2326 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
2327 return tevent_req_post(req, ev);
2330 struct tevent_req *cli_tcon_andx_send(TALLOC_CTX *mem_ctx,
2331 struct event_context *ev,
2332 struct cli_state *cli,
2333 const char *share, const char *dev,
2334 const char *pass, int passlen)
2336 struct tevent_req *req, *subreq;
2339 req = cli_tcon_andx_create(mem_ctx, ev, cli, share, dev, pass, passlen,
2344 if (subreq == NULL) {
2347 status = cli_smb_req_send(subreq);
2348 if (!NT_STATUS_IS_OK(status)) {
2349 tevent_req_nterror(req, status);
2350 return tevent_req_post(req, ev);
2355 static void cli_tcon_andx_done(struct tevent_req *subreq)
2357 struct tevent_req *req = tevent_req_callback_data(
2358 subreq, struct tevent_req);
2359 struct cli_tcon_andx_state *state = tevent_req_data(
2360 req, struct cli_tcon_andx_state);
2361 struct cli_state *cli = state->cli;
2370 status = cli_smb_recv(subreq, state, &in, 0, &wct, &vwv,
2371 &num_bytes, &bytes);
2372 TALLOC_FREE(subreq);
2373 if (!NT_STATUS_IS_OK(status)) {
2374 tevent_req_nterror(req, status);
2381 if (clistr_pull_talloc(cli,
2383 SVAL(inbuf, smb_flg2),
2387 STR_TERMINATE|STR_ASCII) == -1) {
2388 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2392 cli->dev = talloc_strdup(cli, "");
2393 if (cli->dev == NULL) {
2394 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2399 if ((cli_state_protocol(cli) >= PROTOCOL_NT1) && (num_bytes == 3)) {
2400 /* almost certainly win95 - enable bug fixes */
2405 * Make sure that we have the optional support 16-bit field. WCT > 2.
2406 * Avoids issues when connecting to Win9x boxes sharing files
2409 cli->dfsroot = false;
2411 if ((wct > 2) && (cli_state_protocol(cli) >= PROTOCOL_LANMAN2)) {
2412 cli->dfsroot = ((SVAL(vwv+2, 0) & SMB_SHARE_IN_DFS) != 0);
2415 cli->smb1.tid = SVAL(inbuf,smb_tid);
2416 tevent_req_done(req);
2419 NTSTATUS cli_tcon_andx_recv(struct tevent_req *req)
2421 return tevent_req_simple_recv_ntstatus(req);
2424 NTSTATUS cli_tcon_andx(struct cli_state *cli, const char *share,
2425 const char *dev, const char *pass, int passlen)
2427 TALLOC_CTX *frame = talloc_stackframe();
2428 struct event_context *ev;
2429 struct tevent_req *req;
2430 NTSTATUS status = NT_STATUS_OK;
2432 if (cli_has_async_calls(cli)) {
2434 * Can't use sync call while an async call is in flight
2436 status = NT_STATUS_INVALID_PARAMETER;
2440 ev = event_context_init(frame);
2442 status = NT_STATUS_NO_MEMORY;
2446 req = cli_tcon_andx_send(frame, ev, cli, share, dev, pass, passlen);
2448 status = NT_STATUS_NO_MEMORY;
2452 if (!tevent_req_poll(req, ev)) {
2453 status = map_nt_error_from_unix(errno);
2457 status = cli_tcon_andx_recv(req);
2463 /****************************************************************************
2464 Send a tree disconnect.
2465 ****************************************************************************/
2467 struct cli_tdis_state {
2468 struct cli_state *cli;
2471 static void cli_tdis_done(struct tevent_req *subreq);
2473 struct tevent_req *cli_tdis_send(TALLOC_CTX *mem_ctx,
2474 struct tevent_context *ev,
2475 struct cli_state *cli)
2477 struct tevent_req *req, *subreq;
2478 struct cli_tdis_state *state;
2480 req = tevent_req_create(mem_ctx, &state, struct cli_tdis_state);
2486 subreq = cli_smb_send(state, ev, cli, SMBtdis, 0, 0, NULL, 0, NULL);
2487 if (tevent_req_nomem(subreq, req)) {
2488 return tevent_req_post(req, ev);
2490 tevent_req_set_callback(subreq, cli_tdis_done, req);
2494 static void cli_tdis_done(struct tevent_req *subreq)
2496 struct tevent_req *req = tevent_req_callback_data(
2497 subreq, struct tevent_req);
2498 struct cli_tdis_state *state = tevent_req_data(
2499 req, struct cli_tdis_state);
2502 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
2503 TALLOC_FREE(subreq);
2504 if (!NT_STATUS_IS_OK(status)) {
2505 tevent_req_nterror(req, status);
2508 state->cli->smb1.tid = UINT16_MAX;
2509 tevent_req_done(req);
2512 NTSTATUS cli_tdis_recv(struct tevent_req *req)
2514 return tevent_req_simple_recv_ntstatus(req);
2517 NTSTATUS cli_tdis(struct cli_state *cli)
2519 struct tevent_context *ev;
2520 struct tevent_req *req;
2521 NTSTATUS status = NT_STATUS_NO_MEMORY;
2523 if (cli_has_async_calls(cli)) {
2524 return NT_STATUS_INVALID_PARAMETER;
2526 ev = tevent_context_init(talloc_tos());
2530 req = cli_tdis_send(ev, ev, cli);
2534 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2537 status = cli_tdis_recv(req);
2543 /****************************************************************************
2544 Send a negprot command.
2545 ****************************************************************************/
2547 struct cli_negprot_state {
2548 struct cli_state *cli;
2551 static void cli_negprot_done(struct tevent_req *subreq);
2553 struct tevent_req *cli_negprot_send(TALLOC_CTX *mem_ctx,
2554 struct event_context *ev,
2555 struct cli_state *cli)
2557 struct tevent_req *req, *subreq;
2558 struct cli_negprot_state *state;
2559 uint8_t *bytes = NULL;
2562 req = tevent_req_create(mem_ctx, &state, struct cli_negprot_state);
2568 if (cli_state_protocol(cli) < PROTOCOL_NT1)
2569 cli->use_spnego = False;
2571 /* setup the protocol strings */
2572 for (numprots=0; numprots < ARRAY_SIZE(prots); numprots++) {
2574 if (prots[numprots].prot > cli_state_protocol(cli)) {
2577 bytes = (uint8_t *)talloc_append_blob(
2578 state, bytes, data_blob_const(&c, sizeof(c)));
2579 if (tevent_req_nomem(bytes, req)) {
2580 return tevent_req_post(req, ev);
2582 bytes = smb_bytes_push_str(bytes, false,
2583 prots[numprots].name,
2584 strlen(prots[numprots].name)+1,
2586 if (tevent_req_nomem(bytes, req)) {
2587 return tevent_req_post(req, ev);
2591 subreq = cli_smb_send(state, ev, cli, SMBnegprot, 0, 0, NULL,
2592 talloc_get_size(bytes), bytes);
2594 if (tevent_req_nomem(subreq, req)) {
2595 return tevent_req_post(req, ev);
2597 tevent_req_set_callback(subreq, cli_negprot_done, req);
2601 static void cli_negprot_done(struct tevent_req *subreq)
2603 struct tevent_req *req = tevent_req_callback_data(
2604 subreq, struct tevent_req);
2605 struct cli_negprot_state *state = tevent_req_data(
2606 req, struct cli_negprot_state);
2607 struct cli_state *cli = state->cli;
2616 status = cli_smb_recv(subreq, state, &inbuf, 1, &wct, &vwv,
2617 &num_bytes, &bytes);
2618 TALLOC_FREE(subreq);
2619 if (!NT_STATUS_IS_OK(status)) {
2620 tevent_req_nterror(req, status);
2624 protnum = SVAL(vwv, 0);
2626 if ((protnum >= ARRAY_SIZE(prots))
2627 || (prots[protnum].prot > cli_state_protocol(cli))) {
2628 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2632 cli->protocol = prots[protnum].prot;
2634 if ((cli_state_protocol(cli) < PROTOCOL_NT1) &&
2635 client_is_signing_mandatory(cli)) {
2636 DEBUG(0,("cli_negprot: SMB signing is mandatory and the selected protocol level doesn't support it.\n"));
2637 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
2641 if (cli_state_protocol(cli) >= PROTOCOL_NT1) {
2643 bool negotiated_smb_signing = false;
2646 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2651 cli->sec_mode = CVAL(vwv + 1, 0);
2652 cli->max_mux = SVAL(vwv + 1, 1);
2653 cli->max_xmit = IVAL(vwv + 3, 1);
2654 cli->sesskey = IVAL(vwv + 7, 1);
2655 cli->serverzone = SVALS(vwv + 15, 1);
2656 cli->serverzone *= 60;
2657 /* this time arrives in real GMT */
2658 ts = interpret_long_date(((char *)(vwv+11))+1);
2659 cli->servertime = ts.tv_sec;
2660 cli->secblob = data_blob(bytes, num_bytes);
2661 cli->capabilities = IVAL(vwv + 9, 1);
2662 if (cli_state_capabilities(cli) & CAP_RAW_MODE) {
2663 cli->readbraw_supported = True;
2664 cli->writebraw_supported = True;
2666 /* work out if they sent us a workgroup */
2667 if (!(cli_state_capabilities(cli) & CAP_EXTENDED_SECURITY) &&
2668 smb_buflen(inbuf) > 8) {
2670 status = smb_bytes_talloc_string(
2671 cli, (char *)inbuf, &cli->server_domain,
2672 bytes + 8, num_bytes - 8, &ret);
2673 if (tevent_req_nterror(req, status)) {
2679 * As signing is slow we only turn it on if either the client or
2680 * the server require it. JRA.
2683 if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) {
2684 /* Fail if server says signing is mandatory and we don't want to support it. */
2685 if (!client_is_signing_allowed(cli)) {
2686 DEBUG(0,("cli_negprot: SMB signing is mandatory and we have disabled it.\n"));
2687 tevent_req_nterror(req,
2688 NT_STATUS_ACCESS_DENIED);
2691 negotiated_smb_signing = true;
2692 } else if (client_is_signing_mandatory(cli) && client_is_signing_allowed(cli)) {
2693 /* Fail if client says signing is mandatory and the server doesn't support it. */
2694 if (!(cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) {
2695 DEBUG(1,("cli_negprot: SMB signing is mandatory and the server doesn't support it.\n"));
2696 tevent_req_nterror(req,
2697 NT_STATUS_ACCESS_DENIED);
2700 negotiated_smb_signing = true;
2701 } else if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) {
2702 negotiated_smb_signing = true;
2705 if (negotiated_smb_signing) {
2706 cli_set_signing_negotiated(cli);
2709 } else if (cli_state_protocol(cli) >= PROTOCOL_LANMAN1) {
2711 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2715 cli->use_spnego = False;
2716 cli->sec_mode = SVAL(vwv + 1, 0);
2717 cli->max_xmit = SVAL(vwv + 2, 0);
2718 cli->max_mux = SVAL(vwv + 3, 0);
2719 cli->sesskey = IVAL(vwv + 6, 0);
2720 cli->serverzone = SVALS(vwv + 10, 0);
2721 cli->serverzone *= 60;
2722 /* this time is converted to GMT by make_unix_date */
2723 cli->servertime = make_unix_date(
2724 (char *)(vwv + 8), cli->serverzone);
2725 cli->readbraw_supported = ((SVAL(vwv + 5, 0) & 0x1) != 0);
2726 cli->writebraw_supported = ((SVAL(vwv + 5, 0) & 0x2) != 0);
2727 cli->secblob = data_blob(bytes, num_bytes);
2729 /* the old core protocol */
2730 cli->use_spnego = False;
2732 cli->serverzone = get_time_zone(time(NULL));
2733 cli->max_xmit = 1024;
2736 cli->max_xmit = MIN(cli->max_xmit, CLI_BUFFER_SIZE);
2738 /* a way to force ascii SMB */
2739 if (cli->force_ascii) {
2740 cli->capabilities &= ~CAP_UNICODE;
2743 tevent_req_done(req);
2746 NTSTATUS cli_negprot_recv(struct tevent_req *req)
2748 return tevent_req_simple_recv_ntstatus(req);
2751 NTSTATUS cli_negprot(struct cli_state *cli)
2753 TALLOC_CTX *frame = talloc_stackframe();
2754 struct event_context *ev;
2755 struct tevent_req *req;
2756 NTSTATUS status = NT_STATUS_OK;
2758 if (cli_has_async_calls(cli)) {
2760 * Can't use sync call while an async call is in flight
2762 status = NT_STATUS_INVALID_PARAMETER;
2766 ev = event_context_init(frame);
2768 status = NT_STATUS_NO_MEMORY;
2772 req = cli_negprot_send(frame, ev, cli);
2774 status = NT_STATUS_NO_MEMORY;
2778 if (!tevent_req_poll(req, ev)) {
2779 status = map_nt_error_from_unix(errno);
2783 status = cli_negprot_recv(req);
2789 static NTSTATUS cli_connect_sock(const char *host, int name_type,
2790 const struct sockaddr_storage *pss,
2791 const char *myname, uint16_t port,
2792 int sec_timeout, int *pfd, uint16_t *pport)
2794 TALLOC_CTX *frame = talloc_stackframe();
2796 unsigned int i, num_addrs;
2797 const char **called_names;
2798 const char **calling_names;
2803 prog = getenv("LIBSMB_PROG");
2805 fd = sock_exec(prog);
2807 return map_nt_error_from_unix(errno);
2813 if ((pss == NULL) || is_zero_addr(pss)) {
2814 struct sockaddr_storage *addrs;
2815 status = resolve_name_list(talloc_tos(), host, name_type,
2816 &addrs, &num_addrs);
2817 if (!NT_STATUS_IS_OK(status)) {
2825 called_names = talloc_array(talloc_tos(), const char *, num_addrs);
2826 if (called_names == NULL) {
2827 status = NT_STATUS_NO_MEMORY;
2830 called_types = talloc_array(talloc_tos(), int, num_addrs);
2831 if (called_types == NULL) {
2832 status = NT_STATUS_NO_MEMORY;
2835 calling_names = talloc_array(talloc_tos(), const char *, num_addrs);
2836 if (calling_names == NULL) {
2837 status = NT_STATUS_NO_MEMORY;
2840 for (i=0; i<num_addrs; i++) {
2841 called_names[i] = host;
2842 called_types[i] = name_type;
2843 calling_names[i] = myname;
2845 status = smbsock_any_connect(pss, called_names, called_types,
2846 calling_names, NULL, num_addrs, port,
2847 sec_timeout, &fd, NULL, &port);
2848 if (!NT_STATUS_IS_OK(status)) {
2851 set_socket_options(fd, lp_socket_options());
2855 status = NT_STATUS_OK;
2861 NTSTATUS cli_connect_nb(const char *host, const struct sockaddr_storage *dest_ss,
2862 uint16_t port, int name_type, const char *myname,
2863 int signing_state, int flags, struct cli_state **pcli)
2865 TALLOC_CTX *frame = talloc_stackframe();
2866 struct cli_state *cli;
2867 NTSTATUS status = NT_STATUS_NO_MEMORY;
2872 desthost = talloc_strdup(talloc_tos(), host);
2873 if (desthost == NULL) {
2877 p = strchr(host, '#');
2879 name_type = strtol(p+1, NULL, 16);
2880 host = talloc_strndup(talloc_tos(), host, p - host);
2886 status = cli_connect_sock(host, name_type, dest_ss, myname, port,
2888 if (!NT_STATUS_IS_OK(status)) {
2892 cli = cli_state_create(NULL, fd, desthost, NULL, signing_state, flags);
2898 status = NT_STATUS_OK;
2905 establishes a connection to after the negprot.
2906 @param output_cli A fully initialised cli structure, non-null only on success
2907 @param dest_host The netbios name of the remote host
2908 @param dest_ss (optional) The the destination IP, NULL for name based lookup
2909 @param port (optional) The destination port (0 for default)
2911 NTSTATUS cli_start_connection(struct cli_state **output_cli,
2912 const char *my_name,
2913 const char *dest_host,
2914 const struct sockaddr_storage *dest_ss, int port,
2915 int signing_state, int flags)
2918 struct cli_state *cli;
2920 nt_status = cli_connect_nb(dest_host, dest_ss, port, 0x20, my_name,
2921 signing_state, flags, &cli);
2922 if (!NT_STATUS_IS_OK(nt_status)) {
2923 DEBUG(10, ("cli_connect_nb failed: %s\n",
2924 nt_errstr(nt_status)));
2928 nt_status = cli_negprot(cli);
2929 if (!NT_STATUS_IS_OK(nt_status)) {
2930 DEBUG(1, ("failed negprot: %s\n", nt_errstr(nt_status)));
2936 return NT_STATUS_OK;
2941 establishes a connection right up to doing tconX, password specified.
2942 @param output_cli A fully initialised cli structure, non-null only on success
2943 @param dest_host The netbios name of the remote host
2944 @param dest_ip (optional) The the destination IP, NULL for name based lookup
2945 @param port (optional) The destination port (0 for default)
2946 @param service (optional) The share to make the connection to. Should be 'unqualified' in any way.
2947 @param service_type The 'type' of serivice.
2948 @param user Username, unix string
2949 @param domain User's domain
2950 @param password User's password, unencrypted unix string.
2953 NTSTATUS cli_full_connection(struct cli_state **output_cli,
2954 const char *my_name,
2955 const char *dest_host,
2956 const struct sockaddr_storage *dest_ss, int port,
2957 const char *service, const char *service_type,
2958 const char *user, const char *domain,
2959 const char *password, int flags,
2963 struct cli_state *cli = NULL;
2964 int pw_len = password ? strlen(password)+1 : 0;
2968 if (password == NULL) {
2972 nt_status = cli_start_connection(&cli, my_name, dest_host,
2973 dest_ss, port, signing_state,
2976 if (!NT_STATUS_IS_OK(nt_status)) {
2980 nt_status = cli_session_setup(cli, user, password, pw_len, password,
2982 if (!NT_STATUS_IS_OK(nt_status)) {
2984 if (!(flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)) {
2985 DEBUG(1,("failed session setup with %s\n",
2986 nt_errstr(nt_status)));
2991 nt_status = cli_session_setup(cli, "", "", 0, "", 0, domain);
2992 if (!NT_STATUS_IS_OK(nt_status)) {
2993 DEBUG(1,("anonymous failed session setup with %s\n",
2994 nt_errstr(nt_status)));
3001 nt_status = cli_tcon_andx(cli, service, service_type, password,
3003 if (!NT_STATUS_IS_OK(nt_status)) {
3004 DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status)));
3006 if (NT_STATUS_IS_OK(nt_status)) {
3007 nt_status = NT_STATUS_UNSUCCESSFUL;
3013 nt_status = cli_init_creds(cli, user, domain, password);
3014 if (!NT_STATUS_IS_OK(nt_status)) {
3020 return NT_STATUS_OK;
3023 /****************************************************************************
3024 Send an old style tcon.
3025 ****************************************************************************/
3026 NTSTATUS cli_raw_tcon(struct cli_state *cli,
3027 const char *service, const char *pass, const char *dev,
3028 uint16 *max_xmit, uint16 *tid)
3030 struct tevent_req *req;
3035 if (!lp_client_plaintext_auth() && (*pass)) {
3036 DEBUG(1, ("Server requested plaintext password but 'client "
3037 "plaintext auth' is disabled\n"));
3038 return NT_STATUS_ACCESS_DENIED;
3041 bytes = talloc_array(talloc_tos(), uint8_t, 0);
3042 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3043 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
3044 service, strlen(service)+1, NULL);
3045 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3046 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
3047 pass, strlen(pass)+1, NULL);
3048 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3049 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
3050 dev, strlen(dev)+1, NULL);
3052 status = cli_smb(talloc_tos(), cli, SMBtcon, 0, 0, NULL,
3053 talloc_get_size(bytes), bytes, &req,
3054 2, NULL, &ret_vwv, NULL, NULL);
3055 if (!NT_STATUS_IS_OK(status)) {
3059 *max_xmit = SVAL(ret_vwv + 0, 0);
3060 *tid = SVAL(ret_vwv + 1, 0);
3062 return NT_STATUS_OK;
3065 /* Return a cli_state pointing at the IPC$ share for the given server */
3067 struct cli_state *get_ipc_connect(char *server,
3068 struct sockaddr_storage *server_ss,
3069 const struct user_auth_info *user_info)
3071 struct cli_state *cli;
3073 uint32_t flags = CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
3075 if (user_info->use_kerberos) {
3076 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
3079 nt_status = cli_full_connection(&cli, NULL, server, server_ss, 0, "IPC$", "IPC",
3080 user_info->username ? user_info->username : "",
3082 user_info->password ? user_info->password : "",
3086 if (NT_STATUS_IS_OK(nt_status)) {
3088 } else if (is_ipaddress(server)) {
3089 /* windows 9* needs a correct NMB name for connections */
3090 fstring remote_name;
3092 if (name_status_find("*", 0, 0, server_ss, remote_name)) {
3093 cli = get_ipc_connect(remote_name, server_ss, user_info);
3102 * Given the IP address of a master browser on the network, return its
3103 * workgroup and connect to it.
3105 * This function is provided to allow additional processing beyond what
3106 * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
3107 * browsers and obtain each master browsers' list of domains (in case the
3108 * first master browser is recently on the network and has not yet
3109 * synchronized with other master browsers and therefore does not yet have the
3110 * entire network browse list)
3113 struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx,
3114 struct sockaddr_storage *mb_ip,
3115 const struct user_auth_info *user_info,
3116 char **pp_workgroup_out)
3118 char addr[INET6_ADDRSTRLEN];
3120 struct cli_state *cli;
3121 struct sockaddr_storage server_ss;
3123 *pp_workgroup_out = NULL;
3125 print_sockaddr(addr, sizeof(addr), mb_ip);
3126 DEBUG(99, ("Looking up name of master browser %s\n",
3130 * Do a name status query to find out the name of the master browser.
3131 * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
3132 * master browser will not respond to a wildcard query (or, at least,
3133 * an NT4 server acting as the domain master browser will not).
3135 * We might be able to use ONLY the query on MSBROWSE, but that's not
3136 * yet been tested with all Windows versions, so until it is, leave
3137 * the original wildcard query as the first choice and fall back to
3138 * MSBROWSE if the wildcard query fails.
3140 if (!name_status_find("*", 0, 0x1d, mb_ip, name) &&
3141 !name_status_find(MSBROWSE, 1, 0x1d, mb_ip, name)) {
3143 DEBUG(99, ("Could not retrieve name status for %s\n",
3148 if (!find_master_ip(name, &server_ss)) {
3149 DEBUG(99, ("Could not find master ip for %s\n", name));
3153 *pp_workgroup_out = talloc_strdup(ctx, name);
3155 DEBUG(4, ("found master browser %s, %s\n", name, addr));
3157 print_sockaddr(addr, sizeof(addr), &server_ss);
3158 cli = get_ipc_connect(addr, &server_ss, user_info);
3164 * Return the IP address and workgroup of a master browser on the network, and
3168 struct cli_state *get_ipc_connect_master_ip_bcast(TALLOC_CTX *ctx,
3169 const struct user_auth_info *user_info,
3170 char **pp_workgroup_out)
3172 struct sockaddr_storage *ip_list;
3173 struct cli_state *cli;
3177 *pp_workgroup_out = NULL;
3179 DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
3181 /* Go looking for workgroups by broadcasting on the local network */
3183 status = name_resolve_bcast(MSBROWSE, 1, talloc_tos(),
3185 if (!NT_STATUS_IS_OK(status)) {
3186 DEBUG(99, ("No master browsers responded: %s\n",
3187 nt_errstr(status)));
3191 for (i = 0; i < count; i++) {
3192 char addr[INET6_ADDRSTRLEN];
3193 print_sockaddr(addr, sizeof(addr), &ip_list[i]);
3194 DEBUG(99, ("Found master browser %s\n", addr));
3196 cli = get_ipc_connect_master_ip(ctx, &ip_list[i],
3197 user_info, pp_workgroup_out);