2 Unix SMB/CIFS implementation.
3 client connect/disconnect routines
4 Copyright (C) Andrew Tridgell 1994-1998
5 Copyright (C) Andrew Bartlett 2001-2003
6 Copyright (C) Volker Lendecke 2011
7 Copyright (C) Jeremy Allison 2011
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "libsmb/libsmb.h"
25 #include "popt_common.h"
26 #include "../libcli/auth/libcli_auth.h"
27 #include "../libcli/auth/spnego.h"
29 #include "../libcli/auth/ntlmssp.h"
30 #include "libads/kerberos_proto.h"
32 #include "../lib/util/tevent_ntstatus.h"
33 #include "async_smb.h"
34 #include "libsmb/nmblib.h"
41 {PROTOCOL_CORE, "PC NETWORK PROGRAM 1.0"},
42 {PROTOCOL_COREPLUS, "MICROSOFT NETWORKS 1.03"},
43 {PROTOCOL_LANMAN1, "MICROSOFT NETWORKS 3.0"},
44 {PROTOCOL_LANMAN1, "LANMAN1.0"},
45 {PROTOCOL_LANMAN2, "LM1.2X002"},
46 {PROTOCOL_LANMAN2, "DOS LANMAN2.1"},
47 {PROTOCOL_LANMAN2, "LANMAN2.1"},
48 {PROTOCOL_LANMAN2, "Samba"},
49 {PROTOCOL_NT1, "NT LANMAN 1.0"},
50 {PROTOCOL_NT1, "NT LM 0.12"},
53 #define STAR_SMBSERVER "*SMBSERVER"
55 /********************************************************
56 Utility function to ensure we always return at least
57 a valid char * pointer to an empty string for the
58 cli->server_os, cli->server_type and cli->server_domain
60 *******************************************************/
62 static NTSTATUS smb_bytes_talloc_string(TALLOC_CTX *mem_ctx,
69 *destlen = clistr_pull_talloc(mem_ctx,
71 SVAL(inbuf, smb_flg2),
77 return NT_STATUS_NO_MEMORY;
81 *dest = talloc_strdup(mem_ctx, "");
83 return NT_STATUS_NO_MEMORY;
90 * Set the user session key for a connection
91 * @param cli The cli structure to add it too
92 * @param session_key The session key used. (A copy of this is taken for the cli struct)
96 static void cli_set_session_key (struct cli_state *cli, const DATA_BLOB session_key)
98 cli->user_session_key = data_blob(session_key.data, session_key.length);
101 /****************************************************************************
102 Do an old lanman2 style session setup.
103 ****************************************************************************/
105 struct cli_session_setup_lanman2_state {
106 struct cli_state *cli;
111 static void cli_session_setup_lanman2_done(struct tevent_req *subreq);
113 static struct tevent_req *cli_session_setup_lanman2_send(
114 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
115 struct cli_state *cli, const char *user,
116 const char *pass, size_t passlen,
117 const char *workgroup)
119 struct tevent_req *req, *subreq;
120 struct cli_session_setup_lanman2_state *state;
121 DATA_BLOB lm_response = data_blob_null;
125 uint16_t sec_mode = cli_state_security_mode(cli);
127 req = tevent_req_create(mem_ctx, &state,
128 struct cli_session_setup_lanman2_state);
137 * LANMAN servers predate NT status codes and Unicode and
138 * ignore those smb flags so we must disable the corresponding
139 * default capabilities that would otherwise cause the Unicode
140 * and NT Status flags to be set (and even returned by the
144 cli->capabilities &= ~(CAP_UNICODE | CAP_STATUS32);
147 * if in share level security then don't send a password now
149 if (!(sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) {
154 && (sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)
157 * Encrypted mode needed, and non encrypted password
160 lm_response = data_blob(NULL, 24);
161 if (tevent_req_nomem(lm_response.data, req)) {
162 return tevent_req_post(req, ev);
165 if (!SMBencrypt(pass, cli->secblob.data,
166 (uint8_t *)lm_response.data)) {
167 DEBUG(1, ("Password is > 14 chars in length, and is "
168 "therefore incompatible with Lanman "
169 "authentication\n"));
170 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
171 return tevent_req_post(req, ev);
173 } else if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)
176 * Encrypted mode needed, and encrypted password
179 lm_response = data_blob(pass, passlen);
180 if (tevent_req_nomem(lm_response.data, req)) {
181 return tevent_req_post(req, ev);
183 } else if (passlen > 0) {
185 size_t converted_size;
187 * Plaintext mode needed, assume plaintext supplied.
189 buf = talloc_array(talloc_tos(), uint8_t, 0);
190 buf = smb_bytes_push_str(buf, cli_ucs2(cli), pass, passlen+1,
192 if (tevent_req_nomem(buf, req)) {
193 return tevent_req_post(req, ev);
195 lm_response = data_blob(pass, passlen);
197 if (tevent_req_nomem(lm_response.data, req)) {
198 return tevent_req_post(req, ev);
202 SCVAL(vwv+0, 0, 0xff);
205 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
208 SIVAL(vwv+5, 0, cli_state_server_session_key(cli));
209 SSVAL(vwv+7, 0, lm_response.length);
211 bytes = talloc_array(state, uint8_t, lm_response.length);
212 if (tevent_req_nomem(bytes, req)) {
213 return tevent_req_post(req, ev);
215 if (lm_response.length != 0) {
216 memcpy(bytes, lm_response.data, lm_response.length);
218 data_blob_free(&lm_response);
220 tmp = talloc_strdup_upper(talloc_tos(), user);
221 if (tevent_req_nomem(tmp, req)) {
222 return tevent_req_post(req, ev);
224 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), tmp, strlen(tmp)+1,
228 tmp = talloc_strdup_upper(talloc_tos(), workgroup);
229 if (tevent_req_nomem(tmp, req)) {
230 return tevent_req_post(req, ev);
232 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), tmp, strlen(tmp)+1,
234 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Unix", 5, NULL);
235 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Samba", 6, NULL);
237 if (tevent_req_nomem(bytes, req)) {
238 return tevent_req_post(req, ev);
241 subreq = cli_smb_send(state, ev, cli, SMBsesssetupX, 0, 10, vwv,
242 talloc_get_size(bytes), bytes);
243 if (tevent_req_nomem(subreq, req)) {
244 return tevent_req_post(req, ev);
246 tevent_req_set_callback(subreq, cli_session_setup_lanman2_done, req);
250 static void cli_session_setup_lanman2_done(struct tevent_req *subreq)
252 struct tevent_req *req = tevent_req_callback_data(
253 subreq, struct tevent_req);
254 struct cli_session_setup_lanman2_state *state = tevent_req_data(
255 req, struct cli_session_setup_lanman2_state);
256 struct cli_state *cli = state->cli;
267 status = cli_smb_recv(subreq, state, &in, 3, &wct, &vwv,
270 if (!NT_STATUS_IS_OK(status)) {
271 tevent_req_nterror(req, status);
278 cli_state_set_uid(state->cli, SVAL(inbuf, smb_uid));
279 cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0);
281 status = smb_bytes_talloc_string(cli,
288 if (!NT_STATUS_IS_OK(status)) {
289 tevent_req_nterror(req, status);
294 status = smb_bytes_talloc_string(cli,
301 if (!NT_STATUS_IS_OK(status)) {
302 tevent_req_nterror(req, status);
307 status = smb_bytes_talloc_string(cli,
314 if (!NT_STATUS_IS_OK(status)) {
315 tevent_req_nterror(req, status);
320 status = cli_set_username(cli, state->user);
321 if (tevent_req_nterror(req, status)) {
324 tevent_req_done(req);
327 static NTSTATUS cli_session_setup_lanman2_recv(struct tevent_req *req)
329 return tevent_req_simple_recv_ntstatus(req);
332 static NTSTATUS cli_session_setup_lanman2(struct cli_state *cli, const char *user,
333 const char *pass, size_t passlen,
334 const char *workgroup)
336 TALLOC_CTX *frame = talloc_stackframe();
337 struct event_context *ev;
338 struct tevent_req *req;
339 NTSTATUS status = NT_STATUS_NO_MEMORY;
341 if (cli_has_async_calls(cli)) {
343 * Can't use sync call while an async call is in flight
345 status = NT_STATUS_INVALID_PARAMETER;
348 ev = event_context_init(frame);
352 req = cli_session_setup_lanman2_send(frame, ev, cli, user, pass, passlen,
357 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
360 status = cli_session_setup_lanman2_recv(req);
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_state_capabilities(cli) & (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_state_get_vc_num(cli));
420 SIVAL(vwv+5, 0, cli_state_server_session_key(cli));
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;
492 status = cli_smb_recv(subreq, state, &in, 3, &wct, &vwv,
495 if (!NT_STATUS_IS_OK(status)) {
496 tevent_req_nterror(req, status);
503 cli_state_set_uid(state->cli, SVAL(inbuf, smb_uid));
504 cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0);
506 status = smb_bytes_talloc_string(cli,
513 if (!NT_STATUS_IS_OK(status)) {
514 tevent_req_nterror(req, status);
519 status = smb_bytes_talloc_string(cli,
526 if (!NT_STATUS_IS_OK(status)) {
527 tevent_req_nterror(req, status);
532 status = smb_bytes_talloc_string(cli,
539 if (!NT_STATUS_IS_OK(status)) {
540 tevent_req_nterror(req, status);
545 status = cli_set_username(cli, "");
546 if (!NT_STATUS_IS_OK(status)) {
547 tevent_req_nterror(req, status);
550 tevent_req_done(req);
553 NTSTATUS cli_session_setup_guest_recv(struct tevent_req *req)
555 return tevent_req_simple_recv_ntstatus(req);
558 static NTSTATUS cli_session_setup_guest(struct cli_state *cli)
560 TALLOC_CTX *frame = talloc_stackframe();
561 struct event_context *ev;
562 struct tevent_req *req;
563 NTSTATUS status = NT_STATUS_OK;
565 if (cli_has_async_calls(cli)) {
567 * Can't use sync call while an async call is in flight
569 status = NT_STATUS_INVALID_PARAMETER;
573 ev = event_context_init(frame);
575 status = NT_STATUS_NO_MEMORY;
579 req = cli_session_setup_guest_send(frame, ev, cli);
581 status = NT_STATUS_NO_MEMORY;
585 if (!tevent_req_poll(req, ev)) {
586 status = map_nt_error_from_unix(errno);
590 status = cli_session_setup_guest_recv(req);
596 /****************************************************************************
597 Do a NT1 plaintext session setup.
598 ****************************************************************************/
600 struct cli_session_setup_plain_state {
601 struct cli_state *cli;
606 static void cli_session_setup_plain_done(struct tevent_req *subreq);
608 static struct tevent_req *cli_session_setup_plain_send(
609 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
610 struct cli_state *cli,
611 const char *user, const char *pass, const char *workgroup)
613 struct tevent_req *req, *subreq;
614 struct cli_session_setup_plain_state *state;
620 req = tevent_req_create(mem_ctx, &state,
621 struct cli_session_setup_plain_state);
629 SCVAL(vwv+0, 0, 0xff);
632 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
634 SSVAL(vwv+4, 0, cli_state_get_vc_num(cli));
635 SIVAL(vwv+5, 0, cli_state_server_session_key(cli));
640 SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli));
642 bytes = talloc_array(state, uint8_t, 0);
643 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), pass, strlen(pass)+1,
645 if (tevent_req_nomem(bytes, req)) {
646 return tevent_req_post(req, ev);
648 SSVAL(vwv + (cli_ucs2(cli) ? 8 : 7), 0, passlen);
650 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
651 user, strlen(user)+1, NULL);
652 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
653 workgroup, strlen(workgroup)+1, NULL);
654 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
657 version = talloc_asprintf(talloc_tos(), "Samba %s",
658 samba_version_string());
659 if (tevent_req_nomem(version, req)){
660 return tevent_req_post(req, ev);
662 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
663 version, strlen(version)+1, NULL);
664 TALLOC_FREE(version);
666 if (tevent_req_nomem(bytes, req)) {
667 return tevent_req_post(req, ev);
670 subreq = cli_smb_send(state, ev, cli, SMBsesssetupX, 0, 13, vwv,
671 talloc_get_size(bytes), bytes);
672 if (tevent_req_nomem(subreq, req)) {
673 return tevent_req_post(req, ev);
675 tevent_req_set_callback(subreq, cli_session_setup_plain_done, req);
679 static void cli_session_setup_plain_done(struct tevent_req *subreq)
681 struct tevent_req *req = tevent_req_callback_data(
682 subreq, struct tevent_req);
683 struct cli_session_setup_plain_state *state = tevent_req_data(
684 req, struct cli_session_setup_plain_state);
685 struct cli_state *cli = state->cli;
696 status = cli_smb_recv(subreq, state, &in, 3, &wct, &vwv,
699 if (tevent_req_nterror(req, status)) {
706 cli_state_set_uid(state->cli, SVAL(inbuf, smb_uid));
707 cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0);
709 status = smb_bytes_talloc_string(cli,
716 if (!NT_STATUS_IS_OK(status)) {
717 tevent_req_nterror(req, status);
722 status = smb_bytes_talloc_string(cli,
729 if (!NT_STATUS_IS_OK(status)) {
730 tevent_req_nterror(req, status);
735 status = smb_bytes_talloc_string(cli,
742 if (!NT_STATUS_IS_OK(status)) {
743 tevent_req_nterror(req, status);
748 status = cli_set_username(cli, state->user);
749 if (tevent_req_nterror(req, status)) {
753 tevent_req_done(req);
756 static NTSTATUS cli_session_setup_plain_recv(struct tevent_req *req)
758 return tevent_req_simple_recv_ntstatus(req);
761 static NTSTATUS cli_session_setup_plain(struct cli_state *cli,
762 const char *user, const char *pass,
763 const char *workgroup)
765 TALLOC_CTX *frame = talloc_stackframe();
766 struct event_context *ev;
767 struct tevent_req *req;
768 NTSTATUS status = NT_STATUS_NO_MEMORY;
770 if (cli_has_async_calls(cli)) {
772 * Can't use sync call while an async call is in flight
774 status = NT_STATUS_INVALID_PARAMETER;
777 ev = event_context_init(frame);
781 req = cli_session_setup_plain_send(frame, ev, cli, user, pass,
786 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
789 status = cli_session_setup_plain_recv(req);
795 /****************************************************************************
796 do a NT1 NTLM/LM encrypted session setup - for when extended security
798 @param cli client state to create do session setup on
800 @param pass *either* cleartext password (passlen !=24) or LM response.
801 @param ntpass NT response, implies ntpasslen >=24, implies pass is not clear
802 @param workgroup The user's domain.
803 ****************************************************************************/
805 struct cli_session_setup_nt1_state {
806 struct cli_state *cli;
809 DATA_BLOB session_key;
813 static void cli_session_setup_nt1_done(struct tevent_req *subreq);
815 static struct tevent_req *cli_session_setup_nt1_send(
816 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
817 struct cli_state *cli, const char *user,
818 const char *pass, size_t passlen,
819 const char *ntpass, size_t ntpasslen,
820 const char *workgroup)
822 struct tevent_req *req, *subreq;
823 struct cli_session_setup_nt1_state *state;
824 DATA_BLOB lm_response = data_blob_null;
825 DATA_BLOB nt_response = data_blob_null;
826 DATA_BLOB session_key = data_blob_null;
829 char *workgroup_upper;
831 req = tevent_req_create(mem_ctx, &state,
832 struct cli_session_setup_nt1_state);
841 /* do nothing - guest login */
842 } else if (passlen != 24) {
843 if (lp_client_ntlmv2_auth()) {
844 DATA_BLOB server_chal;
845 DATA_BLOB names_blob;
847 server_chal = data_blob(cli->secblob.data,
848 MIN(cli->secblob.length, 8));
849 if (tevent_req_nomem(server_chal.data, req)) {
850 return tevent_req_post(req, ev);
854 * note that the 'workgroup' here is a best
855 * guess - we don't know the server's domain
856 * at this point. Windows clients also don't
859 names_blob = NTLMv2_generate_names_blob(
860 NULL, NULL, workgroup);
862 if (tevent_req_nomem(names_blob.data, req)) {
863 return tevent_req_post(req, ev);
866 if (!SMBNTLMv2encrypt(NULL, user, workgroup, pass,
867 &server_chal, &names_blob,
868 &lm_response, &nt_response,
869 NULL, &session_key)) {
870 data_blob_free(&names_blob);
871 data_blob_free(&server_chal);
873 req, NT_STATUS_ACCESS_DENIED);
874 return tevent_req_post(req, ev);
876 data_blob_free(&names_blob);
877 data_blob_free(&server_chal);
881 E_md4hash(pass, nt_hash);
884 nt_response = data_blob_null;
886 nt_response = data_blob(NULL, 24);
887 if (tevent_req_nomem(nt_response.data, req)) {
888 return tevent_req_post(req, ev);
891 SMBNTencrypt(pass, cli->secblob.data,
894 /* non encrypted password supplied. Ignore ntpass. */
895 if (lp_client_lanman_auth()) {
897 lm_response = data_blob(NULL, 24);
898 if (tevent_req_nomem(lm_response.data, req)) {
899 return tevent_req_post(req, ev);
902 if (!SMBencrypt(pass,cli->secblob.data,
905 * Oops, the LM response is
906 * invalid, just put the NT
907 * response there instead
909 data_blob_free(&lm_response);
910 lm_response = data_blob(
916 * LM disabled, place NT# in LM field
919 lm_response = data_blob(
920 nt_response.data, nt_response.length);
923 if (tevent_req_nomem(lm_response.data, req)) {
924 return tevent_req_post(req, ev);
927 session_key = data_blob(NULL, 16);
928 if (tevent_req_nomem(session_key.data, req)) {
929 return tevent_req_post(req, ev);
932 E_deshash(pass, session_key.data);
933 memset(&session_key.data[8], '\0', 8);
935 SMBsesskeygen_ntv1(nt_hash, session_key.data);
939 /* pre-encrypted password supplied. Only used for
940 security=server, can't do
941 signing because we don't have original key */
943 lm_response = data_blob(pass, passlen);
944 if (tevent_req_nomem(lm_response.data, req)) {
945 return tevent_req_post(req, ev);
948 nt_response = data_blob(ntpass, ntpasslen);
949 if (tevent_req_nomem(nt_response.data, req)) {
950 return tevent_req_post(req, ev);
955 state->response = data_blob_talloc(
956 state, lm_response.data, lm_response.length);
958 state->response = data_blob_talloc(
959 state, nt_response.data, nt_response.length);
961 if (tevent_req_nomem(state->response.data, req)) {
962 return tevent_req_post(req, ev);
965 if (session_key.data) {
966 state->session_key = data_blob_talloc(
967 state, session_key.data, session_key.length);
968 if (tevent_req_nomem(state->session_key.data, req)) {
969 return tevent_req_post(req, ev);
972 data_blob_free(&session_key);
974 SCVAL(vwv+0, 0, 0xff);
977 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
979 SSVAL(vwv+4, 0, cli_state_get_vc_num(cli));
980 SIVAL(vwv+5, 0, cli_state_server_session_key(cli));
981 SSVAL(vwv+7, 0, lm_response.length);
982 SSVAL(vwv+8, 0, nt_response.length);
985 SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli));
987 bytes = talloc_array(state, uint8_t,
988 lm_response.length + nt_response.length);
989 if (tevent_req_nomem(bytes, req)) {
990 return tevent_req_post(req, ev);
992 if (lm_response.length != 0) {
993 memcpy(bytes, lm_response.data, lm_response.length);
995 if (nt_response.length != 0) {
996 memcpy(bytes + lm_response.length,
997 nt_response.data, nt_response.length);
999 data_blob_free(&lm_response);
1000 data_blob_free(&nt_response);
1002 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
1003 user, strlen(user)+1, NULL);
1006 * Upper case here might help some NTLMv2 implementations
1008 workgroup_upper = talloc_strdup_upper(talloc_tos(), workgroup);
1009 if (tevent_req_nomem(workgroup_upper, req)) {
1010 return tevent_req_post(req, ev);
1012 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
1013 workgroup_upper, strlen(workgroup_upper)+1,
1015 TALLOC_FREE(workgroup_upper);
1017 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Unix", 5, NULL);
1018 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Samba", 6, NULL);
1019 if (tevent_req_nomem(bytes, req)) {
1020 return tevent_req_post(req, ev);
1023 subreq = cli_smb_send(state, ev, cli, SMBsesssetupX, 0, 13, vwv,
1024 talloc_get_size(bytes), bytes);
1025 if (tevent_req_nomem(subreq, req)) {
1026 return tevent_req_post(req, ev);
1028 tevent_req_set_callback(subreq, cli_session_setup_nt1_done, req);
1032 static void cli_session_setup_nt1_done(struct tevent_req *subreq)
1034 struct tevent_req *req = tevent_req_callback_data(
1035 subreq, struct tevent_req);
1036 struct cli_session_setup_nt1_state *state = tevent_req_data(
1037 req, struct cli_session_setup_nt1_state);
1038 struct cli_state *cli = state->cli;
1049 status = cli_smb_recv(subreq, state, &in, 3, &wct, &vwv,
1050 &num_bytes, &bytes);
1051 TALLOC_FREE(subreq);
1052 if (!NT_STATUS_IS_OK(status)) {
1053 tevent_req_nterror(req, status);
1060 cli_state_set_uid(state->cli, SVAL(inbuf, smb_uid));
1061 cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0);
1063 status = smb_bytes_talloc_string(cli,
1069 if (!NT_STATUS_IS_OK(status)) {
1070 tevent_req_nterror(req, status);
1075 status = smb_bytes_talloc_string(cli,
1081 if (!NT_STATUS_IS_OK(status)) {
1082 tevent_req_nterror(req, status);
1087 status = smb_bytes_talloc_string(cli,
1089 &cli->server_domain,
1093 if (!NT_STATUS_IS_OK(status)) {
1094 tevent_req_nterror(req, status);
1099 status = cli_set_username(cli, state->user);
1100 if (tevent_req_nterror(req, status)) {
1103 if (cli_simple_set_signing(cli, state->session_key, state->response)
1104 && !cli_check_sign_mac(cli, (char *)in, 1)) {
1105 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1108 if (state->session_key.data) {
1109 /* Have plaintext orginal */
1110 cli_set_session_key(cli, state->session_key);
1112 tevent_req_done(req);
1115 static NTSTATUS cli_session_setup_nt1_recv(struct tevent_req *req)
1117 return tevent_req_simple_recv_ntstatus(req);
1120 static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user,
1121 const char *pass, size_t passlen,
1122 const char *ntpass, size_t ntpasslen,
1123 const char *workgroup)
1125 TALLOC_CTX *frame = talloc_stackframe();
1126 struct event_context *ev;
1127 struct tevent_req *req;
1128 NTSTATUS status = NT_STATUS_NO_MEMORY;
1130 if (cli_has_async_calls(cli)) {
1132 * Can't use sync call while an async call is in flight
1134 status = NT_STATUS_INVALID_PARAMETER;
1137 ev = event_context_init(frame);
1141 req = cli_session_setup_nt1_send(frame, ev, cli, user, pass, passlen,
1142 ntpass, ntpasslen, workgroup);
1146 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1149 status = cli_session_setup_nt1_recv(req);
1155 /* The following is calculated from :
1157 * (smb_wcnt * 2) = 24 (smb_wcnt == 12 in cli_session_setup_blob_send() )
1158 * (strlen("Unix") + 1 + strlen("Samba") + 1) * 2 = 22 (unicode strings at
1162 #define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22)
1164 struct cli_sesssetup_blob_state {
1165 struct tevent_context *ev;
1166 struct cli_state *cli;
1168 uint16_t max_blob_size;
1177 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state *state,
1178 struct tevent_req **psubreq);
1179 static void cli_sesssetup_blob_done(struct tevent_req *subreq);
1181 static struct tevent_req *cli_sesssetup_blob_send(TALLOC_CTX *mem_ctx,
1182 struct tevent_context *ev,
1183 struct cli_state *cli,
1186 struct tevent_req *req, *subreq;
1187 struct cli_sesssetup_blob_state *state;
1188 uint32_t usable_space;
1190 req = tevent_req_create(mem_ctx, &state,
1191 struct cli_sesssetup_blob_state);
1199 usable_space = cli_state_available_size(cli,
1200 BASE_SESSSETUP_BLOB_PACKET_SIZE);
1202 if (usable_space == 0) {
1203 DEBUG(1, ("cli_session_setup_blob: cli->max_xmit too small "
1204 "(not possible to send %u bytes)\n",
1205 BASE_SESSSETUP_BLOB_PACKET_SIZE + 1));
1206 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1207 return tevent_req_post(req, ev);
1209 state->max_blob_size = MIN(usable_space, 0xFFFF);
1211 if (!cli_sesssetup_blob_next(state, &subreq)) {
1212 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1213 return tevent_req_post(req, ev);
1215 tevent_req_set_callback(subreq, cli_sesssetup_blob_done, req);
1219 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state *state,
1220 struct tevent_req **psubreq)
1222 struct tevent_req *subreq;
1225 SCVAL(state->vwv+0, 0, 0xFF);
1226 SCVAL(state->vwv+0, 1, 0);
1227 SSVAL(state->vwv+1, 0, 0);
1228 SSVAL(state->vwv+2, 0, CLI_BUFFER_SIZE);
1229 SSVAL(state->vwv+3, 0, 2);
1230 SSVAL(state->vwv+4, 0, 1);
1231 SIVAL(state->vwv+5, 0, 0);
1233 thistime = MIN(state->blob.length, state->max_blob_size);
1234 SSVAL(state->vwv+7, 0, thistime);
1236 SSVAL(state->vwv+8, 0, 0);
1237 SSVAL(state->vwv+9, 0, 0);
1238 SIVAL(state->vwv+10, 0,
1239 cli_session_setup_capabilities(state->cli)
1240 | CAP_EXTENDED_SECURITY);
1242 state->buf = (uint8_t *)talloc_memdup(state, state->blob.data,
1244 if (state->buf == NULL) {
1247 state->blob.data += thistime;
1248 state->blob.length -= thistime;
1250 state->buf = smb_bytes_push_str(state->buf, cli_ucs2(state->cli),
1252 state->buf = smb_bytes_push_str(state->buf, cli_ucs2(state->cli),
1254 if (state->buf == NULL) {
1257 subreq = cli_smb_send(state, state->ev, state->cli, SMBsesssetupX, 0,
1259 talloc_get_size(state->buf), state->buf);
1260 if (subreq == NULL) {
1267 static void cli_sesssetup_blob_done(struct tevent_req *subreq)
1269 struct tevent_req *req = tevent_req_callback_data(
1270 subreq, struct tevent_req);
1271 struct cli_sesssetup_blob_state *state = tevent_req_data(
1272 req, struct cli_sesssetup_blob_state);
1273 struct cli_state *cli = state->cli;
1280 uint16_t blob_length;
1284 status = cli_smb_recv(subreq, state, &inbuf, 4, &wct, &vwv,
1285 &num_bytes, &bytes);
1286 TALLOC_FREE(subreq);
1287 if (!NT_STATUS_IS_OK(status)
1288 && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1289 tevent_req_nterror(req, status);
1293 state->status = status;
1294 TALLOC_FREE(state->buf);
1296 state->inbuf = (char *)inbuf;
1297 cli_state_set_uid(state->cli, SVAL(inbuf, smb_uid));
1298 cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0);
1300 blob_length = SVAL(vwv+3, 0);
1301 if (blob_length > num_bytes) {
1302 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1305 state->ret_blob = data_blob_const(bytes, blob_length);
1307 p = bytes + blob_length;
1309 status = smb_bytes_talloc_string(cli,
1316 if (!NT_STATUS_IS_OK(status)) {
1317 tevent_req_nterror(req, status);
1322 status = smb_bytes_talloc_string(cli,
1329 if (!NT_STATUS_IS_OK(status)) {
1330 tevent_req_nterror(req, status);
1335 status = smb_bytes_talloc_string(cli,
1337 &cli->server_domain,
1342 if (!NT_STATUS_IS_OK(status)) {
1343 tevent_req_nterror(req, status);
1348 if (state->blob.length != 0) {
1352 if (!cli_sesssetup_blob_next(state, &subreq)) {
1353 tevent_req_oom(req);
1356 tevent_req_set_callback(subreq, cli_sesssetup_blob_done, req);
1359 tevent_req_done(req);
1362 static NTSTATUS cli_sesssetup_blob_recv(struct tevent_req *req,
1363 TALLOC_CTX *mem_ctx,
1367 struct cli_sesssetup_blob_state *state = tevent_req_data(
1368 req, struct cli_sesssetup_blob_state);
1372 if (tevent_req_is_nterror(req, &status)) {
1373 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
1377 inbuf = talloc_move(mem_ctx, &state->inbuf);
1378 if (pblob != NULL) {
1379 *pblob = state->ret_blob;
1381 if (pinbuf != NULL) {
1384 /* could be NT_STATUS_MORE_PROCESSING_REQUIRED */
1385 return state->status;
1390 /****************************************************************************
1391 Use in-memory credentials cache
1392 ****************************************************************************/
1394 static void use_in_memory_ccache(void) {
1395 setenv(KRB5_ENV_CCNAME, "MEMORY:cliconnect", 1);
1398 /****************************************************************************
1399 Do a spnego/kerberos encrypted session setup.
1400 ****************************************************************************/
1402 struct cli_session_setup_kerberos_state {
1403 struct cli_state *cli;
1404 DATA_BLOB negTokenTarg;
1405 DATA_BLOB session_key_krb5;
1406 ADS_STATUS ads_status;
1409 static void cli_session_setup_kerberos_done(struct tevent_req *subreq);
1411 static struct tevent_req *cli_session_setup_kerberos_send(
1412 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
1413 const char *principal)
1415 struct tevent_req *req, *subreq;
1416 struct cli_session_setup_kerberos_state *state;
1419 DEBUG(2,("Doing kerberos session setup\n"));
1421 req = tevent_req_create(mem_ctx, &state,
1422 struct cli_session_setup_kerberos_state);
1427 state->ads_status = ADS_SUCCESS;
1430 * Ok, this is cheating: spnego_gen_krb5_negTokenInit can block if
1431 * we have to acquire a ticket. To be fixed later :-)
1433 rc = spnego_gen_krb5_negTokenInit(state, principal, 0, &state->negTokenTarg,
1434 &state->session_key_krb5, 0, NULL);
1436 DEBUG(1, ("cli_session_setup_kerberos: "
1437 "spnego_gen_krb5_negTokenInit failed: %s\n",
1438 error_message(rc)));
1439 state->ads_status = ADS_ERROR_KRB5(rc);
1440 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
1441 return tevent_req_post(req, ev);
1445 file_save("negTokenTarg.dat", state->negTokenTarg.data,
1446 state->negTokenTarg.length);
1449 subreq = cli_sesssetup_blob_send(state, ev, cli, state->negTokenTarg);
1450 if (tevent_req_nomem(subreq, req)) {
1451 return tevent_req_post(req, ev);
1453 tevent_req_set_callback(subreq, cli_session_setup_kerberos_done, req);
1457 static void cli_session_setup_kerberos_done(struct tevent_req *subreq)
1459 struct tevent_req *req = tevent_req_callback_data(
1460 subreq, struct tevent_req);
1461 struct cli_session_setup_kerberos_state *state = tevent_req_data(
1462 req, struct cli_session_setup_kerberos_state);
1466 status = cli_sesssetup_blob_recv(subreq, talloc_tos(), NULL, &inbuf);
1467 if (!NT_STATUS_IS_OK(status)) {
1468 TALLOC_FREE(subreq);
1469 tevent_req_nterror(req, status);
1473 cli_set_session_key(state->cli, state->session_key_krb5);
1475 if (cli_simple_set_signing(state->cli, state->session_key_krb5,
1477 && !cli_check_sign_mac(state->cli, inbuf, 1)) {
1478 TALLOC_FREE(subreq);
1479 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1482 TALLOC_FREE(subreq);
1483 tevent_req_done(req);
1486 static ADS_STATUS cli_session_setup_kerberos_recv(struct tevent_req *req)
1488 struct cli_session_setup_kerberos_state *state = tevent_req_data(
1489 req, struct cli_session_setup_kerberos_state);
1492 if (tevent_req_is_nterror(req, &status)) {
1493 return ADS_ERROR_NT(status);
1495 return state->ads_status;
1498 static ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli,
1499 const char *principal)
1501 struct tevent_context *ev;
1502 struct tevent_req *req;
1503 ADS_STATUS status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1505 if (cli_has_async_calls(cli)) {
1506 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1508 ev = tevent_context_init(talloc_tos());
1512 req = cli_session_setup_kerberos_send(ev, ev, cli, principal);
1516 if (!tevent_req_poll(req, ev)) {
1517 status = ADS_ERROR_SYSTEM(errno);
1520 status = cli_session_setup_kerberos_recv(req);
1525 #endif /* HAVE_KRB5 */
1527 /****************************************************************************
1528 Do a spnego/NTLMSSP encrypted session setup.
1529 ****************************************************************************/
1531 struct cli_session_setup_ntlmssp_state {
1532 struct tevent_context *ev;
1533 struct cli_state *cli;
1534 struct ntlmssp_state *ntlmssp_state;
1539 static int cli_session_setup_ntlmssp_state_destructor(
1540 struct cli_session_setup_ntlmssp_state *state)
1542 if (state->ntlmssp_state != NULL) {
1543 TALLOC_FREE(state->ntlmssp_state);
1548 static void cli_session_setup_ntlmssp_done(struct tevent_req *req);
1550 static struct tevent_req *cli_session_setup_ntlmssp_send(
1551 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
1552 const char *user, const char *pass, const char *domain)
1554 struct tevent_req *req, *subreq;
1555 struct cli_session_setup_ntlmssp_state *state;
1558 const char *OIDs_ntlm[] = {OID_NTLMSSP, NULL};
1560 req = tevent_req_create(mem_ctx, &state,
1561 struct cli_session_setup_ntlmssp_state);
1569 state->ntlmssp_state = NULL;
1570 talloc_set_destructor(
1571 state, cli_session_setup_ntlmssp_state_destructor);
1573 status = ntlmssp_client_start(state,
1576 lp_client_ntlmv2_auth(),
1577 &state->ntlmssp_state);
1578 if (!NT_STATUS_IS_OK(status)) {
1581 ntlmssp_want_feature(state->ntlmssp_state,
1582 NTLMSSP_FEATURE_SESSION_KEY);
1583 if (cli->use_ccache) {
1584 ntlmssp_want_feature(state->ntlmssp_state,
1585 NTLMSSP_FEATURE_CCACHE);
1587 status = ntlmssp_set_username(state->ntlmssp_state, user);
1588 if (!NT_STATUS_IS_OK(status)) {
1591 status = ntlmssp_set_domain(state->ntlmssp_state, domain);
1592 if (!NT_STATUS_IS_OK(status)) {
1595 status = ntlmssp_set_password(state->ntlmssp_state, pass);
1596 if (!NT_STATUS_IS_OK(status)) {
1599 status = ntlmssp_update(state->ntlmssp_state, data_blob_null,
1601 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1605 state->blob_out = spnego_gen_negTokenInit(state, OIDs_ntlm, &blob_out, NULL);
1606 data_blob_free(&blob_out);
1608 subreq = cli_sesssetup_blob_send(state, ev, cli, state->blob_out);
1609 if (tevent_req_nomem(subreq, req)) {
1610 return tevent_req_post(req, ev);
1612 tevent_req_set_callback(subreq, cli_session_setup_ntlmssp_done, req);
1615 tevent_req_nterror(req, status);
1616 return tevent_req_post(req, ev);
1619 static void cli_session_setup_ntlmssp_done(struct tevent_req *subreq)
1621 struct tevent_req *req = tevent_req_callback_data(
1622 subreq, struct tevent_req);
1623 struct cli_session_setup_ntlmssp_state *state = tevent_req_data(
1624 req, struct cli_session_setup_ntlmssp_state);
1625 DATA_BLOB blob_in, msg_in, blob_out;
1630 status = cli_sesssetup_blob_recv(subreq, talloc_tos(), &blob_in,
1632 TALLOC_FREE(subreq);
1633 data_blob_free(&state->blob_out);
1635 if (NT_STATUS_IS_OK(status)) {
1636 if (state->cli->server_domain[0] == '\0') {
1637 TALLOC_FREE(state->cli->server_domain);
1638 state->cli->server_domain = talloc_strdup(state->cli,
1639 state->ntlmssp_state->server.netbios_domain);
1640 if (state->cli->server_domain == NULL) {
1641 TALLOC_FREE(subreq);
1642 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1646 cli_set_session_key(
1647 state->cli, state->ntlmssp_state->session_key);
1649 if (cli_simple_set_signing(
1650 state->cli, state->ntlmssp_state->session_key,
1652 && !cli_check_sign_mac(state->cli, inbuf, 1)) {
1653 TALLOC_FREE(subreq);
1654 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1657 TALLOC_FREE(subreq);
1658 TALLOC_FREE(state->ntlmssp_state);
1659 tevent_req_done(req);
1662 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1663 tevent_req_nterror(req, status);
1667 if (blob_in.length == 0) {
1668 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
1672 if ((state->turn == 1)
1673 && NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1674 DATA_BLOB tmp_blob = data_blob_null;
1675 /* the server might give us back two challenges */
1676 parse_ret = spnego_parse_challenge(state, blob_in, &msg_in,
1678 data_blob_free(&tmp_blob);
1680 parse_ret = spnego_parse_auth_response(state, blob_in, status,
1681 OID_NTLMSSP, &msg_in);
1686 DEBUG(3,("Failed to parse auth response\n"));
1687 if (NT_STATUS_IS_OK(status)
1688 || NT_STATUS_EQUAL(status,
1689 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1691 req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1696 status = ntlmssp_update(state->ntlmssp_state, msg_in, &blob_out);
1698 if (!NT_STATUS_IS_OK(status)
1699 && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1700 TALLOC_FREE(subreq);
1701 TALLOC_FREE(state->ntlmssp_state);
1702 tevent_req_nterror(req, status);
1706 state->blob_out = spnego_gen_auth(state, blob_out);
1707 TALLOC_FREE(subreq);
1708 if (tevent_req_nomem(state->blob_out.data, req)) {
1712 subreq = cli_sesssetup_blob_send(state, state->ev, state->cli,
1714 if (tevent_req_nomem(subreq, req)) {
1717 tevent_req_set_callback(subreq, cli_session_setup_ntlmssp_done, req);
1720 static NTSTATUS cli_session_setup_ntlmssp_recv(struct tevent_req *req)
1722 struct cli_session_setup_ntlmssp_state *state = tevent_req_data(
1723 req, struct cli_session_setup_ntlmssp_state);
1726 if (tevent_req_is_nterror(req, &status)) {
1727 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
1730 return NT_STATUS_OK;
1733 static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli,
1738 struct tevent_context *ev;
1739 struct tevent_req *req;
1740 NTSTATUS status = NT_STATUS_NO_MEMORY;
1742 if (cli_has_async_calls(cli)) {
1743 return NT_STATUS_INVALID_PARAMETER;
1745 ev = tevent_context_init(talloc_tos());
1749 req = cli_session_setup_ntlmssp_send(ev, ev, cli, user, pass, domain);
1753 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1756 status = cli_session_setup_ntlmssp_recv(req);
1762 /****************************************************************************
1763 Do a spnego encrypted session setup.
1765 user_domain: The shortname of the domain the user/machine is a member of.
1766 dest_realm: The realm we're connecting to, if NULL we use our default realm.
1767 ****************************************************************************/
1769 static ADS_STATUS cli_session_setup_spnego(struct cli_state *cli,
1772 const char *user_domain,
1773 const char * dest_realm)
1775 char *principal = NULL;
1776 char *OIDs[ASN1_MAX_OIDS];
1779 const char *p = NULL;
1780 char *account = NULL;
1783 DEBUG(3,("Doing spnego session setup (blob length=%lu)\n", (unsigned long)cli->secblob.length));
1785 /* the server might not even do spnego */
1786 if (cli->secblob.length <= 16) {
1787 DEBUG(3,("server didn't supply a full spnego negprot\n"));
1792 file_save("negprot.dat", cli->secblob.data, cli->secblob.length);
1795 /* there is 16 bytes of GUID before the real spnego packet starts */
1796 blob = data_blob(cli->secblob.data+16, cli->secblob.length-16);
1798 /* The server sent us the first part of the SPNEGO exchange in the
1799 * negprot reply. It is WRONG to depend on the principal sent in the
1800 * negprot reply, but right now we do it. If we don't receive one,
1801 * we try to best guess, then fall back to NTLM. */
1802 if (!spnego_parse_negTokenInit(talloc_tos(), blob, OIDs, &principal, NULL) ||
1804 data_blob_free(&blob);
1805 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1807 data_blob_free(&blob);
1809 /* make sure the server understands kerberos */
1810 for (i=0;OIDs[i];i++) {
1812 DEBUG(3,("got OID=%s\n", OIDs[i]));
1814 DEBUGADD(3,("got OID=%s\n", OIDs[i]));
1815 if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0 ||
1816 strcmp(OIDs[i], OID_KERBEROS5) == 0) {
1817 cli->got_kerberos_mechanism = True;
1819 talloc_free(OIDs[i]);
1822 DEBUG(3,("got principal=%s\n", principal ? principal : "<null>"));
1824 status = cli_set_username(cli, user);
1825 if (!NT_STATUS_IS_OK(status)) {
1826 TALLOC_FREE(principal);
1827 return ADS_ERROR_NT(status);
1831 /* If password is set we reauthenticate to kerberos server
1832 * and do not store results */
1834 if (cli->got_kerberos_mechanism && cli->use_kerberos) {
1836 const char *remote_name = cli_state_remote_name(cli);
1838 if (pass && *pass) {
1841 use_in_memory_ccache();
1842 ret = kerberos_kinit_password(user, pass, 0 /* no time correction for now */, NULL);
1845 TALLOC_FREE(principal);
1846 DEBUG(0, ("Kinit failed: %s\n", error_message(ret)));
1847 if (cli->fallback_after_kerberos)
1849 return ADS_ERROR_KRB5(ret);
1853 /* We may not be allowed to use the server-supplied SPNEGO principal, or it may not have been supplied to us
1855 if (!lp_client_use_spnego_principal() || strequal(principal, ADS_IGNORE_PRINCIPAL)) {
1856 TALLOC_FREE(principal);
1859 if (principal == NULL &&
1860 !is_ipaddress(remote_name) &&
1861 !strequal(STAR_SMBSERVER,
1865 DEBUG(3,("cli_session_setup_spnego: using target "
1866 "hostname not SPNEGO principal\n"));
1868 host = strchr_m(remote_name, '.');
1870 realm = SMB_STRDUP(dest_realm);
1872 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1878 realm = kerberos_get_realm_from_hostname(remote_name);
1880 /* NetBIOS name - use our realm. */
1881 realm = kerberos_get_default_realm_from_ccache();
1885 if (realm == NULL || *realm == '\0') {
1886 realm = SMB_STRDUP(lp_realm());
1888 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1891 DEBUG(3,("cli_session_setup_spnego: cannot "
1892 "get realm from dest_realm %s, "
1893 "desthost %s. Using default "
1894 "smb.conf realm %s\n",
1895 dest_realm ? dest_realm : "<null>",
1900 principal = talloc_asprintf(talloc_tos(),
1906 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1908 DEBUG(3,("cli_session_setup_spnego: guessed "
1909 "server principal=%s\n",
1910 principal ? principal : "<null>"));
1916 rc = cli_session_setup_kerberos(cli, principal);
1917 if (ADS_ERR_OK(rc) || !cli->fallback_after_kerberos) {
1918 TALLOC_FREE(principal);
1925 TALLOC_FREE(principal);
1929 account = talloc_strdup(talloc_tos(), user);
1931 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1934 /* when falling back to ntlmssp while authenticating with a machine
1935 * account strip off the realm - gd */
1937 if ((p = strchr_m(user, '@')) != NULL) {
1938 account[PTR_DIFF(p,user)] = '\0';
1941 return ADS_ERROR_NT(cli_session_setup_ntlmssp(cli, account, pass, user_domain));
1944 /****************************************************************************
1945 Send a session setup. The username and workgroup is in UNIX character
1946 format and must be converted to DOS codepage format before sending. If the
1947 password is in plaintext, the same should be done.
1948 ****************************************************************************/
1950 NTSTATUS cli_session_setup(struct cli_state *cli,
1952 const char *pass, int passlen,
1953 const char *ntpass, int ntpasslen,
1954 const char *workgroup)
1958 uint16_t sec_mode = cli_state_security_mode(cli);
1961 user2 = talloc_strdup(talloc_tos(), user);
1963 user2 = talloc_strdup(talloc_tos(), "");
1965 if (user2 == NULL) {
1966 return NT_STATUS_NO_MEMORY;
1973 /* allow for workgroups as part of the username */
1974 if ((p=strchr_m(user2,'\\')) || (p=strchr_m(user2,'/')) ||
1975 (p=strchr_m(user2,*lp_winbind_separator()))) {
1982 if (cli_state_protocol(cli) < PROTOCOL_LANMAN1) {
1984 * Ensure cli->server_domain,
1985 * cli->server_os and cli->server_type
1986 * are valid pointers.
1988 cli->server_domain = talloc_strdup(cli, "");
1989 cli->server_os = talloc_strdup(cli, "");
1990 cli->server_type = talloc_strdup(cli, "");
1991 if (cli->server_domain == NULL ||
1992 cli->server_os == NULL ||
1993 cli->server_type == NULL) {
1994 return NT_STATUS_NO_MEMORY;
1996 return NT_STATUS_OK;
1999 /* now work out what sort of session setup we are going to
2000 do. I have split this into separate functions to make the
2001 flow a bit easier to understand (tridge) */
2003 /* if its an older server then we have to use the older request format */
2005 if (cli_state_protocol(cli) < PROTOCOL_NT1) {
2006 if (!lp_client_lanman_auth() && passlen != 24 && (*pass)) {
2007 DEBUG(1, ("Server requested LM password but 'client lanman auth = no'"
2008 " or 'client ntlmv2 auth = yes'\n"));
2009 return NT_STATUS_ACCESS_DENIED;
2012 if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0 &&
2013 !lp_client_plaintext_auth() && (*pass)) {
2014 DEBUG(1, ("Server requested LM password but 'client plaintext auth = no'"
2015 " or 'client ntlmv2 auth = yes'\n"));
2016 return NT_STATUS_ACCESS_DENIED;
2019 return cli_session_setup_lanman2(cli, user, pass, passlen,
2023 /* if no user is supplied then we have to do an anonymous connection.
2024 passwords are ignored */
2026 if (!user || !*user)
2027 return cli_session_setup_guest(cli);
2029 /* if the server is share level then send a plaintext null
2030 password at this point. The password is sent in the tree
2033 if ((sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0)
2034 return cli_session_setup_plain(cli, user, "", workgroup);
2036 /* if the server doesn't support encryption then we have to use
2037 plaintext. The second password is ignored */
2039 if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) {
2040 if (!lp_client_plaintext_auth() && (*pass)) {
2041 DEBUG(1, ("Server requested LM password but 'client plaintext auth = no'"
2042 " or 'client ntlmv2 auth = yes'\n"));
2043 return NT_STATUS_ACCESS_DENIED;
2045 return cli_session_setup_plain(cli, user, pass, workgroup);
2048 /* if the server supports extended security then use SPNEGO */
2050 if (cli_state_capabilities(cli) & CAP_EXTENDED_SECURITY) {
2051 const char *remote_realm = cli_state_remote_realm(cli);
2052 ADS_STATUS status = cli_session_setup_spnego(cli, user, pass,
2055 if (!ADS_ERR_OK(status)) {
2056 DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status)));
2057 return ads_ntstatus(status);
2062 /* otherwise do a NT1 style session setup */
2063 status = cli_session_setup_nt1(cli, user, pass, passlen,
2064 ntpass, ntpasslen, workgroup);
2065 if (!NT_STATUS_IS_OK(status)) {
2066 DEBUG(3,("cli_session_setup: NT1 session setup "
2067 "failed: %s\n", nt_errstr(status)));
2072 return NT_STATUS_OK;
2075 /****************************************************************************
2077 *****************************************************************************/
2079 struct cli_ulogoff_state {
2080 struct cli_state *cli;
2084 static void cli_ulogoff_done(struct tevent_req *subreq);
2086 struct tevent_req *cli_ulogoff_send(TALLOC_CTX *mem_ctx,
2087 struct tevent_context *ev,
2088 struct cli_state *cli)
2090 struct tevent_req *req, *subreq;
2091 struct cli_ulogoff_state *state;
2093 req = tevent_req_create(mem_ctx, &state, struct cli_ulogoff_state);
2099 SCVAL(state->vwv+0, 0, 0xFF);
2100 SCVAL(state->vwv+1, 0, 0);
2101 SSVAL(state->vwv+2, 0, 0);
2103 subreq = cli_smb_send(state, ev, cli, SMBulogoffX, 0, 2, state->vwv,
2105 if (tevent_req_nomem(subreq, req)) {
2106 return tevent_req_post(req, ev);
2108 tevent_req_set_callback(subreq, cli_ulogoff_done, req);
2112 static void cli_ulogoff_done(struct tevent_req *subreq)
2114 struct tevent_req *req = tevent_req_callback_data(
2115 subreq, struct tevent_req);
2116 struct cli_ulogoff_state *state = tevent_req_data(
2117 req, struct cli_ulogoff_state);
2120 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
2121 if (!NT_STATUS_IS_OK(status)) {
2122 tevent_req_nterror(req, status);
2125 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
2126 tevent_req_done(req);
2129 NTSTATUS cli_ulogoff_recv(struct tevent_req *req)
2131 return tevent_req_simple_recv_ntstatus(req);
2134 NTSTATUS cli_ulogoff(struct cli_state *cli)
2136 struct tevent_context *ev;
2137 struct tevent_req *req;
2138 NTSTATUS status = NT_STATUS_NO_MEMORY;
2140 if (cli_has_async_calls(cli)) {
2141 return NT_STATUS_INVALID_PARAMETER;
2143 ev = tevent_context_init(talloc_tos());
2147 req = cli_ulogoff_send(ev, ev, cli);
2151 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2154 status = cli_ulogoff_recv(req);
2160 /****************************************************************************
2162 ****************************************************************************/
2164 struct cli_tcon_andx_state {
2165 struct cli_state *cli;
2170 static void cli_tcon_andx_done(struct tevent_req *subreq);
2172 struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx,
2173 struct event_context *ev,
2174 struct cli_state *cli,
2175 const char *share, const char *dev,
2176 const char *pass, int passlen,
2177 struct tevent_req **psmbreq)
2179 struct tevent_req *req, *subreq;
2180 struct cli_tcon_andx_state *state;
2185 uint16_t sec_mode = cli_state_security_mode(cli);
2189 req = tevent_req_create(mem_ctx, &state, struct cli_tcon_andx_state);
2196 cli->share = talloc_strdup(cli, share);
2201 /* in user level security don't send a password now */
2202 if (sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {
2205 } else if (pass == NULL) {
2206 DEBUG(1, ("Server not using user level security and no "
2207 "password supplied.\n"));
2211 if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) &&
2212 *pass && passlen != 24) {
2213 if (!lp_client_lanman_auth()) {
2214 DEBUG(1, ("Server requested LANMAN password "
2215 "(share-level security) but "
2216 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2221 * Non-encrypted passwords - convert to DOS codepage before
2224 SMBencrypt(pass, cli->secblob.data, p24);
2226 pass = (const char *)p24;
2228 if((sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL
2229 |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE))
2233 if (!lp_client_plaintext_auth() && (*pass)) {
2234 DEBUG(1, ("Server requested plaintext "
2236 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2241 * Non-encrypted passwords - convert to DOS codepage
2244 tmp_pass = talloc_array(talloc_tos(), uint8, 0);
2245 if (tevent_req_nomem(tmp_pass, req)) {
2246 return tevent_req_post(req, ev);
2248 tmp_pass = trans2_bytes_push_str(tmp_pass,
2249 false, /* always DOS */
2253 if (tevent_req_nomem(tmp_pass, req)) {
2254 return tevent_req_post(req, ev);
2256 pass = (const char *)tmp_pass;
2257 passlen = talloc_get_size(tmp_pass);
2261 SCVAL(vwv+0, 0, 0xFF);
2264 SSVAL(vwv+2, 0, TCONX_FLAG_EXTENDED_RESPONSE);
2265 SSVAL(vwv+3, 0, passlen);
2267 if (passlen && pass) {
2268 bytes = (uint8_t *)talloc_memdup(state, pass, passlen);
2270 bytes = talloc_array(state, uint8_t, 0);
2276 tmp = talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
2277 cli_state_remote_name(cli), share);
2282 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), tmp, strlen(tmp)+1,
2287 * Add the devicetype
2289 tmp = talloc_strdup_upper(talloc_tos(), dev);
2294 bytes = smb_bytes_push_str(bytes, false, tmp, strlen(tmp)+1, NULL);
2297 if (bytes == NULL) {
2302 state->bytes.iov_base = (void *)bytes;
2303 state->bytes.iov_len = talloc_get_size(bytes);
2305 subreq = cli_smb_req_create(state, ev, cli, SMBtconX, 0, 4, vwv,
2307 if (subreq == NULL) {
2311 tevent_req_set_callback(subreq, cli_tcon_andx_done, req);
2316 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
2317 return tevent_req_post(req, ev);
2320 struct tevent_req *cli_tcon_andx_send(TALLOC_CTX *mem_ctx,
2321 struct event_context *ev,
2322 struct cli_state *cli,
2323 const char *share, const char *dev,
2324 const char *pass, int passlen)
2326 struct tevent_req *req, *subreq;
2329 req = cli_tcon_andx_create(mem_ctx, ev, cli, share, dev, pass, passlen,
2334 if (subreq == NULL) {
2337 status = cli_smb_req_send(subreq);
2338 if (!NT_STATUS_IS_OK(status)) {
2339 tevent_req_nterror(req, status);
2340 return tevent_req_post(req, ev);
2345 static void cli_tcon_andx_done(struct tevent_req *subreq)
2347 struct tevent_req *req = tevent_req_callback_data(
2348 subreq, struct tevent_req);
2349 struct cli_tcon_andx_state *state = tevent_req_data(
2350 req, struct cli_tcon_andx_state);
2351 struct cli_state *cli = state->cli;
2360 status = cli_smb_recv(subreq, state, &in, 0, &wct, &vwv,
2361 &num_bytes, &bytes);
2362 TALLOC_FREE(subreq);
2363 if (!NT_STATUS_IS_OK(status)) {
2364 tevent_req_nterror(req, status);
2371 if (clistr_pull_talloc(cli,
2373 SVAL(inbuf, smb_flg2),
2377 STR_TERMINATE|STR_ASCII) == -1) {
2378 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2382 cli->dev = talloc_strdup(cli, "");
2383 if (cli->dev == NULL) {
2384 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2389 if ((cli_state_protocol(cli) >= PROTOCOL_NT1) && (num_bytes == 3)) {
2390 /* almost certainly win95 - enable bug fixes */
2395 * Make sure that we have the optional support 16-bit field. WCT > 2.
2396 * Avoids issues when connecting to Win9x boxes sharing files
2399 cli->dfsroot = false;
2401 if ((wct > 2) && (cli_state_protocol(cli) >= PROTOCOL_LANMAN2)) {
2402 cli->dfsroot = ((SVAL(vwv+2, 0) & SMB_SHARE_IN_DFS) != 0);
2405 cli->smb1.tid = SVAL(inbuf,smb_tid);
2406 tevent_req_done(req);
2409 NTSTATUS cli_tcon_andx_recv(struct tevent_req *req)
2411 return tevent_req_simple_recv_ntstatus(req);
2414 NTSTATUS cli_tcon_andx(struct cli_state *cli, const char *share,
2415 const char *dev, const char *pass, int passlen)
2417 TALLOC_CTX *frame = talloc_stackframe();
2418 struct event_context *ev;
2419 struct tevent_req *req;
2420 NTSTATUS status = NT_STATUS_OK;
2422 if (cli_has_async_calls(cli)) {
2424 * Can't use sync call while an async call is in flight
2426 status = NT_STATUS_INVALID_PARAMETER;
2430 ev = event_context_init(frame);
2432 status = NT_STATUS_NO_MEMORY;
2436 req = cli_tcon_andx_send(frame, ev, cli, share, dev, pass, passlen);
2438 status = NT_STATUS_NO_MEMORY;
2442 if (!tevent_req_poll(req, ev)) {
2443 status = map_nt_error_from_unix(errno);
2447 status = cli_tcon_andx_recv(req);
2453 /****************************************************************************
2454 Send a tree disconnect.
2455 ****************************************************************************/
2457 struct cli_tdis_state {
2458 struct cli_state *cli;
2461 static void cli_tdis_done(struct tevent_req *subreq);
2463 struct tevent_req *cli_tdis_send(TALLOC_CTX *mem_ctx,
2464 struct tevent_context *ev,
2465 struct cli_state *cli)
2467 struct tevent_req *req, *subreq;
2468 struct cli_tdis_state *state;
2470 req = tevent_req_create(mem_ctx, &state, struct cli_tdis_state);
2476 subreq = cli_smb_send(state, ev, cli, SMBtdis, 0, 0, NULL, 0, NULL);
2477 if (tevent_req_nomem(subreq, req)) {
2478 return tevent_req_post(req, ev);
2480 tevent_req_set_callback(subreq, cli_tdis_done, req);
2484 static void cli_tdis_done(struct tevent_req *subreq)
2486 struct tevent_req *req = tevent_req_callback_data(
2487 subreq, struct tevent_req);
2488 struct cli_tdis_state *state = tevent_req_data(
2489 req, struct cli_tdis_state);
2492 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
2493 TALLOC_FREE(subreq);
2494 if (!NT_STATUS_IS_OK(status)) {
2495 tevent_req_nterror(req, status);
2498 state->cli->smb1.tid = UINT16_MAX;
2499 tevent_req_done(req);
2502 NTSTATUS cli_tdis_recv(struct tevent_req *req)
2504 return tevent_req_simple_recv_ntstatus(req);
2507 NTSTATUS cli_tdis(struct cli_state *cli)
2509 struct tevent_context *ev;
2510 struct tevent_req *req;
2511 NTSTATUS status = NT_STATUS_NO_MEMORY;
2513 if (cli_has_async_calls(cli)) {
2514 return NT_STATUS_INVALID_PARAMETER;
2516 ev = tevent_context_init(talloc_tos());
2520 req = cli_tdis_send(ev, ev, cli);
2524 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2527 status = cli_tdis_recv(req);
2533 /****************************************************************************
2534 Send a negprot command.
2535 ****************************************************************************/
2537 struct cli_negprot_state {
2538 struct cli_state *cli;
2541 static void cli_negprot_done(struct tevent_req *subreq);
2543 struct tevent_req *cli_negprot_send(TALLOC_CTX *mem_ctx,
2544 struct event_context *ev,
2545 struct cli_state *cli)
2547 struct tevent_req *req, *subreq;
2548 struct cli_negprot_state *state;
2549 uint8_t *bytes = NULL;
2552 req = tevent_req_create(mem_ctx, &state, struct cli_negprot_state);
2558 if (cli_state_protocol(cli) < 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_state_protocol(cli)) {
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);
2581 subreq = cli_smb_send(state, ev, cli, SMBnegprot, 0, 0, NULL,
2582 talloc_get_size(bytes), bytes);
2584 if (tevent_req_nomem(subreq, req)) {
2585 return tevent_req_post(req, ev);
2587 tevent_req_set_callback(subreq, cli_negprot_done, req);
2591 static void cli_negprot_done(struct tevent_req *subreq)
2593 struct tevent_req *req = tevent_req_callback_data(
2594 subreq, struct tevent_req);
2595 struct cli_negprot_state *state = tevent_req_data(
2596 req, struct cli_negprot_state);
2597 struct cli_state *cli = state->cli;
2605 uint32_t server_capabilities = 0;
2607 status = cli_smb_recv(subreq, state, &inbuf, 1, &wct, &vwv,
2608 &num_bytes, &bytes);
2609 TALLOC_FREE(subreq);
2610 if (!NT_STATUS_IS_OK(status)) {
2611 tevent_req_nterror(req, status);
2615 protnum = SVAL(vwv, 0);
2617 if ((protnum >= ARRAY_SIZE(prots))
2618 || (prots[protnum].prot > cli_state_protocol(cli))) {
2619 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2623 cli->protocol = prots[protnum].prot;
2625 if ((cli_state_protocol(cli) < PROTOCOL_NT1) &&
2626 client_is_signing_mandatory(cli)) {
2627 DEBUG(0,("cli_negprot: SMB signing is mandatory and the selected protocol level doesn't support it.\n"));
2628 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
2632 if (cli_state_protocol(cli) >= PROTOCOL_NT1) {
2634 const char *client_signing = NULL;
2635 bool server_mandatory;
2636 bool server_allowed;
2637 const char *server_signing = NULL;
2641 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2646 cli->sec_mode = CVAL(vwv + 1, 0);
2647 cli->max_mux = SVAL(vwv + 1, 1);
2648 cli->max_xmit = IVAL(vwv + 3, 1);
2649 cli->sesskey = IVAL(vwv + 7, 1);
2650 cli->serverzone = SVALS(vwv + 15, 1);
2651 cli->serverzone *= 60;
2652 /* this time arrives in real GMT */
2653 ts = interpret_long_date(((char *)(vwv+11))+1);
2654 cli->servertime = ts.tv_sec;
2655 cli->secblob = data_blob(bytes, num_bytes);
2656 server_capabilities = IVAL(vwv + 9, 1);
2657 if (server_capabilities & CAP_RAW_MODE) {
2658 cli->readbraw_supported = True;
2659 cli->writebraw_supported = True;
2661 /* work out if they sent us a workgroup */
2662 if (!(server_capabilities & CAP_EXTENDED_SECURITY) &&
2663 smb_buflen(inbuf) > 8) {
2665 status = smb_bytes_talloc_string(
2666 cli, (char *)inbuf, &cli->server_domain,
2667 bytes + 8, num_bytes - 8, &ret);
2668 if (tevent_req_nterror(req, status)) {
2673 client_signing = "disabled";
2674 if (client_is_signing_allowed(cli)) {
2675 client_signing = "allowed";
2677 if (client_is_signing_mandatory(cli)) {
2678 client_signing = "required";
2681 server_signing = "not supported";
2682 if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) {
2683 server_signing = "supported";
2684 server_allowed = true;
2686 if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) {
2687 server_signing = "required";
2688 server_mandatory = true;
2691 ok = cli_set_signing_negotiated(cli,
2695 DEBUG(1,("cli_negprot: SMB signing is required, "
2696 "but client[%s] and server[%s] mismatch\n",
2697 client_signing, server_signing));
2698 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
2702 } else if (cli_state_protocol(cli) >= PROTOCOL_LANMAN1) {
2704 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
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));
2726 cli->max_xmit = 1024;
2730 if (cli->max_xmit < 1024) {
2731 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2735 if (cli->max_mux < 1) {
2736 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2740 cli->max_xmit = MIN(cli->max_xmit, CLI_BUFFER_SIZE);
2742 cli->capabilities = server_capabilities;
2744 /* a way to force ascii SMB */
2745 if (cli->force_ascii) {
2746 cli->capabilities &= ~CAP_UNICODE;
2749 tevent_req_done(req);
2752 NTSTATUS cli_negprot_recv(struct tevent_req *req)
2754 return tevent_req_simple_recv_ntstatus(req);
2757 NTSTATUS cli_negprot(struct cli_state *cli)
2759 TALLOC_CTX *frame = talloc_stackframe();
2760 struct event_context *ev;
2761 struct tevent_req *req;
2762 NTSTATUS status = NT_STATUS_OK;
2764 if (cli_has_async_calls(cli)) {
2766 * Can't use sync call while an async call is in flight
2768 status = NT_STATUS_INVALID_PARAMETER;
2772 ev = event_context_init(frame);
2774 status = NT_STATUS_NO_MEMORY;
2778 req = cli_negprot_send(frame, ev, cli);
2780 status = NT_STATUS_NO_MEMORY;
2784 if (!tevent_req_poll(req, ev)) {
2785 status = map_nt_error_from_unix(errno);
2789 status = cli_negprot_recv(req);
2795 static NTSTATUS cli_connect_sock(const char *host, int name_type,
2796 const struct sockaddr_storage *pss,
2797 const char *myname, uint16_t port,
2798 int sec_timeout, int *pfd, uint16_t *pport)
2800 TALLOC_CTX *frame = talloc_stackframe();
2802 unsigned int i, num_addrs;
2803 const char **called_names;
2804 const char **calling_names;
2809 prog = getenv("LIBSMB_PROG");
2811 fd = sock_exec(prog);
2813 return map_nt_error_from_unix(errno);
2819 if ((pss == NULL) || is_zero_addr(pss)) {
2820 struct sockaddr_storage *addrs;
2821 status = resolve_name_list(talloc_tos(), host, name_type,
2822 &addrs, &num_addrs);
2823 if (!NT_STATUS_IS_OK(status)) {
2831 called_names = talloc_array(talloc_tos(), const char *, num_addrs);
2832 if (called_names == NULL) {
2833 status = NT_STATUS_NO_MEMORY;
2836 called_types = talloc_array(talloc_tos(), int, num_addrs);
2837 if (called_types == NULL) {
2838 status = NT_STATUS_NO_MEMORY;
2841 calling_names = talloc_array(talloc_tos(), const char *, num_addrs);
2842 if (calling_names == NULL) {
2843 status = NT_STATUS_NO_MEMORY;
2846 for (i=0; i<num_addrs; i++) {
2847 called_names[i] = host;
2848 called_types[i] = name_type;
2849 calling_names[i] = myname;
2851 status = smbsock_any_connect(pss, called_names, called_types,
2852 calling_names, NULL, num_addrs, port,
2853 sec_timeout, &fd, NULL, &port);
2854 if (!NT_STATUS_IS_OK(status)) {
2857 set_socket_options(fd, lp_socket_options());
2861 status = NT_STATUS_OK;
2867 NTSTATUS cli_connect_nb(const char *host, const struct sockaddr_storage *dest_ss,
2868 uint16_t port, int name_type, const char *myname,
2869 int signing_state, int flags, struct cli_state **pcli)
2871 TALLOC_CTX *frame = talloc_stackframe();
2872 struct cli_state *cli;
2873 NTSTATUS status = NT_STATUS_NO_MEMORY;
2878 desthost = talloc_strdup(talloc_tos(), host);
2879 if (desthost == NULL) {
2883 p = strchr(host, '#');
2885 name_type = strtol(p+1, NULL, 16);
2886 host = talloc_strndup(talloc_tos(), host, p - host);
2892 status = cli_connect_sock(host, name_type, dest_ss, myname, port,
2894 if (!NT_STATUS_IS_OK(status)) {
2898 cli = cli_state_create(NULL, fd, desthost, NULL, signing_state, flags);
2904 status = NT_STATUS_OK;
2911 establishes a connection to after the negprot.
2912 @param output_cli A fully initialised cli structure, non-null only on success
2913 @param dest_host The netbios name of the remote host
2914 @param dest_ss (optional) The the destination IP, NULL for name based lookup
2915 @param port (optional) The destination port (0 for default)
2917 NTSTATUS cli_start_connection(struct cli_state **output_cli,
2918 const char *my_name,
2919 const char *dest_host,
2920 const struct sockaddr_storage *dest_ss, int port,
2921 int signing_state, int flags)
2924 struct cli_state *cli;
2926 nt_status = cli_connect_nb(dest_host, dest_ss, port, 0x20, my_name,
2927 signing_state, flags, &cli);
2928 if (!NT_STATUS_IS_OK(nt_status)) {
2929 DEBUG(10, ("cli_connect_nb failed: %s\n",
2930 nt_errstr(nt_status)));
2934 nt_status = cli_negprot(cli);
2935 if (!NT_STATUS_IS_OK(nt_status)) {
2936 DEBUG(1, ("failed negprot: %s\n", nt_errstr(nt_status)));
2942 return NT_STATUS_OK;
2947 establishes a connection right up to doing tconX, password specified.
2948 @param output_cli A fully initialised cli structure, non-null only on success
2949 @param dest_host The netbios name of the remote host
2950 @param dest_ip (optional) The the destination IP, NULL for name based lookup
2951 @param port (optional) The destination port (0 for default)
2952 @param service (optional) The share to make the connection to. Should be 'unqualified' in any way.
2953 @param service_type The 'type' of serivice.
2954 @param user Username, unix string
2955 @param domain User's domain
2956 @param password User's password, unencrypted unix string.
2959 NTSTATUS cli_full_connection(struct cli_state **output_cli,
2960 const char *my_name,
2961 const char *dest_host,
2962 const struct sockaddr_storage *dest_ss, int port,
2963 const char *service, const char *service_type,
2964 const char *user, const char *domain,
2965 const char *password, int flags,
2969 struct cli_state *cli = NULL;
2970 int pw_len = password ? strlen(password)+1 : 0;
2974 if (password == NULL) {
2978 nt_status = cli_start_connection(&cli, my_name, dest_host,
2979 dest_ss, port, signing_state,
2982 if (!NT_STATUS_IS_OK(nt_status)) {
2986 nt_status = cli_session_setup(cli, user, password, pw_len, password,
2988 if (!NT_STATUS_IS_OK(nt_status)) {
2990 if (!(flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)) {
2991 DEBUG(1,("failed session setup with %s\n",
2992 nt_errstr(nt_status)));
2997 nt_status = cli_session_setup(cli, "", "", 0, "", 0, domain);
2998 if (!NT_STATUS_IS_OK(nt_status)) {
2999 DEBUG(1,("anonymous failed session setup with %s\n",
3000 nt_errstr(nt_status)));
3007 nt_status = cli_tcon_andx(cli, service, service_type, password,
3009 if (!NT_STATUS_IS_OK(nt_status)) {
3010 DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status)));
3012 if (NT_STATUS_IS_OK(nt_status)) {
3013 nt_status = NT_STATUS_UNSUCCESSFUL;
3019 nt_status = cli_init_creds(cli, user, domain, password);
3020 if (!NT_STATUS_IS_OK(nt_status)) {
3026 return NT_STATUS_OK;
3029 /****************************************************************************
3030 Send an old style tcon.
3031 ****************************************************************************/
3032 NTSTATUS cli_raw_tcon(struct cli_state *cli,
3033 const char *service, const char *pass, const char *dev,
3034 uint16 *max_xmit, uint16 *tid)
3036 struct tevent_req *req;
3041 if (!lp_client_plaintext_auth() && (*pass)) {
3042 DEBUG(1, ("Server requested plaintext password but 'client "
3043 "plaintext auth' is disabled\n"));
3044 return NT_STATUS_ACCESS_DENIED;
3047 bytes = talloc_array(talloc_tos(), uint8_t, 0);
3048 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3049 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
3050 service, strlen(service)+1, NULL);
3051 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3052 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
3053 pass, strlen(pass)+1, NULL);
3054 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3055 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
3056 dev, strlen(dev)+1, NULL);
3058 status = cli_smb(talloc_tos(), cli, SMBtcon, 0, 0, NULL,
3059 talloc_get_size(bytes), bytes, &req,
3060 2, NULL, &ret_vwv, NULL, NULL);
3061 if (!NT_STATUS_IS_OK(status)) {
3065 *max_xmit = SVAL(ret_vwv + 0, 0);
3066 *tid = SVAL(ret_vwv + 1, 0);
3068 return NT_STATUS_OK;
3071 /* Return a cli_state pointing at the IPC$ share for the given server */
3073 struct cli_state *get_ipc_connect(char *server,
3074 struct sockaddr_storage *server_ss,
3075 const struct user_auth_info *user_info)
3077 struct cli_state *cli;
3079 uint32_t flags = CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
3081 if (user_info->use_kerberos) {
3082 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
3085 nt_status = cli_full_connection(&cli, NULL, server, server_ss, 0, "IPC$", "IPC",
3086 user_info->username ? user_info->username : "",
3088 user_info->password ? user_info->password : "",
3092 if (NT_STATUS_IS_OK(nt_status)) {
3094 } else if (is_ipaddress(server)) {
3095 /* windows 9* needs a correct NMB name for connections */
3096 fstring remote_name;
3098 if (name_status_find("*", 0, 0, server_ss, remote_name)) {
3099 cli = get_ipc_connect(remote_name, server_ss, user_info);
3108 * Given the IP address of a master browser on the network, return its
3109 * workgroup and connect to it.
3111 * This function is provided to allow additional processing beyond what
3112 * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
3113 * browsers and obtain each master browsers' list of domains (in case the
3114 * first master browser is recently on the network and has not yet
3115 * synchronized with other master browsers and therefore does not yet have the
3116 * entire network browse list)
3119 struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx,
3120 struct sockaddr_storage *mb_ip,
3121 const struct user_auth_info *user_info,
3122 char **pp_workgroup_out)
3124 char addr[INET6_ADDRSTRLEN];
3126 struct cli_state *cli;
3127 struct sockaddr_storage server_ss;
3129 *pp_workgroup_out = NULL;
3131 print_sockaddr(addr, sizeof(addr), mb_ip);
3132 DEBUG(99, ("Looking up name of master browser %s\n",
3136 * Do a name status query to find out the name of the master browser.
3137 * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
3138 * master browser will not respond to a wildcard query (or, at least,
3139 * an NT4 server acting as the domain master browser will not).
3141 * We might be able to use ONLY the query on MSBROWSE, but that's not
3142 * yet been tested with all Windows versions, so until it is, leave
3143 * the original wildcard query as the first choice and fall back to
3144 * MSBROWSE if the wildcard query fails.
3146 if (!name_status_find("*", 0, 0x1d, mb_ip, name) &&
3147 !name_status_find(MSBROWSE, 1, 0x1d, mb_ip, name)) {
3149 DEBUG(99, ("Could not retrieve name status for %s\n",
3154 if (!find_master_ip(name, &server_ss)) {
3155 DEBUG(99, ("Could not find master ip for %s\n", name));
3159 *pp_workgroup_out = talloc_strdup(ctx, name);
3161 DEBUG(4, ("found master browser %s, %s\n", name, addr));
3163 print_sockaddr(addr, sizeof(addr), &server_ss);
3164 cli = get_ipc_connect(addr, &server_ss, user_info);
3170 * Return the IP address and workgroup of a master browser on the network, and
3174 struct cli_state *get_ipc_connect_master_ip_bcast(TALLOC_CTX *ctx,
3175 const struct user_auth_info *user_info,
3176 char **pp_workgroup_out)
3178 struct sockaddr_storage *ip_list;
3179 struct cli_state *cli;
3183 *pp_workgroup_out = NULL;
3185 DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
3187 /* Go looking for workgroups by broadcasting on the local network */
3189 status = name_resolve_bcast(MSBROWSE, 1, talloc_tos(),
3191 if (!NT_STATUS_IS_OK(status)) {
3192 DEBUG(99, ("No master browsers responded: %s\n",
3193 nt_errstr(status)));
3197 for (i = 0; i < count; i++) {
3198 char addr[INET6_ADDRSTRLEN];
3199 print_sockaddr(addr, sizeof(addr), &ip_list[i]);
3200 DEBUG(99, ("Found master browser %s\n", addr));
3202 cli = get_ipc_connect_master_ip(ctx, &ip_list[i],
3203 user_info, pp_workgroup_out);