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 "popt_common.h"
25 #include "../libcli/auth/libcli_auth.h"
26 #include "../libcli/auth/spnego.h"
28 #include "../libcli/auth/ntlmssp.h"
29 #include "libads/kerberos_proto.h"
31 #include "../lib/util/tevent_ntstatus.h"
32 #include "async_smb.h"
33 #include "libsmb/nmblib.h"
39 {PROTOCOL_CORE, "PC NETWORK PROGRAM 1.0"},
40 {PROTOCOL_COREPLUS, "MICROSOFT NETWORKS 1.03"},
41 {PROTOCOL_LANMAN1, "MICROSOFT NETWORKS 3.0"},
42 {PROTOCOL_LANMAN1, "LANMAN1.0"},
43 {PROTOCOL_LANMAN2, "LM1.2X002"},
44 {PROTOCOL_LANMAN2, "DOS LANMAN2.1"},
45 {PROTOCOL_LANMAN2, "LANMAN2.1"},
46 {PROTOCOL_LANMAN2, "Samba"},
47 {PROTOCOL_NT1, "NT LANMAN 1.0"},
48 {PROTOCOL_NT1, "NT LM 0.12"},
51 #define STAR_SMBSERVER "*SMBSERVER"
53 /********************************************************
54 Utility function to ensure we always return at least
55 a valid char * pointer to an empty string for the
56 cli->server_os, cli->server_type and cli->server_domain
58 *******************************************************/
60 static NTSTATUS smb_bytes_talloc_string(struct cli_state *cli,
67 *destlen = clistr_pull_talloc(cli,
69 SVAL(inbuf, smb_flg2),
75 return NT_STATUS_NO_MEMORY;
79 *dest = talloc_strdup(cli, "");
81 return NT_STATUS_NO_MEMORY;
88 * Set the user session key for a connection
89 * @param cli The cli structure to add it too
90 * @param session_key The session key used. (A copy of this is taken for the cli struct)
94 static void cli_set_session_key (struct cli_state *cli, const DATA_BLOB session_key)
96 cli->user_session_key = data_blob(session_key.data, session_key.length);
99 /****************************************************************************
100 Do an old lanman2 style session setup.
101 ****************************************************************************/
103 struct cli_session_setup_lanman2_state {
104 struct cli_state *cli;
109 static void cli_session_setup_lanman2_done(struct tevent_req *subreq);
111 static struct tevent_req *cli_session_setup_lanman2_send(
112 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
113 struct cli_state *cli, const char *user,
114 const char *pass, size_t passlen,
115 const char *workgroup)
117 struct tevent_req *req, *subreq;
118 struct cli_session_setup_lanman2_state *state;
119 DATA_BLOB lm_response = data_blob_null;
124 req = tevent_req_create(mem_ctx, &state,
125 struct cli_session_setup_lanman2_state);
134 * LANMAN servers predate NT status codes and Unicode and
135 * ignore those smb flags so we must disable the corresponding
136 * default capabilities that would otherwise cause the Unicode
137 * and NT Status flags to be set (and even returned by the
141 cli->capabilities &= ~(CAP_UNICODE | CAP_STATUS32);
144 * if in share level security then don't send a password now
146 if (!(cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) {
151 && (cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)
154 * Encrypted mode needed, and non encrypted password
157 lm_response = data_blob(NULL, 24);
158 if (tevent_req_nomem(lm_response.data, req)) {
159 return tevent_req_post(req, ev);
162 if (!SMBencrypt(pass, cli->secblob.data,
163 (uint8_t *)lm_response.data)) {
164 DEBUG(1, ("Password is > 14 chars in length, and is "
165 "therefore incompatible with Lanman "
166 "authentication\n"));
167 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
168 return tevent_req_post(req, ev);
170 } else if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)
173 * Encrypted mode needed, and encrypted password
176 lm_response = data_blob(pass, passlen);
177 if (tevent_req_nomem(lm_response.data, req)) {
178 return tevent_req_post(req, ev);
180 } else if (passlen > 0) {
182 size_t converted_size;
184 * Plaintext mode needed, assume plaintext supplied.
186 buf = talloc_array(talloc_tos(), uint8_t, 0);
187 buf = smb_bytes_push_str(buf, cli_ucs2(cli), pass, passlen+1,
189 if (tevent_req_nomem(buf, req)) {
190 return tevent_req_post(req, ev);
192 lm_response = data_blob(pass, passlen);
194 if (tevent_req_nomem(lm_response.data, req)) {
195 return tevent_req_post(req, ev);
199 SCVAL(vwv+0, 0, 0xff);
202 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
205 SIVAL(vwv+5, 0, cli->sesskey);
206 SSVAL(vwv+7, 0, lm_response.length);
208 bytes = talloc_array(state, uint8_t, lm_response.length);
209 if (tevent_req_nomem(bytes, req)) {
210 return tevent_req_post(req, ev);
212 if (lm_response.length != 0) {
213 memcpy(bytes, lm_response.data, lm_response.length);
215 data_blob_free(&lm_response);
217 tmp = talloc_strdup_upper(talloc_tos(), user);
218 if (tevent_req_nomem(tmp, req)) {
219 return tevent_req_post(req, ev);
221 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), tmp, strlen(tmp)+1,
225 tmp = talloc_strdup_upper(talloc_tos(), workgroup);
226 if (tevent_req_nomem(tmp, req)) {
227 return tevent_req_post(req, ev);
229 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), tmp, strlen(tmp)+1,
231 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Unix", 5, NULL);
232 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Samba", 6, NULL);
234 if (tevent_req_nomem(bytes, req)) {
235 return tevent_req_post(req, ev);
238 subreq = cli_smb_send(state, ev, cli, SMBsesssetupX, 0, 10, vwv,
239 talloc_get_size(bytes), bytes);
240 if (tevent_req_nomem(subreq, req)) {
241 return tevent_req_post(req, ev);
243 tevent_req_set_callback(subreq, cli_session_setup_lanman2_done, req);
247 static void cli_session_setup_lanman2_done(struct tevent_req *subreq)
249 struct tevent_req *req = tevent_req_callback_data(
250 subreq, struct tevent_req);
251 struct cli_session_setup_lanman2_state *state = tevent_req_data(
252 req, struct cli_session_setup_lanman2_state);
253 struct cli_state *cli = state->cli;
262 status = cli_smb_recv(subreq, state, &in, 0, NULL, NULL,
265 if (!NT_STATUS_IS_OK(status)) {
266 tevent_req_nterror(req, status);
273 cli->vuid = SVAL(inbuf, smb_uid);
275 status = smb_bytes_talloc_string(cli,
282 if (!NT_STATUS_IS_OK(status)) {
283 tevent_req_nterror(req, status);
288 status = smb_bytes_talloc_string(cli,
295 if (!NT_STATUS_IS_OK(status)) {
296 tevent_req_nterror(req, status);
301 status = smb_bytes_talloc_string(cli,
308 if (!NT_STATUS_IS_OK(status)) {
309 tevent_req_nterror(req, status);
314 if (strstr(cli->server_type, "Samba")) {
315 cli->is_samba = True;
317 status = cli_set_username(cli, state->user);
318 if (tevent_req_nterror(req, status)) {
321 tevent_req_done(req);
324 static NTSTATUS cli_session_setup_lanman2_recv(struct tevent_req *req)
326 return tevent_req_simple_recv_ntstatus(req);
329 static NTSTATUS cli_session_setup_lanman2(struct cli_state *cli, const char *user,
330 const char *pass, size_t passlen,
331 const char *workgroup)
333 TALLOC_CTX *frame = talloc_stackframe();
334 struct event_context *ev;
335 struct tevent_req *req;
336 NTSTATUS status = NT_STATUS_NO_MEMORY;
338 if (cli_has_async_calls(cli)) {
340 * Can't use sync call while an async call is in flight
342 status = NT_STATUS_INVALID_PARAMETER;
345 ev = event_context_init(frame);
349 req = cli_session_setup_lanman2_send(frame, ev, cli, user, pass, passlen,
354 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
357 status = cli_session_setup_lanman2_recv(req);
360 if (!NT_STATUS_IS_OK(status)) {
361 cli_set_error(cli, status);
366 /****************************************************************************
367 Work out suitable capabilities to offer the server.
368 ****************************************************************************/
370 static uint32 cli_session_setup_capabilities(struct cli_state *cli)
372 uint32 capabilities = CAP_NT_SMBS;
374 if (!cli->force_dos_errors)
375 capabilities |= CAP_STATUS32;
377 if (cli->use_level_II_oplocks)
378 capabilities |= CAP_LEVEL_II_OPLOCKS;
380 capabilities |= (cli->capabilities & (CAP_UNICODE|CAP_LARGE_FILES|CAP_LARGE_READX|CAP_LARGE_WRITEX|CAP_DFS));
384 /****************************************************************************
385 Do a NT1 guest session setup.
386 ****************************************************************************/
388 struct cli_session_setup_guest_state {
389 struct cli_state *cli;
394 static void cli_session_setup_guest_done(struct tevent_req *subreq);
396 struct tevent_req *cli_session_setup_guest_create(TALLOC_CTX *mem_ctx,
397 struct event_context *ev,
398 struct cli_state *cli,
399 struct tevent_req **psmbreq)
401 struct tevent_req *req, *subreq;
402 struct cli_session_setup_guest_state *state;
406 req = tevent_req_create(mem_ctx, &state,
407 struct cli_session_setup_guest_state);
414 SCVAL(vwv+0, 0, 0xFF);
417 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
419 SSVAL(vwv+4, 0, cli->pid);
420 SIVAL(vwv+5, 0, cli->sesskey);
425 SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli));
427 bytes = talloc_array(state, uint8_t, 0);
429 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "", 1, /* username */
431 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "", 1, /* workgroup */
433 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Unix", 5, NULL);
434 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Samba", 6, NULL);
441 state->bytes.iov_base = (void *)bytes;
442 state->bytes.iov_len = talloc_get_size(bytes);
444 subreq = cli_smb_req_create(state, ev, cli, SMBsesssetupX, 0, 13, vwv,
446 if (subreq == NULL) {
450 tevent_req_set_callback(subreq, cli_session_setup_guest_done, req);
455 struct tevent_req *cli_session_setup_guest_send(TALLOC_CTX *mem_ctx,
456 struct event_context *ev,
457 struct cli_state *cli)
459 struct tevent_req *req, *subreq;
462 req = cli_session_setup_guest_create(mem_ctx, ev, cli, &subreq);
467 status = cli_smb_req_send(subreq);
468 if (NT_STATUS_IS_OK(status)) {
469 tevent_req_nterror(req, status);
470 return tevent_req_post(req, ev);
475 static void cli_session_setup_guest_done(struct tevent_req *subreq)
477 struct tevent_req *req = tevent_req_callback_data(
478 subreq, struct tevent_req);
479 struct cli_session_setup_guest_state *state = tevent_req_data(
480 req, struct cli_session_setup_guest_state);
481 struct cli_state *cli = state->cli;
490 status = cli_smb_recv(subreq, state, &in, 0, NULL, NULL,
493 if (!NT_STATUS_IS_OK(status)) {
494 tevent_req_nterror(req, status);
501 cli->vuid = SVAL(inbuf, smb_uid);
503 status = smb_bytes_talloc_string(cli,
510 if (!NT_STATUS_IS_OK(status)) {
511 tevent_req_nterror(req, status);
516 status = smb_bytes_talloc_string(cli,
523 if (!NT_STATUS_IS_OK(status)) {
524 tevent_req_nterror(req, status);
529 status = smb_bytes_talloc_string(cli,
536 if (!NT_STATUS_IS_OK(status)) {
537 tevent_req_nterror(req, status);
542 if (strstr(cli->server_type, "Samba")) {
543 cli->is_samba = True;
546 status = cli_set_username(cli, "");
547 if (!NT_STATUS_IS_OK(status)) {
548 tevent_req_nterror(req, status);
551 tevent_req_done(req);
554 NTSTATUS cli_session_setup_guest_recv(struct tevent_req *req)
556 return tevent_req_simple_recv_ntstatus(req);
559 static NTSTATUS cli_session_setup_guest(struct cli_state *cli)
561 TALLOC_CTX *frame = talloc_stackframe();
562 struct event_context *ev;
563 struct tevent_req *req;
564 NTSTATUS status = NT_STATUS_OK;
566 if (cli_has_async_calls(cli)) {
568 * Can't use sync call while an async call is in flight
570 status = NT_STATUS_INVALID_PARAMETER;
574 ev = event_context_init(frame);
576 status = NT_STATUS_NO_MEMORY;
580 req = cli_session_setup_guest_send(frame, ev, cli);
582 status = NT_STATUS_NO_MEMORY;
586 if (!tevent_req_poll(req, ev)) {
587 status = map_nt_error_from_unix(errno);
591 status = cli_session_setup_guest_recv(req);
594 if (!NT_STATUS_IS_OK(status)) {
595 cli_set_error(cli, status);
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->pid);
639 SIVAL(vwv+5, 0, cli->sesskey);
644 SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli));
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;
698 status = cli_smb_recv(subreq, state, &in, 0, NULL, NULL,
701 if (tevent_req_nterror(req, status)) {
708 cli->vuid = SVAL(inbuf, smb_uid);
710 status = smb_bytes_talloc_string(cli,
717 if (!NT_STATUS_IS_OK(status)) {
718 tevent_req_nterror(req, status);
723 status = smb_bytes_talloc_string(cli,
730 if (!NT_STATUS_IS_OK(status)) {
731 tevent_req_nterror(req, status);
736 status = smb_bytes_talloc_string(cli,
743 if (!NT_STATUS_IS_OK(status)) {
744 tevent_req_nterror(req, status);
749 status = cli_set_username(cli, state->user);
750 if (tevent_req_nterror(req, status)) {
753 if (strstr(cli->server_type, "Samba")) {
754 cli->is_samba = True;
756 tevent_req_done(req);
759 static NTSTATUS cli_session_setup_plain_recv(struct tevent_req *req)
761 return tevent_req_simple_recv_ntstatus(req);
764 static NTSTATUS cli_session_setup_plain(struct cli_state *cli,
765 const char *user, const char *pass,
766 const char *workgroup)
768 TALLOC_CTX *frame = talloc_stackframe();
769 struct event_context *ev;
770 struct tevent_req *req;
771 NTSTATUS status = NT_STATUS_NO_MEMORY;
773 if (cli_has_async_calls(cli)) {
775 * Can't use sync call while an async call is in flight
777 status = NT_STATUS_INVALID_PARAMETER;
780 ev = event_context_init(frame);
784 req = cli_session_setup_plain_send(frame, ev, cli, user, pass,
789 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
792 status = cli_session_setup_plain_recv(req);
795 if (!NT_STATUS_IS_OK(status)) {
796 cli_set_error(cli, status);
801 /****************************************************************************
802 do a NT1 NTLM/LM encrypted session setup - for when extended security
804 @param cli client state to create do session setup on
806 @param pass *either* cleartext password (passlen !=24) or LM response.
807 @param ntpass NT response, implies ntpasslen >=24, implies pass is not clear
808 @param workgroup The user's domain.
809 ****************************************************************************/
811 struct cli_session_setup_nt1_state {
812 struct cli_state *cli;
815 DATA_BLOB session_key;
819 static void cli_session_setup_nt1_done(struct tevent_req *subreq);
821 static struct tevent_req *cli_session_setup_nt1_send(
822 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
823 struct cli_state *cli, const char *user,
824 const char *pass, size_t passlen,
825 const char *ntpass, size_t ntpasslen,
826 const char *workgroup)
828 struct tevent_req *req, *subreq;
829 struct cli_session_setup_nt1_state *state;
830 DATA_BLOB lm_response = data_blob_null;
831 DATA_BLOB nt_response = data_blob_null;
832 DATA_BLOB session_key = data_blob_null;
835 char *workgroup_upper;
837 req = tevent_req_create(mem_ctx, &state,
838 struct cli_session_setup_nt1_state);
847 /* do nothing - guest login */
848 } else if (passlen != 24) {
849 if (lp_client_ntlmv2_auth()) {
850 DATA_BLOB server_chal;
851 DATA_BLOB names_blob;
853 server_chal = data_blob(cli->secblob.data,
854 MIN(cli->secblob.length, 8));
855 if (tevent_req_nomem(server_chal.data, req)) {
856 return tevent_req_post(req, ev);
860 * note that the 'workgroup' here is a best
861 * guess - we don't know the server's domain
862 * at this point. The 'server name' is also
865 names_blob = NTLMv2_generate_names_blob(
866 NULL, cli->called.name, workgroup);
868 if (tevent_req_nomem(names_blob.data, req)) {
869 return tevent_req_post(req, ev);
872 if (!SMBNTLMv2encrypt(NULL, user, workgroup, pass,
873 &server_chal, &names_blob,
874 &lm_response, &nt_response,
875 NULL, &session_key)) {
876 data_blob_free(&names_blob);
877 data_blob_free(&server_chal);
879 req, NT_STATUS_ACCESS_DENIED);
880 return tevent_req_post(req, ev);
882 data_blob_free(&names_blob);
883 data_blob_free(&server_chal);
887 E_md4hash(pass, nt_hash);
890 nt_response = data_blob_null;
892 nt_response = data_blob(NULL, 24);
893 if (tevent_req_nomem(nt_response.data, req)) {
894 return tevent_req_post(req, ev);
897 SMBNTencrypt(pass, cli->secblob.data,
900 /* non encrypted password supplied. Ignore ntpass. */
901 if (lp_client_lanman_auth()) {
903 lm_response = data_blob(NULL, 24);
904 if (tevent_req_nomem(lm_response.data, req)) {
905 return tevent_req_post(req, ev);
908 if (!SMBencrypt(pass,cli->secblob.data,
911 * Oops, the LM response is
912 * invalid, just put the NT
913 * response there instead
915 data_blob_free(&lm_response);
916 lm_response = data_blob(
922 * LM disabled, place NT# in LM field
925 lm_response = data_blob(
926 nt_response.data, nt_response.length);
929 if (tevent_req_nomem(lm_response.data, req)) {
930 return tevent_req_post(req, ev);
933 session_key = data_blob(NULL, 16);
934 if (tevent_req_nomem(session_key.data, req)) {
935 return tevent_req_post(req, ev);
938 E_deshash(pass, session_key.data);
939 memset(&session_key.data[8], '\0', 8);
941 SMBsesskeygen_ntv1(nt_hash, session_key.data);
944 cli_temp_set_signing(cli);
946 /* pre-encrypted password supplied. Only used for
947 security=server, can't do
948 signing because we don't have original key */
950 lm_response = data_blob(pass, passlen);
951 if (tevent_req_nomem(lm_response.data, req)) {
952 return tevent_req_post(req, ev);
955 nt_response = data_blob(ntpass, ntpasslen);
956 if (tevent_req_nomem(nt_response.data, req)) {
957 return tevent_req_post(req, ev);
962 state->response = data_blob_talloc(
963 state, lm_response.data, lm_response.length);
965 state->response = data_blob_talloc(
966 state, nt_response.data, nt_response.length);
968 if (tevent_req_nomem(state->response.data, req)) {
969 return tevent_req_post(req, ev);
972 if (session_key.data) {
973 state->session_key = data_blob_talloc(
974 state, session_key.data, session_key.length);
975 if (tevent_req_nomem(state->session_key.data, req)) {
976 return tevent_req_post(req, ev);
979 data_blob_free(&session_key);
981 SCVAL(vwv+0, 0, 0xff);
984 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
986 SSVAL(vwv+4, 0, cli->pid);
987 SIVAL(vwv+5, 0, cli->sesskey);
988 SSVAL(vwv+7, 0, lm_response.length);
989 SSVAL(vwv+8, 0, nt_response.length);
992 SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli));
994 bytes = talloc_array(state, uint8_t,
995 lm_response.length + nt_response.length);
996 if (tevent_req_nomem(bytes, req)) {
997 return tevent_req_post(req, ev);
999 if (lm_response.length != 0) {
1000 memcpy(bytes, lm_response.data, lm_response.length);
1002 if (nt_response.length != 0) {
1003 memcpy(bytes + lm_response.length,
1004 nt_response.data, nt_response.length);
1006 data_blob_free(&lm_response);
1007 data_blob_free(&nt_response);
1009 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
1010 user, strlen(user)+1, NULL);
1013 * Upper case here might help some NTLMv2 implementations
1015 workgroup_upper = talloc_strdup_upper(talloc_tos(), workgroup);
1016 if (tevent_req_nomem(workgroup_upper, req)) {
1017 return tevent_req_post(req, ev);
1019 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
1020 workgroup_upper, strlen(workgroup_upper)+1,
1022 TALLOC_FREE(workgroup_upper);
1024 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Unix", 5, NULL);
1025 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Samba", 6, NULL);
1026 if (tevent_req_nomem(bytes, req)) {
1027 return tevent_req_post(req, ev);
1030 subreq = cli_smb_send(state, ev, cli, SMBsesssetupX, 0, 13, vwv,
1031 talloc_get_size(bytes), bytes);
1032 if (tevent_req_nomem(subreq, req)) {
1033 return tevent_req_post(req, ev);
1035 tevent_req_set_callback(subreq, cli_session_setup_nt1_done, req);
1039 static void cli_session_setup_nt1_done(struct tevent_req *subreq)
1041 struct tevent_req *req = tevent_req_callback_data(
1042 subreq, struct tevent_req);
1043 struct cli_session_setup_nt1_state *state = tevent_req_data(
1044 req, struct cli_session_setup_nt1_state);
1045 struct cli_state *cli = state->cli;
1054 status = cli_smb_recv(subreq, state, &in, 0, NULL, NULL,
1055 &num_bytes, &bytes);
1056 TALLOC_FREE(subreq);
1057 if (!NT_STATUS_IS_OK(status)) {
1058 tevent_req_nterror(req, status);
1065 cli->vuid = SVAL(inbuf, smb_uid);
1067 status = smb_bytes_talloc_string(cli,
1073 if (!NT_STATUS_IS_OK(status)) {
1074 tevent_req_nterror(req, status);
1079 status = smb_bytes_talloc_string(cli,
1085 if (!NT_STATUS_IS_OK(status)) {
1086 tevent_req_nterror(req, status);
1091 status = smb_bytes_talloc_string(cli,
1093 &cli->server_domain,
1097 if (!NT_STATUS_IS_OK(status)) {
1098 tevent_req_nterror(req, status);
1103 if (strstr(cli->server_type, "Samba")) {
1104 cli->is_samba = True;
1107 status = cli_set_username(cli, state->user);
1108 if (tevent_req_nterror(req, status)) {
1111 if (cli_simple_set_signing(cli, state->session_key, state->response)
1112 && !cli_check_sign_mac(cli, (char *)in, 1)) {
1113 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1116 if (state->session_key.data) {
1117 /* Have plaintext orginal */
1118 cli_set_session_key(cli, state->session_key);
1120 tevent_req_done(req);
1123 static NTSTATUS cli_session_setup_nt1_recv(struct tevent_req *req)
1125 return tevent_req_simple_recv_ntstatus(req);
1128 static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user,
1129 const char *pass, size_t passlen,
1130 const char *ntpass, size_t ntpasslen,
1131 const char *workgroup)
1133 TALLOC_CTX *frame = talloc_stackframe();
1134 struct event_context *ev;
1135 struct tevent_req *req;
1136 NTSTATUS status = NT_STATUS_NO_MEMORY;
1138 if (cli_has_async_calls(cli)) {
1140 * Can't use sync call while an async call is in flight
1142 status = NT_STATUS_INVALID_PARAMETER;
1145 ev = event_context_init(frame);
1149 req = cli_session_setup_nt1_send(frame, ev, cli, user, pass, passlen,
1150 ntpass, ntpasslen, workgroup);
1154 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1157 status = cli_session_setup_nt1_recv(req);
1160 if (!NT_STATUS_IS_OK(status)) {
1161 cli_set_error(cli, status);
1166 /* The following is calculated from :
1168 * (smb_wcnt * 2) = 24 (smb_wcnt == 12 in cli_session_setup_blob_send() )
1169 * (strlen("Unix") + 1 + strlen("Samba") + 1) * 2 = 22 (unicode strings at
1173 #define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22)
1175 struct cli_sesssetup_blob_state {
1176 struct tevent_context *ev;
1177 struct cli_state *cli;
1179 uint16_t max_blob_size;
1188 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state *state,
1189 struct tevent_req **psubreq);
1190 static void cli_sesssetup_blob_done(struct tevent_req *subreq);
1192 static struct tevent_req *cli_sesssetup_blob_send(TALLOC_CTX *mem_ctx,
1193 struct tevent_context *ev,
1194 struct cli_state *cli,
1197 struct tevent_req *req, *subreq;
1198 struct cli_sesssetup_blob_state *state;
1200 req = tevent_req_create(mem_ctx, &state,
1201 struct cli_sesssetup_blob_state);
1209 if (cli->max_xmit < BASE_SESSSETUP_BLOB_PACKET_SIZE + 1) {
1210 DEBUG(1, ("cli_session_setup_blob: cli->max_xmit too small "
1211 "(was %u, need minimum %u)\n",
1212 (unsigned int)cli->max_xmit,
1213 BASE_SESSSETUP_BLOB_PACKET_SIZE));
1214 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1215 return tevent_req_post(req, ev);
1217 state->max_blob_size =
1218 MIN(cli->max_xmit - BASE_SESSSETUP_BLOB_PACKET_SIZE, 0xFFFF);
1220 if (!cli_sesssetup_blob_next(state, &subreq)) {
1221 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1222 return tevent_req_post(req, ev);
1224 tevent_req_set_callback(subreq, cli_sesssetup_blob_done, req);
1228 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state *state,
1229 struct tevent_req **psubreq)
1231 struct tevent_req *subreq;
1234 SCVAL(state->vwv+0, 0, 0xFF);
1235 SCVAL(state->vwv+0, 1, 0);
1236 SSVAL(state->vwv+1, 0, 0);
1237 SSVAL(state->vwv+2, 0, CLI_BUFFER_SIZE);
1238 SSVAL(state->vwv+3, 0, 2);
1239 SSVAL(state->vwv+4, 0, 1);
1240 SIVAL(state->vwv+5, 0, 0);
1242 thistime = MIN(state->blob.length, state->max_blob_size);
1243 SSVAL(state->vwv+7, 0, thistime);
1245 SSVAL(state->vwv+8, 0, 0);
1246 SSVAL(state->vwv+9, 0, 0);
1247 SIVAL(state->vwv+10, 0,
1248 cli_session_setup_capabilities(state->cli)
1249 | CAP_EXTENDED_SECURITY);
1251 state->buf = (uint8_t *)talloc_memdup(state, state->blob.data,
1253 if (state->buf == NULL) {
1256 state->blob.data += thistime;
1257 state->blob.length -= thistime;
1259 state->buf = smb_bytes_push_str(state->buf, cli_ucs2(state->cli),
1261 state->buf = smb_bytes_push_str(state->buf, cli_ucs2(state->cli),
1263 if (state->buf == NULL) {
1266 subreq = cli_smb_send(state, state->ev, state->cli, SMBsesssetupX, 0,
1268 talloc_get_size(state->buf), state->buf);
1269 if (subreq == NULL) {
1276 static void cli_sesssetup_blob_done(struct tevent_req *subreq)
1278 struct tevent_req *req = tevent_req_callback_data(
1279 subreq, struct tevent_req);
1280 struct cli_sesssetup_blob_state *state = tevent_req_data(
1281 req, struct cli_sesssetup_blob_state);
1282 struct cli_state *cli = state->cli;
1289 uint16_t blob_length;
1293 status = cli_smb_recv(subreq, state, &inbuf, 1, &wct, &vwv,
1294 &num_bytes, &bytes);
1295 TALLOC_FREE(subreq);
1296 if (!NT_STATUS_IS_OK(status)
1297 && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1298 tevent_req_nterror(req, status);
1302 state->status = status;
1303 TALLOC_FREE(state->buf);
1305 state->inbuf = (char *)inbuf;
1306 cli->vuid = SVAL(state->inbuf, smb_uid);
1308 blob_length = SVAL(vwv+3, 0);
1309 if (blob_length > num_bytes) {
1310 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1313 state->ret_blob = data_blob_const(bytes, blob_length);
1315 p = bytes + blob_length;
1317 status = smb_bytes_talloc_string(cli,
1324 if (!NT_STATUS_IS_OK(status)) {
1325 tevent_req_nterror(req, status);
1330 status = smb_bytes_talloc_string(cli,
1337 if (!NT_STATUS_IS_OK(status)) {
1338 tevent_req_nterror(req, status);
1343 status = smb_bytes_talloc_string(cli,
1345 &cli->server_domain,
1350 if (!NT_STATUS_IS_OK(status)) {
1351 tevent_req_nterror(req, status);
1356 if (strstr(cli->server_type, "Samba")) {
1357 cli->is_samba = True;
1360 if (state->blob.length != 0) {
1364 if (!cli_sesssetup_blob_next(state, &subreq)) {
1365 tevent_req_nomem(NULL, req);
1368 tevent_req_set_callback(subreq, cli_sesssetup_blob_done, req);
1371 tevent_req_done(req);
1374 static NTSTATUS cli_sesssetup_blob_recv(struct tevent_req *req,
1375 TALLOC_CTX *mem_ctx,
1379 struct cli_sesssetup_blob_state *state = tevent_req_data(
1380 req, struct cli_sesssetup_blob_state);
1384 if (tevent_req_is_nterror(req, &status)) {
1385 state->cli->vuid = 0;
1389 inbuf = talloc_move(mem_ctx, &state->inbuf);
1390 if (pblob != NULL) {
1391 *pblob = state->ret_blob;
1393 if (pinbuf != NULL) {
1396 /* could be NT_STATUS_MORE_PROCESSING_REQUIRED */
1397 return state->status;
1402 /****************************************************************************
1403 Use in-memory credentials cache
1404 ****************************************************************************/
1406 static void use_in_memory_ccache(void) {
1407 setenv(KRB5_ENV_CCNAME, "MEMORY:cliconnect", 1);
1410 /****************************************************************************
1411 Do a spnego/kerberos encrypted session setup.
1412 ****************************************************************************/
1414 struct cli_session_setup_kerberos_state {
1415 struct cli_state *cli;
1416 DATA_BLOB negTokenTarg;
1417 DATA_BLOB session_key_krb5;
1418 ADS_STATUS ads_status;
1421 static void cli_session_setup_kerberos_done(struct tevent_req *subreq);
1423 static struct tevent_req *cli_session_setup_kerberos_send(
1424 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
1425 const char *principal, const char *workgroup)
1427 struct tevent_req *req, *subreq;
1428 struct cli_session_setup_kerberos_state *state;
1431 DEBUG(2,("Doing kerberos session setup\n"));
1433 req = tevent_req_create(mem_ctx, &state,
1434 struct cli_session_setup_kerberos_state);
1439 state->ads_status = ADS_SUCCESS;
1441 cli_temp_set_signing(cli);
1444 * Ok, this is cheating: spnego_gen_krb5_negTokenInit can block if
1445 * we have to acquire a ticket. To be fixed later :-)
1447 rc = spnego_gen_krb5_negTokenInit(state, principal, 0, &state->negTokenTarg,
1448 &state->session_key_krb5, 0, NULL);
1450 DEBUG(1, ("cli_session_setup_kerberos: "
1451 "spnego_gen_krb5_negTokenInit failed: %s\n",
1452 error_message(rc)));
1453 state->ads_status = ADS_ERROR_KRB5(rc);
1454 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
1455 return tevent_req_post(req, ev);
1459 file_save("negTokenTarg.dat", state->negTokenTarg.data,
1460 state->negTokenTarg.length);
1463 subreq = cli_sesssetup_blob_send(state, ev, cli, state->negTokenTarg);
1464 if (tevent_req_nomem(subreq, req)) {
1465 return tevent_req_post(req, ev);
1467 tevent_req_set_callback(subreq, cli_session_setup_kerberos_done, req);
1471 static void cli_session_setup_kerberos_done(struct tevent_req *subreq)
1473 struct tevent_req *req = tevent_req_callback_data(
1474 subreq, struct tevent_req);
1475 struct cli_session_setup_kerberos_state *state = tevent_req_data(
1476 req, struct cli_session_setup_kerberos_state);
1480 status = cli_sesssetup_blob_recv(subreq, talloc_tos(), NULL, &inbuf);
1481 if (!NT_STATUS_IS_OK(status)) {
1482 TALLOC_FREE(subreq);
1483 tevent_req_nterror(req, status);
1487 cli_set_session_key(state->cli, state->session_key_krb5);
1489 if (cli_simple_set_signing(state->cli, state->session_key_krb5,
1491 && !cli_check_sign_mac(state->cli, inbuf, 1)) {
1492 TALLOC_FREE(subreq);
1493 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1496 TALLOC_FREE(subreq);
1497 tevent_req_done(req);
1500 static ADS_STATUS cli_session_setup_kerberos_recv(struct tevent_req *req)
1502 struct cli_session_setup_kerberos_state *state = tevent_req_data(
1503 req, struct cli_session_setup_kerberos_state);
1506 if (tevent_req_is_nterror(req, &status)) {
1507 return ADS_ERROR_NT(status);
1509 return state->ads_status;
1512 static ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli,
1513 const char *principal,
1514 const char *workgroup)
1516 struct tevent_context *ev;
1517 struct tevent_req *req;
1518 ADS_STATUS status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1520 if (cli_has_async_calls(cli)) {
1521 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1523 ev = tevent_context_init(talloc_tos());
1527 req = cli_session_setup_kerberos_send(ev, ev, cli, principal,
1532 if (!tevent_req_poll(req, ev)) {
1533 status = ADS_ERROR_SYSTEM(errno);
1536 status = cli_session_setup_kerberos_recv(req);
1541 #endif /* HAVE_KRB5 */
1543 /****************************************************************************
1544 Do a spnego/NTLMSSP encrypted session setup.
1545 ****************************************************************************/
1547 struct cli_session_setup_ntlmssp_state {
1548 struct tevent_context *ev;
1549 struct cli_state *cli;
1550 struct ntlmssp_state *ntlmssp_state;
1555 static int cli_session_setup_ntlmssp_state_destructor(
1556 struct cli_session_setup_ntlmssp_state *state)
1558 if (state->ntlmssp_state != NULL) {
1559 TALLOC_FREE(state->ntlmssp_state);
1564 static void cli_session_setup_ntlmssp_done(struct tevent_req *req);
1566 static struct tevent_req *cli_session_setup_ntlmssp_send(
1567 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
1568 const char *user, const char *pass, const char *domain)
1570 struct tevent_req *req, *subreq;
1571 struct cli_session_setup_ntlmssp_state *state;
1574 const char *OIDs_ntlm[] = {OID_NTLMSSP, NULL};
1576 req = tevent_req_create(mem_ctx, &state,
1577 struct cli_session_setup_ntlmssp_state);
1585 state->ntlmssp_state = NULL;
1586 talloc_set_destructor(
1587 state, cli_session_setup_ntlmssp_state_destructor);
1589 cli_temp_set_signing(cli);
1591 status = ntlmssp_client_start(state,
1594 lp_client_ntlmv2_auth(),
1595 &state->ntlmssp_state);
1596 if (!NT_STATUS_IS_OK(status)) {
1599 ntlmssp_want_feature(state->ntlmssp_state,
1600 NTLMSSP_FEATURE_SESSION_KEY);
1601 if (cli->use_ccache) {
1602 ntlmssp_want_feature(state->ntlmssp_state,
1603 NTLMSSP_FEATURE_CCACHE);
1605 status = ntlmssp_set_username(state->ntlmssp_state, user);
1606 if (!NT_STATUS_IS_OK(status)) {
1609 status = ntlmssp_set_domain(state->ntlmssp_state, domain);
1610 if (!NT_STATUS_IS_OK(status)) {
1613 status = ntlmssp_set_password(state->ntlmssp_state, pass);
1614 if (!NT_STATUS_IS_OK(status)) {
1617 status = ntlmssp_update(state->ntlmssp_state, data_blob_null,
1619 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1623 state->blob_out = spnego_gen_negTokenInit(state, OIDs_ntlm, &blob_out, NULL);
1624 data_blob_free(&blob_out);
1626 subreq = cli_sesssetup_blob_send(state, ev, cli, state->blob_out);
1627 if (tevent_req_nomem(subreq, req)) {
1628 return tevent_req_post(req, ev);
1630 tevent_req_set_callback(subreq, cli_session_setup_ntlmssp_done, req);
1633 tevent_req_nterror(req, status);
1634 return tevent_req_post(req, ev);
1637 static void cli_session_setup_ntlmssp_done(struct tevent_req *subreq)
1639 struct tevent_req *req = tevent_req_callback_data(
1640 subreq, struct tevent_req);
1641 struct cli_session_setup_ntlmssp_state *state = tevent_req_data(
1642 req, struct cli_session_setup_ntlmssp_state);
1643 DATA_BLOB blob_in, msg_in, blob_out;
1648 status = cli_sesssetup_blob_recv(subreq, talloc_tos(), &blob_in,
1650 TALLOC_FREE(subreq);
1651 data_blob_free(&state->blob_out);
1653 if (NT_STATUS_IS_OK(status)) {
1654 if (state->cli->server_domain[0] == '\0') {
1655 TALLOC_FREE(state->cli->server_domain);
1656 state->cli->server_domain = talloc_strdup(state->cli,
1657 state->ntlmssp_state->server.netbios_domain);
1658 if (state->cli->server_domain == NULL) {
1659 TALLOC_FREE(subreq);
1660 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1664 cli_set_session_key(
1665 state->cli, state->ntlmssp_state->session_key);
1667 if (cli_simple_set_signing(
1668 state->cli, state->ntlmssp_state->session_key,
1670 && !cli_check_sign_mac(state->cli, inbuf, 1)) {
1671 TALLOC_FREE(subreq);
1672 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1675 TALLOC_FREE(subreq);
1676 TALLOC_FREE(state->ntlmssp_state);
1677 tevent_req_done(req);
1680 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1681 tevent_req_nterror(req, status);
1685 if (blob_in.length == 0) {
1686 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
1690 if ((state->turn == 1)
1691 && NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1692 DATA_BLOB tmp_blob = data_blob_null;
1693 /* the server might give us back two challenges */
1694 parse_ret = spnego_parse_challenge(state, blob_in, &msg_in,
1696 data_blob_free(&tmp_blob);
1698 parse_ret = spnego_parse_auth_response(state, blob_in, status,
1699 OID_NTLMSSP, &msg_in);
1704 DEBUG(3,("Failed to parse auth response\n"));
1705 if (NT_STATUS_IS_OK(status)
1706 || NT_STATUS_EQUAL(status,
1707 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1709 req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1714 status = ntlmssp_update(state->ntlmssp_state, msg_in, &blob_out);
1716 if (!NT_STATUS_IS_OK(status)
1717 && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1718 TALLOC_FREE(subreq);
1719 TALLOC_FREE(state->ntlmssp_state);
1720 tevent_req_nterror(req, status);
1724 state->blob_out = spnego_gen_auth(state, blob_out);
1725 TALLOC_FREE(subreq);
1726 if (tevent_req_nomem(state->blob_out.data, req)) {
1730 subreq = cli_sesssetup_blob_send(state, state->ev, state->cli,
1732 if (tevent_req_nomem(subreq, req)) {
1735 tevent_req_set_callback(subreq, cli_session_setup_ntlmssp_done, req);
1738 static NTSTATUS cli_session_setup_ntlmssp_recv(struct tevent_req *req)
1740 struct cli_session_setup_ntlmssp_state *state = tevent_req_data(
1741 req, struct cli_session_setup_ntlmssp_state);
1744 if (tevent_req_is_nterror(req, &status)) {
1745 state->cli->vuid = 0;
1748 return NT_STATUS_OK;
1751 static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli,
1756 struct tevent_context *ev;
1757 struct tevent_req *req;
1758 NTSTATUS status = NT_STATUS_NO_MEMORY;
1760 if (cli_has_async_calls(cli)) {
1761 return NT_STATUS_INVALID_PARAMETER;
1763 ev = tevent_context_init(talloc_tos());
1767 req = cli_session_setup_ntlmssp_send(ev, ev, cli, user, pass, domain);
1771 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1774 status = cli_session_setup_ntlmssp_recv(req);
1777 if (!NT_STATUS_IS_OK(status)) {
1778 cli_set_error(cli, status);
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 ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user,
1791 const char *pass, const char *user_domain,
1792 const char * dest_realm)
1794 char *principal = NULL;
1795 char *OIDs[ASN1_MAX_OIDS];
1798 const char *p = NULL;
1799 char *account = NULL;
1802 DEBUG(3,("Doing spnego session setup (blob length=%lu)\n", (unsigned long)cli->secblob.length));
1804 /* the server might not even do spnego */
1805 if (cli->secblob.length <= 16) {
1806 DEBUG(3,("server didn't supply a full spnego negprot\n"));
1811 file_save("negprot.dat", cli->secblob.data, cli->secblob.length);
1814 /* there is 16 bytes of GUID before the real spnego packet starts */
1815 blob = data_blob(cli->secblob.data+16, cli->secblob.length-16);
1817 /* The server sent us the first part of the SPNEGO exchange in the
1818 * negprot reply. It is WRONG to depend on the principal sent in the
1819 * negprot reply, but right now we do it. If we don't receive one,
1820 * we try to best guess, then fall back to NTLM. */
1821 if (!spnego_parse_negTokenInit(talloc_tos(), blob, OIDs, &principal, NULL) ||
1823 data_blob_free(&blob);
1824 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1826 data_blob_free(&blob);
1828 /* make sure the server understands kerberos */
1829 for (i=0;OIDs[i];i++) {
1831 DEBUG(3,("got OID=%s\n", OIDs[i]));
1833 DEBUGADD(3,("got OID=%s\n", OIDs[i]));
1834 if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0 ||
1835 strcmp(OIDs[i], OID_KERBEROS5) == 0) {
1836 cli->got_kerberos_mechanism = True;
1838 talloc_free(OIDs[i]);
1841 DEBUG(3,("got principal=%s\n", principal ? principal : "<null>"));
1843 status = cli_set_username(cli, user);
1844 if (!NT_STATUS_IS_OK(status)) {
1845 TALLOC_FREE(principal);
1846 return ADS_ERROR_NT(status);
1850 /* If password is set we reauthenticate to kerberos server
1851 * and do not store results */
1853 if (cli->got_kerberos_mechanism && cli->use_kerberos) {
1856 if (pass && *pass) {
1859 use_in_memory_ccache();
1860 ret = kerberos_kinit_password(user, pass, 0 /* no time correction for now */, NULL);
1863 TALLOC_FREE(principal);
1864 DEBUG(0, ("Kinit failed: %s\n", error_message(ret)));
1865 if (cli->fallback_after_kerberos)
1867 return ADS_ERROR_KRB5(ret);
1871 /* We may not be allowed to use the server-supplied SPNEGO principal, or it may not have been supplied to us
1873 if (!lp_client_use_spnego_principal() || strequal(principal, ADS_IGNORE_PRINCIPAL)) {
1874 TALLOC_FREE(principal);
1877 if (principal == NULL &&
1878 !is_ipaddress(cli->desthost) &&
1879 !strequal(STAR_SMBSERVER,
1883 DEBUG(3,("cli_session_setup_spnego: using target "
1884 "hostname not SPNEGO principal\n"));
1886 host = strchr_m(cli->desthost, '.');
1888 realm = SMB_STRDUP(dest_realm);
1893 realm = kerberos_get_realm_from_hostname(cli->desthost);
1895 /* NetBIOS name - use our realm. */
1896 realm = kerberos_get_default_realm_from_ccache();
1900 if (realm && *realm) {
1901 principal = talloc_asprintf(talloc_tos(),
1907 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1909 DEBUG(3,("cli_session_setup_spnego: guessed "
1910 "server principal=%s\n",
1911 principal ? principal : "<null>"));
1917 rc = cli_session_setup_kerberos(cli, principal,
1919 if (ADS_ERR_OK(rc) || !cli->fallback_after_kerberos) {
1920 TALLOC_FREE(principal);
1927 TALLOC_FREE(principal);
1931 account = talloc_strdup(talloc_tos(), user);
1933 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1936 /* when falling back to ntlmssp while authenticating with a machine
1937 * account strip off the realm - gd */
1939 if ((p = strchr_m(user, '@')) != NULL) {
1940 account[PTR_DIFF(p,user)] = '\0';
1943 return ADS_ERROR_NT(cli_session_setup_ntlmssp(cli, account, pass, user_domain));
1946 /****************************************************************************
1947 Send a session setup. The username and workgroup is in UNIX character
1948 format and must be converted to DOS codepage format before sending. If the
1949 password is in plaintext, the same should be done.
1950 ****************************************************************************/
1952 NTSTATUS cli_session_setup(struct cli_state *cli,
1954 const char *pass, int passlen,
1955 const char *ntpass, int ntpasslen,
1956 const char *workgroup)
1962 user2 = talloc_strdup(talloc_tos(), user);
1964 user2 = talloc_strdup(talloc_tos(), "");
1966 if (user2 == NULL) {
1967 return NT_STATUS_NO_MEMORY;
1974 /* allow for workgroups as part of the username */
1975 if ((p=strchr_m(user2,'\\')) || (p=strchr_m(user2,'/')) ||
1976 (p=strchr_m(user2,*lp_winbind_separator()))) {
1982 if (cli->protocol < PROTOCOL_LANMAN1) {
1983 return NT_STATUS_OK;
1986 /* now work out what sort of session setup we are going to
1987 do. I have split this into separate functions to make the
1988 flow a bit easier to understand (tridge) */
1990 /* if its an older server then we have to use the older request format */
1992 if (cli->protocol < PROTOCOL_NT1) {
1993 if (!lp_client_lanman_auth() && passlen != 24 && (*pass)) {
1994 DEBUG(1, ("Server requested LM password but 'client lanman auth = no'"
1995 " or 'client ntlmv2 auth = yes'\n"));
1996 return NT_STATUS_ACCESS_DENIED;
1999 if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0 &&
2000 !lp_client_plaintext_auth() && (*pass)) {
2001 DEBUG(1, ("Server requested LM password but 'client plaintext auth = no'"
2002 " or 'client ntlmv2 auth = yes'\n"));
2003 return NT_STATUS_ACCESS_DENIED;
2006 return cli_session_setup_lanman2(cli, user, pass, passlen,
2010 /* if no user is supplied then we have to do an anonymous connection.
2011 passwords are ignored */
2013 if (!user || !*user)
2014 return cli_session_setup_guest(cli);
2016 /* if the server is share level then send a plaintext null
2017 password at this point. The password is sent in the tree
2020 if ((cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0)
2021 return cli_session_setup_plain(cli, user, "", workgroup);
2023 /* if the server doesn't support encryption then we have to use
2024 plaintext. The second password is ignored */
2026 if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) {
2027 if (!lp_client_plaintext_auth() && (*pass)) {
2028 DEBUG(1, ("Server requested LM password but 'client plaintext auth = no'"
2029 " or 'client ntlmv2 auth = yes'\n"));
2030 return NT_STATUS_ACCESS_DENIED;
2032 return cli_session_setup_plain(cli, user, pass, workgroup);
2035 /* if the server supports extended security then use SPNEGO */
2037 if (cli->capabilities & CAP_EXTENDED_SECURITY) {
2038 ADS_STATUS status = cli_session_setup_spnego(cli, user, pass,
2040 if (!ADS_ERR_OK(status)) {
2041 DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status)));
2042 return ads_ntstatus(status);
2047 /* otherwise do a NT1 style session setup */
2048 status = cli_session_setup_nt1(cli, user, pass, passlen,
2049 ntpass, ntpasslen, workgroup);
2050 if (!NT_STATUS_IS_OK(status)) {
2051 DEBUG(3,("cli_session_setup: NT1 session setup "
2052 "failed: %s\n", nt_errstr(status)));
2057 if (strstr(cli->server_type, "Samba")) {
2058 cli->is_samba = True;
2061 return NT_STATUS_OK;
2064 /****************************************************************************
2066 *****************************************************************************/
2068 struct cli_ulogoff_state {
2069 struct cli_state *cli;
2073 static void cli_ulogoff_done(struct tevent_req *subreq);
2075 struct tevent_req *cli_ulogoff_send(TALLOC_CTX *mem_ctx,
2076 struct tevent_context *ev,
2077 struct cli_state *cli)
2079 struct tevent_req *req, *subreq;
2080 struct cli_ulogoff_state *state;
2082 req = tevent_req_create(mem_ctx, &state, struct cli_ulogoff_state);
2088 SCVAL(state->vwv+0, 0, 0xFF);
2089 SCVAL(state->vwv+1, 0, 0);
2090 SSVAL(state->vwv+2, 0, 0);
2092 subreq = cli_smb_send(state, ev, cli, SMBulogoffX, 0, 2, state->vwv,
2094 if (tevent_req_nomem(subreq, req)) {
2095 return tevent_req_post(req, ev);
2097 tevent_req_set_callback(subreq, cli_ulogoff_done, req);
2101 static void cli_ulogoff_done(struct tevent_req *subreq)
2103 struct tevent_req *req = tevent_req_callback_data(
2104 subreq, struct tevent_req);
2105 struct cli_ulogoff_state *state = tevent_req_data(
2106 req, struct cli_ulogoff_state);
2109 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
2110 if (!NT_STATUS_IS_OK(status)) {
2111 tevent_req_nterror(req, status);
2114 state->cli->vuid = -1;
2115 tevent_req_done(req);
2118 NTSTATUS cli_ulogoff_recv(struct tevent_req *req)
2120 return tevent_req_simple_recv_ntstatus(req);
2123 NTSTATUS cli_ulogoff(struct cli_state *cli)
2125 struct tevent_context *ev;
2126 struct tevent_req *req;
2127 NTSTATUS status = NT_STATUS_NO_MEMORY;
2129 if (cli_has_async_calls(cli)) {
2130 return NT_STATUS_INVALID_PARAMETER;
2132 ev = tevent_context_init(talloc_tos());
2136 req = cli_ulogoff_send(ev, ev, cli);
2140 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2143 status = cli_ulogoff_recv(req);
2146 if (!NT_STATUS_IS_OK(status)) {
2147 cli_set_error(cli, status);
2152 /****************************************************************************
2154 ****************************************************************************/
2156 struct cli_tcon_andx_state {
2157 struct cli_state *cli;
2162 static void cli_tcon_andx_done(struct tevent_req *subreq);
2164 struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx,
2165 struct event_context *ev,
2166 struct cli_state *cli,
2167 const char *share, const char *dev,
2168 const char *pass, int passlen,
2169 struct tevent_req **psmbreq)
2171 struct tevent_req *req, *subreq;
2172 struct cli_tcon_andx_state *state;
2180 req = tevent_req_create(mem_ctx, &state, struct cli_tcon_andx_state);
2187 cli->share = talloc_strdup(cli, share);
2192 /* in user level security don't send a password now */
2193 if (cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {
2196 } else if (pass == NULL) {
2197 DEBUG(1, ("Server not using user level security and no "
2198 "password supplied.\n"));
2202 if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) &&
2203 *pass && passlen != 24) {
2204 if (!lp_client_lanman_auth()) {
2205 DEBUG(1, ("Server requested LANMAN password "
2206 "(share-level security) but "
2207 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2212 * Non-encrypted passwords - convert to DOS codepage before
2215 SMBencrypt(pass, cli->secblob.data, p24);
2217 pass = (const char *)p24;
2219 if((cli->sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL
2220 |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE))
2224 if (!lp_client_plaintext_auth() && (*pass)) {
2225 DEBUG(1, ("Server requested plaintext "
2227 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2232 * Non-encrypted passwords - convert to DOS codepage
2235 tmp_pass = talloc_array(talloc_tos(), char, 128);
2236 if (tmp_pass == NULL) {
2237 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2238 return tevent_req_post(req, ev);
2240 passlen = clistr_push(cli,
2243 talloc_get_size(tmp_pass),
2245 if (passlen == -1) {
2246 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2247 return tevent_req_post(req, ev);
2253 SCVAL(vwv+0, 0, 0xFF);
2256 SSVAL(vwv+2, 0, TCONX_FLAG_EXTENDED_RESPONSE);
2257 SSVAL(vwv+3, 0, passlen);
2259 if (passlen && pass) {
2260 bytes = (uint8_t *)talloc_memdup(state, pass, passlen);
2262 bytes = talloc_array(state, uint8_t, 0);
2268 tmp = talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
2269 cli->desthost, share);
2274 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), tmp, strlen(tmp)+1,
2279 * Add the devicetype
2281 tmp = talloc_strdup_upper(talloc_tos(), dev);
2286 bytes = smb_bytes_push_str(bytes, false, tmp, strlen(tmp)+1, NULL);
2289 if (bytes == NULL) {
2294 state->bytes.iov_base = (void *)bytes;
2295 state->bytes.iov_len = talloc_get_size(bytes);
2297 subreq = cli_smb_req_create(state, ev, cli, SMBtconX, 0, 4, vwv,
2299 if (subreq == NULL) {
2303 tevent_req_set_callback(subreq, cli_tcon_andx_done, req);
2308 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
2309 return tevent_req_post(req, ev);
2312 struct tevent_req *cli_tcon_andx_send(TALLOC_CTX *mem_ctx,
2313 struct event_context *ev,
2314 struct cli_state *cli,
2315 const char *share, const char *dev,
2316 const char *pass, int passlen)
2318 struct tevent_req *req, *subreq;
2321 req = cli_tcon_andx_create(mem_ctx, ev, cli, share, dev, pass, passlen,
2326 if (subreq == NULL) {
2329 status = cli_smb_req_send(subreq);
2330 if (!NT_STATUS_IS_OK(status)) {
2331 tevent_req_nterror(req, status);
2332 return tevent_req_post(req, ev);
2337 static void cli_tcon_andx_done(struct tevent_req *subreq)
2339 struct tevent_req *req = tevent_req_callback_data(
2340 subreq, struct tevent_req);
2341 struct cli_tcon_andx_state *state = tevent_req_data(
2342 req, struct cli_tcon_andx_state);
2343 struct cli_state *cli = state->cli;
2352 status = cli_smb_recv(subreq, state, &in, 0, &wct, &vwv,
2353 &num_bytes, &bytes);
2354 TALLOC_FREE(subreq);
2355 if (!NT_STATUS_IS_OK(status)) {
2356 tevent_req_nterror(req, status);
2363 if (clistr_pull_talloc(cli,
2365 SVAL(inbuf, smb_flg2),
2369 STR_TERMINATE|STR_ASCII) == -1) {
2370 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2374 cli->dev = talloc_strdup(cli, "");
2375 if (cli->dev == NULL) {
2376 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2381 if ((cli->protocol >= PROTOCOL_NT1) && (num_bytes == 3)) {
2382 /* almost certainly win95 - enable bug fixes */
2387 * Make sure that we have the optional support 16-bit field. WCT > 2.
2388 * Avoids issues when connecting to Win9x boxes sharing files
2391 cli->dfsroot = false;
2393 if ((wct > 2) && (cli->protocol >= PROTOCOL_LANMAN2)) {
2394 cli->dfsroot = ((SVAL(vwv+2, 0) & SMB_SHARE_IN_DFS) != 0);
2397 cli->cnum = SVAL(inbuf,smb_tid);
2398 tevent_req_done(req);
2401 NTSTATUS cli_tcon_andx_recv(struct tevent_req *req)
2403 return tevent_req_simple_recv_ntstatus(req);
2406 NTSTATUS cli_tcon_andx(struct cli_state *cli, const char *share,
2407 const char *dev, const char *pass, int passlen)
2409 TALLOC_CTX *frame = talloc_stackframe();
2410 struct event_context *ev;
2411 struct tevent_req *req;
2412 NTSTATUS status = NT_STATUS_OK;
2414 if (cli_has_async_calls(cli)) {
2416 * Can't use sync call while an async call is in flight
2418 status = NT_STATUS_INVALID_PARAMETER;
2422 ev = event_context_init(frame);
2424 status = NT_STATUS_NO_MEMORY;
2428 req = cli_tcon_andx_send(frame, ev, cli, share, dev, pass, passlen);
2430 status = NT_STATUS_NO_MEMORY;
2434 if (!tevent_req_poll(req, ev)) {
2435 status = map_nt_error_from_unix(errno);
2439 status = cli_tcon_andx_recv(req);
2442 if (!NT_STATUS_IS_OK(status)) {
2443 cli_set_error(cli, status);
2448 /****************************************************************************
2449 Send a tree disconnect.
2450 ****************************************************************************/
2452 struct cli_tdis_state {
2453 struct cli_state *cli;
2456 static void cli_tdis_done(struct tevent_req *subreq);
2458 struct tevent_req *cli_tdis_send(TALLOC_CTX *mem_ctx,
2459 struct tevent_context *ev,
2460 struct cli_state *cli)
2462 struct tevent_req *req, *subreq;
2463 struct cli_tdis_state *state;
2465 req = tevent_req_create(mem_ctx, &state, struct cli_tdis_state);
2471 subreq = cli_smb_send(state, ev, cli, SMBtdis, 0, 0, NULL, 0, NULL);
2472 if (tevent_req_nomem(subreq, req)) {
2473 return tevent_req_post(req, ev);
2475 tevent_req_set_callback(subreq, cli_tdis_done, req);
2479 static void cli_tdis_done(struct tevent_req *subreq)
2481 struct tevent_req *req = tevent_req_callback_data(
2482 subreq, struct tevent_req);
2483 struct cli_tdis_state *state = tevent_req_data(
2484 req, struct cli_tdis_state);
2487 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
2488 TALLOC_FREE(subreq);
2489 if (!NT_STATUS_IS_OK(status)) {
2490 tevent_req_nterror(req, status);
2493 state->cli->cnum = -1;
2494 tevent_req_done(req);
2497 NTSTATUS cli_tdis_recv(struct tevent_req *req)
2499 return tevent_req_simple_recv_ntstatus(req);
2502 NTSTATUS cli_tdis(struct cli_state *cli)
2504 struct tevent_context *ev;
2505 struct tevent_req *req;
2506 NTSTATUS status = NT_STATUS_NO_MEMORY;
2508 if (cli_has_async_calls(cli)) {
2509 return NT_STATUS_INVALID_PARAMETER;
2511 ev = tevent_context_init(talloc_tos());
2515 req = cli_tdis_send(ev, ev, cli);
2519 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2522 status = cli_tdis_recv(req);
2525 if (!NT_STATUS_IS_OK(status)) {
2526 cli_set_error(cli, status);
2531 /****************************************************************************
2532 Send a negprot command.
2533 ****************************************************************************/
2535 struct cli_negprot_state {
2536 struct cli_state *cli;
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)
2545 struct tevent_req *req, *subreq;
2546 struct cli_negprot_state *state;
2547 uint8_t *bytes = NULL;
2551 req = tevent_req_create(mem_ctx, &state, struct cli_negprot_state);
2557 if (cli->protocol < PROTOCOL_NT1)
2558 cli->use_spnego = False;
2560 /* setup the protocol strings */
2561 for (numprots=0; numprots < ARRAY_SIZE(prots); numprots++) {
2563 if (prots[numprots].prot > cli->protocol) {
2566 bytes = (uint8_t *)talloc_append_blob(
2567 state, bytes, data_blob_const(&c, sizeof(c)));
2568 if (tevent_req_nomem(bytes, req)) {
2569 return tevent_req_post(req, ev);
2571 bytes = smb_bytes_push_str(bytes, false,
2572 prots[numprots].name,
2573 strlen(prots[numprots].name)+1,
2575 if (tevent_req_nomem(bytes, req)) {
2576 return tevent_req_post(req, ev);
2583 subreq = cli_smb_send(state, ev, cli, SMBnegprot, 0, 0, NULL,
2584 talloc_get_size(bytes), bytes);
2587 if (tevent_req_nomem(subreq, req)) {
2588 return tevent_req_post(req, ev);
2590 tevent_req_set_callback(subreq, cli_negprot_done, req);
2594 static void cli_negprot_done(struct tevent_req *subreq)
2596 struct tevent_req *req = tevent_req_callback_data(
2597 subreq, struct tevent_req);
2598 struct cli_negprot_state *state = tevent_req_data(
2599 req, struct cli_negprot_state);
2600 struct cli_state *cli = state->cli;
2609 status = cli_smb_recv(subreq, state, &inbuf, 1, &wct, &vwv,
2610 &num_bytes, &bytes);
2611 TALLOC_FREE(subreq);
2612 if (!NT_STATUS_IS_OK(status)) {
2613 tevent_req_nterror(req, status);
2617 protnum = SVAL(vwv, 0);
2619 if ((protnum >= ARRAY_SIZE(prots))
2620 || (prots[protnum].prot > cli->protocol)) {
2621 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2625 cli->protocol = prots[protnum].prot;
2627 if ((cli->protocol < PROTOCOL_NT1) &&
2628 client_is_signing_mandatory(cli)) {
2629 DEBUG(0,("cli_negprot: SMB signing is mandatory and the selected protocol level doesn't support it.\n"));
2630 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
2634 if (cli->protocol >= PROTOCOL_NT1) {
2636 bool negotiated_smb_signing = false;
2639 cli->sec_mode = CVAL(vwv + 1, 0);
2640 cli->max_mux = SVAL(vwv + 1, 1);
2641 cli->max_xmit = IVAL(vwv + 3, 1);
2642 cli->sesskey = IVAL(vwv + 7, 1);
2643 cli->serverzone = SVALS(vwv + 15, 1);
2644 cli->serverzone *= 60;
2645 /* this time arrives in real GMT */
2646 ts = interpret_long_date(((char *)(vwv+11))+1);
2647 cli->servertime = ts.tv_sec;
2648 cli->secblob = data_blob(bytes, num_bytes);
2649 cli->capabilities = IVAL(vwv + 9, 1);
2650 if (cli->capabilities & CAP_RAW_MODE) {
2651 cli->readbraw_supported = True;
2652 cli->writebraw_supported = True;
2654 /* work out if they sent us a workgroup */
2655 if (!(cli->capabilities & CAP_EXTENDED_SECURITY) &&
2656 smb_buflen(cli->inbuf) > 8) {
2657 clistr_pull(cli->inbuf, cli->server_domain,
2658 bytes+8, sizeof(cli->server_domain),
2660 STR_UNICODE|STR_NOALIGN);
2664 * As signing is slow we only turn it on if either the client or
2665 * the server require it. JRA.
2668 if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) {
2669 /* Fail if server says signing is mandatory and we don't want to support it. */
2670 if (!client_is_signing_allowed(cli)) {
2671 DEBUG(0,("cli_negprot: SMB signing is mandatory and we have disabled it.\n"));
2672 tevent_req_nterror(req,
2673 NT_STATUS_ACCESS_DENIED);
2676 negotiated_smb_signing = true;
2677 } else if (client_is_signing_mandatory(cli) && client_is_signing_allowed(cli)) {
2678 /* Fail if client says signing is mandatory and the server doesn't support it. */
2679 if (!(cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) {
2680 DEBUG(1,("cli_negprot: SMB signing is mandatory and the server doesn't support it.\n"));
2681 tevent_req_nterror(req,
2682 NT_STATUS_ACCESS_DENIED);
2685 negotiated_smb_signing = true;
2686 } else if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) {
2687 negotiated_smb_signing = true;
2690 if (negotiated_smb_signing) {
2691 cli_set_signing_negotiated(cli);
2694 if (cli->capabilities & (CAP_LARGE_READX|CAP_LARGE_WRITEX)) {
2695 SAFE_FREE(cli->outbuf);
2696 SAFE_FREE(cli->inbuf);
2697 cli->outbuf = (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE+LARGE_WRITEX_HDR_SIZE+SAFETY_MARGIN);
2698 cli->inbuf = (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE+LARGE_WRITEX_HDR_SIZE+SAFETY_MARGIN);
2699 if (!cli->outbuf || !cli->inbuf) {
2700 tevent_req_nterror(req,
2701 NT_STATUS_NO_MEMORY);
2704 cli->bufsize = CLI_SAMBA_MAX_LARGE_READX_SIZE + LARGE_WRITEX_HDR_SIZE;
2707 } else if (cli->protocol >= PROTOCOL_LANMAN1) {
2708 cli->use_spnego = False;
2709 cli->sec_mode = SVAL(vwv + 1, 0);
2710 cli->max_xmit = SVAL(vwv + 2, 0);
2711 cli->max_mux = SVAL(vwv + 3, 0);
2712 cli->sesskey = IVAL(vwv + 6, 0);
2713 cli->serverzone = SVALS(vwv + 10, 0);
2714 cli->serverzone *= 60;
2715 /* this time is converted to GMT by make_unix_date */
2716 cli->servertime = make_unix_date(
2717 (char *)(vwv + 8), cli->serverzone);
2718 cli->readbraw_supported = ((SVAL(vwv + 5, 0) & 0x1) != 0);
2719 cli->writebraw_supported = ((SVAL(vwv + 5, 0) & 0x2) != 0);
2720 cli->secblob = data_blob(bytes, num_bytes);
2722 /* the old core protocol */
2723 cli->use_spnego = False;
2725 cli->serverzone = get_time_zone(time(NULL));
2728 cli->max_xmit = MIN(cli->max_xmit, CLI_BUFFER_SIZE);
2730 /* a way to force ascii SMB */
2731 if (getenv("CLI_FORCE_ASCII"))
2732 cli->capabilities &= ~CAP_UNICODE;
2734 tevent_req_done(req);
2737 NTSTATUS cli_negprot_recv(struct tevent_req *req)
2739 return tevent_req_simple_recv_ntstatus(req);
2742 NTSTATUS cli_negprot(struct cli_state *cli)
2744 TALLOC_CTX *frame = talloc_stackframe();
2745 struct event_context *ev;
2746 struct tevent_req *req;
2747 NTSTATUS status = NT_STATUS_OK;
2749 if (cli_has_async_calls(cli)) {
2751 * Can't use sync call while an async call is in flight
2753 status = NT_STATUS_INVALID_PARAMETER;
2757 ev = event_context_init(frame);
2759 status = NT_STATUS_NO_MEMORY;
2763 req = cli_negprot_send(frame, ev, cli);
2765 status = NT_STATUS_NO_MEMORY;
2769 if (!tevent_req_poll(req, ev)) {
2770 status = map_nt_error_from_unix(errno);
2774 status = cli_negprot_recv(req);
2777 if (!NT_STATUS_IS_OK(status)) {
2778 cli_set_error(cli, status);
2783 /****************************************************************************
2784 Send a session request. See rfc1002.txt 4.3 and 4.3.2.
2785 ****************************************************************************/
2787 bool cli_session_request(struct cli_state *cli,
2788 struct nmb_name *calling, struct nmb_name *called)
2795 /* 445 doesn't have session request */
2796 if (cli->port == 445)
2799 memcpy(&(cli->calling), calling, sizeof(*calling));
2800 memcpy(&(cli->called ), called , sizeof(*called ));
2802 /* put in the destination name */
2804 tmp = name_mangle(talloc_tos(), cli->called.name,
2805 cli->called.name_type);
2810 p = cli->outbuf+len;
2811 namelen = name_len((unsigned char *)tmp, talloc_get_size(tmp));
2813 memcpy(p, tmp, namelen);
2820 tmp = name_mangle(talloc_tos(), cli->calling.name,
2821 cli->calling.name_type);
2826 p = cli->outbuf+len;
2827 namelen = name_len((unsigned char *)tmp, talloc_get_size(tmp));
2829 memcpy(p, tmp, namelen);
2834 /* send a session request (RFC 1002) */
2835 /* setup the packet length
2836 * Remove four bytes from the length count, since the length
2837 * field in the NBT Session Service header counts the number
2838 * of bytes which follow. The cli_send_smb() function knows
2839 * about this and accounts for those four bytes.
2843 _smb_setlen(cli->outbuf,len);
2844 SCVAL(cli->outbuf,0,0x81);
2847 DEBUG(5,("Sent session request\n"));
2849 if (!cli_receive_smb(cli))
2852 if (CVAL(cli->inbuf,0) == 0x84) {
2853 /* C. Hoch 9/14/95 Start */
2854 /* For information, here is the response structure.
2855 * We do the byte-twiddling to for portability.
2856 struct RetargetResponse{
2858 unsigned char flags;
2864 uint16_t port = (CVAL(cli->inbuf,8)<<8)+CVAL(cli->inbuf,9);
2865 struct in_addr dest_ip;
2868 /* SESSION RETARGET */
2869 putip((char *)&dest_ip,cli->inbuf+4);
2870 in_addr_to_sockaddr_storage(&cli->dest_ss, dest_ip);
2872 status = open_socket_out(&cli->dest_ss, port,
2873 LONG_CONNECT_TIMEOUT, &cli->fd);
2874 if (!NT_STATUS_IS_OK(status)) {
2878 DEBUG(3,("Retargeted\n"));
2880 set_socket_options(cli->fd, lp_socket_options());
2887 DEBUG(0,("Retarget recursion - failing\n"));
2891 ret = cli_session_request(cli, calling, called);
2895 } /* C. Hoch 9/14/95 End */
2897 if (CVAL(cli->inbuf,0) != 0x82) {
2898 /* This is the wrong place to put the error... JRA. */
2899 cli->rap_error = CVAL(cli->inbuf,4);
2909 static void smb_sock_connected(struct tevent_req *req)
2911 struct fd_struct *pfd = tevent_req_callback_data(
2912 req, struct fd_struct);
2916 status = open_socket_out_defer_recv(req, &fd);
2917 if (NT_STATUS_IS_OK(status)) {
2922 static NTSTATUS open_smb_socket(const struct sockaddr_storage *pss,
2923 uint16_t *port, int timeout, int *pfd)
2925 struct event_context *ev;
2926 struct tevent_req *r139, *r445;
2927 struct fd_struct *fd139, *fd445;
2928 NTSTATUS status = NT_STATUS_NO_MEMORY;
2931 return open_socket_out(pss, *port, timeout, pfd);
2934 ev = event_context_init(talloc_tos());
2936 return NT_STATUS_NO_MEMORY;
2939 fd139 = talloc(ev, struct fd_struct);
2940 if (fd139 == NULL) {
2945 fd445 = talloc(ev, struct fd_struct);
2946 if (fd445 == NULL) {
2951 r445 = open_socket_out_defer_send(ev, ev, timeval_set(0, 0),
2953 r139 = open_socket_out_defer_send(ev, ev, timeval_set(0, 3000),
2955 if ((r445 == NULL) || (r139 == NULL)) {
2958 tevent_req_set_callback(r445, smb_sock_connected, fd445);
2959 tevent_req_set_callback(r139, smb_sock_connected, fd139);
2961 while ((fd445->fd == -1) && (fd139->fd == -1)
2962 && (tevent_req_is_in_progress(r139)
2963 || tevent_req_is_in_progress(r445))) {
2964 event_loop_once(ev);
2967 if ((fd139->fd != -1) && (fd445->fd != -1)) {
2972 if (fd445->fd != -1) {
2975 status = NT_STATUS_OK;
2978 if (fd139->fd != -1) {
2981 status = NT_STATUS_OK;
2985 status = open_socket_out_defer_recv(r445, &fd445->fd);
2991 /****************************************************************************
2992 Open the client sockets.
2993 ****************************************************************************/
2995 NTSTATUS cli_connect(struct cli_state *cli,
2997 struct sockaddr_storage *dest_ss)
3000 int name_type = 0x20;
3001 TALLOC_CTX *frame = talloc_stackframe();
3002 unsigned int num_addrs = 0;
3004 struct sockaddr_storage *ss_arr = NULL;
3007 /* reasonable default hostname */
3009 host = STAR_SMBSERVER;
3012 cli->desthost = talloc_strdup(cli, host);
3013 if (cli->desthost == NULL) {
3014 return NT_STATUS_NO_MEMORY;
3017 /* allow hostnames of the form NAME#xx and do a netbios lookup */
3018 if ((p = strchr(cli->desthost, '#'))) {
3019 name_type = strtol(p+1, NULL, 16);
3023 if (!dest_ss || is_zero_addr(dest_ss)) {
3024 NTSTATUS status =resolve_name_list(frame,
3029 if (!NT_STATUS_IS_OK(status)) {
3031 return NT_STATUS_BAD_NETWORK_NAME;
3035 ss_arr = TALLOC_P(frame, struct sockaddr_storage);
3038 return NT_STATUS_NO_MEMORY;
3043 for (i = 0; i < num_addrs; i++) {
3044 cli->dest_ss = ss_arr[i];
3045 if (getenv("LIBSMB_PROG")) {
3046 cli->fd = sock_exec(getenv("LIBSMB_PROG"));
3048 uint16_t port = cli->port;
3050 status = open_smb_socket(&cli->dest_ss, &port,
3051 cli->timeout, &cli->fd);
3052 if (NT_STATUS_IS_OK(status)) {
3056 if (cli->fd == -1) {
3057 char addr[INET6_ADDRSTRLEN];
3058 print_sockaddr(addr, sizeof(addr), &ss_arr[i]);
3059 DEBUG(2,("Error connecting to %s (%s)\n",
3060 dest_ss?addr:host,strerror(errno)));
3062 /* Exit from loop on first connection. */
3067 if (cli->fd == -1) {
3069 return map_nt_error_from_unix(errno);
3073 *dest_ss = cli->dest_ss;
3076 set_socket_options(cli->fd, lp_socket_options());
3079 return NT_STATUS_OK;
3083 establishes a connection to after the negprot.
3084 @param output_cli A fully initialised cli structure, non-null only on success
3085 @param dest_host The netbios name of the remote host
3086 @param dest_ss (optional) The the destination IP, NULL for name based lookup
3087 @param port (optional) The destination port (0 for default)
3089 NTSTATUS cli_start_connection(struct cli_state **output_cli,
3090 const char *my_name,
3091 const char *dest_host,
3092 struct sockaddr_storage *dest_ss, int port,
3093 int signing_state, int flags)
3096 struct nmb_name calling;
3097 struct nmb_name called;
3098 struct cli_state *cli;
3099 struct sockaddr_storage ss;
3102 my_name = global_myname();
3104 if (!(cli = cli_initialise_ex(signing_state))) {
3105 return NT_STATUS_NO_MEMORY;
3108 make_nmb_name(&calling, my_name, 0x0);
3109 make_nmb_name(&called , dest_host, 0x20);
3111 cli_set_port(cli, port);
3112 cli_set_timeout(cli, 10000); /* 10 seconds. */
3122 DEBUG(3,("Connecting to host=%s\n", dest_host));
3124 nt_status = cli_connect(cli, dest_host, &ss);
3125 if (!NT_STATUS_IS_OK(nt_status)) {
3126 char addr[INET6_ADDRSTRLEN];
3127 print_sockaddr(addr, sizeof(addr), &ss);
3128 DEBUG(1,("cli_start_connection: failed to connect to %s (%s). Error %s\n",
3129 nmb_namestr(&called), addr, nt_errstr(nt_status) ));
3134 if (!cli_session_request(cli, &calling, &called)) {
3136 DEBUG(1,("session request to %s failed (%s)\n",
3137 called.name, cli_errstr(cli)));
3138 if ((p=strchr(called.name, '.')) && !is_ipaddress(called.name)) {
3142 if (strcmp(called.name, STAR_SMBSERVER)) {
3143 make_nmb_name(&called , STAR_SMBSERVER, 0x20);
3146 return NT_STATUS_BAD_NETWORK_NAME;
3149 if (flags & CLI_FULL_CONNECTION_DONT_SPNEGO)
3150 cli->use_spnego = False;
3151 else if (flags & CLI_FULL_CONNECTION_USE_KERBEROS)
3152 cli->use_kerberos = True;
3154 if ((flags & CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS) &&
3155 cli->use_kerberos) {
3156 cli->fallback_after_kerberos = true;
3158 if (flags & CLI_FULL_CONNECTION_USE_CCACHE) {
3159 cli->use_ccache = true;
3162 nt_status = cli_negprot(cli);
3163 if (!NT_STATUS_IS_OK(nt_status)) {
3164 DEBUG(1, ("failed negprot: %s\n", nt_errstr(nt_status)));
3170 return NT_STATUS_OK;
3175 establishes a connection right up to doing tconX, password specified.
3176 @param output_cli A fully initialised cli structure, non-null only on success
3177 @param dest_host The netbios name of the remote host
3178 @param dest_ip (optional) The the destination IP, NULL for name based lookup
3179 @param port (optional) The destination port (0 for default)
3180 @param service (optional) The share to make the connection to. Should be 'unqualified' in any way.
3181 @param service_type The 'type' of serivice.
3182 @param user Username, unix string
3183 @param domain User's domain
3184 @param password User's password, unencrypted unix string.
3187 NTSTATUS cli_full_connection(struct cli_state **output_cli,
3188 const char *my_name,
3189 const char *dest_host,
3190 struct sockaddr_storage *dest_ss, int port,
3191 const char *service, const char *service_type,
3192 const char *user, const char *domain,
3193 const char *password, int flags,
3197 struct cli_state *cli = NULL;
3198 int pw_len = password ? strlen(password)+1 : 0;
3202 if (password == NULL) {
3206 nt_status = cli_start_connection(&cli, my_name, dest_host,
3207 dest_ss, port, signing_state,
3210 if (!NT_STATUS_IS_OK(nt_status)) {
3214 cli->use_oplocks = ((flags & CLI_FULL_CONNECTION_OPLOCKS) != 0);
3215 cli->use_level_II_oplocks =
3216 ((flags & CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS) != 0);
3218 nt_status = cli_session_setup(cli, user, password, pw_len, password,
3220 if (!NT_STATUS_IS_OK(nt_status)) {
3222 if (!(flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)) {
3223 DEBUG(1,("failed session setup with %s\n",
3224 nt_errstr(nt_status)));
3229 nt_status = cli_session_setup(cli, "", "", 0, "", 0, domain);
3230 if (!NT_STATUS_IS_OK(nt_status)) {
3231 DEBUG(1,("anonymous failed session setup with %s\n",
3232 nt_errstr(nt_status)));
3239 nt_status = cli_tcon_andx(cli, service, service_type, password,
3241 if (!NT_STATUS_IS_OK(nt_status)) {
3242 DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status)));
3244 if (NT_STATUS_IS_OK(nt_status)) {
3245 nt_status = NT_STATUS_UNSUCCESSFUL;
3251 nt_status = cli_init_creds(cli, user, domain, password);
3252 if (!NT_STATUS_IS_OK(nt_status)) {
3258 return NT_STATUS_OK;
3261 /****************************************************************************
3262 Attempt a NetBIOS session request, falling back to *SMBSERVER if needed.
3263 ****************************************************************************/
3265 bool attempt_netbios_session_request(struct cli_state **ppcli, const char *srchost, const char *desthost,
3266 struct sockaddr_storage *pdest_ss)
3268 struct nmb_name calling, called;
3270 make_nmb_name(&calling, srchost, 0x0);
3273 * If the called name is an IP address
3274 * then use *SMBSERVER immediately.
3277 if(is_ipaddress(desthost)) {
3278 make_nmb_name(&called, STAR_SMBSERVER, 0x20);
3280 make_nmb_name(&called, desthost, 0x20);
3283 if (!cli_session_request(*ppcli, &calling, &called)) {
3285 struct nmb_name smbservername;
3287 make_nmb_name(&smbservername, STAR_SMBSERVER, 0x20);
3290 * If the name wasn't *SMBSERVER then
3291 * try with *SMBSERVER if the first name fails.
3294 if (nmb_name_equal(&called, &smbservername)) {
3297 * The name used was *SMBSERVER, don't bother with another name.
3300 DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER \
3301 with error %s.\n", desthost, cli_errstr(*ppcli) ));
3306 cli_shutdown(*ppcli);
3308 *ppcli = cli_initialise();
3310 /* Out of memory... */
3314 status = cli_connect(*ppcli, desthost, pdest_ss);
3315 if (!NT_STATUS_IS_OK(status) ||
3316 !cli_session_request(*ppcli, &calling, &smbservername)) {
3317 DEBUG(0,("attempt_netbios_session_request: %s rejected the session for \
3318 name *SMBSERVER with error %s\n", desthost, cli_errstr(*ppcli) ));
3326 /****************************************************************************
3327 Send an old style tcon.
3328 ****************************************************************************/
3329 NTSTATUS cli_raw_tcon(struct cli_state *cli,
3330 const char *service, const char *pass, const char *dev,
3331 uint16 *max_xmit, uint16 *tid)
3333 struct tevent_req *req;
3338 if (!lp_client_plaintext_auth() && (*pass)) {
3339 DEBUG(1, ("Server requested plaintext password but 'client "
3340 "plaintext auth' is disabled\n"));
3341 return NT_STATUS_ACCESS_DENIED;
3344 bytes = talloc_array(talloc_tos(), uint8_t, 0);
3345 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3346 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
3347 service, strlen(service)+1, NULL);
3348 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3349 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
3350 pass, strlen(pass)+1, NULL);
3351 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3352 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
3353 dev, strlen(dev)+1, NULL);
3355 status = cli_smb(talloc_tos(), cli, SMBtcon, 0, 0, NULL,
3356 talloc_get_size(bytes), bytes, &req,
3357 2, NULL, &ret_vwv, NULL, NULL);
3358 if (!NT_STATUS_IS_OK(status)) {
3362 *max_xmit = SVAL(ret_vwv + 0, 0);
3363 *tid = SVAL(ret_vwv + 1, 0);
3365 return NT_STATUS_OK;
3368 /* Return a cli_state pointing at the IPC$ share for the given server */
3370 struct cli_state *get_ipc_connect(char *server,
3371 struct sockaddr_storage *server_ss,
3372 const struct user_auth_info *user_info)
3374 struct cli_state *cli;
3376 uint32_t flags = CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
3378 if (user_info->use_kerberos) {
3379 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
3382 nt_status = cli_full_connection(&cli, NULL, server, server_ss, 0, "IPC$", "IPC",
3383 user_info->username ? user_info->username : "",
3385 user_info->password ? user_info->password : "",
3389 if (NT_STATUS_IS_OK(nt_status)) {
3391 } else if (is_ipaddress(server)) {
3392 /* windows 9* needs a correct NMB name for connections */
3393 fstring remote_name;
3395 if (name_status_find("*", 0, 0, server_ss, remote_name)) {
3396 cli = get_ipc_connect(remote_name, server_ss, user_info);
3405 * Given the IP address of a master browser on the network, return its
3406 * workgroup and connect to it.
3408 * This function is provided to allow additional processing beyond what
3409 * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
3410 * browsers and obtain each master browsers' list of domains (in case the
3411 * first master browser is recently on the network and has not yet
3412 * synchronized with other master browsers and therefore does not yet have the
3413 * entire network browse list)
3416 struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx,
3417 struct sockaddr_storage *mb_ip,
3418 const struct user_auth_info *user_info,
3419 char **pp_workgroup_out)
3421 char addr[INET6_ADDRSTRLEN];
3423 struct cli_state *cli;
3424 struct sockaddr_storage server_ss;
3426 *pp_workgroup_out = NULL;
3428 print_sockaddr(addr, sizeof(addr), mb_ip);
3429 DEBUG(99, ("Looking up name of master browser %s\n",
3433 * Do a name status query to find out the name of the master browser.
3434 * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
3435 * master browser will not respond to a wildcard query (or, at least,
3436 * an NT4 server acting as the domain master browser will not).
3438 * We might be able to use ONLY the query on MSBROWSE, but that's not
3439 * yet been tested with all Windows versions, so until it is, leave
3440 * the original wildcard query as the first choice and fall back to
3441 * MSBROWSE if the wildcard query fails.
3443 if (!name_status_find("*", 0, 0x1d, mb_ip, name) &&
3444 !name_status_find(MSBROWSE, 1, 0x1d, mb_ip, name)) {
3446 DEBUG(99, ("Could not retrieve name status for %s\n",
3451 if (!find_master_ip(name, &server_ss)) {
3452 DEBUG(99, ("Could not find master ip for %s\n", name));
3456 *pp_workgroup_out = talloc_strdup(ctx, name);
3458 DEBUG(4, ("found master browser %s, %s\n", name, addr));
3460 print_sockaddr(addr, sizeof(addr), &server_ss);
3461 cli = get_ipc_connect(addr, &server_ss, user_info);
3467 * Return the IP address and workgroup of a master browser on the network, and
3471 struct cli_state *get_ipc_connect_master_ip_bcast(TALLOC_CTX *ctx,
3472 const struct user_auth_info *user_info,
3473 char **pp_workgroup_out)
3475 struct sockaddr_storage *ip_list;
3476 struct cli_state *cli;
3480 *pp_workgroup_out = NULL;
3482 DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
3484 /* Go looking for workgroups by broadcasting on the local network */
3486 status = name_resolve_bcast(MSBROWSE, 1, talloc_tos(),
3488 if (!NT_STATUS_IS_OK(status)) {
3489 DEBUG(99, ("No master browsers responded: %s\n",
3490 nt_errstr(status)));
3494 for (i = 0; i < count; i++) {
3495 char addr[INET6_ADDRSTRLEN];
3496 print_sockaddr(addr, sizeof(addr), &ip_list[i]);
3497 DEBUG(99, ("Found master browser %s\n", addr));
3499 cli = get_ipc_connect_master_ip(ctx, &ip_list[i],
3500 user_info, pp_workgroup_out);