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"
40 {PROTOCOL_CORE, "PC NETWORK PROGRAM 1.0"},
41 {PROTOCOL_COREPLUS, "MICROSOFT NETWORKS 1.03"},
42 {PROTOCOL_LANMAN1, "MICROSOFT NETWORKS 3.0"},
43 {PROTOCOL_LANMAN1, "LANMAN1.0"},
44 {PROTOCOL_LANMAN2, "LM1.2X002"},
45 {PROTOCOL_LANMAN2, "DOS LANMAN2.1"},
46 {PROTOCOL_LANMAN2, "LANMAN2.1"},
47 {PROTOCOL_LANMAN2, "Samba"},
48 {PROTOCOL_NT1, "NT LANMAN 1.0"},
49 {PROTOCOL_NT1, "NT LM 0.12"},
52 #define STAR_SMBSERVER "*SMBSERVER"
54 /********************************************************
55 Utility function to ensure we always return at least
56 a valid char * pointer to an empty string for the
57 cli->server_os, cli->server_type and cli->server_domain
59 *******************************************************/
61 static NTSTATUS smb_bytes_talloc_string(struct cli_state *cli,
68 *destlen = clistr_pull_talloc(cli,
70 SVAL(inbuf, smb_flg2),
76 return NT_STATUS_NO_MEMORY;
80 *dest = talloc_strdup(cli, "");
82 return NT_STATUS_NO_MEMORY;
89 * Set the user session key for a connection
90 * @param cli The cli structure to add it too
91 * @param session_key The session key used. (A copy of this is taken for the cli struct)
95 static void cli_set_session_key (struct cli_state *cli, const DATA_BLOB session_key)
97 cli->user_session_key = data_blob(session_key.data, session_key.length);
100 /****************************************************************************
101 Do an old lanman2 style session setup.
102 ****************************************************************************/
104 struct cli_session_setup_lanman2_state {
105 struct cli_state *cli;
110 static void cli_session_setup_lanman2_done(struct tevent_req *subreq);
112 static struct tevent_req *cli_session_setup_lanman2_send(
113 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
114 struct cli_state *cli, const char *user,
115 const char *pass, size_t passlen,
116 const char *workgroup)
118 struct tevent_req *req, *subreq;
119 struct cli_session_setup_lanman2_state *state;
120 DATA_BLOB lm_response = data_blob_null;
125 req = tevent_req_create(mem_ctx, &state,
126 struct cli_session_setup_lanman2_state);
135 * LANMAN servers predate NT status codes and Unicode and
136 * ignore those smb flags so we must disable the corresponding
137 * default capabilities that would otherwise cause the Unicode
138 * and NT Status flags to be set (and even returned by the
142 cli->capabilities &= ~(CAP_UNICODE | CAP_STATUS32);
145 * if in share level security then don't send a password now
147 if (!(cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) {
152 && (cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)
155 * Encrypted mode needed, and non encrypted password
158 lm_response = data_blob(NULL, 24);
159 if (tevent_req_nomem(lm_response.data, req)) {
160 return tevent_req_post(req, ev);
163 if (!SMBencrypt(pass, cli->secblob.data,
164 (uint8_t *)lm_response.data)) {
165 DEBUG(1, ("Password is > 14 chars in length, and is "
166 "therefore incompatible with Lanman "
167 "authentication\n"));
168 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
169 return tevent_req_post(req, ev);
171 } else if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)
174 * Encrypted mode needed, and encrypted password
177 lm_response = data_blob(pass, passlen);
178 if (tevent_req_nomem(lm_response.data, req)) {
179 return tevent_req_post(req, ev);
181 } else if (passlen > 0) {
183 size_t converted_size;
185 * Plaintext mode needed, assume plaintext supplied.
187 buf = talloc_array(talloc_tos(), uint8_t, 0);
188 buf = smb_bytes_push_str(buf, cli_ucs2(cli), pass, passlen+1,
190 if (tevent_req_nomem(buf, req)) {
191 return tevent_req_post(req, ev);
193 lm_response = data_blob(pass, passlen);
195 if (tevent_req_nomem(lm_response.data, req)) {
196 return tevent_req_post(req, ev);
200 SCVAL(vwv+0, 0, 0xff);
203 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
206 SIVAL(vwv+5, 0, cli->sesskey);
207 SSVAL(vwv+7, 0, lm_response.length);
209 bytes = talloc_array(state, uint8_t, lm_response.length);
210 if (tevent_req_nomem(bytes, req)) {
211 return tevent_req_post(req, ev);
213 if (lm_response.length != 0) {
214 memcpy(bytes, lm_response.data, lm_response.length);
216 data_blob_free(&lm_response);
218 tmp = talloc_strdup_upper(talloc_tos(), user);
219 if (tevent_req_nomem(tmp, req)) {
220 return tevent_req_post(req, ev);
222 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), tmp, strlen(tmp)+1,
226 tmp = talloc_strdup_upper(talloc_tos(), workgroup);
227 if (tevent_req_nomem(tmp, req)) {
228 return tevent_req_post(req, ev);
230 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), tmp, strlen(tmp)+1,
232 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Unix", 5, NULL);
233 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Samba", 6, NULL);
235 if (tevent_req_nomem(bytes, req)) {
236 return tevent_req_post(req, ev);
239 subreq = cli_smb_send(state, ev, cli, SMBsesssetupX, 0, 10, vwv,
240 talloc_get_size(bytes), bytes);
241 if (tevent_req_nomem(subreq, req)) {
242 return tevent_req_post(req, ev);
244 tevent_req_set_callback(subreq, cli_session_setup_lanman2_done, req);
248 static void cli_session_setup_lanman2_done(struct tevent_req *subreq)
250 struct tevent_req *req = tevent_req_callback_data(
251 subreq, struct tevent_req);
252 struct cli_session_setup_lanman2_state *state = tevent_req_data(
253 req, struct cli_session_setup_lanman2_state);
254 struct cli_state *cli = state->cli;
263 status = cli_smb_recv(subreq, state, &in, 0, NULL, NULL,
266 if (!NT_STATUS_IS_OK(status)) {
267 tevent_req_nterror(req, status);
274 cli->vuid = SVAL(inbuf, smb_uid);
276 status = smb_bytes_talloc_string(cli,
283 if (!NT_STATUS_IS_OK(status)) {
284 tevent_req_nterror(req, status);
289 status = smb_bytes_talloc_string(cli,
296 if (!NT_STATUS_IS_OK(status)) {
297 tevent_req_nterror(req, status);
302 status = smb_bytes_talloc_string(cli,
309 if (!NT_STATUS_IS_OK(status)) {
310 tevent_req_nterror(req, status);
315 if (strstr(cli->server_type, "Samba")) {
316 cli->is_samba = True;
318 status = cli_set_username(cli, state->user);
319 if (tevent_req_nterror(req, status)) {
322 tevent_req_done(req);
325 static NTSTATUS cli_session_setup_lanman2_recv(struct tevent_req *req)
327 return tevent_req_simple_recv_ntstatus(req);
330 static NTSTATUS cli_session_setup_lanman2(struct cli_state *cli, const char *user,
331 const char *pass, size_t passlen,
332 const char *workgroup)
334 TALLOC_CTX *frame = talloc_stackframe();
335 struct event_context *ev;
336 struct tevent_req *req;
337 NTSTATUS status = NT_STATUS_NO_MEMORY;
339 if (cli_has_async_calls(cli)) {
341 * Can't use sync call while an async call is in flight
343 status = NT_STATUS_INVALID_PARAMETER;
346 ev = event_context_init(frame);
350 req = cli_session_setup_lanman2_send(frame, ev, cli, user, pass, passlen,
355 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
358 status = cli_session_setup_lanman2_recv(req);
361 if (!NT_STATUS_IS_OK(status)) {
362 cli_set_error(cli, status);
367 /****************************************************************************
368 Work out suitable capabilities to offer the server.
369 ****************************************************************************/
371 static uint32 cli_session_setup_capabilities(struct cli_state *cli)
373 uint32 capabilities = CAP_NT_SMBS;
375 if (!cli->force_dos_errors)
376 capabilities |= CAP_STATUS32;
378 if (cli->use_level_II_oplocks)
379 capabilities |= CAP_LEVEL_II_OPLOCKS;
381 capabilities |= (cli->capabilities & (CAP_UNICODE|CAP_LARGE_FILES|CAP_LARGE_READX|CAP_LARGE_WRITEX|CAP_DFS));
385 /****************************************************************************
386 Do a NT1 guest session setup.
387 ****************************************************************************/
389 struct cli_session_setup_guest_state {
390 struct cli_state *cli;
395 static void cli_session_setup_guest_done(struct tevent_req *subreq);
397 struct tevent_req *cli_session_setup_guest_create(TALLOC_CTX *mem_ctx,
398 struct event_context *ev,
399 struct cli_state *cli,
400 struct tevent_req **psmbreq)
402 struct tevent_req *req, *subreq;
403 struct cli_session_setup_guest_state *state;
407 req = tevent_req_create(mem_ctx, &state,
408 struct cli_session_setup_guest_state);
415 SCVAL(vwv+0, 0, 0xFF);
418 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
420 SSVAL(vwv+4, 0, cli->pid);
421 SIVAL(vwv+5, 0, cli->sesskey);
426 SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli));
428 bytes = talloc_array(state, uint8_t, 0);
430 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "", 1, /* username */
432 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "", 1, /* workgroup */
434 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Unix", 5, NULL);
435 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Samba", 6, NULL);
442 state->bytes.iov_base = (void *)bytes;
443 state->bytes.iov_len = talloc_get_size(bytes);
445 subreq = cli_smb_req_create(state, ev, cli, SMBsesssetupX, 0, 13, vwv,
447 if (subreq == NULL) {
451 tevent_req_set_callback(subreq, cli_session_setup_guest_done, req);
456 struct tevent_req *cli_session_setup_guest_send(TALLOC_CTX *mem_ctx,
457 struct event_context *ev,
458 struct cli_state *cli)
460 struct tevent_req *req, *subreq;
463 req = cli_session_setup_guest_create(mem_ctx, ev, cli, &subreq);
468 status = cli_smb_req_send(subreq);
469 if (NT_STATUS_IS_OK(status)) {
470 tevent_req_nterror(req, status);
471 return tevent_req_post(req, ev);
476 static void cli_session_setup_guest_done(struct tevent_req *subreq)
478 struct tevent_req *req = tevent_req_callback_data(
479 subreq, struct tevent_req);
480 struct cli_session_setup_guest_state *state = tevent_req_data(
481 req, struct cli_session_setup_guest_state);
482 struct cli_state *cli = state->cli;
491 status = cli_smb_recv(subreq, state, &in, 0, NULL, NULL,
494 if (!NT_STATUS_IS_OK(status)) {
495 tevent_req_nterror(req, status);
502 cli->vuid = SVAL(inbuf, smb_uid);
504 status = smb_bytes_talloc_string(cli,
511 if (!NT_STATUS_IS_OK(status)) {
512 tevent_req_nterror(req, status);
517 status = smb_bytes_talloc_string(cli,
524 if (!NT_STATUS_IS_OK(status)) {
525 tevent_req_nterror(req, status);
530 status = smb_bytes_talloc_string(cli,
537 if (!NT_STATUS_IS_OK(status)) {
538 tevent_req_nterror(req, status);
543 if (strstr(cli->server_type, "Samba")) {
544 cli->is_samba = True;
547 status = cli_set_username(cli, "");
548 if (!NT_STATUS_IS_OK(status)) {
549 tevent_req_nterror(req, status);
552 tevent_req_done(req);
555 NTSTATUS cli_session_setup_guest_recv(struct tevent_req *req)
557 return tevent_req_simple_recv_ntstatus(req);
560 static NTSTATUS cli_session_setup_guest(struct cli_state *cli)
562 TALLOC_CTX *frame = talloc_stackframe();
563 struct event_context *ev;
564 struct tevent_req *req;
565 NTSTATUS status = NT_STATUS_OK;
567 if (cli_has_async_calls(cli)) {
569 * Can't use sync call while an async call is in flight
571 status = NT_STATUS_INVALID_PARAMETER;
575 ev = event_context_init(frame);
577 status = NT_STATUS_NO_MEMORY;
581 req = cli_session_setup_guest_send(frame, ev, cli);
583 status = NT_STATUS_NO_MEMORY;
587 if (!tevent_req_poll(req, ev)) {
588 status = map_nt_error_from_unix(errno);
592 status = cli_session_setup_guest_recv(req);
595 if (!NT_STATUS_IS_OK(status)) {
596 cli_set_error(cli, status);
601 /****************************************************************************
602 Do a NT1 plaintext session setup.
603 ****************************************************************************/
605 struct cli_session_setup_plain_state {
606 struct cli_state *cli;
611 static void cli_session_setup_plain_done(struct tevent_req *subreq);
613 static struct tevent_req *cli_session_setup_plain_send(
614 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
615 struct cli_state *cli,
616 const char *user, const char *pass, const char *workgroup)
618 struct tevent_req *req, *subreq;
619 struct cli_session_setup_plain_state *state;
625 req = tevent_req_create(mem_ctx, &state,
626 struct cli_session_setup_plain_state);
634 SCVAL(vwv+0, 0, 0xff);
637 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
639 SSVAL(vwv+4, 0, cli->pid);
640 SIVAL(vwv+5, 0, cli->sesskey);
645 SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli));
647 bytes = talloc_array(state, uint8_t, 0);
648 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), pass, strlen(pass)+1,
650 if (tevent_req_nomem(bytes, req)) {
651 return tevent_req_post(req, ev);
653 SSVAL(vwv + (cli_ucs2(cli) ? 8 : 7), 0, passlen);
655 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
656 user, strlen(user)+1, NULL);
657 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
658 workgroup, strlen(workgroup)+1, NULL);
659 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
662 version = talloc_asprintf(talloc_tos(), "Samba %s",
663 samba_version_string());
664 if (tevent_req_nomem(version, req)){
665 return tevent_req_post(req, ev);
667 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
668 version, strlen(version)+1, NULL);
669 TALLOC_FREE(version);
671 if (tevent_req_nomem(bytes, req)) {
672 return tevent_req_post(req, ev);
675 subreq = cli_smb_send(state, ev, cli, SMBsesssetupX, 0, 13, vwv,
676 talloc_get_size(bytes), bytes);
677 if (tevent_req_nomem(subreq, req)) {
678 return tevent_req_post(req, ev);
680 tevent_req_set_callback(subreq, cli_session_setup_plain_done, req);
684 static void cli_session_setup_plain_done(struct tevent_req *subreq)
686 struct tevent_req *req = tevent_req_callback_data(
687 subreq, struct tevent_req);
688 struct cli_session_setup_plain_state *state = tevent_req_data(
689 req, struct cli_session_setup_plain_state);
690 struct cli_state *cli = state->cli;
699 status = cli_smb_recv(subreq, state, &in, 0, NULL, NULL,
702 if (tevent_req_nterror(req, status)) {
709 cli->vuid = SVAL(inbuf, smb_uid);
711 status = smb_bytes_talloc_string(cli,
718 if (!NT_STATUS_IS_OK(status)) {
719 tevent_req_nterror(req, status);
724 status = smb_bytes_talloc_string(cli,
731 if (!NT_STATUS_IS_OK(status)) {
732 tevent_req_nterror(req, status);
737 status = smb_bytes_talloc_string(cli,
744 if (!NT_STATUS_IS_OK(status)) {
745 tevent_req_nterror(req, status);
750 status = cli_set_username(cli, state->user);
751 if (tevent_req_nterror(req, status)) {
754 if (strstr(cli->server_type, "Samba")) {
755 cli->is_samba = True;
757 tevent_req_done(req);
760 static NTSTATUS cli_session_setup_plain_recv(struct tevent_req *req)
762 return tevent_req_simple_recv_ntstatus(req);
765 static NTSTATUS cli_session_setup_plain(struct cli_state *cli,
766 const char *user, const char *pass,
767 const char *workgroup)
769 TALLOC_CTX *frame = talloc_stackframe();
770 struct event_context *ev;
771 struct tevent_req *req;
772 NTSTATUS status = NT_STATUS_NO_MEMORY;
774 if (cli_has_async_calls(cli)) {
776 * Can't use sync call while an async call is in flight
778 status = NT_STATUS_INVALID_PARAMETER;
781 ev = event_context_init(frame);
785 req = cli_session_setup_plain_send(frame, ev, cli, user, pass,
790 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
793 status = cli_session_setup_plain_recv(req);
796 if (!NT_STATUS_IS_OK(status)) {
797 cli_set_error(cli, status);
802 /****************************************************************************
803 do a NT1 NTLM/LM encrypted session setup - for when extended security
805 @param cli client state to create do session setup on
807 @param pass *either* cleartext password (passlen !=24) or LM response.
808 @param ntpass NT response, implies ntpasslen >=24, implies pass is not clear
809 @param workgroup The user's domain.
810 ****************************************************************************/
812 struct cli_session_setup_nt1_state {
813 struct cli_state *cli;
816 DATA_BLOB session_key;
820 static void cli_session_setup_nt1_done(struct tevent_req *subreq);
822 static struct tevent_req *cli_session_setup_nt1_send(
823 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
824 struct cli_state *cli, const char *user,
825 const char *pass, size_t passlen,
826 const char *ntpass, size_t ntpasslen,
827 const char *workgroup)
829 struct tevent_req *req, *subreq;
830 struct cli_session_setup_nt1_state *state;
831 DATA_BLOB lm_response = data_blob_null;
832 DATA_BLOB nt_response = data_blob_null;
833 DATA_BLOB session_key = data_blob_null;
836 char *workgroup_upper;
838 req = tevent_req_create(mem_ctx, &state,
839 struct cli_session_setup_nt1_state);
848 /* do nothing - guest login */
849 } else if (passlen != 24) {
850 if (lp_client_ntlmv2_auth()) {
851 DATA_BLOB server_chal;
852 DATA_BLOB names_blob;
854 server_chal = data_blob(cli->secblob.data,
855 MIN(cli->secblob.length, 8));
856 if (tevent_req_nomem(server_chal.data, req)) {
857 return tevent_req_post(req, ev);
861 * note that the 'workgroup' here is a best
862 * guess - we don't know the server's domain
863 * at this point. The 'server name' is also
866 names_blob = NTLMv2_generate_names_blob(
867 NULL, cli->called.name, workgroup);
869 if (tevent_req_nomem(names_blob.data, req)) {
870 return tevent_req_post(req, ev);
873 if (!SMBNTLMv2encrypt(NULL, user, workgroup, pass,
874 &server_chal, &names_blob,
875 &lm_response, &nt_response,
876 NULL, &session_key)) {
877 data_blob_free(&names_blob);
878 data_blob_free(&server_chal);
880 req, NT_STATUS_ACCESS_DENIED);
881 return tevent_req_post(req, ev);
883 data_blob_free(&names_blob);
884 data_blob_free(&server_chal);
888 E_md4hash(pass, nt_hash);
891 nt_response = data_blob_null;
893 nt_response = data_blob(NULL, 24);
894 if (tevent_req_nomem(nt_response.data, req)) {
895 return tevent_req_post(req, ev);
898 SMBNTencrypt(pass, cli->secblob.data,
901 /* non encrypted password supplied. Ignore ntpass. */
902 if (lp_client_lanman_auth()) {
904 lm_response = data_blob(NULL, 24);
905 if (tevent_req_nomem(lm_response.data, req)) {
906 return tevent_req_post(req, ev);
909 if (!SMBencrypt(pass,cli->secblob.data,
912 * Oops, the LM response is
913 * invalid, just put the NT
914 * response there instead
916 data_blob_free(&lm_response);
917 lm_response = data_blob(
923 * LM disabled, place NT# in LM field
926 lm_response = data_blob(
927 nt_response.data, nt_response.length);
930 if (tevent_req_nomem(lm_response.data, req)) {
931 return tevent_req_post(req, ev);
934 session_key = data_blob(NULL, 16);
935 if (tevent_req_nomem(session_key.data, req)) {
936 return tevent_req_post(req, ev);
939 E_deshash(pass, session_key.data);
940 memset(&session_key.data[8], '\0', 8);
942 SMBsesskeygen_ntv1(nt_hash, session_key.data);
945 cli_temp_set_signing(cli);
947 /* pre-encrypted password supplied. Only used for
948 security=server, can't do
949 signing because we don't have original key */
951 lm_response = data_blob(pass, passlen);
952 if (tevent_req_nomem(lm_response.data, req)) {
953 return tevent_req_post(req, ev);
956 nt_response = data_blob(ntpass, ntpasslen);
957 if (tevent_req_nomem(nt_response.data, req)) {
958 return tevent_req_post(req, ev);
963 state->response = data_blob_talloc(
964 state, lm_response.data, lm_response.length);
966 state->response = data_blob_talloc(
967 state, nt_response.data, nt_response.length);
969 if (tevent_req_nomem(state->response.data, req)) {
970 return tevent_req_post(req, ev);
973 if (session_key.data) {
974 state->session_key = data_blob_talloc(
975 state, session_key.data, session_key.length);
976 if (tevent_req_nomem(state->session_key.data, req)) {
977 return tevent_req_post(req, ev);
980 data_blob_free(&session_key);
982 SCVAL(vwv+0, 0, 0xff);
985 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
987 SSVAL(vwv+4, 0, cli->pid);
988 SIVAL(vwv+5, 0, cli->sesskey);
989 SSVAL(vwv+7, 0, lm_response.length);
990 SSVAL(vwv+8, 0, nt_response.length);
993 SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli));
995 bytes = talloc_array(state, uint8_t,
996 lm_response.length + nt_response.length);
997 if (tevent_req_nomem(bytes, req)) {
998 return tevent_req_post(req, ev);
1000 if (lm_response.length != 0) {
1001 memcpy(bytes, lm_response.data, lm_response.length);
1003 if (nt_response.length != 0) {
1004 memcpy(bytes + lm_response.length,
1005 nt_response.data, nt_response.length);
1007 data_blob_free(&lm_response);
1008 data_blob_free(&nt_response);
1010 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
1011 user, strlen(user)+1, NULL);
1014 * Upper case here might help some NTLMv2 implementations
1016 workgroup_upper = talloc_strdup_upper(talloc_tos(), workgroup);
1017 if (tevent_req_nomem(workgroup_upper, req)) {
1018 return tevent_req_post(req, ev);
1020 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
1021 workgroup_upper, strlen(workgroup_upper)+1,
1023 TALLOC_FREE(workgroup_upper);
1025 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Unix", 5, NULL);
1026 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Samba", 6, NULL);
1027 if (tevent_req_nomem(bytes, req)) {
1028 return tevent_req_post(req, ev);
1031 subreq = cli_smb_send(state, ev, cli, SMBsesssetupX, 0, 13, vwv,
1032 talloc_get_size(bytes), bytes);
1033 if (tevent_req_nomem(subreq, req)) {
1034 return tevent_req_post(req, ev);
1036 tevent_req_set_callback(subreq, cli_session_setup_nt1_done, req);
1040 static void cli_session_setup_nt1_done(struct tevent_req *subreq)
1042 struct tevent_req *req = tevent_req_callback_data(
1043 subreq, struct tevent_req);
1044 struct cli_session_setup_nt1_state *state = tevent_req_data(
1045 req, struct cli_session_setup_nt1_state);
1046 struct cli_state *cli = state->cli;
1055 status = cli_smb_recv(subreq, state, &in, 0, NULL, NULL,
1056 &num_bytes, &bytes);
1057 TALLOC_FREE(subreq);
1058 if (!NT_STATUS_IS_OK(status)) {
1059 tevent_req_nterror(req, status);
1066 cli->vuid = SVAL(inbuf, smb_uid);
1068 status = smb_bytes_talloc_string(cli,
1074 if (!NT_STATUS_IS_OK(status)) {
1075 tevent_req_nterror(req, status);
1080 status = smb_bytes_talloc_string(cli,
1086 if (!NT_STATUS_IS_OK(status)) {
1087 tevent_req_nterror(req, status);
1092 status = smb_bytes_talloc_string(cli,
1094 &cli->server_domain,
1098 if (!NT_STATUS_IS_OK(status)) {
1099 tevent_req_nterror(req, status);
1104 if (strstr(cli->server_type, "Samba")) {
1105 cli->is_samba = True;
1108 status = cli_set_username(cli, state->user);
1109 if (tevent_req_nterror(req, status)) {
1112 if (cli_simple_set_signing(cli, state->session_key, state->response)
1113 && !cli_check_sign_mac(cli, (char *)in, 1)) {
1114 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1117 if (state->session_key.data) {
1118 /* Have plaintext orginal */
1119 cli_set_session_key(cli, state->session_key);
1121 tevent_req_done(req);
1124 static NTSTATUS cli_session_setup_nt1_recv(struct tevent_req *req)
1126 return tevent_req_simple_recv_ntstatus(req);
1129 static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user,
1130 const char *pass, size_t passlen,
1131 const char *ntpass, size_t ntpasslen,
1132 const char *workgroup)
1134 TALLOC_CTX *frame = talloc_stackframe();
1135 struct event_context *ev;
1136 struct tevent_req *req;
1137 NTSTATUS status = NT_STATUS_NO_MEMORY;
1139 if (cli_has_async_calls(cli)) {
1141 * Can't use sync call while an async call is in flight
1143 status = NT_STATUS_INVALID_PARAMETER;
1146 ev = event_context_init(frame);
1150 req = cli_session_setup_nt1_send(frame, ev, cli, user, pass, passlen,
1151 ntpass, ntpasslen, workgroup);
1155 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1158 status = cli_session_setup_nt1_recv(req);
1161 if (!NT_STATUS_IS_OK(status)) {
1162 cli_set_error(cli, status);
1167 /* The following is calculated from :
1169 * (smb_wcnt * 2) = 24 (smb_wcnt == 12 in cli_session_setup_blob_send() )
1170 * (strlen("Unix") + 1 + strlen("Samba") + 1) * 2 = 22 (unicode strings at
1174 #define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22)
1176 struct cli_sesssetup_blob_state {
1177 struct tevent_context *ev;
1178 struct cli_state *cli;
1180 uint16_t max_blob_size;
1189 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state *state,
1190 struct tevent_req **psubreq);
1191 static void cli_sesssetup_blob_done(struct tevent_req *subreq);
1193 static struct tevent_req *cli_sesssetup_blob_send(TALLOC_CTX *mem_ctx,
1194 struct tevent_context *ev,
1195 struct cli_state *cli,
1198 struct tevent_req *req, *subreq;
1199 struct cli_sesssetup_blob_state *state;
1201 req = tevent_req_create(mem_ctx, &state,
1202 struct cli_sesssetup_blob_state);
1210 if (cli->max_xmit < BASE_SESSSETUP_BLOB_PACKET_SIZE + 1) {
1211 DEBUG(1, ("cli_session_setup_blob: cli->max_xmit too small "
1212 "(was %u, need minimum %u)\n",
1213 (unsigned int)cli->max_xmit,
1214 BASE_SESSSETUP_BLOB_PACKET_SIZE));
1215 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1216 return tevent_req_post(req, ev);
1218 state->max_blob_size =
1219 MIN(cli->max_xmit - BASE_SESSSETUP_BLOB_PACKET_SIZE, 0xFFFF);
1221 if (!cli_sesssetup_blob_next(state, &subreq)) {
1222 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1223 return tevent_req_post(req, ev);
1225 tevent_req_set_callback(subreq, cli_sesssetup_blob_done, req);
1229 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state *state,
1230 struct tevent_req **psubreq)
1232 struct tevent_req *subreq;
1235 SCVAL(state->vwv+0, 0, 0xFF);
1236 SCVAL(state->vwv+0, 1, 0);
1237 SSVAL(state->vwv+1, 0, 0);
1238 SSVAL(state->vwv+2, 0, CLI_BUFFER_SIZE);
1239 SSVAL(state->vwv+3, 0, 2);
1240 SSVAL(state->vwv+4, 0, 1);
1241 SIVAL(state->vwv+5, 0, 0);
1243 thistime = MIN(state->blob.length, state->max_blob_size);
1244 SSVAL(state->vwv+7, 0, thistime);
1246 SSVAL(state->vwv+8, 0, 0);
1247 SSVAL(state->vwv+9, 0, 0);
1248 SIVAL(state->vwv+10, 0,
1249 cli_session_setup_capabilities(state->cli)
1250 | CAP_EXTENDED_SECURITY);
1252 state->buf = (uint8_t *)talloc_memdup(state, state->blob.data,
1254 if (state->buf == NULL) {
1257 state->blob.data += thistime;
1258 state->blob.length -= thistime;
1260 state->buf = smb_bytes_push_str(state->buf, cli_ucs2(state->cli),
1262 state->buf = smb_bytes_push_str(state->buf, cli_ucs2(state->cli),
1264 if (state->buf == NULL) {
1267 subreq = cli_smb_send(state, state->ev, state->cli, SMBsesssetupX, 0,
1269 talloc_get_size(state->buf), state->buf);
1270 if (subreq == NULL) {
1277 static void cli_sesssetup_blob_done(struct tevent_req *subreq)
1279 struct tevent_req *req = tevent_req_callback_data(
1280 subreq, struct tevent_req);
1281 struct cli_sesssetup_blob_state *state = tevent_req_data(
1282 req, struct cli_sesssetup_blob_state);
1283 struct cli_state *cli = state->cli;
1290 uint16_t blob_length;
1294 status = cli_smb_recv(subreq, state, &inbuf, 1, &wct, &vwv,
1295 &num_bytes, &bytes);
1296 TALLOC_FREE(subreq);
1297 if (!NT_STATUS_IS_OK(status)
1298 && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1299 tevent_req_nterror(req, status);
1303 state->status = status;
1304 TALLOC_FREE(state->buf);
1306 state->inbuf = (char *)inbuf;
1307 cli->vuid = SVAL(state->inbuf, smb_uid);
1309 blob_length = SVAL(vwv+3, 0);
1310 if (blob_length > num_bytes) {
1311 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1314 state->ret_blob = data_blob_const(bytes, blob_length);
1316 p = bytes + blob_length;
1318 status = smb_bytes_talloc_string(cli,
1325 if (!NT_STATUS_IS_OK(status)) {
1326 tevent_req_nterror(req, status);
1331 status = smb_bytes_talloc_string(cli,
1338 if (!NT_STATUS_IS_OK(status)) {
1339 tevent_req_nterror(req, status);
1344 status = smb_bytes_talloc_string(cli,
1346 &cli->server_domain,
1351 if (!NT_STATUS_IS_OK(status)) {
1352 tevent_req_nterror(req, status);
1357 if (strstr(cli->server_type, "Samba")) {
1358 cli->is_samba = True;
1361 if (state->blob.length != 0) {
1365 if (!cli_sesssetup_blob_next(state, &subreq)) {
1366 tevent_req_nomem(NULL, req);
1369 tevent_req_set_callback(subreq, cli_sesssetup_blob_done, req);
1372 tevent_req_done(req);
1375 static NTSTATUS cli_sesssetup_blob_recv(struct tevent_req *req,
1376 TALLOC_CTX *mem_ctx,
1380 struct cli_sesssetup_blob_state *state = tevent_req_data(
1381 req, struct cli_sesssetup_blob_state);
1385 if (tevent_req_is_nterror(req, &status)) {
1386 state->cli->vuid = 0;
1390 inbuf = talloc_move(mem_ctx, &state->inbuf);
1391 if (pblob != NULL) {
1392 *pblob = state->ret_blob;
1394 if (pinbuf != NULL) {
1397 /* could be NT_STATUS_MORE_PROCESSING_REQUIRED */
1398 return state->status;
1403 /****************************************************************************
1404 Use in-memory credentials cache
1405 ****************************************************************************/
1407 static void use_in_memory_ccache(void) {
1408 setenv(KRB5_ENV_CCNAME, "MEMORY:cliconnect", 1);
1411 /****************************************************************************
1412 Do a spnego/kerberos encrypted session setup.
1413 ****************************************************************************/
1415 struct cli_session_setup_kerberos_state {
1416 struct cli_state *cli;
1417 DATA_BLOB negTokenTarg;
1418 DATA_BLOB session_key_krb5;
1419 ADS_STATUS ads_status;
1422 static void cli_session_setup_kerberos_done(struct tevent_req *subreq);
1424 static struct tevent_req *cli_session_setup_kerberos_send(
1425 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
1426 const char *principal, const char *workgroup)
1428 struct tevent_req *req, *subreq;
1429 struct cli_session_setup_kerberos_state *state;
1432 DEBUG(2,("Doing kerberos session setup\n"));
1434 req = tevent_req_create(mem_ctx, &state,
1435 struct cli_session_setup_kerberos_state);
1440 state->ads_status = ADS_SUCCESS;
1442 cli_temp_set_signing(cli);
1445 * Ok, this is cheating: spnego_gen_krb5_negTokenInit can block if
1446 * we have to acquire a ticket. To be fixed later :-)
1448 rc = spnego_gen_krb5_negTokenInit(state, principal, 0, &state->negTokenTarg,
1449 &state->session_key_krb5, 0, NULL);
1451 DEBUG(1, ("cli_session_setup_kerberos: "
1452 "spnego_gen_krb5_negTokenInit failed: %s\n",
1453 error_message(rc)));
1454 state->ads_status = ADS_ERROR_KRB5(rc);
1455 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
1456 return tevent_req_post(req, ev);
1460 file_save("negTokenTarg.dat", state->negTokenTarg.data,
1461 state->negTokenTarg.length);
1464 subreq = cli_sesssetup_blob_send(state, ev, cli, state->negTokenTarg);
1465 if (tevent_req_nomem(subreq, req)) {
1466 return tevent_req_post(req, ev);
1468 tevent_req_set_callback(subreq, cli_session_setup_kerberos_done, req);
1472 static void cli_session_setup_kerberos_done(struct tevent_req *subreq)
1474 struct tevent_req *req = tevent_req_callback_data(
1475 subreq, struct tevent_req);
1476 struct cli_session_setup_kerberos_state *state = tevent_req_data(
1477 req, struct cli_session_setup_kerberos_state);
1481 status = cli_sesssetup_blob_recv(subreq, talloc_tos(), NULL, &inbuf);
1482 if (!NT_STATUS_IS_OK(status)) {
1483 TALLOC_FREE(subreq);
1484 tevent_req_nterror(req, status);
1488 cli_set_session_key(state->cli, state->session_key_krb5);
1490 if (cli_simple_set_signing(state->cli, state->session_key_krb5,
1492 && !cli_check_sign_mac(state->cli, inbuf, 1)) {
1493 TALLOC_FREE(subreq);
1494 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1497 TALLOC_FREE(subreq);
1498 tevent_req_done(req);
1501 static ADS_STATUS cli_session_setup_kerberos_recv(struct tevent_req *req)
1503 struct cli_session_setup_kerberos_state *state = tevent_req_data(
1504 req, struct cli_session_setup_kerberos_state);
1507 if (tevent_req_is_nterror(req, &status)) {
1508 return ADS_ERROR_NT(status);
1510 return state->ads_status;
1513 static ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli,
1514 const char *principal,
1515 const char *workgroup)
1517 struct tevent_context *ev;
1518 struct tevent_req *req;
1519 ADS_STATUS status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1521 if (cli_has_async_calls(cli)) {
1522 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1524 ev = tevent_context_init(talloc_tos());
1528 req = cli_session_setup_kerberos_send(ev, ev, cli, principal,
1533 if (!tevent_req_poll(req, ev)) {
1534 status = ADS_ERROR_SYSTEM(errno);
1537 status = cli_session_setup_kerberos_recv(req);
1542 #endif /* HAVE_KRB5 */
1544 /****************************************************************************
1545 Do a spnego/NTLMSSP encrypted session setup.
1546 ****************************************************************************/
1548 struct cli_session_setup_ntlmssp_state {
1549 struct tevent_context *ev;
1550 struct cli_state *cli;
1551 struct ntlmssp_state *ntlmssp_state;
1556 static int cli_session_setup_ntlmssp_state_destructor(
1557 struct cli_session_setup_ntlmssp_state *state)
1559 if (state->ntlmssp_state != NULL) {
1560 TALLOC_FREE(state->ntlmssp_state);
1565 static void cli_session_setup_ntlmssp_done(struct tevent_req *req);
1567 static struct tevent_req *cli_session_setup_ntlmssp_send(
1568 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
1569 const char *user, const char *pass, const char *domain)
1571 struct tevent_req *req, *subreq;
1572 struct cli_session_setup_ntlmssp_state *state;
1575 const char *OIDs_ntlm[] = {OID_NTLMSSP, NULL};
1577 req = tevent_req_create(mem_ctx, &state,
1578 struct cli_session_setup_ntlmssp_state);
1586 state->ntlmssp_state = NULL;
1587 talloc_set_destructor(
1588 state, cli_session_setup_ntlmssp_state_destructor);
1590 cli_temp_set_signing(cli);
1592 status = ntlmssp_client_start(state,
1595 lp_client_ntlmv2_auth(),
1596 &state->ntlmssp_state);
1597 if (!NT_STATUS_IS_OK(status)) {
1600 ntlmssp_want_feature(state->ntlmssp_state,
1601 NTLMSSP_FEATURE_SESSION_KEY);
1602 if (cli->use_ccache) {
1603 ntlmssp_want_feature(state->ntlmssp_state,
1604 NTLMSSP_FEATURE_CCACHE);
1606 status = ntlmssp_set_username(state->ntlmssp_state, user);
1607 if (!NT_STATUS_IS_OK(status)) {
1610 status = ntlmssp_set_domain(state->ntlmssp_state, domain);
1611 if (!NT_STATUS_IS_OK(status)) {
1614 status = ntlmssp_set_password(state->ntlmssp_state, pass);
1615 if (!NT_STATUS_IS_OK(status)) {
1618 status = ntlmssp_update(state->ntlmssp_state, data_blob_null,
1620 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1624 state->blob_out = spnego_gen_negTokenInit(state, OIDs_ntlm, &blob_out, NULL);
1625 data_blob_free(&blob_out);
1627 subreq = cli_sesssetup_blob_send(state, ev, cli, state->blob_out);
1628 if (tevent_req_nomem(subreq, req)) {
1629 return tevent_req_post(req, ev);
1631 tevent_req_set_callback(subreq, cli_session_setup_ntlmssp_done, req);
1634 tevent_req_nterror(req, status);
1635 return tevent_req_post(req, ev);
1638 static void cli_session_setup_ntlmssp_done(struct tevent_req *subreq)
1640 struct tevent_req *req = tevent_req_callback_data(
1641 subreq, struct tevent_req);
1642 struct cli_session_setup_ntlmssp_state *state = tevent_req_data(
1643 req, struct cli_session_setup_ntlmssp_state);
1644 DATA_BLOB blob_in, msg_in, blob_out;
1649 status = cli_sesssetup_blob_recv(subreq, talloc_tos(), &blob_in,
1651 TALLOC_FREE(subreq);
1652 data_blob_free(&state->blob_out);
1654 if (NT_STATUS_IS_OK(status)) {
1655 if (state->cli->server_domain[0] == '\0') {
1656 TALLOC_FREE(state->cli->server_domain);
1657 state->cli->server_domain = talloc_strdup(state->cli,
1658 state->ntlmssp_state->server.netbios_domain);
1659 if (state->cli->server_domain == NULL) {
1660 TALLOC_FREE(subreq);
1661 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1665 cli_set_session_key(
1666 state->cli, state->ntlmssp_state->session_key);
1668 if (cli_simple_set_signing(
1669 state->cli, state->ntlmssp_state->session_key,
1671 && !cli_check_sign_mac(state->cli, inbuf, 1)) {
1672 TALLOC_FREE(subreq);
1673 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1676 TALLOC_FREE(subreq);
1677 TALLOC_FREE(state->ntlmssp_state);
1678 tevent_req_done(req);
1681 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1682 tevent_req_nterror(req, status);
1686 if (blob_in.length == 0) {
1687 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
1691 if ((state->turn == 1)
1692 && NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1693 DATA_BLOB tmp_blob = data_blob_null;
1694 /* the server might give us back two challenges */
1695 parse_ret = spnego_parse_challenge(state, blob_in, &msg_in,
1697 data_blob_free(&tmp_blob);
1699 parse_ret = spnego_parse_auth_response(state, blob_in, status,
1700 OID_NTLMSSP, &msg_in);
1705 DEBUG(3,("Failed to parse auth response\n"));
1706 if (NT_STATUS_IS_OK(status)
1707 || NT_STATUS_EQUAL(status,
1708 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1710 req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1715 status = ntlmssp_update(state->ntlmssp_state, msg_in, &blob_out);
1717 if (!NT_STATUS_IS_OK(status)
1718 && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1719 TALLOC_FREE(subreq);
1720 TALLOC_FREE(state->ntlmssp_state);
1721 tevent_req_nterror(req, status);
1725 state->blob_out = spnego_gen_auth(state, blob_out);
1726 TALLOC_FREE(subreq);
1727 if (tevent_req_nomem(state->blob_out.data, req)) {
1731 subreq = cli_sesssetup_blob_send(state, state->ev, state->cli,
1733 if (tevent_req_nomem(subreq, req)) {
1736 tevent_req_set_callback(subreq, cli_session_setup_ntlmssp_done, req);
1739 static NTSTATUS cli_session_setup_ntlmssp_recv(struct tevent_req *req)
1741 struct cli_session_setup_ntlmssp_state *state = tevent_req_data(
1742 req, struct cli_session_setup_ntlmssp_state);
1745 if (tevent_req_is_nterror(req, &status)) {
1746 state->cli->vuid = 0;
1749 return NT_STATUS_OK;
1752 static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli,
1757 struct tevent_context *ev;
1758 struct tevent_req *req;
1759 NTSTATUS status = NT_STATUS_NO_MEMORY;
1761 if (cli_has_async_calls(cli)) {
1762 return NT_STATUS_INVALID_PARAMETER;
1764 ev = tevent_context_init(talloc_tos());
1768 req = cli_session_setup_ntlmssp_send(ev, ev, cli, user, pass, domain);
1772 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1775 status = cli_session_setup_ntlmssp_recv(req);
1778 if (!NT_STATUS_IS_OK(status)) {
1779 cli_set_error(cli, status);
1784 /****************************************************************************
1785 Do a spnego encrypted session setup.
1787 user_domain: The shortname of the domain the user/machine is a member of.
1788 dest_realm: The realm we're connecting to, if NULL we use our default realm.
1789 ****************************************************************************/
1791 ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user,
1792 const char *pass, const char *user_domain,
1793 const char * dest_realm)
1795 char *principal = NULL;
1796 char *OIDs[ASN1_MAX_OIDS];
1799 const char *p = NULL;
1800 char *account = NULL;
1803 DEBUG(3,("Doing spnego session setup (blob length=%lu)\n", (unsigned long)cli->secblob.length));
1805 /* the server might not even do spnego */
1806 if (cli->secblob.length <= 16) {
1807 DEBUG(3,("server didn't supply a full spnego negprot\n"));
1812 file_save("negprot.dat", cli->secblob.data, cli->secblob.length);
1815 /* there is 16 bytes of GUID before the real spnego packet starts */
1816 blob = data_blob(cli->secblob.data+16, cli->secblob.length-16);
1818 /* The server sent us the first part of the SPNEGO exchange in the
1819 * negprot reply. It is WRONG to depend on the principal sent in the
1820 * negprot reply, but right now we do it. If we don't receive one,
1821 * we try to best guess, then fall back to NTLM. */
1822 if (!spnego_parse_negTokenInit(talloc_tos(), blob, OIDs, &principal, NULL) ||
1824 data_blob_free(&blob);
1825 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1827 data_blob_free(&blob);
1829 /* make sure the server understands kerberos */
1830 for (i=0;OIDs[i];i++) {
1832 DEBUG(3,("got OID=%s\n", OIDs[i]));
1834 DEBUGADD(3,("got OID=%s\n", OIDs[i]));
1835 if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0 ||
1836 strcmp(OIDs[i], OID_KERBEROS5) == 0) {
1837 cli->got_kerberos_mechanism = True;
1839 talloc_free(OIDs[i]);
1842 DEBUG(3,("got principal=%s\n", principal ? principal : "<null>"));
1844 status = cli_set_username(cli, user);
1845 if (!NT_STATUS_IS_OK(status)) {
1846 TALLOC_FREE(principal);
1847 return ADS_ERROR_NT(status);
1851 /* If password is set we reauthenticate to kerberos server
1852 * and do not store results */
1854 if (cli->got_kerberos_mechanism && cli->use_kerberos) {
1857 if (pass && *pass) {
1860 use_in_memory_ccache();
1861 ret = kerberos_kinit_password(user, pass, 0 /* no time correction for now */, NULL);
1864 TALLOC_FREE(principal);
1865 DEBUG(0, ("Kinit failed: %s\n", error_message(ret)));
1866 if (cli->fallback_after_kerberos)
1868 return ADS_ERROR_KRB5(ret);
1872 /* We may not be allowed to use the server-supplied SPNEGO principal, or it may not have been supplied to us
1874 if (!lp_client_use_spnego_principal() || strequal(principal, ADS_IGNORE_PRINCIPAL)) {
1875 TALLOC_FREE(principal);
1878 if (principal == NULL &&
1879 !is_ipaddress(cli->desthost) &&
1880 !strequal(STAR_SMBSERVER,
1884 DEBUG(3,("cli_session_setup_spnego: using target "
1885 "hostname not SPNEGO principal\n"));
1887 host = strchr_m(cli->desthost, '.');
1889 realm = SMB_STRDUP(dest_realm);
1894 realm = kerberos_get_realm_from_hostname(cli->desthost);
1896 /* NetBIOS name - use our realm. */
1897 realm = kerberos_get_default_realm_from_ccache();
1901 if (realm && *realm) {
1902 principal = talloc_asprintf(talloc_tos(),
1908 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1910 DEBUG(3,("cli_session_setup_spnego: guessed "
1911 "server principal=%s\n",
1912 principal ? principal : "<null>"));
1918 rc = cli_session_setup_kerberos(cli, principal,
1920 if (ADS_ERR_OK(rc) || !cli->fallback_after_kerberos) {
1921 TALLOC_FREE(principal);
1928 TALLOC_FREE(principal);
1932 account = talloc_strdup(talloc_tos(), user);
1934 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1937 /* when falling back to ntlmssp while authenticating with a machine
1938 * account strip off the realm - gd */
1940 if ((p = strchr_m(user, '@')) != NULL) {
1941 account[PTR_DIFF(p,user)] = '\0';
1944 return ADS_ERROR_NT(cli_session_setup_ntlmssp(cli, account, pass, user_domain));
1947 /****************************************************************************
1948 Send a session setup. The username and workgroup is in UNIX character
1949 format and must be converted to DOS codepage format before sending. If the
1950 password is in plaintext, the same should be done.
1951 ****************************************************************************/
1953 NTSTATUS cli_session_setup(struct cli_state *cli,
1955 const char *pass, int passlen,
1956 const char *ntpass, int ntpasslen,
1957 const char *workgroup)
1963 user2 = talloc_strdup(talloc_tos(), user);
1965 user2 = talloc_strdup(talloc_tos(), "");
1967 if (user2 == NULL) {
1968 return NT_STATUS_NO_MEMORY;
1975 /* allow for workgroups as part of the username */
1976 if ((p=strchr_m(user2,'\\')) || (p=strchr_m(user2,'/')) ||
1977 (p=strchr_m(user2,*lp_winbind_separator()))) {
1983 if (cli->protocol < PROTOCOL_LANMAN1) {
1984 return NT_STATUS_OK;
1987 /* now work out what sort of session setup we are going to
1988 do. I have split this into separate functions to make the
1989 flow a bit easier to understand (tridge) */
1991 /* if its an older server then we have to use the older request format */
1993 if (cli->protocol < PROTOCOL_NT1) {
1994 if (!lp_client_lanman_auth() && passlen != 24 && (*pass)) {
1995 DEBUG(1, ("Server requested LM password but 'client lanman auth = no'"
1996 " or 'client ntlmv2 auth = yes'\n"));
1997 return NT_STATUS_ACCESS_DENIED;
2000 if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0 &&
2001 !lp_client_plaintext_auth() && (*pass)) {
2002 DEBUG(1, ("Server requested LM password but 'client plaintext auth = no'"
2003 " or 'client ntlmv2 auth = yes'\n"));
2004 return NT_STATUS_ACCESS_DENIED;
2007 return cli_session_setup_lanman2(cli, user, pass, passlen,
2011 /* if no user is supplied then we have to do an anonymous connection.
2012 passwords are ignored */
2014 if (!user || !*user)
2015 return cli_session_setup_guest(cli);
2017 /* if the server is share level then send a plaintext null
2018 password at this point. The password is sent in the tree
2021 if ((cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0)
2022 return cli_session_setup_plain(cli, user, "", workgroup);
2024 /* if the server doesn't support encryption then we have to use
2025 plaintext. The second password is ignored */
2027 if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) {
2028 if (!lp_client_plaintext_auth() && (*pass)) {
2029 DEBUG(1, ("Server requested LM password but 'client plaintext auth = no'"
2030 " or 'client ntlmv2 auth = yes'\n"));
2031 return NT_STATUS_ACCESS_DENIED;
2033 return cli_session_setup_plain(cli, user, pass, workgroup);
2036 /* if the server supports extended security then use SPNEGO */
2038 if (cli->capabilities & CAP_EXTENDED_SECURITY) {
2039 ADS_STATUS status = cli_session_setup_spnego(cli, user, pass,
2041 if (!ADS_ERR_OK(status)) {
2042 DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status)));
2043 return ads_ntstatus(status);
2048 /* otherwise do a NT1 style session setup */
2049 status = cli_session_setup_nt1(cli, user, pass, passlen,
2050 ntpass, ntpasslen, workgroup);
2051 if (!NT_STATUS_IS_OK(status)) {
2052 DEBUG(3,("cli_session_setup: NT1 session setup "
2053 "failed: %s\n", nt_errstr(status)));
2058 if (strstr(cli->server_type, "Samba")) {
2059 cli->is_samba = True;
2062 return NT_STATUS_OK;
2065 /****************************************************************************
2067 *****************************************************************************/
2069 struct cli_ulogoff_state {
2070 struct cli_state *cli;
2074 static void cli_ulogoff_done(struct tevent_req *subreq);
2076 struct tevent_req *cli_ulogoff_send(TALLOC_CTX *mem_ctx,
2077 struct tevent_context *ev,
2078 struct cli_state *cli)
2080 struct tevent_req *req, *subreq;
2081 struct cli_ulogoff_state *state;
2083 req = tevent_req_create(mem_ctx, &state, struct cli_ulogoff_state);
2089 SCVAL(state->vwv+0, 0, 0xFF);
2090 SCVAL(state->vwv+1, 0, 0);
2091 SSVAL(state->vwv+2, 0, 0);
2093 subreq = cli_smb_send(state, ev, cli, SMBulogoffX, 0, 2, state->vwv,
2095 if (tevent_req_nomem(subreq, req)) {
2096 return tevent_req_post(req, ev);
2098 tevent_req_set_callback(subreq, cli_ulogoff_done, req);
2102 static void cli_ulogoff_done(struct tevent_req *subreq)
2104 struct tevent_req *req = tevent_req_callback_data(
2105 subreq, struct tevent_req);
2106 struct cli_ulogoff_state *state = tevent_req_data(
2107 req, struct cli_ulogoff_state);
2110 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
2111 if (!NT_STATUS_IS_OK(status)) {
2112 tevent_req_nterror(req, status);
2115 state->cli->vuid = -1;
2116 tevent_req_done(req);
2119 NTSTATUS cli_ulogoff_recv(struct tevent_req *req)
2121 return tevent_req_simple_recv_ntstatus(req);
2124 NTSTATUS cli_ulogoff(struct cli_state *cli)
2126 struct tevent_context *ev;
2127 struct tevent_req *req;
2128 NTSTATUS status = NT_STATUS_NO_MEMORY;
2130 if (cli_has_async_calls(cli)) {
2131 return NT_STATUS_INVALID_PARAMETER;
2133 ev = tevent_context_init(talloc_tos());
2137 req = cli_ulogoff_send(ev, ev, cli);
2141 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2144 status = cli_ulogoff_recv(req);
2147 if (!NT_STATUS_IS_OK(status)) {
2148 cli_set_error(cli, status);
2153 /****************************************************************************
2155 ****************************************************************************/
2157 struct cli_tcon_andx_state {
2158 struct cli_state *cli;
2163 static void cli_tcon_andx_done(struct tevent_req *subreq);
2165 struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx,
2166 struct event_context *ev,
2167 struct cli_state *cli,
2168 const char *share, const char *dev,
2169 const char *pass, int passlen,
2170 struct tevent_req **psmbreq)
2172 struct tevent_req *req, *subreq;
2173 struct cli_tcon_andx_state *state;
2181 req = tevent_req_create(mem_ctx, &state, struct cli_tcon_andx_state);
2188 cli->share = talloc_strdup(cli, share);
2193 /* in user level security don't send a password now */
2194 if (cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {
2197 } else if (pass == NULL) {
2198 DEBUG(1, ("Server not using user level security and no "
2199 "password supplied.\n"));
2203 if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) &&
2204 *pass && passlen != 24) {
2205 if (!lp_client_lanman_auth()) {
2206 DEBUG(1, ("Server requested LANMAN password "
2207 "(share-level security) but "
2208 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2213 * Non-encrypted passwords - convert to DOS codepage before
2216 SMBencrypt(pass, cli->secblob.data, p24);
2218 pass = (const char *)p24;
2220 if((cli->sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL
2221 |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE))
2225 if (!lp_client_plaintext_auth() && (*pass)) {
2226 DEBUG(1, ("Server requested plaintext "
2228 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2233 * Non-encrypted passwords - convert to DOS codepage
2236 tmp_pass = talloc_array(talloc_tos(), char, 128);
2237 if (tmp_pass == NULL) {
2238 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2239 return tevent_req_post(req, ev);
2241 passlen = clistr_push(cli,
2244 talloc_get_size(tmp_pass),
2246 if (passlen == -1) {
2247 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2248 return tevent_req_post(req, ev);
2254 SCVAL(vwv+0, 0, 0xFF);
2257 SSVAL(vwv+2, 0, TCONX_FLAG_EXTENDED_RESPONSE);
2258 SSVAL(vwv+3, 0, passlen);
2260 if (passlen && pass) {
2261 bytes = (uint8_t *)talloc_memdup(state, pass, passlen);
2263 bytes = talloc_array(state, uint8_t, 0);
2269 tmp = talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
2270 cli->desthost, share);
2275 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), tmp, strlen(tmp)+1,
2280 * Add the devicetype
2282 tmp = talloc_strdup_upper(talloc_tos(), dev);
2287 bytes = smb_bytes_push_str(bytes, false, tmp, strlen(tmp)+1, NULL);
2290 if (bytes == NULL) {
2295 state->bytes.iov_base = (void *)bytes;
2296 state->bytes.iov_len = talloc_get_size(bytes);
2298 subreq = cli_smb_req_create(state, ev, cli, SMBtconX, 0, 4, vwv,
2300 if (subreq == NULL) {
2304 tevent_req_set_callback(subreq, cli_tcon_andx_done, req);
2309 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
2310 return tevent_req_post(req, ev);
2313 struct tevent_req *cli_tcon_andx_send(TALLOC_CTX *mem_ctx,
2314 struct event_context *ev,
2315 struct cli_state *cli,
2316 const char *share, const char *dev,
2317 const char *pass, int passlen)
2319 struct tevent_req *req, *subreq;
2322 req = cli_tcon_andx_create(mem_ctx, ev, cli, share, dev, pass, passlen,
2327 if (subreq == NULL) {
2330 status = cli_smb_req_send(subreq);
2331 if (!NT_STATUS_IS_OK(status)) {
2332 tevent_req_nterror(req, status);
2333 return tevent_req_post(req, ev);
2338 static void cli_tcon_andx_done(struct tevent_req *subreq)
2340 struct tevent_req *req = tevent_req_callback_data(
2341 subreq, struct tevent_req);
2342 struct cli_tcon_andx_state *state = tevent_req_data(
2343 req, struct cli_tcon_andx_state);
2344 struct cli_state *cli = state->cli;
2353 status = cli_smb_recv(subreq, state, &in, 0, &wct, &vwv,
2354 &num_bytes, &bytes);
2355 TALLOC_FREE(subreq);
2356 if (!NT_STATUS_IS_OK(status)) {
2357 tevent_req_nterror(req, status);
2364 if (clistr_pull_talloc(cli,
2366 SVAL(inbuf, smb_flg2),
2370 STR_TERMINATE|STR_ASCII) == -1) {
2371 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2375 cli->dev = talloc_strdup(cli, "");
2376 if (cli->dev == NULL) {
2377 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2382 if ((cli->protocol >= PROTOCOL_NT1) && (num_bytes == 3)) {
2383 /* almost certainly win95 - enable bug fixes */
2388 * Make sure that we have the optional support 16-bit field. WCT > 2.
2389 * Avoids issues when connecting to Win9x boxes sharing files
2392 cli->dfsroot = false;
2394 if ((wct > 2) && (cli->protocol >= PROTOCOL_LANMAN2)) {
2395 cli->dfsroot = ((SVAL(vwv+2, 0) & SMB_SHARE_IN_DFS) != 0);
2398 cli->cnum = SVAL(inbuf,smb_tid);
2399 tevent_req_done(req);
2402 NTSTATUS cli_tcon_andx_recv(struct tevent_req *req)
2404 return tevent_req_simple_recv_ntstatus(req);
2407 NTSTATUS cli_tcon_andx(struct cli_state *cli, const char *share,
2408 const char *dev, const char *pass, int passlen)
2410 TALLOC_CTX *frame = talloc_stackframe();
2411 struct event_context *ev;
2412 struct tevent_req *req;
2413 NTSTATUS status = NT_STATUS_OK;
2415 if (cli_has_async_calls(cli)) {
2417 * Can't use sync call while an async call is in flight
2419 status = NT_STATUS_INVALID_PARAMETER;
2423 ev = event_context_init(frame);
2425 status = NT_STATUS_NO_MEMORY;
2429 req = cli_tcon_andx_send(frame, ev, cli, share, dev, pass, passlen);
2431 status = NT_STATUS_NO_MEMORY;
2435 if (!tevent_req_poll(req, ev)) {
2436 status = map_nt_error_from_unix(errno);
2440 status = cli_tcon_andx_recv(req);
2443 if (!NT_STATUS_IS_OK(status)) {
2444 cli_set_error(cli, status);
2449 /****************************************************************************
2450 Send a tree disconnect.
2451 ****************************************************************************/
2453 struct cli_tdis_state {
2454 struct cli_state *cli;
2457 static void cli_tdis_done(struct tevent_req *subreq);
2459 struct tevent_req *cli_tdis_send(TALLOC_CTX *mem_ctx,
2460 struct tevent_context *ev,
2461 struct cli_state *cli)
2463 struct tevent_req *req, *subreq;
2464 struct cli_tdis_state *state;
2466 req = tevent_req_create(mem_ctx, &state, struct cli_tdis_state);
2472 subreq = cli_smb_send(state, ev, cli, SMBtdis, 0, 0, NULL, 0, NULL);
2473 if (tevent_req_nomem(subreq, req)) {
2474 return tevent_req_post(req, ev);
2476 tevent_req_set_callback(subreq, cli_tdis_done, req);
2480 static void cli_tdis_done(struct tevent_req *subreq)
2482 struct tevent_req *req = tevent_req_callback_data(
2483 subreq, struct tevent_req);
2484 struct cli_tdis_state *state = tevent_req_data(
2485 req, struct cli_tdis_state);
2488 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
2489 TALLOC_FREE(subreq);
2490 if (!NT_STATUS_IS_OK(status)) {
2491 tevent_req_nterror(req, status);
2494 state->cli->cnum = -1;
2495 tevent_req_done(req);
2498 NTSTATUS cli_tdis_recv(struct tevent_req *req)
2500 return tevent_req_simple_recv_ntstatus(req);
2503 NTSTATUS cli_tdis(struct cli_state *cli)
2505 struct tevent_context *ev;
2506 struct tevent_req *req;
2507 NTSTATUS status = NT_STATUS_NO_MEMORY;
2509 if (cli_has_async_calls(cli)) {
2510 return NT_STATUS_INVALID_PARAMETER;
2512 ev = tevent_context_init(talloc_tos());
2516 req = cli_tdis_send(ev, ev, cli);
2520 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2523 status = cli_tdis_recv(req);
2526 if (!NT_STATUS_IS_OK(status)) {
2527 cli_set_error(cli, status);
2532 /****************************************************************************
2533 Send a negprot command.
2534 ****************************************************************************/
2536 struct cli_negprot_state {
2537 struct cli_state *cli;
2540 static void cli_negprot_done(struct tevent_req *subreq);
2542 struct tevent_req *cli_negprot_send(TALLOC_CTX *mem_ctx,
2543 struct event_context *ev,
2544 struct cli_state *cli)
2546 struct tevent_req *req, *subreq;
2547 struct cli_negprot_state *state;
2548 uint8_t *bytes = NULL;
2552 req = tevent_req_create(mem_ctx, &state, struct cli_negprot_state);
2558 if (cli->protocol < PROTOCOL_NT1)
2559 cli->use_spnego = False;
2561 /* setup the protocol strings */
2562 for (numprots=0; numprots < ARRAY_SIZE(prots); numprots++) {
2564 if (prots[numprots].prot > cli->protocol) {
2567 bytes = (uint8_t *)talloc_append_blob(
2568 state, bytes, data_blob_const(&c, sizeof(c)));
2569 if (tevent_req_nomem(bytes, req)) {
2570 return tevent_req_post(req, ev);
2572 bytes = smb_bytes_push_str(bytes, false,
2573 prots[numprots].name,
2574 strlen(prots[numprots].name)+1,
2576 if (tevent_req_nomem(bytes, req)) {
2577 return tevent_req_post(req, ev);
2584 subreq = cli_smb_send(state, ev, cli, SMBnegprot, 0, 0, NULL,
2585 talloc_get_size(bytes), bytes);
2588 if (tevent_req_nomem(subreq, req)) {
2589 return tevent_req_post(req, ev);
2591 tevent_req_set_callback(subreq, cli_negprot_done, req);
2595 static void cli_negprot_done(struct tevent_req *subreq)
2597 struct tevent_req *req = tevent_req_callback_data(
2598 subreq, struct tevent_req);
2599 struct cli_negprot_state *state = tevent_req_data(
2600 req, struct cli_negprot_state);
2601 struct cli_state *cli = state->cli;
2610 status = cli_smb_recv(subreq, state, &inbuf, 1, &wct, &vwv,
2611 &num_bytes, &bytes);
2612 TALLOC_FREE(subreq);
2613 if (!NT_STATUS_IS_OK(status)) {
2614 tevent_req_nterror(req, status);
2618 protnum = SVAL(vwv, 0);
2620 if ((protnum >= ARRAY_SIZE(prots))
2621 || (prots[protnum].prot > cli->protocol)) {
2622 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2626 cli->protocol = prots[protnum].prot;
2628 if ((cli->protocol < PROTOCOL_NT1) &&
2629 client_is_signing_mandatory(cli)) {
2630 DEBUG(0,("cli_negprot: SMB signing is mandatory and the selected protocol level doesn't support it.\n"));
2631 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
2635 if (cli->protocol >= PROTOCOL_NT1) {
2637 bool negotiated_smb_signing = false;
2640 cli->sec_mode = CVAL(vwv + 1, 0);
2641 cli->max_mux = SVAL(vwv + 1, 1);
2642 cli->max_xmit = IVAL(vwv + 3, 1);
2643 cli->sesskey = IVAL(vwv + 7, 1);
2644 cli->serverzone = SVALS(vwv + 15, 1);
2645 cli->serverzone *= 60;
2646 /* this time arrives in real GMT */
2647 ts = interpret_long_date(((char *)(vwv+11))+1);
2648 cli->servertime = ts.tv_sec;
2649 cli->secblob = data_blob(bytes, num_bytes);
2650 cli->capabilities = IVAL(vwv + 9, 1);
2651 if (cli->capabilities & CAP_RAW_MODE) {
2652 cli->readbraw_supported = True;
2653 cli->writebraw_supported = True;
2655 /* work out if they sent us a workgroup */
2656 if (!(cli->capabilities & CAP_EXTENDED_SECURITY) &&
2657 smb_buflen(cli->inbuf) > 8) {
2658 clistr_pull(cli->inbuf, cli->server_domain,
2659 bytes+8, sizeof(cli->server_domain),
2661 STR_UNICODE|STR_NOALIGN);
2665 * As signing is slow we only turn it on if either the client or
2666 * the server require it. JRA.
2669 if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) {
2670 /* Fail if server says signing is mandatory and we don't want to support it. */
2671 if (!client_is_signing_allowed(cli)) {
2672 DEBUG(0,("cli_negprot: SMB signing is mandatory and we have disabled it.\n"));
2673 tevent_req_nterror(req,
2674 NT_STATUS_ACCESS_DENIED);
2677 negotiated_smb_signing = true;
2678 } else if (client_is_signing_mandatory(cli) && client_is_signing_allowed(cli)) {
2679 /* Fail if client says signing is mandatory and the server doesn't support it. */
2680 if (!(cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) {
2681 DEBUG(1,("cli_negprot: SMB signing is mandatory and the server doesn't support it.\n"));
2682 tevent_req_nterror(req,
2683 NT_STATUS_ACCESS_DENIED);
2686 negotiated_smb_signing = true;
2687 } else if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) {
2688 negotiated_smb_signing = true;
2691 if (negotiated_smb_signing) {
2692 cli_set_signing_negotiated(cli);
2695 if (cli->capabilities & (CAP_LARGE_READX|CAP_LARGE_WRITEX)) {
2696 SAFE_FREE(cli->outbuf);
2697 SAFE_FREE(cli->inbuf);
2698 cli->outbuf = (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE+LARGE_WRITEX_HDR_SIZE+SAFETY_MARGIN);
2699 cli->inbuf = (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE+LARGE_WRITEX_HDR_SIZE+SAFETY_MARGIN);
2700 if (!cli->outbuf || !cli->inbuf) {
2701 tevent_req_nterror(req,
2702 NT_STATUS_NO_MEMORY);
2705 cli->bufsize = CLI_SAMBA_MAX_LARGE_READX_SIZE + LARGE_WRITEX_HDR_SIZE;
2708 } else if (cli->protocol >= PROTOCOL_LANMAN1) {
2709 cli->use_spnego = False;
2710 cli->sec_mode = SVAL(vwv + 1, 0);
2711 cli->max_xmit = SVAL(vwv + 2, 0);
2712 cli->max_mux = SVAL(vwv + 3, 0);
2713 cli->sesskey = IVAL(vwv + 6, 0);
2714 cli->serverzone = SVALS(vwv + 10, 0);
2715 cli->serverzone *= 60;
2716 /* this time is converted to GMT by make_unix_date */
2717 cli->servertime = make_unix_date(
2718 (char *)(vwv + 8), cli->serverzone);
2719 cli->readbraw_supported = ((SVAL(vwv + 5, 0) & 0x1) != 0);
2720 cli->writebraw_supported = ((SVAL(vwv + 5, 0) & 0x2) != 0);
2721 cli->secblob = data_blob(bytes, num_bytes);
2723 /* the old core protocol */
2724 cli->use_spnego = False;
2726 cli->serverzone = get_time_zone(time(NULL));
2729 cli->max_xmit = MIN(cli->max_xmit, CLI_BUFFER_SIZE);
2731 /* a way to force ascii SMB */
2732 if (getenv("CLI_FORCE_ASCII"))
2733 cli->capabilities &= ~CAP_UNICODE;
2735 tevent_req_done(req);
2738 NTSTATUS cli_negprot_recv(struct tevent_req *req)
2740 return tevent_req_simple_recv_ntstatus(req);
2743 NTSTATUS cli_negprot(struct cli_state *cli)
2745 TALLOC_CTX *frame = talloc_stackframe();
2746 struct event_context *ev;
2747 struct tevent_req *req;
2748 NTSTATUS status = NT_STATUS_OK;
2750 if (cli_has_async_calls(cli)) {
2752 * Can't use sync call while an async call is in flight
2754 status = NT_STATUS_INVALID_PARAMETER;
2758 ev = event_context_init(frame);
2760 status = NT_STATUS_NO_MEMORY;
2764 req = cli_negprot_send(frame, ev, cli);
2766 status = NT_STATUS_NO_MEMORY;
2770 if (!tevent_req_poll(req, ev)) {
2771 status = map_nt_error_from_unix(errno);
2775 status = cli_negprot_recv(req);
2778 if (!NT_STATUS_IS_OK(status)) {
2779 cli_set_error(cli, status);
2784 /****************************************************************************
2785 Send a session request. See rfc1002.txt 4.3 and 4.3.2.
2786 ****************************************************************************/
2788 bool cli_session_request(struct cli_state *cli,
2789 struct nmb_name *calling, struct nmb_name *called)
2796 /* 445 doesn't have session request */
2797 if (cli->port == 445)
2800 memcpy(&(cli->calling), calling, sizeof(*calling));
2801 memcpy(&(cli->called ), called , sizeof(*called ));
2803 /* put in the destination name */
2805 tmp = name_mangle(talloc_tos(), cli->called.name,
2806 cli->called.name_type);
2811 p = cli->outbuf+len;
2812 namelen = name_len((unsigned char *)tmp, talloc_get_size(tmp));
2814 memcpy(p, tmp, namelen);
2821 tmp = name_mangle(talloc_tos(), cli->calling.name,
2822 cli->calling.name_type);
2827 p = cli->outbuf+len;
2828 namelen = name_len((unsigned char *)tmp, talloc_get_size(tmp));
2830 memcpy(p, tmp, namelen);
2835 /* send a session request (RFC 1002) */
2836 /* setup the packet length
2837 * Remove four bytes from the length count, since the length
2838 * field in the NBT Session Service header counts the number
2839 * of bytes which follow. The cli_send_smb() function knows
2840 * about this and accounts for those four bytes.
2844 _smb_setlen(cli->outbuf,len);
2845 SCVAL(cli->outbuf,0,0x81);
2848 DEBUG(5,("Sent session request\n"));
2850 if (!cli_receive_smb(cli))
2853 if (CVAL(cli->inbuf,0) == 0x84) {
2854 /* C. Hoch 9/14/95 Start */
2855 /* For information, here is the response structure.
2856 * We do the byte-twiddling to for portability.
2857 struct RetargetResponse{
2859 unsigned char flags;
2865 uint16_t port = (CVAL(cli->inbuf,8)<<8)+CVAL(cli->inbuf,9);
2866 struct in_addr dest_ip;
2869 /* SESSION RETARGET */
2870 putip((char *)&dest_ip,cli->inbuf+4);
2871 in_addr_to_sockaddr_storage(&cli->dest_ss, dest_ip);
2873 status = open_socket_out(&cli->dest_ss, port,
2874 LONG_CONNECT_TIMEOUT, &cli->fd);
2875 if (!NT_STATUS_IS_OK(status)) {
2879 DEBUG(3,("Retargeted\n"));
2881 set_socket_options(cli->fd, lp_socket_options());
2888 DEBUG(0,("Retarget recursion - failing\n"));
2892 ret = cli_session_request(cli, calling, called);
2896 } /* C. Hoch 9/14/95 End */
2898 if (CVAL(cli->inbuf,0) != 0x82) {
2899 /* This is the wrong place to put the error... JRA. */
2900 cli->rap_error = CVAL(cli->inbuf,4);
2910 static void smb_sock_connected(struct tevent_req *req)
2912 struct fd_struct *pfd = tevent_req_callback_data(
2913 req, struct fd_struct);
2917 status = open_socket_out_defer_recv(req, &fd);
2918 if (NT_STATUS_IS_OK(status)) {
2923 static NTSTATUS open_smb_socket(const struct sockaddr_storage *pss,
2924 uint16_t *port, int timeout, int *pfd)
2926 struct event_context *ev;
2927 struct tevent_req *r139, *r445;
2928 struct fd_struct *fd139, *fd445;
2929 NTSTATUS status = NT_STATUS_NO_MEMORY;
2932 return open_socket_out(pss, *port, timeout, pfd);
2935 ev = event_context_init(talloc_tos());
2937 return NT_STATUS_NO_MEMORY;
2940 fd139 = talloc(ev, struct fd_struct);
2941 if (fd139 == NULL) {
2946 fd445 = talloc(ev, struct fd_struct);
2947 if (fd445 == NULL) {
2952 r445 = open_socket_out_defer_send(ev, ev, timeval_set(0, 0),
2954 r139 = open_socket_out_defer_send(ev, ev, timeval_set(0, 3000),
2956 if ((r445 == NULL) || (r139 == NULL)) {
2959 tevent_req_set_callback(r445, smb_sock_connected, fd445);
2960 tevent_req_set_callback(r139, smb_sock_connected, fd139);
2962 while ((fd445->fd == -1) && (fd139->fd == -1)
2963 && (tevent_req_is_in_progress(r139)
2964 || tevent_req_is_in_progress(r445))) {
2965 event_loop_once(ev);
2968 if ((fd139->fd != -1) && (fd445->fd != -1)) {
2973 if (fd445->fd != -1) {
2976 status = NT_STATUS_OK;
2979 if (fd139->fd != -1) {
2982 status = NT_STATUS_OK;
2986 status = open_socket_out_defer_recv(r445, &fd445->fd);
2992 /****************************************************************************
2993 Open the client sockets.
2994 ****************************************************************************/
2996 NTSTATUS cli_connect(struct cli_state *cli,
2998 struct sockaddr_storage *dest_ss)
3001 int name_type = 0x20;
3002 TALLOC_CTX *frame = talloc_stackframe();
3003 unsigned int num_addrs = 0;
3005 struct sockaddr_storage *ss_arr = NULL;
3008 /* reasonable default hostname */
3010 host = STAR_SMBSERVER;
3013 cli->desthost = talloc_strdup(cli, host);
3014 if (cli->desthost == NULL) {
3015 return NT_STATUS_NO_MEMORY;
3018 /* allow hostnames of the form NAME#xx and do a netbios lookup */
3019 if ((p = strchr(cli->desthost, '#'))) {
3020 name_type = strtol(p+1, NULL, 16);
3024 if (!dest_ss || is_zero_addr(dest_ss)) {
3025 NTSTATUS status =resolve_name_list(frame,
3030 if (!NT_STATUS_IS_OK(status)) {
3032 return NT_STATUS_BAD_NETWORK_NAME;
3036 ss_arr = TALLOC_P(frame, struct sockaddr_storage);
3039 return NT_STATUS_NO_MEMORY;
3044 for (i = 0; i < num_addrs; i++) {
3045 cli->dest_ss = ss_arr[i];
3046 if (getenv("LIBSMB_PROG")) {
3047 cli->fd = sock_exec(getenv("LIBSMB_PROG"));
3049 uint16_t port = cli->port;
3051 status = open_smb_socket(&cli->dest_ss, &port,
3052 cli->timeout, &cli->fd);
3053 if (NT_STATUS_IS_OK(status)) {
3057 if (cli->fd == -1) {
3058 char addr[INET6_ADDRSTRLEN];
3059 print_sockaddr(addr, sizeof(addr), &ss_arr[i]);
3060 DEBUG(2,("Error connecting to %s (%s)\n",
3061 dest_ss?addr:host,strerror(errno)));
3063 /* Exit from loop on first connection. */
3068 if (cli->fd == -1) {
3070 return map_nt_error_from_unix(errno);
3074 *dest_ss = cli->dest_ss;
3077 set_socket_options(cli->fd, lp_socket_options());
3080 return NT_STATUS_OK;
3084 establishes a connection to after the negprot.
3085 @param output_cli A fully initialised cli structure, non-null only on success
3086 @param dest_host The netbios name of the remote host
3087 @param dest_ss (optional) The the destination IP, NULL for name based lookup
3088 @param port (optional) The destination port (0 for default)
3090 NTSTATUS cli_start_connection(struct cli_state **output_cli,
3091 const char *my_name,
3092 const char *dest_host,
3093 struct sockaddr_storage *dest_ss, int port,
3094 int signing_state, int flags)
3097 struct nmb_name calling;
3098 struct nmb_name called;
3099 struct cli_state *cli;
3100 struct sockaddr_storage ss;
3103 my_name = global_myname();
3105 if (!(cli = cli_initialise_ex(signing_state))) {
3106 return NT_STATUS_NO_MEMORY;
3109 make_nmb_name(&calling, my_name, 0x0);
3110 make_nmb_name(&called , dest_host, 0x20);
3112 cli_set_port(cli, port);
3113 cli_set_timeout(cli, 10000); /* 10 seconds. */
3123 DEBUG(3,("Connecting to host=%s\n", dest_host));
3125 nt_status = cli_connect(cli, dest_host, &ss);
3126 if (!NT_STATUS_IS_OK(nt_status)) {
3127 char addr[INET6_ADDRSTRLEN];
3128 print_sockaddr(addr, sizeof(addr), &ss);
3129 DEBUG(1,("cli_start_connection: failed to connect to %s (%s). Error %s\n",
3130 nmb_namestr(&called), addr, nt_errstr(nt_status) ));
3135 if (!cli_session_request(cli, &calling, &called)) {
3137 DEBUG(1,("session request to %s failed (%s)\n",
3138 called.name, cli_errstr(cli)));
3139 if ((p=strchr(called.name, '.')) && !is_ipaddress(called.name)) {
3143 if (strcmp(called.name, STAR_SMBSERVER)) {
3144 make_nmb_name(&called , STAR_SMBSERVER, 0x20);
3147 return NT_STATUS_BAD_NETWORK_NAME;
3150 if (flags & CLI_FULL_CONNECTION_DONT_SPNEGO)
3151 cli->use_spnego = False;
3152 else if (flags & CLI_FULL_CONNECTION_USE_KERBEROS)
3153 cli->use_kerberos = True;
3155 if ((flags & CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS) &&
3156 cli->use_kerberos) {
3157 cli->fallback_after_kerberos = true;
3159 if (flags & CLI_FULL_CONNECTION_USE_CCACHE) {
3160 cli->use_ccache = true;
3163 nt_status = cli_negprot(cli);
3164 if (!NT_STATUS_IS_OK(nt_status)) {
3165 DEBUG(1, ("failed negprot: %s\n", nt_errstr(nt_status)));
3171 return NT_STATUS_OK;
3176 establishes a connection right up to doing tconX, password specified.
3177 @param output_cli A fully initialised cli structure, non-null only on success
3178 @param dest_host The netbios name of the remote host
3179 @param dest_ip (optional) The the destination IP, NULL for name based lookup
3180 @param port (optional) The destination port (0 for default)
3181 @param service (optional) The share to make the connection to. Should be 'unqualified' in any way.
3182 @param service_type The 'type' of serivice.
3183 @param user Username, unix string
3184 @param domain User's domain
3185 @param password User's password, unencrypted unix string.
3188 NTSTATUS cli_full_connection(struct cli_state **output_cli,
3189 const char *my_name,
3190 const char *dest_host,
3191 struct sockaddr_storage *dest_ss, int port,
3192 const char *service, const char *service_type,
3193 const char *user, const char *domain,
3194 const char *password, int flags,
3198 struct cli_state *cli = NULL;
3199 int pw_len = password ? strlen(password)+1 : 0;
3203 if (password == NULL) {
3207 nt_status = cli_start_connection(&cli, my_name, dest_host,
3208 dest_ss, port, signing_state,
3211 if (!NT_STATUS_IS_OK(nt_status)) {
3215 cli->use_oplocks = ((flags & CLI_FULL_CONNECTION_OPLOCKS) != 0);
3216 cli->use_level_II_oplocks =
3217 ((flags & CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS) != 0);
3219 nt_status = cli_session_setup(cli, user, password, pw_len, password,
3221 if (!NT_STATUS_IS_OK(nt_status)) {
3223 if (!(flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)) {
3224 DEBUG(1,("failed session setup with %s\n",
3225 nt_errstr(nt_status)));
3230 nt_status = cli_session_setup(cli, "", "", 0, "", 0, domain);
3231 if (!NT_STATUS_IS_OK(nt_status)) {
3232 DEBUG(1,("anonymous failed session setup with %s\n",
3233 nt_errstr(nt_status)));
3240 nt_status = cli_tcon_andx(cli, service, service_type, password,
3242 if (!NT_STATUS_IS_OK(nt_status)) {
3243 DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status)));
3245 if (NT_STATUS_IS_OK(nt_status)) {
3246 nt_status = NT_STATUS_UNSUCCESSFUL;
3252 nt_status = cli_init_creds(cli, user, domain, password);
3253 if (!NT_STATUS_IS_OK(nt_status)) {
3259 return NT_STATUS_OK;
3262 /****************************************************************************
3263 Attempt a NetBIOS session request, falling back to *SMBSERVER if needed.
3264 ****************************************************************************/
3266 bool attempt_netbios_session_request(struct cli_state **ppcli, const char *srchost, const char *desthost,
3267 struct sockaddr_storage *pdest_ss)
3269 struct nmb_name calling, called;
3271 make_nmb_name(&calling, srchost, 0x0);
3274 * If the called name is an IP address
3275 * then use *SMBSERVER immediately.
3278 if(is_ipaddress(desthost)) {
3279 make_nmb_name(&called, STAR_SMBSERVER, 0x20);
3281 make_nmb_name(&called, desthost, 0x20);
3284 if (!cli_session_request(*ppcli, &calling, &called)) {
3286 struct nmb_name smbservername;
3288 make_nmb_name(&smbservername, STAR_SMBSERVER, 0x20);
3291 * If the name wasn't *SMBSERVER then
3292 * try with *SMBSERVER if the first name fails.
3295 if (nmb_name_equal(&called, &smbservername)) {
3298 * The name used was *SMBSERVER, don't bother with another name.
3301 DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER \
3302 with error %s.\n", desthost, cli_errstr(*ppcli) ));
3307 cli_shutdown(*ppcli);
3309 *ppcli = cli_initialise();
3311 /* Out of memory... */
3315 status = cli_connect(*ppcli, desthost, pdest_ss);
3316 if (!NT_STATUS_IS_OK(status) ||
3317 !cli_session_request(*ppcli, &calling, &smbservername)) {
3318 DEBUG(0,("attempt_netbios_session_request: %s rejected the session for \
3319 name *SMBSERVER with error %s\n", desthost, cli_errstr(*ppcli) ));
3327 /****************************************************************************
3328 Send an old style tcon.
3329 ****************************************************************************/
3330 NTSTATUS cli_raw_tcon(struct cli_state *cli,
3331 const char *service, const char *pass, const char *dev,
3332 uint16 *max_xmit, uint16 *tid)
3334 struct tevent_req *req;
3339 if (!lp_client_plaintext_auth() && (*pass)) {
3340 DEBUG(1, ("Server requested plaintext password but 'client "
3341 "plaintext auth' is disabled\n"));
3342 return NT_STATUS_ACCESS_DENIED;
3345 bytes = talloc_array(talloc_tos(), uint8_t, 0);
3346 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3347 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
3348 service, strlen(service)+1, NULL);
3349 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3350 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
3351 pass, strlen(pass)+1, NULL);
3352 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3353 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
3354 dev, strlen(dev)+1, NULL);
3356 status = cli_smb(talloc_tos(), cli, SMBtcon, 0, 0, NULL,
3357 talloc_get_size(bytes), bytes, &req,
3358 2, NULL, &ret_vwv, NULL, NULL);
3359 if (!NT_STATUS_IS_OK(status)) {
3363 *max_xmit = SVAL(ret_vwv + 0, 0);
3364 *tid = SVAL(ret_vwv + 1, 0);
3366 return NT_STATUS_OK;
3369 /* Return a cli_state pointing at the IPC$ share for the given server */
3371 struct cli_state *get_ipc_connect(char *server,
3372 struct sockaddr_storage *server_ss,
3373 const struct user_auth_info *user_info)
3375 struct cli_state *cli;
3377 uint32_t flags = CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
3379 if (user_info->use_kerberos) {
3380 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
3383 nt_status = cli_full_connection(&cli, NULL, server, server_ss, 0, "IPC$", "IPC",
3384 user_info->username ? user_info->username : "",
3386 user_info->password ? user_info->password : "",
3390 if (NT_STATUS_IS_OK(nt_status)) {
3392 } else if (is_ipaddress(server)) {
3393 /* windows 9* needs a correct NMB name for connections */
3394 fstring remote_name;
3396 if (name_status_find("*", 0, 0, server_ss, remote_name)) {
3397 cli = get_ipc_connect(remote_name, server_ss, user_info);
3406 * Given the IP address of a master browser on the network, return its
3407 * workgroup and connect to it.
3409 * This function is provided to allow additional processing beyond what
3410 * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
3411 * browsers and obtain each master browsers' list of domains (in case the
3412 * first master browser is recently on the network and has not yet
3413 * synchronized with other master browsers and therefore does not yet have the
3414 * entire network browse list)
3417 struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx,
3418 struct sockaddr_storage *mb_ip,
3419 const struct user_auth_info *user_info,
3420 char **pp_workgroup_out)
3422 char addr[INET6_ADDRSTRLEN];
3424 struct cli_state *cli;
3425 struct sockaddr_storage server_ss;
3427 *pp_workgroup_out = NULL;
3429 print_sockaddr(addr, sizeof(addr), mb_ip);
3430 DEBUG(99, ("Looking up name of master browser %s\n",
3434 * Do a name status query to find out the name of the master browser.
3435 * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
3436 * master browser will not respond to a wildcard query (or, at least,
3437 * an NT4 server acting as the domain master browser will not).
3439 * We might be able to use ONLY the query on MSBROWSE, but that's not
3440 * yet been tested with all Windows versions, so until it is, leave
3441 * the original wildcard query as the first choice and fall back to
3442 * MSBROWSE if the wildcard query fails.
3444 if (!name_status_find("*", 0, 0x1d, mb_ip, name) &&
3445 !name_status_find(MSBROWSE, 1, 0x1d, mb_ip, name)) {
3447 DEBUG(99, ("Could not retrieve name status for %s\n",
3452 if (!find_master_ip(name, &server_ss)) {
3453 DEBUG(99, ("Could not find master ip for %s\n", name));
3457 *pp_workgroup_out = talloc_strdup(ctx, name);
3459 DEBUG(4, ("found master browser %s, %s\n", name, addr));
3461 print_sockaddr(addr, sizeof(addr), &server_ss);
3462 cli = get_ipc_connect(addr, &server_ss, user_info);
3468 * Return the IP address and workgroup of a master browser on the network, and
3472 struct cli_state *get_ipc_connect_master_ip_bcast(TALLOC_CTX *ctx,
3473 const struct user_auth_info *user_info,
3474 char **pp_workgroup_out)
3476 struct sockaddr_storage *ip_list;
3477 struct cli_state *cli;
3481 *pp_workgroup_out = NULL;
3483 DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
3485 /* Go looking for workgroups by broadcasting on the local network */
3487 status = name_resolve_bcast(MSBROWSE, 1, talloc_tos(),
3489 if (!NT_STATUS_IS_OK(status)) {
3490 DEBUG(99, ("No master browsers responded: %s\n",
3491 nt_errstr(status)));
3495 for (i = 0; i < count; i++) {
3496 char addr[INET6_ADDRSTRLEN];
3497 print_sockaddr(addr, sizeof(addr), &ip_list[i]);
3498 DEBUG(99, ("Found master browser %s\n", addr));
3500 cli = get_ipc_connect_master_ip(ctx, &ip_list[i],
3501 user_info, pp_workgroup_out);