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 * if in share level security then don't send a password now
139 if (!(sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) {
144 && (sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)
147 * Encrypted mode needed, and non encrypted password
150 lm_response = data_blob(NULL, 24);
151 if (tevent_req_nomem(lm_response.data, req)) {
152 return tevent_req_post(req, ev);
155 if (!SMBencrypt(pass, cli->secblob.data,
156 (uint8_t *)lm_response.data)) {
157 DEBUG(1, ("Password is > 14 chars in length, and is "
158 "therefore incompatible with Lanman "
159 "authentication\n"));
160 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
161 return tevent_req_post(req, ev);
163 } else if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)
166 * Encrypted mode needed, and encrypted password
169 lm_response = data_blob(pass, passlen);
170 if (tevent_req_nomem(lm_response.data, req)) {
171 return tevent_req_post(req, ev);
173 } else if (passlen > 0) {
175 size_t converted_size;
177 * Plaintext mode needed, assume plaintext supplied.
179 buf = talloc_array(talloc_tos(), uint8_t, 0);
180 buf = smb_bytes_push_str(buf, cli_ucs2(cli), pass, passlen+1,
182 if (tevent_req_nomem(buf, req)) {
183 return tevent_req_post(req, ev);
185 lm_response = data_blob(pass, passlen);
187 if (tevent_req_nomem(lm_response.data, req)) {
188 return tevent_req_post(req, ev);
192 SCVAL(vwv+0, 0, 0xff);
195 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
198 SIVAL(vwv+5, 0, cli_state_server_session_key(cli));
199 SSVAL(vwv+7, 0, lm_response.length);
201 bytes = talloc_array(state, uint8_t, lm_response.length);
202 if (tevent_req_nomem(bytes, req)) {
203 return tevent_req_post(req, ev);
205 if (lm_response.length != 0) {
206 memcpy(bytes, lm_response.data, lm_response.length);
208 data_blob_free(&lm_response);
210 tmp = talloc_strdup_upper(talloc_tos(), user);
211 if (tevent_req_nomem(tmp, req)) {
212 return tevent_req_post(req, ev);
214 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), tmp, strlen(tmp)+1,
218 tmp = talloc_strdup_upper(talloc_tos(), workgroup);
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,
224 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Unix", 5, NULL);
225 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Samba", 6, NULL);
227 if (tevent_req_nomem(bytes, req)) {
228 return tevent_req_post(req, ev);
231 subreq = cli_smb_send(state, ev, cli, SMBsesssetupX, 0, 10, vwv,
232 talloc_get_size(bytes), bytes);
233 if (tevent_req_nomem(subreq, req)) {
234 return tevent_req_post(req, ev);
236 tevent_req_set_callback(subreq, cli_session_setup_lanman2_done, req);
240 static void cli_session_setup_lanman2_done(struct tevent_req *subreq)
242 struct tevent_req *req = tevent_req_callback_data(
243 subreq, struct tevent_req);
244 struct cli_session_setup_lanman2_state *state = tevent_req_data(
245 req, struct cli_session_setup_lanman2_state);
246 struct cli_state *cli = state->cli;
257 status = cli_smb_recv(subreq, state, &in, 3, &wct, &vwv,
260 if (!NT_STATUS_IS_OK(status)) {
261 tevent_req_nterror(req, status);
268 cli_state_set_uid(state->cli, SVAL(inbuf, smb_uid));
269 cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0);
271 status = smb_bytes_talloc_string(cli,
278 if (!NT_STATUS_IS_OK(status)) {
279 tevent_req_nterror(req, status);
284 status = smb_bytes_talloc_string(cli,
291 if (!NT_STATUS_IS_OK(status)) {
292 tevent_req_nterror(req, status);
297 status = smb_bytes_talloc_string(cli,
304 if (!NT_STATUS_IS_OK(status)) {
305 tevent_req_nterror(req, status);
310 status = cli_set_username(cli, state->user);
311 if (tevent_req_nterror(req, status)) {
314 tevent_req_done(req);
317 static NTSTATUS cli_session_setup_lanman2_recv(struct tevent_req *req)
319 return tevent_req_simple_recv_ntstatus(req);
322 static NTSTATUS cli_session_setup_lanman2(struct cli_state *cli, const char *user,
323 const char *pass, size_t passlen,
324 const char *workgroup)
326 TALLOC_CTX *frame = talloc_stackframe();
327 struct event_context *ev;
328 struct tevent_req *req;
329 NTSTATUS status = NT_STATUS_NO_MEMORY;
331 if (cli_has_async_calls(cli)) {
333 * Can't use sync call while an async call is in flight
335 status = NT_STATUS_INVALID_PARAMETER;
338 ev = event_context_init(frame);
342 req = cli_session_setup_lanman2_send(frame, ev, cli, user, pass, passlen,
347 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
350 status = cli_session_setup_lanman2_recv(req);
356 /****************************************************************************
357 Work out suitable capabilities to offer the server.
358 ****************************************************************************/
360 static uint32_t cli_session_setup_capabilities(struct cli_state *cli,
361 uint32_t sesssetup_capabilities)
363 uint32_t client_capabilities = cli_state_capabilities(cli);
366 * We only send capabilities based on the mask for:
367 * - client only flags
368 * - flags used in both directions
370 * We do not echo the server only flags.
372 client_capabilities &= (SMB_CAP_BOTH_MASK | SMB_CAP_CLIENT_MASK);
375 * Session Setup specific flags CAP_DYNAMIC_REAUTH
376 * and CAP_EXTENDED_SECURITY are passed by the caller.
377 * We need that in order to do guest logins even if
378 * CAP_EXTENDED_SECURITY is negotiated.
380 client_capabilities &= ~(CAP_DYNAMIC_REAUTH|CAP_EXTENDED_SECURITY);
381 sesssetup_capabilities &= (CAP_DYNAMIC_REAUTH|CAP_EXTENDED_SECURITY);
382 client_capabilities |= sesssetup_capabilities;
384 return client_capabilities;
387 /****************************************************************************
388 Do a NT1 guest session setup.
389 ****************************************************************************/
391 struct cli_session_setup_guest_state {
392 struct cli_state *cli;
397 static void cli_session_setup_guest_done(struct tevent_req *subreq);
399 struct tevent_req *cli_session_setup_guest_create(TALLOC_CTX *mem_ctx,
400 struct event_context *ev,
401 struct cli_state *cli,
402 struct tevent_req **psmbreq)
404 struct tevent_req *req, *subreq;
405 struct cli_session_setup_guest_state *state;
409 req = tevent_req_create(mem_ctx, &state,
410 struct cli_session_setup_guest_state);
417 SCVAL(vwv+0, 0, 0xFF);
420 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
422 SSVAL(vwv+4, 0, cli_state_get_vc_num(cli));
423 SIVAL(vwv+5, 0, cli_state_server_session_key(cli));
428 SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli, 0));
430 bytes = talloc_array(state, uint8_t, 0);
432 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "", 1, /* username */
434 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "", 1, /* workgroup */
436 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Unix", 5, NULL);
437 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Samba", 6, NULL);
444 state->bytes.iov_base = (void *)bytes;
445 state->bytes.iov_len = talloc_get_size(bytes);
447 subreq = cli_smb_req_create(state, ev, cli, SMBsesssetupX, 0, 13, vwv,
449 if (subreq == NULL) {
453 tevent_req_set_callback(subreq, cli_session_setup_guest_done, req);
458 struct tevent_req *cli_session_setup_guest_send(TALLOC_CTX *mem_ctx,
459 struct event_context *ev,
460 struct cli_state *cli)
462 struct tevent_req *req, *subreq;
465 req = cli_session_setup_guest_create(mem_ctx, ev, cli, &subreq);
470 status = cli_smb_req_send(subreq);
471 if (NT_STATUS_IS_OK(status)) {
472 tevent_req_nterror(req, status);
473 return tevent_req_post(req, ev);
478 static void cli_session_setup_guest_done(struct tevent_req *subreq)
480 struct tevent_req *req = tevent_req_callback_data(
481 subreq, struct tevent_req);
482 struct cli_session_setup_guest_state *state = tevent_req_data(
483 req, struct cli_session_setup_guest_state);
484 struct cli_state *cli = state->cli;
495 status = cli_smb_recv(subreq, state, &in, 3, &wct, &vwv,
498 if (!NT_STATUS_IS_OK(status)) {
499 tevent_req_nterror(req, status);
506 cli_state_set_uid(state->cli, SVAL(inbuf, smb_uid));
507 cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0);
509 status = smb_bytes_talloc_string(cli,
516 if (!NT_STATUS_IS_OK(status)) {
517 tevent_req_nterror(req, status);
522 status = smb_bytes_talloc_string(cli,
529 if (!NT_STATUS_IS_OK(status)) {
530 tevent_req_nterror(req, status);
535 status = smb_bytes_talloc_string(cli,
542 if (!NT_STATUS_IS_OK(status)) {
543 tevent_req_nterror(req, status);
548 status = cli_set_username(cli, "");
549 if (!NT_STATUS_IS_OK(status)) {
550 tevent_req_nterror(req, status);
553 tevent_req_done(req);
556 NTSTATUS cli_session_setup_guest_recv(struct tevent_req *req)
558 return tevent_req_simple_recv_ntstatus(req);
561 static NTSTATUS cli_session_setup_guest(struct cli_state *cli)
563 TALLOC_CTX *frame = talloc_stackframe();
564 struct event_context *ev;
565 struct tevent_req *req;
566 NTSTATUS status = NT_STATUS_OK;
568 if (cli_has_async_calls(cli)) {
570 * Can't use sync call while an async call is in flight
572 status = NT_STATUS_INVALID_PARAMETER;
576 ev = event_context_init(frame);
578 status = NT_STATUS_NO_MEMORY;
582 req = cli_session_setup_guest_send(frame, ev, cli);
584 status = NT_STATUS_NO_MEMORY;
588 if (!tevent_req_poll(req, ev)) {
589 status = map_nt_error_from_unix(errno);
593 status = cli_session_setup_guest_recv(req);
599 /****************************************************************************
600 Do a NT1 plaintext session setup.
601 ****************************************************************************/
603 struct cli_session_setup_plain_state {
604 struct cli_state *cli;
609 static void cli_session_setup_plain_done(struct tevent_req *subreq);
611 static struct tevent_req *cli_session_setup_plain_send(
612 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
613 struct cli_state *cli,
614 const char *user, const char *pass, const char *workgroup)
616 struct tevent_req *req, *subreq;
617 struct cli_session_setup_plain_state *state;
623 req = tevent_req_create(mem_ctx, &state,
624 struct cli_session_setup_plain_state);
632 SCVAL(vwv+0, 0, 0xff);
635 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
637 SSVAL(vwv+4, 0, cli_state_get_vc_num(cli));
638 SIVAL(vwv+5, 0, cli_state_server_session_key(cli));
643 SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli, 0));
645 bytes = talloc_array(state, uint8_t, 0);
646 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), pass, strlen(pass)+1,
648 if (tevent_req_nomem(bytes, req)) {
649 return tevent_req_post(req, ev);
651 SSVAL(vwv + (cli_ucs2(cli) ? 8 : 7), 0, passlen);
653 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
654 user, strlen(user)+1, NULL);
655 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
656 workgroup, strlen(workgroup)+1, NULL);
657 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
660 version = talloc_asprintf(talloc_tos(), "Samba %s",
661 samba_version_string());
662 if (tevent_req_nomem(version, req)){
663 return tevent_req_post(req, ev);
665 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
666 version, strlen(version)+1, NULL);
667 TALLOC_FREE(version);
669 if (tevent_req_nomem(bytes, req)) {
670 return tevent_req_post(req, ev);
673 subreq = cli_smb_send(state, ev, cli, SMBsesssetupX, 0, 13, vwv,
674 talloc_get_size(bytes), bytes);
675 if (tevent_req_nomem(subreq, req)) {
676 return tevent_req_post(req, ev);
678 tevent_req_set_callback(subreq, cli_session_setup_plain_done, req);
682 static void cli_session_setup_plain_done(struct tevent_req *subreq)
684 struct tevent_req *req = tevent_req_callback_data(
685 subreq, struct tevent_req);
686 struct cli_session_setup_plain_state *state = tevent_req_data(
687 req, struct cli_session_setup_plain_state);
688 struct cli_state *cli = state->cli;
699 status = cli_smb_recv(subreq, state, &in, 3, &wct, &vwv,
702 if (tevent_req_nterror(req, status)) {
709 cli_state_set_uid(state->cli, SVAL(inbuf, smb_uid));
710 cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0);
712 status = smb_bytes_talloc_string(cli,
719 if (!NT_STATUS_IS_OK(status)) {
720 tevent_req_nterror(req, status);
725 status = smb_bytes_talloc_string(cli,
732 if (!NT_STATUS_IS_OK(status)) {
733 tevent_req_nterror(req, status);
738 status = smb_bytes_talloc_string(cli,
745 if (!NT_STATUS_IS_OK(status)) {
746 tevent_req_nterror(req, status);
751 status = cli_set_username(cli, state->user);
752 if (tevent_req_nterror(req, status)) {
756 tevent_req_done(req);
759 static NTSTATUS cli_session_setup_plain_recv(struct tevent_req *req)
761 return tevent_req_simple_recv_ntstatus(req);
764 static NTSTATUS cli_session_setup_plain(struct cli_state *cli,
765 const char *user, const char *pass,
766 const char *workgroup)
768 TALLOC_CTX *frame = talloc_stackframe();
769 struct event_context *ev;
770 struct tevent_req *req;
771 NTSTATUS status = NT_STATUS_NO_MEMORY;
773 if (cli_has_async_calls(cli)) {
775 * Can't use sync call while an async call is in flight
777 status = NT_STATUS_INVALID_PARAMETER;
780 ev = event_context_init(frame);
784 req = cli_session_setup_plain_send(frame, ev, cli, user, pass,
789 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
792 status = cli_session_setup_plain_recv(req);
798 /****************************************************************************
799 do a NT1 NTLM/LM encrypted session setup - for when extended security
801 @param cli client state to create do session setup on
803 @param pass *either* cleartext password (passlen !=24) or LM response.
804 @param ntpass NT response, implies ntpasslen >=24, implies pass is not clear
805 @param workgroup The user's domain.
806 ****************************************************************************/
808 struct cli_session_setup_nt1_state {
809 struct cli_state *cli;
812 DATA_BLOB session_key;
816 static void cli_session_setup_nt1_done(struct tevent_req *subreq);
818 static struct tevent_req *cli_session_setup_nt1_send(
819 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
820 struct cli_state *cli, const char *user,
821 const char *pass, size_t passlen,
822 const char *ntpass, size_t ntpasslen,
823 const char *workgroup)
825 struct tevent_req *req, *subreq;
826 struct cli_session_setup_nt1_state *state;
827 DATA_BLOB lm_response = data_blob_null;
828 DATA_BLOB nt_response = data_blob_null;
829 DATA_BLOB session_key = data_blob_null;
832 char *workgroup_upper;
834 req = tevent_req_create(mem_ctx, &state,
835 struct cli_session_setup_nt1_state);
844 /* do nothing - guest login */
845 } else if (passlen != 24) {
846 if (lp_client_ntlmv2_auth()) {
847 DATA_BLOB server_chal;
848 DATA_BLOB names_blob;
850 server_chal = data_blob(cli->secblob.data,
851 MIN(cli->secblob.length, 8));
852 if (tevent_req_nomem(server_chal.data, req)) {
853 return tevent_req_post(req, ev);
857 * note that the 'workgroup' here is a best
858 * guess - we don't know the server's domain
859 * at this point. Windows clients also don't
862 names_blob = NTLMv2_generate_names_blob(
863 NULL, NULL, workgroup);
865 if (tevent_req_nomem(names_blob.data, req)) {
866 return tevent_req_post(req, ev);
869 if (!SMBNTLMv2encrypt(NULL, user, workgroup, pass,
870 &server_chal, &names_blob,
871 &lm_response, &nt_response,
872 NULL, &session_key)) {
873 data_blob_free(&names_blob);
874 data_blob_free(&server_chal);
876 req, NT_STATUS_ACCESS_DENIED);
877 return tevent_req_post(req, ev);
879 data_blob_free(&names_blob);
880 data_blob_free(&server_chal);
884 E_md4hash(pass, nt_hash);
887 nt_response = data_blob_null;
889 nt_response = data_blob(NULL, 24);
890 if (tevent_req_nomem(nt_response.data, req)) {
891 return tevent_req_post(req, ev);
894 SMBNTencrypt(pass, cli->secblob.data,
897 /* non encrypted password supplied. Ignore ntpass. */
898 if (lp_client_lanman_auth()) {
900 lm_response = data_blob(NULL, 24);
901 if (tevent_req_nomem(lm_response.data, req)) {
902 return tevent_req_post(req, ev);
905 if (!SMBencrypt(pass,cli->secblob.data,
908 * Oops, the LM response is
909 * invalid, just put the NT
910 * response there instead
912 data_blob_free(&lm_response);
913 lm_response = data_blob(
919 * LM disabled, place NT# in LM field
922 lm_response = data_blob(
923 nt_response.data, nt_response.length);
926 if (tevent_req_nomem(lm_response.data, req)) {
927 return tevent_req_post(req, ev);
930 session_key = data_blob(NULL, 16);
931 if (tevent_req_nomem(session_key.data, req)) {
932 return tevent_req_post(req, ev);
935 E_deshash(pass, session_key.data);
936 memset(&session_key.data[8], '\0', 8);
938 SMBsesskeygen_ntv1(nt_hash, session_key.data);
942 /* pre-encrypted password supplied. Only used for
943 security=server, can't do
944 signing because we don't have original key */
946 lm_response = data_blob(pass, passlen);
947 if (tevent_req_nomem(lm_response.data, req)) {
948 return tevent_req_post(req, ev);
951 nt_response = data_blob(ntpass, ntpasslen);
952 if (tevent_req_nomem(nt_response.data, req)) {
953 return tevent_req_post(req, ev);
958 state->response = data_blob_talloc(
959 state, lm_response.data, lm_response.length);
961 state->response = data_blob_talloc(
962 state, nt_response.data, nt_response.length);
964 if (tevent_req_nomem(state->response.data, req)) {
965 return tevent_req_post(req, ev);
968 if (session_key.data) {
969 state->session_key = data_blob_talloc(
970 state, session_key.data, session_key.length);
971 if (tevent_req_nomem(state->session_key.data, req)) {
972 return tevent_req_post(req, ev);
975 data_blob_free(&session_key);
977 SCVAL(vwv+0, 0, 0xff);
980 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
982 SSVAL(vwv+4, 0, cli_state_get_vc_num(cli));
983 SIVAL(vwv+5, 0, cli_state_server_session_key(cli));
984 SSVAL(vwv+7, 0, lm_response.length);
985 SSVAL(vwv+8, 0, nt_response.length);
988 SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli, 0));
990 bytes = talloc_array(state, uint8_t,
991 lm_response.length + nt_response.length);
992 if (tevent_req_nomem(bytes, req)) {
993 return tevent_req_post(req, ev);
995 if (lm_response.length != 0) {
996 memcpy(bytes, lm_response.data, lm_response.length);
998 if (nt_response.length != 0) {
999 memcpy(bytes + lm_response.length,
1000 nt_response.data, nt_response.length);
1002 data_blob_free(&lm_response);
1003 data_blob_free(&nt_response);
1005 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
1006 user, strlen(user)+1, NULL);
1009 * Upper case here might help some NTLMv2 implementations
1011 workgroup_upper = talloc_strdup_upper(talloc_tos(), workgroup);
1012 if (tevent_req_nomem(workgroup_upper, req)) {
1013 return tevent_req_post(req, ev);
1015 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
1016 workgroup_upper, strlen(workgroup_upper)+1,
1018 TALLOC_FREE(workgroup_upper);
1020 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Unix", 5, NULL);
1021 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Samba", 6, NULL);
1022 if (tevent_req_nomem(bytes, req)) {
1023 return tevent_req_post(req, ev);
1026 subreq = cli_smb_send(state, ev, cli, SMBsesssetupX, 0, 13, vwv,
1027 talloc_get_size(bytes), bytes);
1028 if (tevent_req_nomem(subreq, req)) {
1029 return tevent_req_post(req, ev);
1031 tevent_req_set_callback(subreq, cli_session_setup_nt1_done, req);
1035 static void cli_session_setup_nt1_done(struct tevent_req *subreq)
1037 struct tevent_req *req = tevent_req_callback_data(
1038 subreq, struct tevent_req);
1039 struct cli_session_setup_nt1_state *state = tevent_req_data(
1040 req, struct cli_session_setup_nt1_state);
1041 struct cli_state *cli = state->cli;
1052 status = cli_smb_recv(subreq, state, &in, 3, &wct, &vwv,
1053 &num_bytes, &bytes);
1054 TALLOC_FREE(subreq);
1055 if (!NT_STATUS_IS_OK(status)) {
1056 tevent_req_nterror(req, status);
1063 cli_state_set_uid(state->cli, SVAL(inbuf, smb_uid));
1064 cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0);
1066 status = smb_bytes_talloc_string(cli,
1072 if (!NT_STATUS_IS_OK(status)) {
1073 tevent_req_nterror(req, status);
1078 status = smb_bytes_talloc_string(cli,
1084 if (!NT_STATUS_IS_OK(status)) {
1085 tevent_req_nterror(req, status);
1090 status = smb_bytes_talloc_string(cli,
1092 &cli->server_domain,
1096 if (!NT_STATUS_IS_OK(status)) {
1097 tevent_req_nterror(req, status);
1102 status = cli_set_username(cli, state->user);
1103 if (tevent_req_nterror(req, status)) {
1106 if (cli_simple_set_signing(cli, state->session_key, state->response)
1107 && !cli_check_sign_mac(cli, (char *)in, 1)) {
1108 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1111 if (state->session_key.data) {
1112 /* Have plaintext orginal */
1113 cli_set_session_key(cli, state->session_key);
1115 tevent_req_done(req);
1118 static NTSTATUS cli_session_setup_nt1_recv(struct tevent_req *req)
1120 return tevent_req_simple_recv_ntstatus(req);
1123 static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user,
1124 const char *pass, size_t passlen,
1125 const char *ntpass, size_t ntpasslen,
1126 const char *workgroup)
1128 TALLOC_CTX *frame = talloc_stackframe();
1129 struct event_context *ev;
1130 struct tevent_req *req;
1131 NTSTATUS status = NT_STATUS_NO_MEMORY;
1133 if (cli_has_async_calls(cli)) {
1135 * Can't use sync call while an async call is in flight
1137 status = NT_STATUS_INVALID_PARAMETER;
1140 ev = event_context_init(frame);
1144 req = cli_session_setup_nt1_send(frame, ev, cli, user, pass, passlen,
1145 ntpass, ntpasslen, workgroup);
1149 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1152 status = cli_session_setup_nt1_recv(req);
1158 /* The following is calculated from :
1160 * (smb_wcnt * 2) = 24 (smb_wcnt == 12 in cli_session_setup_blob_send() )
1161 * (strlen("Unix") + 1 + strlen("Samba") + 1) * 2 = 22 (unicode strings at
1165 #define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22)
1167 struct cli_sesssetup_blob_state {
1168 struct tevent_context *ev;
1169 struct cli_state *cli;
1171 uint16_t max_blob_size;
1180 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state *state,
1181 struct tevent_req **psubreq);
1182 static void cli_sesssetup_blob_done(struct tevent_req *subreq);
1184 static struct tevent_req *cli_sesssetup_blob_send(TALLOC_CTX *mem_ctx,
1185 struct tevent_context *ev,
1186 struct cli_state *cli,
1189 struct tevent_req *req, *subreq;
1190 struct cli_sesssetup_blob_state *state;
1191 uint32_t usable_space;
1193 req = tevent_req_create(mem_ctx, &state,
1194 struct cli_sesssetup_blob_state);
1202 usable_space = cli_state_available_size(cli,
1203 BASE_SESSSETUP_BLOB_PACKET_SIZE);
1205 if (usable_space == 0) {
1206 DEBUG(1, ("cli_session_setup_blob: cli->max_xmit too small "
1207 "(not possible to send %u bytes)\n",
1208 BASE_SESSSETUP_BLOB_PACKET_SIZE + 1));
1209 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1210 return tevent_req_post(req, ev);
1212 state->max_blob_size = MIN(usable_space, 0xFFFF);
1214 if (!cli_sesssetup_blob_next(state, &subreq)) {
1215 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1216 return tevent_req_post(req, ev);
1218 tevent_req_set_callback(subreq, cli_sesssetup_blob_done, req);
1222 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state *state,
1223 struct tevent_req **psubreq)
1225 struct tevent_req *subreq;
1228 SCVAL(state->vwv+0, 0, 0xFF);
1229 SCVAL(state->vwv+0, 1, 0);
1230 SSVAL(state->vwv+1, 0, 0);
1231 SSVAL(state->vwv+2, 0, CLI_BUFFER_SIZE);
1232 SSVAL(state->vwv+3, 0, 2);
1233 SSVAL(state->vwv+4, 0, 1);
1234 SIVAL(state->vwv+5, 0, 0);
1236 thistime = MIN(state->blob.length, state->max_blob_size);
1237 SSVAL(state->vwv+7, 0, thistime);
1239 SSVAL(state->vwv+8, 0, 0);
1240 SSVAL(state->vwv+9, 0, 0);
1241 SIVAL(state->vwv+10, 0,
1242 cli_session_setup_capabilities(state->cli, CAP_EXTENDED_SECURITY));
1244 state->buf = (uint8_t *)talloc_memdup(state, state->blob.data,
1246 if (state->buf == NULL) {
1249 state->blob.data += thistime;
1250 state->blob.length -= thistime;
1252 state->buf = smb_bytes_push_str(state->buf, cli_ucs2(state->cli),
1254 state->buf = smb_bytes_push_str(state->buf, cli_ucs2(state->cli),
1256 if (state->buf == NULL) {
1259 subreq = cli_smb_send(state, state->ev, state->cli, SMBsesssetupX, 0,
1261 talloc_get_size(state->buf), state->buf);
1262 if (subreq == NULL) {
1269 static void cli_sesssetup_blob_done(struct tevent_req *subreq)
1271 struct tevent_req *req = tevent_req_callback_data(
1272 subreq, struct tevent_req);
1273 struct cli_sesssetup_blob_state *state = tevent_req_data(
1274 req, struct cli_sesssetup_blob_state);
1275 struct cli_state *cli = state->cli;
1282 uint16_t blob_length;
1286 status = cli_smb_recv(subreq, state, &inbuf, 4, &wct, &vwv,
1287 &num_bytes, &bytes);
1288 TALLOC_FREE(subreq);
1289 if (!NT_STATUS_IS_OK(status)
1290 && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1291 tevent_req_nterror(req, status);
1295 state->status = status;
1296 TALLOC_FREE(state->buf);
1298 state->inbuf = (char *)inbuf;
1299 cli_state_set_uid(state->cli, SVAL(inbuf, smb_uid));
1300 cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0);
1302 blob_length = SVAL(vwv+3, 0);
1303 if (blob_length > num_bytes) {
1304 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1307 state->ret_blob = data_blob_const(bytes, blob_length);
1309 p = bytes + blob_length;
1311 status = smb_bytes_talloc_string(cli,
1318 if (!NT_STATUS_IS_OK(status)) {
1319 tevent_req_nterror(req, status);
1324 status = smb_bytes_talloc_string(cli,
1331 if (!NT_STATUS_IS_OK(status)) {
1332 tevent_req_nterror(req, status);
1337 status = smb_bytes_talloc_string(cli,
1339 &cli->server_domain,
1344 if (!NT_STATUS_IS_OK(status)) {
1345 tevent_req_nterror(req, status);
1350 if (state->blob.length != 0) {
1354 if (!cli_sesssetup_blob_next(state, &subreq)) {
1355 tevent_req_oom(req);
1358 tevent_req_set_callback(subreq, cli_sesssetup_blob_done, req);
1361 tevent_req_done(req);
1364 static NTSTATUS cli_sesssetup_blob_recv(struct tevent_req *req,
1365 TALLOC_CTX *mem_ctx,
1369 struct cli_sesssetup_blob_state *state = tevent_req_data(
1370 req, struct cli_sesssetup_blob_state);
1374 if (tevent_req_is_nterror(req, &status)) {
1375 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
1379 inbuf = talloc_move(mem_ctx, &state->inbuf);
1380 if (pblob != NULL) {
1381 *pblob = state->ret_blob;
1383 if (pinbuf != NULL) {
1386 /* could be NT_STATUS_MORE_PROCESSING_REQUIRED */
1387 return state->status;
1392 /****************************************************************************
1393 Use in-memory credentials cache
1394 ****************************************************************************/
1396 static void use_in_memory_ccache(void) {
1397 setenv(KRB5_ENV_CCNAME, "MEMORY:cliconnect", 1);
1400 /****************************************************************************
1401 Do a spnego/kerberos encrypted session setup.
1402 ****************************************************************************/
1404 struct cli_session_setup_kerberos_state {
1405 struct cli_state *cli;
1406 DATA_BLOB negTokenTarg;
1407 DATA_BLOB session_key_krb5;
1408 ADS_STATUS ads_status;
1411 static void cli_session_setup_kerberos_done(struct tevent_req *subreq);
1413 static struct tevent_req *cli_session_setup_kerberos_send(
1414 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
1415 const char *principal)
1417 struct tevent_req *req, *subreq;
1418 struct cli_session_setup_kerberos_state *state;
1421 DEBUG(2,("Doing kerberos session setup\n"));
1423 req = tevent_req_create(mem_ctx, &state,
1424 struct cli_session_setup_kerberos_state);
1429 state->ads_status = ADS_SUCCESS;
1432 * Ok, this is cheating: spnego_gen_krb5_negTokenInit can block if
1433 * we have to acquire a ticket. To be fixed later :-)
1435 rc = spnego_gen_krb5_negTokenInit(state, principal, 0, &state->negTokenTarg,
1436 &state->session_key_krb5, 0, NULL);
1438 DEBUG(1, ("cli_session_setup_kerberos: "
1439 "spnego_gen_krb5_negTokenInit failed: %s\n",
1440 error_message(rc)));
1441 state->ads_status = ADS_ERROR_KRB5(rc);
1442 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
1443 return tevent_req_post(req, ev);
1447 file_save("negTokenTarg.dat", state->negTokenTarg.data,
1448 state->negTokenTarg.length);
1451 subreq = cli_sesssetup_blob_send(state, ev, cli, state->negTokenTarg);
1452 if (tevent_req_nomem(subreq, req)) {
1453 return tevent_req_post(req, ev);
1455 tevent_req_set_callback(subreq, cli_session_setup_kerberos_done, req);
1459 static void cli_session_setup_kerberos_done(struct tevent_req *subreq)
1461 struct tevent_req *req = tevent_req_callback_data(
1462 subreq, struct tevent_req);
1463 struct cli_session_setup_kerberos_state *state = tevent_req_data(
1464 req, struct cli_session_setup_kerberos_state);
1468 status = cli_sesssetup_blob_recv(subreq, talloc_tos(), NULL, &inbuf);
1469 if (!NT_STATUS_IS_OK(status)) {
1470 TALLOC_FREE(subreq);
1471 tevent_req_nterror(req, status);
1475 cli_set_session_key(state->cli, state->session_key_krb5);
1477 if (cli_simple_set_signing(state->cli, state->session_key_krb5,
1479 && !cli_check_sign_mac(state->cli, inbuf, 1)) {
1480 TALLOC_FREE(subreq);
1481 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1484 TALLOC_FREE(subreq);
1485 tevent_req_done(req);
1488 static ADS_STATUS cli_session_setup_kerberos_recv(struct tevent_req *req)
1490 struct cli_session_setup_kerberos_state *state = tevent_req_data(
1491 req, struct cli_session_setup_kerberos_state);
1494 if (tevent_req_is_nterror(req, &status)) {
1495 return ADS_ERROR_NT(status);
1497 return state->ads_status;
1500 static ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli,
1501 const char *principal)
1503 struct tevent_context *ev;
1504 struct tevent_req *req;
1505 ADS_STATUS status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1507 if (cli_has_async_calls(cli)) {
1508 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1510 ev = tevent_context_init(talloc_tos());
1514 req = cli_session_setup_kerberos_send(ev, ev, cli, principal);
1518 if (!tevent_req_poll(req, ev)) {
1519 status = ADS_ERROR_SYSTEM(errno);
1522 status = cli_session_setup_kerberos_recv(req);
1527 #endif /* HAVE_KRB5 */
1529 /****************************************************************************
1530 Do a spnego/NTLMSSP encrypted session setup.
1531 ****************************************************************************/
1533 struct cli_session_setup_ntlmssp_state {
1534 struct tevent_context *ev;
1535 struct cli_state *cli;
1536 struct ntlmssp_state *ntlmssp_state;
1541 static int cli_session_setup_ntlmssp_state_destructor(
1542 struct cli_session_setup_ntlmssp_state *state)
1544 if (state->ntlmssp_state != NULL) {
1545 TALLOC_FREE(state->ntlmssp_state);
1550 static void cli_session_setup_ntlmssp_done(struct tevent_req *req);
1552 static struct tevent_req *cli_session_setup_ntlmssp_send(
1553 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
1554 const char *user, const char *pass, const char *domain)
1556 struct tevent_req *req, *subreq;
1557 struct cli_session_setup_ntlmssp_state *state;
1560 const char *OIDs_ntlm[] = {OID_NTLMSSP, NULL};
1562 req = tevent_req_create(mem_ctx, &state,
1563 struct cli_session_setup_ntlmssp_state);
1571 state->ntlmssp_state = NULL;
1572 talloc_set_destructor(
1573 state, cli_session_setup_ntlmssp_state_destructor);
1575 status = ntlmssp_client_start(state,
1578 lp_client_ntlmv2_auth(),
1579 &state->ntlmssp_state);
1580 if (!NT_STATUS_IS_OK(status)) {
1583 ntlmssp_want_feature(state->ntlmssp_state,
1584 NTLMSSP_FEATURE_SESSION_KEY);
1585 if (cli->use_ccache) {
1586 ntlmssp_want_feature(state->ntlmssp_state,
1587 NTLMSSP_FEATURE_CCACHE);
1589 status = ntlmssp_set_username(state->ntlmssp_state, user);
1590 if (!NT_STATUS_IS_OK(status)) {
1593 status = ntlmssp_set_domain(state->ntlmssp_state, domain);
1594 if (!NT_STATUS_IS_OK(status)) {
1597 status = ntlmssp_set_password(state->ntlmssp_state, pass);
1598 if (!NT_STATUS_IS_OK(status)) {
1601 status = ntlmssp_update(state->ntlmssp_state, data_blob_null,
1603 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1607 state->blob_out = spnego_gen_negTokenInit(state, OIDs_ntlm, &blob_out, NULL);
1608 data_blob_free(&blob_out);
1610 subreq = cli_sesssetup_blob_send(state, ev, cli, state->blob_out);
1611 if (tevent_req_nomem(subreq, req)) {
1612 return tevent_req_post(req, ev);
1614 tevent_req_set_callback(subreq, cli_session_setup_ntlmssp_done, req);
1617 tevent_req_nterror(req, status);
1618 return tevent_req_post(req, ev);
1621 static void cli_session_setup_ntlmssp_done(struct tevent_req *subreq)
1623 struct tevent_req *req = tevent_req_callback_data(
1624 subreq, struct tevent_req);
1625 struct cli_session_setup_ntlmssp_state *state = tevent_req_data(
1626 req, struct cli_session_setup_ntlmssp_state);
1627 DATA_BLOB blob_in, msg_in, blob_out;
1632 status = cli_sesssetup_blob_recv(subreq, talloc_tos(), &blob_in,
1634 TALLOC_FREE(subreq);
1635 data_blob_free(&state->blob_out);
1637 if (NT_STATUS_IS_OK(status)) {
1638 if (state->cli->server_domain[0] == '\0') {
1639 TALLOC_FREE(state->cli->server_domain);
1640 state->cli->server_domain = talloc_strdup(state->cli,
1641 state->ntlmssp_state->server.netbios_domain);
1642 if (state->cli->server_domain == NULL) {
1643 TALLOC_FREE(subreq);
1644 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1648 cli_set_session_key(
1649 state->cli, state->ntlmssp_state->session_key);
1651 if (cli_simple_set_signing(
1652 state->cli, state->ntlmssp_state->session_key,
1654 && !cli_check_sign_mac(state->cli, inbuf, 1)) {
1655 TALLOC_FREE(subreq);
1656 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1659 TALLOC_FREE(subreq);
1660 TALLOC_FREE(state->ntlmssp_state);
1661 tevent_req_done(req);
1664 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1665 tevent_req_nterror(req, status);
1669 if (blob_in.length == 0) {
1670 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
1674 if ((state->turn == 1)
1675 && NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1676 DATA_BLOB tmp_blob = data_blob_null;
1677 /* the server might give us back two challenges */
1678 parse_ret = spnego_parse_challenge(state, blob_in, &msg_in,
1680 data_blob_free(&tmp_blob);
1682 parse_ret = spnego_parse_auth_response(state, blob_in, status,
1683 OID_NTLMSSP, &msg_in);
1688 DEBUG(3,("Failed to parse auth response\n"));
1689 if (NT_STATUS_IS_OK(status)
1690 || NT_STATUS_EQUAL(status,
1691 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1693 req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1698 status = ntlmssp_update(state->ntlmssp_state, msg_in, &blob_out);
1700 if (!NT_STATUS_IS_OK(status)
1701 && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1702 TALLOC_FREE(subreq);
1703 TALLOC_FREE(state->ntlmssp_state);
1704 tevent_req_nterror(req, status);
1708 state->blob_out = spnego_gen_auth(state, blob_out);
1709 TALLOC_FREE(subreq);
1710 if (tevent_req_nomem(state->blob_out.data, req)) {
1714 subreq = cli_sesssetup_blob_send(state, state->ev, state->cli,
1716 if (tevent_req_nomem(subreq, req)) {
1719 tevent_req_set_callback(subreq, cli_session_setup_ntlmssp_done, req);
1722 static NTSTATUS cli_session_setup_ntlmssp_recv(struct tevent_req *req)
1724 struct cli_session_setup_ntlmssp_state *state = tevent_req_data(
1725 req, struct cli_session_setup_ntlmssp_state);
1728 if (tevent_req_is_nterror(req, &status)) {
1729 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
1732 return NT_STATUS_OK;
1735 static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli,
1740 struct tevent_context *ev;
1741 struct tevent_req *req;
1742 NTSTATUS status = NT_STATUS_NO_MEMORY;
1744 if (cli_has_async_calls(cli)) {
1745 return NT_STATUS_INVALID_PARAMETER;
1747 ev = tevent_context_init(talloc_tos());
1751 req = cli_session_setup_ntlmssp_send(ev, ev, cli, user, pass, domain);
1755 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1758 status = cli_session_setup_ntlmssp_recv(req);
1764 /****************************************************************************
1765 Do a spnego encrypted session setup.
1767 user_domain: The shortname of the domain the user/machine is a member of.
1768 dest_realm: The realm we're connecting to, if NULL we use our default realm.
1769 ****************************************************************************/
1771 static ADS_STATUS cli_session_setup_spnego(struct cli_state *cli,
1774 const char *user_domain,
1775 const char * dest_realm)
1777 char *principal = NULL;
1778 char *OIDs[ASN1_MAX_OIDS];
1781 const char *p = NULL;
1782 char *account = NULL;
1785 DEBUG(3,("Doing spnego session setup (blob length=%lu)\n", (unsigned long)cli->secblob.length));
1787 /* the server might not even do spnego */
1788 if (cli->secblob.length <= 16) {
1789 DEBUG(3,("server didn't supply a full spnego negprot\n"));
1794 file_save("negprot.dat", cli->secblob.data, cli->secblob.length);
1797 /* there is 16 bytes of GUID before the real spnego packet starts */
1798 blob = data_blob(cli->secblob.data+16, cli->secblob.length-16);
1800 /* The server sent us the first part of the SPNEGO exchange in the
1801 * negprot reply. It is WRONG to depend on the principal sent in the
1802 * negprot reply, but right now we do it. If we don't receive one,
1803 * we try to best guess, then fall back to NTLM. */
1804 if (!spnego_parse_negTokenInit(talloc_tos(), blob, OIDs, &principal, NULL) ||
1806 data_blob_free(&blob);
1807 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1809 data_blob_free(&blob);
1811 /* make sure the server understands kerberos */
1812 for (i=0;OIDs[i];i++) {
1814 DEBUG(3,("got OID=%s\n", OIDs[i]));
1816 DEBUGADD(3,("got OID=%s\n", OIDs[i]));
1817 if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0 ||
1818 strcmp(OIDs[i], OID_KERBEROS5) == 0) {
1819 cli->got_kerberos_mechanism = True;
1821 talloc_free(OIDs[i]);
1824 DEBUG(3,("got principal=%s\n", principal ? principal : "<null>"));
1826 status = cli_set_username(cli, user);
1827 if (!NT_STATUS_IS_OK(status)) {
1828 TALLOC_FREE(principal);
1829 return ADS_ERROR_NT(status);
1833 /* If password is set we reauthenticate to kerberos server
1834 * and do not store results */
1836 if (cli->got_kerberos_mechanism && cli->use_kerberos) {
1838 const char *remote_name = cli_state_remote_name(cli);
1840 if (pass && *pass) {
1843 use_in_memory_ccache();
1844 ret = kerberos_kinit_password(user, pass, 0 /* no time correction for now */, NULL);
1847 TALLOC_FREE(principal);
1848 DEBUG(0, ("Kinit failed: %s\n", error_message(ret)));
1849 if (cli->fallback_after_kerberos)
1851 return ADS_ERROR_KRB5(ret);
1855 /* We may not be allowed to use the server-supplied SPNEGO principal, or it may not have been supplied to us
1857 if (!lp_client_use_spnego_principal() || strequal(principal, ADS_IGNORE_PRINCIPAL)) {
1858 TALLOC_FREE(principal);
1861 if (principal == NULL &&
1862 !is_ipaddress(remote_name) &&
1863 !strequal(STAR_SMBSERVER,
1867 DEBUG(3,("cli_session_setup_spnego: using target "
1868 "hostname not SPNEGO principal\n"));
1870 host = strchr_m(remote_name, '.');
1872 realm = SMB_STRDUP(dest_realm);
1874 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1880 realm = kerberos_get_realm_from_hostname(remote_name);
1882 /* NetBIOS name - use our realm. */
1883 realm = kerberos_get_default_realm_from_ccache();
1887 if (realm == NULL || *realm == '\0') {
1888 realm = SMB_STRDUP(lp_realm());
1890 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1893 DEBUG(3,("cli_session_setup_spnego: cannot "
1894 "get realm from dest_realm %s, "
1895 "desthost %s. Using default "
1896 "smb.conf realm %s\n",
1897 dest_realm ? dest_realm : "<null>",
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);
1919 if (ADS_ERR_OK(rc) || !cli->fallback_after_kerberos) {
1920 TALLOC_FREE(principal);
1927 TALLOC_FREE(principal);
1931 account = talloc_strdup(talloc_tos(), user);
1933 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1936 /* when falling back to ntlmssp while authenticating with a machine
1937 * account strip off the realm - gd */
1939 if ((p = strchr_m(user, '@')) != NULL) {
1940 account[PTR_DIFF(p,user)] = '\0';
1943 return ADS_ERROR_NT(cli_session_setup_ntlmssp(cli, account, pass, user_domain));
1946 /****************************************************************************
1947 Send a session setup. The username and workgroup is in UNIX character
1948 format and must be converted to DOS codepage format before sending. If the
1949 password is in plaintext, the same should be done.
1950 ****************************************************************************/
1952 NTSTATUS cli_session_setup(struct cli_state *cli,
1954 const char *pass, int passlen,
1955 const char *ntpass, int ntpasslen,
1956 const char *workgroup)
1960 uint16_t sec_mode = cli_state_security_mode(cli);
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()))) {
1984 if (cli_state_protocol(cli) < PROTOCOL_LANMAN1) {
1986 * Ensure cli->server_domain,
1987 * cli->server_os and cli->server_type
1988 * are valid pointers.
1990 cli->server_domain = talloc_strdup(cli, "");
1991 cli->server_os = talloc_strdup(cli, "");
1992 cli->server_type = talloc_strdup(cli, "");
1993 if (cli->server_domain == NULL ||
1994 cli->server_os == NULL ||
1995 cli->server_type == NULL) {
1996 return NT_STATUS_NO_MEMORY;
1998 return NT_STATUS_OK;
2001 /* now work out what sort of session setup we are going to
2002 do. I have split this into separate functions to make the
2003 flow a bit easier to understand (tridge) */
2005 /* if its an older server then we have to use the older request format */
2007 if (cli_state_protocol(cli) < PROTOCOL_NT1) {
2008 if (!lp_client_lanman_auth() && passlen != 24 && (*pass)) {
2009 DEBUG(1, ("Server requested LM password but 'client lanman auth = no'"
2010 " or 'client ntlmv2 auth = yes'\n"));
2011 return NT_STATUS_ACCESS_DENIED;
2014 if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0 &&
2015 !lp_client_plaintext_auth() && (*pass)) {
2016 DEBUG(1, ("Server requested LM password but 'client plaintext auth = no'"
2017 " or 'client ntlmv2 auth = yes'\n"));
2018 return NT_STATUS_ACCESS_DENIED;
2021 return cli_session_setup_lanman2(cli, user, pass, passlen,
2025 /* if no user is supplied then we have to do an anonymous connection.
2026 passwords are ignored */
2028 if (!user || !*user)
2029 return cli_session_setup_guest(cli);
2031 /* if the server is share level then send a plaintext null
2032 password at this point. The password is sent in the tree
2035 if ((sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0)
2036 return cli_session_setup_plain(cli, user, "", workgroup);
2038 /* if the server doesn't support encryption then we have to use
2039 plaintext. The second password is ignored */
2041 if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) {
2042 if (!lp_client_plaintext_auth() && (*pass)) {
2043 DEBUG(1, ("Server requested LM password but 'client plaintext auth = no'"
2044 " or 'client ntlmv2 auth = yes'\n"));
2045 return NT_STATUS_ACCESS_DENIED;
2047 return cli_session_setup_plain(cli, user, pass, workgroup);
2050 /* if the server supports extended security then use SPNEGO */
2052 if (cli_state_capabilities(cli) & CAP_EXTENDED_SECURITY) {
2053 const char *remote_realm = cli_state_remote_realm(cli);
2054 ADS_STATUS status = cli_session_setup_spnego(cli, user, pass,
2057 if (!ADS_ERR_OK(status)) {
2058 DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status)));
2059 return ads_ntstatus(status);
2064 /* otherwise do a NT1 style session setup */
2065 status = cli_session_setup_nt1(cli, user, pass, passlen,
2066 ntpass, ntpasslen, workgroup);
2067 if (!NT_STATUS_IS_OK(status)) {
2068 DEBUG(3,("cli_session_setup: NT1 session setup "
2069 "failed: %s\n", nt_errstr(status)));
2074 return NT_STATUS_OK;
2077 /****************************************************************************
2079 *****************************************************************************/
2081 struct cli_ulogoff_state {
2082 struct cli_state *cli;
2086 static void cli_ulogoff_done(struct tevent_req *subreq);
2088 struct tevent_req *cli_ulogoff_send(TALLOC_CTX *mem_ctx,
2089 struct tevent_context *ev,
2090 struct cli_state *cli)
2092 struct tevent_req *req, *subreq;
2093 struct cli_ulogoff_state *state;
2095 req = tevent_req_create(mem_ctx, &state, struct cli_ulogoff_state);
2101 SCVAL(state->vwv+0, 0, 0xFF);
2102 SCVAL(state->vwv+1, 0, 0);
2103 SSVAL(state->vwv+2, 0, 0);
2105 subreq = cli_smb_send(state, ev, cli, SMBulogoffX, 0, 2, state->vwv,
2107 if (tevent_req_nomem(subreq, req)) {
2108 return tevent_req_post(req, ev);
2110 tevent_req_set_callback(subreq, cli_ulogoff_done, req);
2114 static void cli_ulogoff_done(struct tevent_req *subreq)
2116 struct tevent_req *req = tevent_req_callback_data(
2117 subreq, struct tevent_req);
2118 struct cli_ulogoff_state *state = tevent_req_data(
2119 req, struct cli_ulogoff_state);
2122 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
2123 if (!NT_STATUS_IS_OK(status)) {
2124 tevent_req_nterror(req, status);
2127 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
2128 tevent_req_done(req);
2131 NTSTATUS cli_ulogoff_recv(struct tevent_req *req)
2133 return tevent_req_simple_recv_ntstatus(req);
2136 NTSTATUS cli_ulogoff(struct cli_state *cli)
2138 struct tevent_context *ev;
2139 struct tevent_req *req;
2140 NTSTATUS status = NT_STATUS_NO_MEMORY;
2142 if (cli_has_async_calls(cli)) {
2143 return NT_STATUS_INVALID_PARAMETER;
2145 ev = tevent_context_init(talloc_tos());
2149 req = cli_ulogoff_send(ev, ev, cli);
2153 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2156 status = cli_ulogoff_recv(req);
2162 /****************************************************************************
2164 ****************************************************************************/
2166 struct cli_tcon_andx_state {
2167 struct cli_state *cli;
2172 static void cli_tcon_andx_done(struct tevent_req *subreq);
2174 struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx,
2175 struct event_context *ev,
2176 struct cli_state *cli,
2177 const char *share, const char *dev,
2178 const char *pass, int passlen,
2179 struct tevent_req **psmbreq)
2181 struct tevent_req *req, *subreq;
2182 struct cli_tcon_andx_state *state;
2187 uint16_t sec_mode = cli_state_security_mode(cli);
2191 req = tevent_req_create(mem_ctx, &state, struct cli_tcon_andx_state);
2198 cli->share = talloc_strdup(cli, share);
2203 /* in user level security don't send a password now */
2204 if (sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {
2207 } else if (pass == NULL) {
2208 DEBUG(1, ("Server not using user level security and no "
2209 "password supplied.\n"));
2213 if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) &&
2214 *pass && passlen != 24) {
2215 if (!lp_client_lanman_auth()) {
2216 DEBUG(1, ("Server requested LANMAN password "
2217 "(share-level security) but "
2218 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2223 * Non-encrypted passwords - convert to DOS codepage before
2226 SMBencrypt(pass, cli->secblob.data, p24);
2228 pass = (const char *)p24;
2230 if((sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL
2231 |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE))
2235 if (!lp_client_plaintext_auth() && (*pass)) {
2236 DEBUG(1, ("Server requested plaintext "
2238 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2243 * Non-encrypted passwords - convert to DOS codepage
2246 tmp_pass = talloc_array(talloc_tos(), uint8, 0);
2247 if (tevent_req_nomem(tmp_pass, req)) {
2248 return tevent_req_post(req, ev);
2250 tmp_pass = trans2_bytes_push_str(tmp_pass,
2251 false, /* always DOS */
2255 if (tevent_req_nomem(tmp_pass, req)) {
2256 return tevent_req_post(req, ev);
2258 pass = (const char *)tmp_pass;
2259 passlen = talloc_get_size(tmp_pass);
2263 SCVAL(vwv+0, 0, 0xFF);
2266 SSVAL(vwv+2, 0, TCONX_FLAG_EXTENDED_RESPONSE);
2267 SSVAL(vwv+3, 0, passlen);
2269 if (passlen && pass) {
2270 bytes = (uint8_t *)talloc_memdup(state, pass, passlen);
2272 bytes = talloc_array(state, uint8_t, 0);
2278 tmp = talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
2279 cli_state_remote_name(cli), share);
2284 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), tmp, strlen(tmp)+1,
2289 * Add the devicetype
2291 tmp = talloc_strdup_upper(talloc_tos(), dev);
2296 bytes = smb_bytes_push_str(bytes, false, tmp, strlen(tmp)+1, NULL);
2299 if (bytes == NULL) {
2304 state->bytes.iov_base = (void *)bytes;
2305 state->bytes.iov_len = talloc_get_size(bytes);
2307 subreq = cli_smb_req_create(state, ev, cli, SMBtconX, 0, 4, vwv,
2309 if (subreq == NULL) {
2313 tevent_req_set_callback(subreq, cli_tcon_andx_done, req);
2318 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
2319 return tevent_req_post(req, ev);
2322 struct tevent_req *cli_tcon_andx_send(TALLOC_CTX *mem_ctx,
2323 struct event_context *ev,
2324 struct cli_state *cli,
2325 const char *share, const char *dev,
2326 const char *pass, int passlen)
2328 struct tevent_req *req, *subreq;
2331 req = cli_tcon_andx_create(mem_ctx, ev, cli, share, dev, pass, passlen,
2336 if (subreq == NULL) {
2339 status = cli_smb_req_send(subreq);
2340 if (!NT_STATUS_IS_OK(status)) {
2341 tevent_req_nterror(req, status);
2342 return tevent_req_post(req, ev);
2347 static void cli_tcon_andx_done(struct tevent_req *subreq)
2349 struct tevent_req *req = tevent_req_callback_data(
2350 subreq, struct tevent_req);
2351 struct cli_tcon_andx_state *state = tevent_req_data(
2352 req, struct cli_tcon_andx_state);
2353 struct cli_state *cli = state->cli;
2362 status = cli_smb_recv(subreq, state, &in, 0, &wct, &vwv,
2363 &num_bytes, &bytes);
2364 TALLOC_FREE(subreq);
2365 if (!NT_STATUS_IS_OK(status)) {
2366 tevent_req_nterror(req, status);
2373 if (clistr_pull_talloc(cli,
2375 SVAL(inbuf, smb_flg2),
2379 STR_TERMINATE|STR_ASCII) == -1) {
2380 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2384 cli->dev = talloc_strdup(cli, "");
2385 if (cli->dev == NULL) {
2386 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2391 if ((cli_state_protocol(cli) >= PROTOCOL_NT1) && (num_bytes == 3)) {
2392 /* almost certainly win95 - enable bug fixes */
2397 * Make sure that we have the optional support 16-bit field. WCT > 2.
2398 * Avoids issues when connecting to Win9x boxes sharing files
2401 cli->dfsroot = false;
2403 if ((wct > 2) && (cli_state_protocol(cli) >= PROTOCOL_LANMAN2)) {
2404 cli->dfsroot = ((SVAL(vwv+2, 0) & SMB_SHARE_IN_DFS) != 0);
2407 cli->smb1.tid = SVAL(inbuf,smb_tid);
2408 tevent_req_done(req);
2411 NTSTATUS cli_tcon_andx_recv(struct tevent_req *req)
2413 return tevent_req_simple_recv_ntstatus(req);
2416 NTSTATUS cli_tcon_andx(struct cli_state *cli, const char *share,
2417 const char *dev, const char *pass, int passlen)
2419 TALLOC_CTX *frame = talloc_stackframe();
2420 struct event_context *ev;
2421 struct tevent_req *req;
2422 NTSTATUS status = NT_STATUS_OK;
2424 if (cli_has_async_calls(cli)) {
2426 * Can't use sync call while an async call is in flight
2428 status = NT_STATUS_INVALID_PARAMETER;
2432 ev = event_context_init(frame);
2434 status = NT_STATUS_NO_MEMORY;
2438 req = cli_tcon_andx_send(frame, ev, cli, share, dev, pass, passlen);
2440 status = NT_STATUS_NO_MEMORY;
2444 if (!tevent_req_poll(req, ev)) {
2445 status = map_nt_error_from_unix(errno);
2449 status = cli_tcon_andx_recv(req);
2455 /****************************************************************************
2456 Send a tree disconnect.
2457 ****************************************************************************/
2459 struct cli_tdis_state {
2460 struct cli_state *cli;
2463 static void cli_tdis_done(struct tevent_req *subreq);
2465 struct tevent_req *cli_tdis_send(TALLOC_CTX *mem_ctx,
2466 struct tevent_context *ev,
2467 struct cli_state *cli)
2469 struct tevent_req *req, *subreq;
2470 struct cli_tdis_state *state;
2472 req = tevent_req_create(mem_ctx, &state, struct cli_tdis_state);
2478 subreq = cli_smb_send(state, ev, cli, SMBtdis, 0, 0, NULL, 0, NULL);
2479 if (tevent_req_nomem(subreq, req)) {
2480 return tevent_req_post(req, ev);
2482 tevent_req_set_callback(subreq, cli_tdis_done, req);
2486 static void cli_tdis_done(struct tevent_req *subreq)
2488 struct tevent_req *req = tevent_req_callback_data(
2489 subreq, struct tevent_req);
2490 struct cli_tdis_state *state = tevent_req_data(
2491 req, struct cli_tdis_state);
2494 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
2495 TALLOC_FREE(subreq);
2496 if (!NT_STATUS_IS_OK(status)) {
2497 tevent_req_nterror(req, status);
2500 state->cli->smb1.tid = UINT16_MAX;
2501 tevent_req_done(req);
2504 NTSTATUS cli_tdis_recv(struct tevent_req *req)
2506 return tevent_req_simple_recv_ntstatus(req);
2509 NTSTATUS cli_tdis(struct cli_state *cli)
2511 struct tevent_context *ev;
2512 struct tevent_req *req;
2513 NTSTATUS status = NT_STATUS_NO_MEMORY;
2515 if (cli_has_async_calls(cli)) {
2516 return NT_STATUS_INVALID_PARAMETER;
2518 ev = tevent_context_init(talloc_tos());
2522 req = cli_tdis_send(ev, ev, cli);
2526 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2529 status = cli_tdis_recv(req);
2535 /****************************************************************************
2536 Send a negprot command.
2537 ****************************************************************************/
2539 struct cli_negprot_state {
2540 struct cli_state *cli;
2541 enum protocol_types max_protocol;
2544 static void cli_negprot_done(struct tevent_req *subreq);
2546 struct tevent_req *cli_negprot_send(TALLOC_CTX *mem_ctx,
2547 struct event_context *ev,
2548 struct cli_state *cli,
2549 enum protocol_types max_protocol)
2551 struct tevent_req *req, *subreq;
2552 struct cli_negprot_state *state;
2553 uint8_t *bytes = NULL;
2555 enum protocol_types tmp_protocol;
2557 req = tevent_req_create(mem_ctx, &state, struct cli_negprot_state);
2562 state->max_protocol = max_protocol;
2564 /* setup the protocol strings */
2565 for (numprots=0; numprots < ARRAY_SIZE(prots); numprots++) {
2567 if (prots[numprots].prot > state->max_protocol) {
2570 bytes = (uint8_t *)talloc_append_blob(
2571 state, bytes, data_blob_const(&c, sizeof(c)));
2572 if (tevent_req_nomem(bytes, req)) {
2573 return tevent_req_post(req, ev);
2575 bytes = smb_bytes_push_str(bytes, false,
2576 prots[numprots].name,
2577 strlen(prots[numprots].name)+1,
2579 if (tevent_req_nomem(bytes, req)) {
2580 return tevent_req_post(req, ev);
2584 tmp_protocol = cli->conn.protocol;
2585 cli->conn.protocol = state->max_protocol;
2586 subreq = cli_smb_send(state, ev, cli, SMBnegprot, 0, 0, NULL,
2587 talloc_get_size(bytes), bytes);
2588 cli->conn.protocol = tmp_protocol;
2589 if (tevent_req_nomem(subreq, req)) {
2590 return tevent_req_post(req, ev);
2592 tevent_req_set_callback(subreq, cli_negprot_done, req);
2596 static void cli_negprot_done(struct tevent_req *subreq)
2598 struct tevent_req *req = tevent_req_callback_data(
2599 subreq, struct tevent_req);
2600 struct cli_negprot_state *state = tevent_req_data(
2601 req, struct cli_negprot_state);
2602 struct cli_state *cli = state->cli;
2610 uint32_t client_capabilities = cli->conn.smb1.client.capabilities;
2611 uint32_t both_capabilities;
2612 uint32_t server_capabilities = 0;
2613 uint32_t capabilities;
2614 enum protocol_types protocol;
2616 status = cli_smb_recv(subreq, state, &inbuf, 1, &wct, &vwv,
2617 &num_bytes, &bytes);
2618 TALLOC_FREE(subreq);
2619 if (!NT_STATUS_IS_OK(status)) {
2620 tevent_req_nterror(req, status);
2624 protnum = SVAL(vwv, 0);
2626 if ((protnum >= ARRAY_SIZE(prots))
2627 || (prots[protnum].prot > state->max_protocol)) {
2628 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2632 protocol = prots[protnum].prot;
2634 if ((protocol < PROTOCOL_NT1) &&
2635 client_is_signing_mandatory(cli)) {
2636 DEBUG(0,("cli_negprot: SMB signing is mandatory and the selected protocol level doesn't support it.\n"));
2637 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
2641 if (protocol >= PROTOCOL_NT1) {
2643 const char *client_signing = NULL;
2644 bool server_mandatory;
2645 bool server_allowed;
2646 const char *server_signing = NULL;
2650 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2655 cli->sec_mode = CVAL(vwv + 1, 0);
2656 cli->max_mux = SVAL(vwv + 1, 1);
2657 cli->max_xmit = IVAL(vwv + 3, 1);
2658 cli->sesskey = IVAL(vwv + 7, 1);
2659 cli->serverzone = SVALS(vwv + 15, 1);
2660 cli->serverzone *= 60;
2661 /* this time arrives in real GMT */
2662 ts = interpret_long_date(((char *)(vwv+11))+1);
2663 cli->servertime = ts.tv_sec;
2664 cli->secblob = data_blob(bytes, num_bytes);
2665 server_capabilities = IVAL(vwv + 9, 1);
2666 if (server_capabilities & CAP_RAW_MODE) {
2667 cli->readbraw_supported = True;
2668 cli->writebraw_supported = True;
2670 /* work out if they sent us a workgroup */
2671 if (!(server_capabilities & CAP_EXTENDED_SECURITY) &&
2672 smb_buflen(inbuf) > 8) {
2674 status = smb_bytes_talloc_string(
2675 cli, (char *)inbuf, &cli->server_domain,
2676 bytes + 8, num_bytes - 8, &ret);
2677 if (tevent_req_nterror(req, status)) {
2682 client_signing = "disabled";
2683 if (client_is_signing_allowed(cli)) {
2684 client_signing = "allowed";
2686 if (client_is_signing_mandatory(cli)) {
2687 client_signing = "required";
2690 server_signing = "not supported";
2691 if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) {
2692 server_signing = "supported";
2693 server_allowed = true;
2695 if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) {
2696 server_signing = "required";
2697 server_mandatory = true;
2700 ok = cli_set_signing_negotiated(cli,
2704 DEBUG(1,("cli_negprot: SMB signing is required, "
2705 "but client[%s] and server[%s] mismatch\n",
2706 client_signing, server_signing));
2707 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
2711 } else if (protocol >= PROTOCOL_LANMAN1) {
2713 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2717 cli->sec_mode = SVAL(vwv + 1, 0);
2718 cli->max_xmit = SVAL(vwv + 2, 0);
2719 cli->max_mux = SVAL(vwv + 3, 0);
2720 cli->sesskey = IVAL(vwv + 6, 0);
2721 cli->serverzone = SVALS(vwv + 10, 0);
2722 cli->serverzone *= 60;
2723 /* this time is converted to GMT by make_unix_date */
2724 cli->servertime = make_unix_date(
2725 (char *)(vwv + 8), cli->serverzone);
2726 cli->readbraw_supported = ((SVAL(vwv + 5, 0) & 0x1) != 0);
2727 cli->writebraw_supported = ((SVAL(vwv + 5, 0) & 0x2) != 0);
2728 cli->secblob = data_blob(bytes, num_bytes);
2730 /* the old core protocol */
2732 cli->serverzone = get_time_zone(time(NULL));
2733 cli->max_xmit = 1024;
2737 if (cli->max_xmit < 1024) {
2738 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2742 if (cli->max_mux < 1) {
2743 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2747 cli->max_xmit = MIN(cli->max_xmit, CLI_BUFFER_SIZE);
2750 * Now calculate the negotiated capabilities
2751 * based on the mask for:
2752 * - client only flags
2753 * - flags used in both directions
2754 * - server only flags
2756 both_capabilities = client_capabilities & server_capabilities;
2757 capabilities = client_capabilities & SMB_CAP_CLIENT_MASK;
2758 capabilities |= both_capabilities & SMB_CAP_BOTH_MASK;
2759 capabilities |= server_capabilities & SMB_CAP_SERVER_MASK;
2761 cli->conn.protocol = protocol;
2763 cli->conn.smb1.server.capabilities = server_capabilities;
2764 cli->conn.smb1.capabilities = capabilities;
2766 tevent_req_done(req);
2769 NTSTATUS cli_negprot_recv(struct tevent_req *req)
2771 return tevent_req_simple_recv_ntstatus(req);
2774 NTSTATUS cli_negprot(struct cli_state *cli, enum protocol_types max_protocol)
2776 TALLOC_CTX *frame = talloc_stackframe();
2777 struct event_context *ev;
2778 struct tevent_req *req;
2779 NTSTATUS status = NT_STATUS_OK;
2781 if (cli_has_async_calls(cli)) {
2783 * Can't use sync call while an async call is in flight
2785 status = NT_STATUS_INVALID_PARAMETER;
2789 ev = event_context_init(frame);
2791 status = NT_STATUS_NO_MEMORY;
2795 req = cli_negprot_send(frame, ev, cli, max_protocol);
2797 status = NT_STATUS_NO_MEMORY;
2801 if (!tevent_req_poll(req, ev)) {
2802 status = map_nt_error_from_unix(errno);
2806 status = cli_negprot_recv(req);
2812 static NTSTATUS cli_connect_sock(const char *host, int name_type,
2813 const struct sockaddr_storage *pss,
2814 const char *myname, uint16_t port,
2815 int sec_timeout, int *pfd, uint16_t *pport)
2817 TALLOC_CTX *frame = talloc_stackframe();
2819 unsigned int i, num_addrs;
2820 const char **called_names;
2821 const char **calling_names;
2826 prog = getenv("LIBSMB_PROG");
2828 fd = sock_exec(prog);
2830 return map_nt_error_from_unix(errno);
2836 if ((pss == NULL) || is_zero_addr(pss)) {
2837 struct sockaddr_storage *addrs;
2838 status = resolve_name_list(talloc_tos(), host, name_type,
2839 &addrs, &num_addrs);
2840 if (!NT_STATUS_IS_OK(status)) {
2848 called_names = talloc_array(talloc_tos(), const char *, num_addrs);
2849 if (called_names == NULL) {
2850 status = NT_STATUS_NO_MEMORY;
2853 called_types = talloc_array(talloc_tos(), int, num_addrs);
2854 if (called_types == NULL) {
2855 status = NT_STATUS_NO_MEMORY;
2858 calling_names = talloc_array(talloc_tos(), const char *, num_addrs);
2859 if (calling_names == NULL) {
2860 status = NT_STATUS_NO_MEMORY;
2863 for (i=0; i<num_addrs; i++) {
2864 called_names[i] = host;
2865 called_types[i] = name_type;
2866 calling_names[i] = myname;
2868 status = smbsock_any_connect(pss, called_names, called_types,
2869 calling_names, NULL, num_addrs, port,
2870 sec_timeout, &fd, NULL, &port);
2871 if (!NT_STATUS_IS_OK(status)) {
2874 set_socket_options(fd, lp_socket_options());
2878 status = NT_STATUS_OK;
2884 NTSTATUS cli_connect_nb(const char *host, const struct sockaddr_storage *dest_ss,
2885 uint16_t port, int name_type, const char *myname,
2886 int signing_state, int flags, struct cli_state **pcli)
2888 TALLOC_CTX *frame = talloc_stackframe();
2889 struct cli_state *cli;
2890 NTSTATUS status = NT_STATUS_NO_MEMORY;
2895 desthost = talloc_strdup(talloc_tos(), host);
2896 if (desthost == NULL) {
2900 p = strchr(host, '#');
2902 name_type = strtol(p+1, NULL, 16);
2903 host = talloc_strndup(talloc_tos(), host, p - host);
2909 status = cli_connect_sock(host, name_type, dest_ss, myname, port,
2911 if (!NT_STATUS_IS_OK(status)) {
2915 cli = cli_state_create(NULL, fd, desthost, NULL, signing_state, flags);
2921 status = NT_STATUS_OK;
2928 establishes a connection to after the negprot.
2929 @param output_cli A fully initialised cli structure, non-null only on success
2930 @param dest_host The netbios name of the remote host
2931 @param dest_ss (optional) The the destination IP, NULL for name based lookup
2932 @param port (optional) The destination port (0 for default)
2934 NTSTATUS cli_start_connection(struct cli_state **output_cli,
2935 const char *my_name,
2936 const char *dest_host,
2937 const struct sockaddr_storage *dest_ss, int port,
2938 int signing_state, int flags)
2941 struct cli_state *cli;
2943 nt_status = cli_connect_nb(dest_host, dest_ss, port, 0x20, my_name,
2944 signing_state, flags, &cli);
2945 if (!NT_STATUS_IS_OK(nt_status)) {
2946 DEBUG(10, ("cli_connect_nb failed: %s\n",
2947 nt_errstr(nt_status)));
2951 nt_status = cli_negprot(cli, PROTOCOL_NT1);
2952 if (!NT_STATUS_IS_OK(nt_status)) {
2953 DEBUG(1, ("failed negprot: %s\n", nt_errstr(nt_status)));
2959 return NT_STATUS_OK;
2964 establishes a connection right up to doing tconX, password specified.
2965 @param output_cli A fully initialised cli structure, non-null only on success
2966 @param dest_host The netbios name of the remote host
2967 @param dest_ip (optional) The the destination IP, NULL for name based lookup
2968 @param port (optional) The destination port (0 for default)
2969 @param service (optional) The share to make the connection to. Should be 'unqualified' in any way.
2970 @param service_type The 'type' of serivice.
2971 @param user Username, unix string
2972 @param domain User's domain
2973 @param password User's password, unencrypted unix string.
2976 NTSTATUS cli_full_connection(struct cli_state **output_cli,
2977 const char *my_name,
2978 const char *dest_host,
2979 const struct sockaddr_storage *dest_ss, int port,
2980 const char *service, const char *service_type,
2981 const char *user, const char *domain,
2982 const char *password, int flags,
2986 struct cli_state *cli = NULL;
2987 int pw_len = password ? strlen(password)+1 : 0;
2991 if (password == NULL) {
2995 nt_status = cli_start_connection(&cli, my_name, dest_host,
2996 dest_ss, port, signing_state,
2999 if (!NT_STATUS_IS_OK(nt_status)) {
3003 nt_status = cli_session_setup(cli, user, password, pw_len, password,
3005 if (!NT_STATUS_IS_OK(nt_status)) {
3007 if (!(flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)) {
3008 DEBUG(1,("failed session setup with %s\n",
3009 nt_errstr(nt_status)));
3014 nt_status = cli_session_setup(cli, "", "", 0, "", 0, domain);
3015 if (!NT_STATUS_IS_OK(nt_status)) {
3016 DEBUG(1,("anonymous failed session setup with %s\n",
3017 nt_errstr(nt_status)));
3024 nt_status = cli_tcon_andx(cli, service, service_type, password,
3026 if (!NT_STATUS_IS_OK(nt_status)) {
3027 DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status)));
3029 if (NT_STATUS_IS_OK(nt_status)) {
3030 nt_status = NT_STATUS_UNSUCCESSFUL;
3036 nt_status = cli_init_creds(cli, user, domain, password);
3037 if (!NT_STATUS_IS_OK(nt_status)) {
3043 return NT_STATUS_OK;
3046 /****************************************************************************
3047 Send an old style tcon.
3048 ****************************************************************************/
3049 NTSTATUS cli_raw_tcon(struct cli_state *cli,
3050 const char *service, const char *pass, const char *dev,
3051 uint16 *max_xmit, uint16 *tid)
3053 struct tevent_req *req;
3058 if (!lp_client_plaintext_auth() && (*pass)) {
3059 DEBUG(1, ("Server requested plaintext password but 'client "
3060 "plaintext auth' is disabled\n"));
3061 return NT_STATUS_ACCESS_DENIED;
3064 bytes = talloc_array(talloc_tos(), uint8_t, 0);
3065 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3066 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
3067 service, strlen(service)+1, NULL);
3068 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3069 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
3070 pass, strlen(pass)+1, NULL);
3071 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3072 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
3073 dev, strlen(dev)+1, NULL);
3075 status = cli_smb(talloc_tos(), cli, SMBtcon, 0, 0, NULL,
3076 talloc_get_size(bytes), bytes, &req,
3077 2, NULL, &ret_vwv, NULL, NULL);
3078 if (!NT_STATUS_IS_OK(status)) {
3082 *max_xmit = SVAL(ret_vwv + 0, 0);
3083 *tid = SVAL(ret_vwv + 1, 0);
3085 return NT_STATUS_OK;
3088 /* Return a cli_state pointing at the IPC$ share for the given server */
3090 struct cli_state *get_ipc_connect(char *server,
3091 struct sockaddr_storage *server_ss,
3092 const struct user_auth_info *user_info)
3094 struct cli_state *cli;
3096 uint32_t flags = CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
3098 if (user_info->use_kerberos) {
3099 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
3102 nt_status = cli_full_connection(&cli, NULL, server, server_ss, 0, "IPC$", "IPC",
3103 user_info->username ? user_info->username : "",
3105 user_info->password ? user_info->password : "",
3109 if (NT_STATUS_IS_OK(nt_status)) {
3111 } else if (is_ipaddress(server)) {
3112 /* windows 9* needs a correct NMB name for connections */
3113 fstring remote_name;
3115 if (name_status_find("*", 0, 0, server_ss, remote_name)) {
3116 cli = get_ipc_connect(remote_name, server_ss, user_info);
3125 * Given the IP address of a master browser on the network, return its
3126 * workgroup and connect to it.
3128 * This function is provided to allow additional processing beyond what
3129 * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
3130 * browsers and obtain each master browsers' list of domains (in case the
3131 * first master browser is recently on the network and has not yet
3132 * synchronized with other master browsers and therefore does not yet have the
3133 * entire network browse list)
3136 struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx,
3137 struct sockaddr_storage *mb_ip,
3138 const struct user_auth_info *user_info,
3139 char **pp_workgroup_out)
3141 char addr[INET6_ADDRSTRLEN];
3143 struct cli_state *cli;
3144 struct sockaddr_storage server_ss;
3146 *pp_workgroup_out = NULL;
3148 print_sockaddr(addr, sizeof(addr), mb_ip);
3149 DEBUG(99, ("Looking up name of master browser %s\n",
3153 * Do a name status query to find out the name of the master browser.
3154 * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
3155 * master browser will not respond to a wildcard query (or, at least,
3156 * an NT4 server acting as the domain master browser will not).
3158 * We might be able to use ONLY the query on MSBROWSE, but that's not
3159 * yet been tested with all Windows versions, so until it is, leave
3160 * the original wildcard query as the first choice and fall back to
3161 * MSBROWSE if the wildcard query fails.
3163 if (!name_status_find("*", 0, 0x1d, mb_ip, name) &&
3164 !name_status_find(MSBROWSE, 1, 0x1d, mb_ip, name)) {
3166 DEBUG(99, ("Could not retrieve name status for %s\n",
3171 if (!find_master_ip(name, &server_ss)) {
3172 DEBUG(99, ("Could not find master ip for %s\n", name));
3176 *pp_workgroup_out = talloc_strdup(ctx, name);
3178 DEBUG(4, ("found master browser %s, %s\n", name, addr));
3180 print_sockaddr(addr, sizeof(addr), &server_ss);
3181 cli = get_ipc_connect(addr, &server_ss, user_info);
3187 * Return the IP address and workgroup of a master browser on the network, and
3191 struct cli_state *get_ipc_connect_master_ip_bcast(TALLOC_CTX *ctx,
3192 const struct user_auth_info *user_info,
3193 char **pp_workgroup_out)
3195 struct sockaddr_storage *ip_list;
3196 struct cli_state *cli;
3200 *pp_workgroup_out = NULL;
3202 DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
3204 /* Go looking for workgroups by broadcasting on the local network */
3206 status = name_resolve_bcast(MSBROWSE, 1, talloc_tos(),
3208 if (!NT_STATUS_IS_OK(status)) {
3209 DEBUG(99, ("No master browsers responded: %s\n",
3210 nt_errstr(status)));
3214 for (i = 0; i < count; i++) {
3215 char addr[INET6_ADDRSTRLEN];
3216 print_sockaddr(addr, sizeof(addr), &ip_list[i]);
3217 DEBUG(99, ("Found master browser %s\n", addr));
3219 cli = get_ipc_connect_master_ip(ctx, &ip_list[i],
3220 user_info, pp_workgroup_out);