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 if (strstr(cli->server_type, "Samba")) {
321 cli->is_samba = True;
323 status = cli_set_username(cli, state->user);
324 if (tevent_req_nterror(req, status)) {
327 tevent_req_done(req);
330 static NTSTATUS cli_session_setup_lanman2_recv(struct tevent_req *req)
332 return tevent_req_simple_recv_ntstatus(req);
335 static NTSTATUS cli_session_setup_lanman2(struct cli_state *cli, const char *user,
336 const char *pass, size_t passlen,
337 const char *workgroup)
339 TALLOC_CTX *frame = talloc_stackframe();
340 struct event_context *ev;
341 struct tevent_req *req;
342 NTSTATUS status = NT_STATUS_NO_MEMORY;
344 if (cli_has_async_calls(cli)) {
346 * Can't use sync call while an async call is in flight
348 status = NT_STATUS_INVALID_PARAMETER;
351 ev = event_context_init(frame);
355 req = cli_session_setup_lanman2_send(frame, ev, cli, user, pass, passlen,
360 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
363 status = cli_session_setup_lanman2_recv(req);
369 /****************************************************************************
370 Work out suitable capabilities to offer the server.
371 ****************************************************************************/
373 static uint32 cli_session_setup_capabilities(struct cli_state *cli)
375 uint32 capabilities = CAP_NT_SMBS;
377 if (!cli->force_dos_errors)
378 capabilities |= CAP_STATUS32;
380 if (cli->use_level_II_oplocks)
381 capabilities |= CAP_LEVEL_II_OPLOCKS;
383 capabilities |= (cli_state_capabilities(cli) & (CAP_UNICODE|CAP_LARGE_FILES|CAP_LARGE_READX|CAP_LARGE_WRITEX|CAP_DFS));
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));
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 if (strstr(cli->server_type, "Samba")) {
549 cli->is_samba = True;
552 status = cli_set_username(cli, "");
553 if (!NT_STATUS_IS_OK(status)) {
554 tevent_req_nterror(req, status);
557 tevent_req_done(req);
560 NTSTATUS cli_session_setup_guest_recv(struct tevent_req *req)
562 return tevent_req_simple_recv_ntstatus(req);
565 static NTSTATUS cli_session_setup_guest(struct cli_state *cli)
567 TALLOC_CTX *frame = talloc_stackframe();
568 struct event_context *ev;
569 struct tevent_req *req;
570 NTSTATUS status = NT_STATUS_OK;
572 if (cli_has_async_calls(cli)) {
574 * Can't use sync call while an async call is in flight
576 status = NT_STATUS_INVALID_PARAMETER;
580 ev = event_context_init(frame);
582 status = NT_STATUS_NO_MEMORY;
586 req = cli_session_setup_guest_send(frame, ev, cli);
588 status = NT_STATUS_NO_MEMORY;
592 if (!tevent_req_poll(req, ev)) {
593 status = map_nt_error_from_unix(errno);
597 status = cli_session_setup_guest_recv(req);
603 /****************************************************************************
604 Do a NT1 plaintext session setup.
605 ****************************************************************************/
607 struct cli_session_setup_plain_state {
608 struct cli_state *cli;
613 static void cli_session_setup_plain_done(struct tevent_req *subreq);
615 static struct tevent_req *cli_session_setup_plain_send(
616 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
617 struct cli_state *cli,
618 const char *user, const char *pass, const char *workgroup)
620 struct tevent_req *req, *subreq;
621 struct cli_session_setup_plain_state *state;
627 req = tevent_req_create(mem_ctx, &state,
628 struct cli_session_setup_plain_state);
636 SCVAL(vwv+0, 0, 0xff);
639 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
641 SSVAL(vwv+4, 0, cli_state_get_vc_num(cli));
642 SIVAL(vwv+5, 0, cli_state_server_session_key(cli));
647 SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli));
649 bytes = talloc_array(state, uint8_t, 0);
650 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), pass, strlen(pass)+1,
652 if (tevent_req_nomem(bytes, req)) {
653 return tevent_req_post(req, ev);
655 SSVAL(vwv + (cli_ucs2(cli) ? 8 : 7), 0, passlen);
657 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
658 user, strlen(user)+1, NULL);
659 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
660 workgroup, strlen(workgroup)+1, NULL);
661 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
664 version = talloc_asprintf(talloc_tos(), "Samba %s",
665 samba_version_string());
666 if (tevent_req_nomem(version, req)){
667 return tevent_req_post(req, ev);
669 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
670 version, strlen(version)+1, NULL);
671 TALLOC_FREE(version);
673 if (tevent_req_nomem(bytes, req)) {
674 return tevent_req_post(req, ev);
677 subreq = cli_smb_send(state, ev, cli, SMBsesssetupX, 0, 13, vwv,
678 talloc_get_size(bytes), bytes);
679 if (tevent_req_nomem(subreq, req)) {
680 return tevent_req_post(req, ev);
682 tevent_req_set_callback(subreq, cli_session_setup_plain_done, req);
686 static void cli_session_setup_plain_done(struct tevent_req *subreq)
688 struct tevent_req *req = tevent_req_callback_data(
689 subreq, struct tevent_req);
690 struct cli_session_setup_plain_state *state = tevent_req_data(
691 req, struct cli_session_setup_plain_state);
692 struct cli_state *cli = state->cli;
703 status = cli_smb_recv(subreq, state, &in, 3, &wct, &vwv,
706 if (tevent_req_nterror(req, status)) {
713 cli_state_set_uid(state->cli, SVAL(inbuf, smb_uid));
714 cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0);
716 status = smb_bytes_talloc_string(cli,
723 if (!NT_STATUS_IS_OK(status)) {
724 tevent_req_nterror(req, status);
729 status = smb_bytes_talloc_string(cli,
736 if (!NT_STATUS_IS_OK(status)) {
737 tevent_req_nterror(req, status);
742 status = smb_bytes_talloc_string(cli,
749 if (!NT_STATUS_IS_OK(status)) {
750 tevent_req_nterror(req, status);
755 status = cli_set_username(cli, state->user);
756 if (tevent_req_nterror(req, status)) {
759 if (strstr(cli->server_type, "Samba")) {
760 cli->is_samba = True;
762 tevent_req_done(req);
765 static NTSTATUS cli_session_setup_plain_recv(struct tevent_req *req)
767 return tevent_req_simple_recv_ntstatus(req);
770 static NTSTATUS cli_session_setup_plain(struct cli_state *cli,
771 const char *user, const char *pass,
772 const char *workgroup)
774 TALLOC_CTX *frame = talloc_stackframe();
775 struct event_context *ev;
776 struct tevent_req *req;
777 NTSTATUS status = NT_STATUS_NO_MEMORY;
779 if (cli_has_async_calls(cli)) {
781 * Can't use sync call while an async call is in flight
783 status = NT_STATUS_INVALID_PARAMETER;
786 ev = event_context_init(frame);
790 req = cli_session_setup_plain_send(frame, ev, cli, user, pass,
795 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
798 status = cli_session_setup_plain_recv(req);
804 /****************************************************************************
805 do a NT1 NTLM/LM encrypted session setup - for when extended security
807 @param cli client state to create do session setup on
809 @param pass *either* cleartext password (passlen !=24) or LM response.
810 @param ntpass NT response, implies ntpasslen >=24, implies pass is not clear
811 @param workgroup The user's domain.
812 ****************************************************************************/
814 struct cli_session_setup_nt1_state {
815 struct cli_state *cli;
818 DATA_BLOB session_key;
822 static void cli_session_setup_nt1_done(struct tevent_req *subreq);
824 static struct tevent_req *cli_session_setup_nt1_send(
825 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
826 struct cli_state *cli, const char *user,
827 const char *pass, size_t passlen,
828 const char *ntpass, size_t ntpasslen,
829 const char *workgroup)
831 struct tevent_req *req, *subreq;
832 struct cli_session_setup_nt1_state *state;
833 DATA_BLOB lm_response = data_blob_null;
834 DATA_BLOB nt_response = data_blob_null;
835 DATA_BLOB session_key = data_blob_null;
838 char *workgroup_upper;
840 req = tevent_req_create(mem_ctx, &state,
841 struct cli_session_setup_nt1_state);
850 /* do nothing - guest login */
851 } else if (passlen != 24) {
852 if (lp_client_ntlmv2_auth()) {
853 DATA_BLOB server_chal;
854 DATA_BLOB names_blob;
856 server_chal = data_blob(cli->secblob.data,
857 MIN(cli->secblob.length, 8));
858 if (tevent_req_nomem(server_chal.data, req)) {
859 return tevent_req_post(req, ev);
863 * note that the 'workgroup' here is a best
864 * guess - we don't know the server's domain
865 * at this point. Windows clients also don't
868 names_blob = NTLMv2_generate_names_blob(
869 NULL, NULL, workgroup);
871 if (tevent_req_nomem(names_blob.data, req)) {
872 return tevent_req_post(req, ev);
875 if (!SMBNTLMv2encrypt(NULL, user, workgroup, pass,
876 &server_chal, &names_blob,
877 &lm_response, &nt_response,
878 NULL, &session_key)) {
879 data_blob_free(&names_blob);
880 data_blob_free(&server_chal);
882 req, NT_STATUS_ACCESS_DENIED);
883 return tevent_req_post(req, ev);
885 data_blob_free(&names_blob);
886 data_blob_free(&server_chal);
890 E_md4hash(pass, nt_hash);
893 nt_response = data_blob_null;
895 nt_response = data_blob(NULL, 24);
896 if (tevent_req_nomem(nt_response.data, req)) {
897 return tevent_req_post(req, ev);
900 SMBNTencrypt(pass, cli->secblob.data,
903 /* non encrypted password supplied. Ignore ntpass. */
904 if (lp_client_lanman_auth()) {
906 lm_response = data_blob(NULL, 24);
907 if (tevent_req_nomem(lm_response.data, req)) {
908 return tevent_req_post(req, ev);
911 if (!SMBencrypt(pass,cli->secblob.data,
914 * Oops, the LM response is
915 * invalid, just put the NT
916 * response there instead
918 data_blob_free(&lm_response);
919 lm_response = data_blob(
925 * LM disabled, place NT# in LM field
928 lm_response = data_blob(
929 nt_response.data, nt_response.length);
932 if (tevent_req_nomem(lm_response.data, req)) {
933 return tevent_req_post(req, ev);
936 session_key = data_blob(NULL, 16);
937 if (tevent_req_nomem(session_key.data, req)) {
938 return tevent_req_post(req, ev);
941 E_deshash(pass, session_key.data);
942 memset(&session_key.data[8], '\0', 8);
944 SMBsesskeygen_ntv1(nt_hash, session_key.data);
948 /* pre-encrypted password supplied. Only used for
949 security=server, can't do
950 signing because we don't have original key */
952 lm_response = data_blob(pass, passlen);
953 if (tevent_req_nomem(lm_response.data, req)) {
954 return tevent_req_post(req, ev);
957 nt_response = data_blob(ntpass, ntpasslen);
958 if (tevent_req_nomem(nt_response.data, req)) {
959 return tevent_req_post(req, ev);
964 state->response = data_blob_talloc(
965 state, lm_response.data, lm_response.length);
967 state->response = data_blob_talloc(
968 state, nt_response.data, nt_response.length);
970 if (tevent_req_nomem(state->response.data, req)) {
971 return tevent_req_post(req, ev);
974 if (session_key.data) {
975 state->session_key = data_blob_talloc(
976 state, session_key.data, session_key.length);
977 if (tevent_req_nomem(state->session_key.data, req)) {
978 return tevent_req_post(req, ev);
981 data_blob_free(&session_key);
983 SCVAL(vwv+0, 0, 0xff);
986 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
988 SSVAL(vwv+4, 0, cli_state_get_vc_num(cli));
989 SIVAL(vwv+5, 0, cli_state_server_session_key(cli));
990 SSVAL(vwv+7, 0, lm_response.length);
991 SSVAL(vwv+8, 0, nt_response.length);
994 SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli));
996 bytes = talloc_array(state, uint8_t,
997 lm_response.length + nt_response.length);
998 if (tevent_req_nomem(bytes, req)) {
999 return tevent_req_post(req, ev);
1001 if (lm_response.length != 0) {
1002 memcpy(bytes, lm_response.data, lm_response.length);
1004 if (nt_response.length != 0) {
1005 memcpy(bytes + lm_response.length,
1006 nt_response.data, nt_response.length);
1008 data_blob_free(&lm_response);
1009 data_blob_free(&nt_response);
1011 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
1012 user, strlen(user)+1, NULL);
1015 * Upper case here might help some NTLMv2 implementations
1017 workgroup_upper = talloc_strdup_upper(talloc_tos(), workgroup);
1018 if (tevent_req_nomem(workgroup_upper, req)) {
1019 return tevent_req_post(req, ev);
1021 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
1022 workgroup_upper, strlen(workgroup_upper)+1,
1024 TALLOC_FREE(workgroup_upper);
1026 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Unix", 5, NULL);
1027 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Samba", 6, NULL);
1028 if (tevent_req_nomem(bytes, req)) {
1029 return tevent_req_post(req, ev);
1032 subreq = cli_smb_send(state, ev, cli, SMBsesssetupX, 0, 13, vwv,
1033 talloc_get_size(bytes), bytes);
1034 if (tevent_req_nomem(subreq, req)) {
1035 return tevent_req_post(req, ev);
1037 tevent_req_set_callback(subreq, cli_session_setup_nt1_done, req);
1041 static void cli_session_setup_nt1_done(struct tevent_req *subreq)
1043 struct tevent_req *req = tevent_req_callback_data(
1044 subreq, struct tevent_req);
1045 struct cli_session_setup_nt1_state *state = tevent_req_data(
1046 req, struct cli_session_setup_nt1_state);
1047 struct cli_state *cli = state->cli;
1058 status = cli_smb_recv(subreq, state, &in, 3, &wct, &vwv,
1059 &num_bytes, &bytes);
1060 TALLOC_FREE(subreq);
1061 if (!NT_STATUS_IS_OK(status)) {
1062 tevent_req_nterror(req, status);
1069 cli_state_set_uid(state->cli, SVAL(inbuf, smb_uid));
1070 cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0);
1072 status = smb_bytes_talloc_string(cli,
1078 if (!NT_STATUS_IS_OK(status)) {
1079 tevent_req_nterror(req, status);
1084 status = smb_bytes_talloc_string(cli,
1090 if (!NT_STATUS_IS_OK(status)) {
1091 tevent_req_nterror(req, status);
1096 status = smb_bytes_talloc_string(cli,
1098 &cli->server_domain,
1102 if (!NT_STATUS_IS_OK(status)) {
1103 tevent_req_nterror(req, status);
1108 if (strstr(cli->server_type, "Samba")) {
1109 cli->is_samba = True;
1112 status = cli_set_username(cli, state->user);
1113 if (tevent_req_nterror(req, status)) {
1116 if (cli_simple_set_signing(cli, state->session_key, state->response)
1117 && !cli_check_sign_mac(cli, (char *)in, 1)) {
1118 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1121 if (state->session_key.data) {
1122 /* Have plaintext orginal */
1123 cli_set_session_key(cli, state->session_key);
1125 tevent_req_done(req);
1128 static NTSTATUS cli_session_setup_nt1_recv(struct tevent_req *req)
1130 return tevent_req_simple_recv_ntstatus(req);
1133 static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user,
1134 const char *pass, size_t passlen,
1135 const char *ntpass, size_t ntpasslen,
1136 const char *workgroup)
1138 TALLOC_CTX *frame = talloc_stackframe();
1139 struct event_context *ev;
1140 struct tevent_req *req;
1141 NTSTATUS status = NT_STATUS_NO_MEMORY;
1143 if (cli_has_async_calls(cli)) {
1145 * Can't use sync call while an async call is in flight
1147 status = NT_STATUS_INVALID_PARAMETER;
1150 ev = event_context_init(frame);
1154 req = cli_session_setup_nt1_send(frame, ev, cli, user, pass, passlen,
1155 ntpass, ntpasslen, workgroup);
1159 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1162 status = cli_session_setup_nt1_recv(req);
1168 /* The following is calculated from :
1170 * (smb_wcnt * 2) = 24 (smb_wcnt == 12 in cli_session_setup_blob_send() )
1171 * (strlen("Unix") + 1 + strlen("Samba") + 1) * 2 = 22 (unicode strings at
1175 #define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22)
1177 struct cli_sesssetup_blob_state {
1178 struct tevent_context *ev;
1179 struct cli_state *cli;
1181 uint16_t max_blob_size;
1190 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state *state,
1191 struct tevent_req **psubreq);
1192 static void cli_sesssetup_blob_done(struct tevent_req *subreq);
1194 static struct tevent_req *cli_sesssetup_blob_send(TALLOC_CTX *mem_ctx,
1195 struct tevent_context *ev,
1196 struct cli_state *cli,
1199 struct tevent_req *req, *subreq;
1200 struct cli_sesssetup_blob_state *state;
1201 uint32_t usable_space;
1203 req = tevent_req_create(mem_ctx, &state,
1204 struct cli_sesssetup_blob_state);
1212 usable_space = cli_state_available_size(cli,
1213 BASE_SESSSETUP_BLOB_PACKET_SIZE);
1215 if (usable_space == 0) {
1216 DEBUG(1, ("cli_session_setup_blob: cli->max_xmit too small "
1217 "(not possible to send %u bytes)\n",
1218 BASE_SESSSETUP_BLOB_PACKET_SIZE + 1));
1219 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1220 return tevent_req_post(req, ev);
1222 state->max_blob_size = MIN(usable_space, 0xFFFF);
1224 if (!cli_sesssetup_blob_next(state, &subreq)) {
1225 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1226 return tevent_req_post(req, ev);
1228 tevent_req_set_callback(subreq, cli_sesssetup_blob_done, req);
1232 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state *state,
1233 struct tevent_req **psubreq)
1235 struct tevent_req *subreq;
1238 SCVAL(state->vwv+0, 0, 0xFF);
1239 SCVAL(state->vwv+0, 1, 0);
1240 SSVAL(state->vwv+1, 0, 0);
1241 SSVAL(state->vwv+2, 0, CLI_BUFFER_SIZE);
1242 SSVAL(state->vwv+3, 0, 2);
1243 SSVAL(state->vwv+4, 0, 1);
1244 SIVAL(state->vwv+5, 0, 0);
1246 thistime = MIN(state->blob.length, state->max_blob_size);
1247 SSVAL(state->vwv+7, 0, thistime);
1249 SSVAL(state->vwv+8, 0, 0);
1250 SSVAL(state->vwv+9, 0, 0);
1251 SIVAL(state->vwv+10, 0,
1252 cli_session_setup_capabilities(state->cli)
1253 | CAP_EXTENDED_SECURITY);
1255 state->buf = (uint8_t *)talloc_memdup(state, state->blob.data,
1257 if (state->buf == NULL) {
1260 state->blob.data += thistime;
1261 state->blob.length -= thistime;
1263 state->buf = smb_bytes_push_str(state->buf, cli_ucs2(state->cli),
1265 state->buf = smb_bytes_push_str(state->buf, cli_ucs2(state->cli),
1267 if (state->buf == NULL) {
1270 subreq = cli_smb_send(state, state->ev, state->cli, SMBsesssetupX, 0,
1272 talloc_get_size(state->buf), state->buf);
1273 if (subreq == NULL) {
1280 static void cli_sesssetup_blob_done(struct tevent_req *subreq)
1282 struct tevent_req *req = tevent_req_callback_data(
1283 subreq, struct tevent_req);
1284 struct cli_sesssetup_blob_state *state = tevent_req_data(
1285 req, struct cli_sesssetup_blob_state);
1286 struct cli_state *cli = state->cli;
1293 uint16_t blob_length;
1297 status = cli_smb_recv(subreq, state, &inbuf, 4, &wct, &vwv,
1298 &num_bytes, &bytes);
1299 TALLOC_FREE(subreq);
1300 if (!NT_STATUS_IS_OK(status)
1301 && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1302 tevent_req_nterror(req, status);
1306 state->status = status;
1307 TALLOC_FREE(state->buf);
1309 state->inbuf = (char *)inbuf;
1310 cli_state_set_uid(state->cli, SVAL(inbuf, smb_uid));
1311 cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0);
1313 blob_length = SVAL(vwv+3, 0);
1314 if (blob_length > num_bytes) {
1315 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1318 state->ret_blob = data_blob_const(bytes, blob_length);
1320 p = bytes + blob_length;
1322 status = smb_bytes_talloc_string(cli,
1329 if (!NT_STATUS_IS_OK(status)) {
1330 tevent_req_nterror(req, status);
1335 status = smb_bytes_talloc_string(cli,
1342 if (!NT_STATUS_IS_OK(status)) {
1343 tevent_req_nterror(req, status);
1348 status = smb_bytes_talloc_string(cli,
1350 &cli->server_domain,
1355 if (!NT_STATUS_IS_OK(status)) {
1356 tevent_req_nterror(req, status);
1361 if (strstr(cli->server_type, "Samba")) {
1362 cli->is_samba = True;
1365 if (state->blob.length != 0) {
1369 if (!cli_sesssetup_blob_next(state, &subreq)) {
1370 tevent_req_oom(req);
1373 tevent_req_set_callback(subreq, cli_sesssetup_blob_done, req);
1376 tevent_req_done(req);
1379 static NTSTATUS cli_sesssetup_blob_recv(struct tevent_req *req,
1380 TALLOC_CTX *mem_ctx,
1384 struct cli_sesssetup_blob_state *state = tevent_req_data(
1385 req, struct cli_sesssetup_blob_state);
1389 if (tevent_req_is_nterror(req, &status)) {
1390 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
1394 inbuf = talloc_move(mem_ctx, &state->inbuf);
1395 if (pblob != NULL) {
1396 *pblob = state->ret_blob;
1398 if (pinbuf != NULL) {
1401 /* could be NT_STATUS_MORE_PROCESSING_REQUIRED */
1402 return state->status;
1407 /****************************************************************************
1408 Use in-memory credentials cache
1409 ****************************************************************************/
1411 static void use_in_memory_ccache(void) {
1412 setenv(KRB5_ENV_CCNAME, "MEMORY:cliconnect", 1);
1415 /****************************************************************************
1416 Do a spnego/kerberos encrypted session setup.
1417 ****************************************************************************/
1419 struct cli_session_setup_kerberos_state {
1420 struct cli_state *cli;
1421 DATA_BLOB negTokenTarg;
1422 DATA_BLOB session_key_krb5;
1423 ADS_STATUS ads_status;
1426 static void cli_session_setup_kerberos_done(struct tevent_req *subreq);
1428 static struct tevent_req *cli_session_setup_kerberos_send(
1429 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
1430 const char *principal)
1432 struct tevent_req *req, *subreq;
1433 struct cli_session_setup_kerberos_state *state;
1436 DEBUG(2,("Doing kerberos session setup\n"));
1438 req = tevent_req_create(mem_ctx, &state,
1439 struct cli_session_setup_kerberos_state);
1444 state->ads_status = ADS_SUCCESS;
1447 * Ok, this is cheating: spnego_gen_krb5_negTokenInit can block if
1448 * we have to acquire a ticket. To be fixed later :-)
1450 rc = spnego_gen_krb5_negTokenInit(state, principal, 0, &state->negTokenTarg,
1451 &state->session_key_krb5, 0, NULL);
1453 DEBUG(1, ("cli_session_setup_kerberos: "
1454 "spnego_gen_krb5_negTokenInit failed: %s\n",
1455 error_message(rc)));
1456 state->ads_status = ADS_ERROR_KRB5(rc);
1457 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
1458 return tevent_req_post(req, ev);
1462 file_save("negTokenTarg.dat", state->negTokenTarg.data,
1463 state->negTokenTarg.length);
1466 subreq = cli_sesssetup_blob_send(state, ev, cli, state->negTokenTarg);
1467 if (tevent_req_nomem(subreq, req)) {
1468 return tevent_req_post(req, ev);
1470 tevent_req_set_callback(subreq, cli_session_setup_kerberos_done, req);
1474 static void cli_session_setup_kerberos_done(struct tevent_req *subreq)
1476 struct tevent_req *req = tevent_req_callback_data(
1477 subreq, struct tevent_req);
1478 struct cli_session_setup_kerberos_state *state = tevent_req_data(
1479 req, struct cli_session_setup_kerberos_state);
1483 status = cli_sesssetup_blob_recv(subreq, talloc_tos(), NULL, &inbuf);
1484 if (!NT_STATUS_IS_OK(status)) {
1485 TALLOC_FREE(subreq);
1486 tevent_req_nterror(req, status);
1490 cli_set_session_key(state->cli, state->session_key_krb5);
1492 if (cli_simple_set_signing(state->cli, state->session_key_krb5,
1494 && !cli_check_sign_mac(state->cli, inbuf, 1)) {
1495 TALLOC_FREE(subreq);
1496 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1499 TALLOC_FREE(subreq);
1500 tevent_req_done(req);
1503 static ADS_STATUS cli_session_setup_kerberos_recv(struct tevent_req *req)
1505 struct cli_session_setup_kerberos_state *state = tevent_req_data(
1506 req, struct cli_session_setup_kerberos_state);
1509 if (tevent_req_is_nterror(req, &status)) {
1510 return ADS_ERROR_NT(status);
1512 return state->ads_status;
1515 static ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli,
1516 const char *principal)
1518 struct tevent_context *ev;
1519 struct tevent_req *req;
1520 ADS_STATUS status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1522 if (cli_has_async_calls(cli)) {
1523 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1525 ev = tevent_context_init(talloc_tos());
1529 req = cli_session_setup_kerberos_send(ev, ev, cli, principal);
1533 if (!tevent_req_poll(req, ev)) {
1534 status = ADS_ERROR_SYSTEM(errno);
1537 status = cli_session_setup_kerberos_recv(req);
1542 #endif /* HAVE_KRB5 */
1544 /****************************************************************************
1545 Do a spnego/NTLMSSP encrypted session setup.
1546 ****************************************************************************/
1548 struct cli_session_setup_ntlmssp_state {
1549 struct tevent_context *ev;
1550 struct cli_state *cli;
1551 struct ntlmssp_state *ntlmssp_state;
1556 static int cli_session_setup_ntlmssp_state_destructor(
1557 struct cli_session_setup_ntlmssp_state *state)
1559 if (state->ntlmssp_state != NULL) {
1560 TALLOC_FREE(state->ntlmssp_state);
1565 static void cli_session_setup_ntlmssp_done(struct tevent_req *req);
1567 static struct tevent_req *cli_session_setup_ntlmssp_send(
1568 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
1569 const char *user, const char *pass, const char *domain)
1571 struct tevent_req *req, *subreq;
1572 struct cli_session_setup_ntlmssp_state *state;
1575 const char *OIDs_ntlm[] = {OID_NTLMSSP, NULL};
1577 req = tevent_req_create(mem_ctx, &state,
1578 struct cli_session_setup_ntlmssp_state);
1586 state->ntlmssp_state = NULL;
1587 talloc_set_destructor(
1588 state, cli_session_setup_ntlmssp_state_destructor);
1590 status = ntlmssp_client_start(state,
1593 lp_client_ntlmv2_auth(),
1594 &state->ntlmssp_state);
1595 if (!NT_STATUS_IS_OK(status)) {
1598 ntlmssp_want_feature(state->ntlmssp_state,
1599 NTLMSSP_FEATURE_SESSION_KEY);
1600 if (cli->use_ccache) {
1601 ntlmssp_want_feature(state->ntlmssp_state,
1602 NTLMSSP_FEATURE_CCACHE);
1604 status = ntlmssp_set_username(state->ntlmssp_state, user);
1605 if (!NT_STATUS_IS_OK(status)) {
1608 status = ntlmssp_set_domain(state->ntlmssp_state, domain);
1609 if (!NT_STATUS_IS_OK(status)) {
1612 status = ntlmssp_set_password(state->ntlmssp_state, pass);
1613 if (!NT_STATUS_IS_OK(status)) {
1616 status = ntlmssp_update(state->ntlmssp_state, data_blob_null,
1618 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1622 state->blob_out = spnego_gen_negTokenInit(state, OIDs_ntlm, &blob_out, NULL);
1623 data_blob_free(&blob_out);
1625 subreq = cli_sesssetup_blob_send(state, ev, cli, state->blob_out);
1626 if (tevent_req_nomem(subreq, req)) {
1627 return tevent_req_post(req, ev);
1629 tevent_req_set_callback(subreq, cli_session_setup_ntlmssp_done, req);
1632 tevent_req_nterror(req, status);
1633 return tevent_req_post(req, ev);
1636 static void cli_session_setup_ntlmssp_done(struct tevent_req *subreq)
1638 struct tevent_req *req = tevent_req_callback_data(
1639 subreq, struct tevent_req);
1640 struct cli_session_setup_ntlmssp_state *state = tevent_req_data(
1641 req, struct cli_session_setup_ntlmssp_state);
1642 DATA_BLOB blob_in, msg_in, blob_out;
1647 status = cli_sesssetup_blob_recv(subreq, talloc_tos(), &blob_in,
1649 TALLOC_FREE(subreq);
1650 data_blob_free(&state->blob_out);
1652 if (NT_STATUS_IS_OK(status)) {
1653 if (state->cli->server_domain[0] == '\0') {
1654 TALLOC_FREE(state->cli->server_domain);
1655 state->cli->server_domain = talloc_strdup(state->cli,
1656 state->ntlmssp_state->server.netbios_domain);
1657 if (state->cli->server_domain == NULL) {
1658 TALLOC_FREE(subreq);
1659 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1663 cli_set_session_key(
1664 state->cli, state->ntlmssp_state->session_key);
1666 if (cli_simple_set_signing(
1667 state->cli, state->ntlmssp_state->session_key,
1669 && !cli_check_sign_mac(state->cli, inbuf, 1)) {
1670 TALLOC_FREE(subreq);
1671 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1674 TALLOC_FREE(subreq);
1675 TALLOC_FREE(state->ntlmssp_state);
1676 tevent_req_done(req);
1679 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1680 tevent_req_nterror(req, status);
1684 if (blob_in.length == 0) {
1685 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
1689 if ((state->turn == 1)
1690 && NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1691 DATA_BLOB tmp_blob = data_blob_null;
1692 /* the server might give us back two challenges */
1693 parse_ret = spnego_parse_challenge(state, blob_in, &msg_in,
1695 data_blob_free(&tmp_blob);
1697 parse_ret = spnego_parse_auth_response(state, blob_in, status,
1698 OID_NTLMSSP, &msg_in);
1703 DEBUG(3,("Failed to parse auth response\n"));
1704 if (NT_STATUS_IS_OK(status)
1705 || NT_STATUS_EQUAL(status,
1706 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1708 req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1713 status = ntlmssp_update(state->ntlmssp_state, msg_in, &blob_out);
1715 if (!NT_STATUS_IS_OK(status)
1716 && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1717 TALLOC_FREE(subreq);
1718 TALLOC_FREE(state->ntlmssp_state);
1719 tevent_req_nterror(req, status);
1723 state->blob_out = spnego_gen_auth(state, blob_out);
1724 TALLOC_FREE(subreq);
1725 if (tevent_req_nomem(state->blob_out.data, req)) {
1729 subreq = cli_sesssetup_blob_send(state, state->ev, state->cli,
1731 if (tevent_req_nomem(subreq, req)) {
1734 tevent_req_set_callback(subreq, cli_session_setup_ntlmssp_done, req);
1737 static NTSTATUS cli_session_setup_ntlmssp_recv(struct tevent_req *req)
1739 struct cli_session_setup_ntlmssp_state *state = tevent_req_data(
1740 req, struct cli_session_setup_ntlmssp_state);
1743 if (tevent_req_is_nterror(req, &status)) {
1744 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
1747 return NT_STATUS_OK;
1750 static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli,
1755 struct tevent_context *ev;
1756 struct tevent_req *req;
1757 NTSTATUS status = NT_STATUS_NO_MEMORY;
1759 if (cli_has_async_calls(cli)) {
1760 return NT_STATUS_INVALID_PARAMETER;
1762 ev = tevent_context_init(talloc_tos());
1766 req = cli_session_setup_ntlmssp_send(ev, ev, cli, user, pass, domain);
1770 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1773 status = cli_session_setup_ntlmssp_recv(req);
1779 /****************************************************************************
1780 Do a spnego encrypted session setup.
1782 user_domain: The shortname of the domain the user/machine is a member of.
1783 dest_realm: The realm we're connecting to, if NULL we use our default realm.
1784 ****************************************************************************/
1786 static ADS_STATUS cli_session_setup_spnego(struct cli_state *cli,
1789 const char *user_domain,
1790 const char * dest_realm)
1792 char *principal = NULL;
1793 char *OIDs[ASN1_MAX_OIDS];
1796 const char *p = NULL;
1797 char *account = NULL;
1800 DEBUG(3,("Doing spnego session setup (blob length=%lu)\n", (unsigned long)cli->secblob.length));
1802 /* the server might not even do spnego */
1803 if (cli->secblob.length <= 16) {
1804 DEBUG(3,("server didn't supply a full spnego negprot\n"));
1809 file_save("negprot.dat", cli->secblob.data, cli->secblob.length);
1812 /* there is 16 bytes of GUID before the real spnego packet starts */
1813 blob = data_blob(cli->secblob.data+16, cli->secblob.length-16);
1815 /* The server sent us the first part of the SPNEGO exchange in the
1816 * negprot reply. It is WRONG to depend on the principal sent in the
1817 * negprot reply, but right now we do it. If we don't receive one,
1818 * we try to best guess, then fall back to NTLM. */
1819 if (!spnego_parse_negTokenInit(talloc_tos(), blob, OIDs, &principal, NULL) ||
1821 data_blob_free(&blob);
1822 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1824 data_blob_free(&blob);
1826 /* make sure the server understands kerberos */
1827 for (i=0;OIDs[i];i++) {
1829 DEBUG(3,("got OID=%s\n", OIDs[i]));
1831 DEBUGADD(3,("got OID=%s\n", OIDs[i]));
1832 if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0 ||
1833 strcmp(OIDs[i], OID_KERBEROS5) == 0) {
1834 cli->got_kerberos_mechanism = True;
1836 talloc_free(OIDs[i]);
1839 DEBUG(3,("got principal=%s\n", principal ? principal : "<null>"));
1841 status = cli_set_username(cli, user);
1842 if (!NT_STATUS_IS_OK(status)) {
1843 TALLOC_FREE(principal);
1844 return ADS_ERROR_NT(status);
1848 /* If password is set we reauthenticate to kerberos server
1849 * and do not store results */
1851 if (cli->got_kerberos_mechanism && cli->use_kerberos) {
1853 const char *remote_name = cli_state_remote_name(cli);
1855 if (pass && *pass) {
1858 use_in_memory_ccache();
1859 ret = kerberos_kinit_password(user, pass, 0 /* no time correction for now */, NULL);
1862 TALLOC_FREE(principal);
1863 DEBUG(0, ("Kinit failed: %s\n", error_message(ret)));
1864 if (cli->fallback_after_kerberos)
1866 return ADS_ERROR_KRB5(ret);
1870 /* We may not be allowed to use the server-supplied SPNEGO principal, or it may not have been supplied to us
1872 if (!lp_client_use_spnego_principal() || strequal(principal, ADS_IGNORE_PRINCIPAL)) {
1873 TALLOC_FREE(principal);
1876 if (principal == NULL &&
1877 !is_ipaddress(remote_name) &&
1878 !strequal(STAR_SMBSERVER,
1882 DEBUG(3,("cli_session_setup_spnego: using target "
1883 "hostname not SPNEGO principal\n"));
1885 host = strchr_m(remote_name, '.');
1887 realm = SMB_STRDUP(dest_realm);
1889 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1895 realm = kerberos_get_realm_from_hostname(remote_name);
1897 /* NetBIOS name - use our realm. */
1898 realm = kerberos_get_default_realm_from_ccache();
1902 if (realm == NULL || *realm == '\0') {
1903 realm = SMB_STRDUP(lp_realm());
1905 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1908 DEBUG(3,("cli_session_setup_spnego: cannot "
1909 "get realm from dest_realm %s, "
1910 "desthost %s. Using default "
1911 "smb.conf realm %s\n",
1912 dest_realm ? dest_realm : "<null>",
1917 principal = talloc_asprintf(talloc_tos(),
1923 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1925 DEBUG(3,("cli_session_setup_spnego: guessed "
1926 "server principal=%s\n",
1927 principal ? principal : "<null>"));
1933 rc = cli_session_setup_kerberos(cli, principal);
1934 if (ADS_ERR_OK(rc) || !cli->fallback_after_kerberos) {
1935 TALLOC_FREE(principal);
1942 TALLOC_FREE(principal);
1946 account = talloc_strdup(talloc_tos(), user);
1948 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1951 /* when falling back to ntlmssp while authenticating with a machine
1952 * account strip off the realm - gd */
1954 if ((p = strchr_m(user, '@')) != NULL) {
1955 account[PTR_DIFF(p,user)] = '\0';
1958 return ADS_ERROR_NT(cli_session_setup_ntlmssp(cli, account, pass, user_domain));
1961 /****************************************************************************
1962 Send a session setup. The username and workgroup is in UNIX character
1963 format and must be converted to DOS codepage format before sending. If the
1964 password is in plaintext, the same should be done.
1965 ****************************************************************************/
1967 NTSTATUS cli_session_setup(struct cli_state *cli,
1969 const char *pass, int passlen,
1970 const char *ntpass, int ntpasslen,
1971 const char *workgroup)
1975 uint16_t sec_mode = cli_state_security_mode(cli);
1978 user2 = talloc_strdup(talloc_tos(), user);
1980 user2 = talloc_strdup(talloc_tos(), "");
1982 if (user2 == NULL) {
1983 return NT_STATUS_NO_MEMORY;
1990 /* allow for workgroups as part of the username */
1991 if ((p=strchr_m(user2,'\\')) || (p=strchr_m(user2,'/')) ||
1992 (p=strchr_m(user2,*lp_winbind_separator()))) {
1999 if (cli_state_protocol(cli) < PROTOCOL_LANMAN1) {
2001 * Ensure cli->server_domain,
2002 * cli->server_os and cli->server_type
2003 * are valid pointers.
2005 cli->server_domain = talloc_strdup(cli, "");
2006 cli->server_os = talloc_strdup(cli, "");
2007 cli->server_type = talloc_strdup(cli, "");
2008 if (cli->server_domain == NULL ||
2009 cli->server_os == NULL ||
2010 cli->server_type == NULL) {
2011 return NT_STATUS_NO_MEMORY;
2013 return NT_STATUS_OK;
2016 /* now work out what sort of session setup we are going to
2017 do. I have split this into separate functions to make the
2018 flow a bit easier to understand (tridge) */
2020 /* if its an older server then we have to use the older request format */
2022 if (cli_state_protocol(cli) < PROTOCOL_NT1) {
2023 if (!lp_client_lanman_auth() && passlen != 24 && (*pass)) {
2024 DEBUG(1, ("Server requested LM password but 'client lanman auth = no'"
2025 " or 'client ntlmv2 auth = yes'\n"));
2026 return NT_STATUS_ACCESS_DENIED;
2029 if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0 &&
2030 !lp_client_plaintext_auth() && (*pass)) {
2031 DEBUG(1, ("Server requested LM password but 'client plaintext auth = no'"
2032 " or 'client ntlmv2 auth = yes'\n"));
2033 return NT_STATUS_ACCESS_DENIED;
2036 return cli_session_setup_lanman2(cli, user, pass, passlen,
2040 /* if no user is supplied then we have to do an anonymous connection.
2041 passwords are ignored */
2043 if (!user || !*user)
2044 return cli_session_setup_guest(cli);
2046 /* if the server is share level then send a plaintext null
2047 password at this point. The password is sent in the tree
2050 if ((sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0)
2051 return cli_session_setup_plain(cli, user, "", workgroup);
2053 /* if the server doesn't support encryption then we have to use
2054 plaintext. The second password is ignored */
2056 if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) {
2057 if (!lp_client_plaintext_auth() && (*pass)) {
2058 DEBUG(1, ("Server requested LM password but 'client plaintext auth = no'"
2059 " or 'client ntlmv2 auth = yes'\n"));
2060 return NT_STATUS_ACCESS_DENIED;
2062 return cli_session_setup_plain(cli, user, pass, workgroup);
2065 /* if the server supports extended security then use SPNEGO */
2067 if (cli_state_capabilities(cli) & CAP_EXTENDED_SECURITY) {
2068 const char *remote_realm = cli_state_remote_realm(cli);
2069 ADS_STATUS status = cli_session_setup_spnego(cli, user, pass,
2072 if (!ADS_ERR_OK(status)) {
2073 DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status)));
2074 return ads_ntstatus(status);
2079 /* otherwise do a NT1 style session setup */
2080 status = cli_session_setup_nt1(cli, user, pass, passlen,
2081 ntpass, ntpasslen, workgroup);
2082 if (!NT_STATUS_IS_OK(status)) {
2083 DEBUG(3,("cli_session_setup: NT1 session setup "
2084 "failed: %s\n", nt_errstr(status)));
2089 if (strstr(cli->server_type, "Samba")) {
2090 cli->is_samba = True;
2093 return NT_STATUS_OK;
2096 /****************************************************************************
2098 *****************************************************************************/
2100 struct cli_ulogoff_state {
2101 struct cli_state *cli;
2105 static void cli_ulogoff_done(struct tevent_req *subreq);
2107 struct tevent_req *cli_ulogoff_send(TALLOC_CTX *mem_ctx,
2108 struct tevent_context *ev,
2109 struct cli_state *cli)
2111 struct tevent_req *req, *subreq;
2112 struct cli_ulogoff_state *state;
2114 req = tevent_req_create(mem_ctx, &state, struct cli_ulogoff_state);
2120 SCVAL(state->vwv+0, 0, 0xFF);
2121 SCVAL(state->vwv+1, 0, 0);
2122 SSVAL(state->vwv+2, 0, 0);
2124 subreq = cli_smb_send(state, ev, cli, SMBulogoffX, 0, 2, state->vwv,
2126 if (tevent_req_nomem(subreq, req)) {
2127 return tevent_req_post(req, ev);
2129 tevent_req_set_callback(subreq, cli_ulogoff_done, req);
2133 static void cli_ulogoff_done(struct tevent_req *subreq)
2135 struct tevent_req *req = tevent_req_callback_data(
2136 subreq, struct tevent_req);
2137 struct cli_ulogoff_state *state = tevent_req_data(
2138 req, struct cli_ulogoff_state);
2141 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
2142 if (!NT_STATUS_IS_OK(status)) {
2143 tevent_req_nterror(req, status);
2146 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
2147 tevent_req_done(req);
2150 NTSTATUS cli_ulogoff_recv(struct tevent_req *req)
2152 return tevent_req_simple_recv_ntstatus(req);
2155 NTSTATUS cli_ulogoff(struct cli_state *cli)
2157 struct tevent_context *ev;
2158 struct tevent_req *req;
2159 NTSTATUS status = NT_STATUS_NO_MEMORY;
2161 if (cli_has_async_calls(cli)) {
2162 return NT_STATUS_INVALID_PARAMETER;
2164 ev = tevent_context_init(talloc_tos());
2168 req = cli_ulogoff_send(ev, ev, cli);
2172 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2175 status = cli_ulogoff_recv(req);
2181 /****************************************************************************
2183 ****************************************************************************/
2185 struct cli_tcon_andx_state {
2186 struct cli_state *cli;
2191 static void cli_tcon_andx_done(struct tevent_req *subreq);
2193 struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx,
2194 struct event_context *ev,
2195 struct cli_state *cli,
2196 const char *share, const char *dev,
2197 const char *pass, int passlen,
2198 struct tevent_req **psmbreq)
2200 struct tevent_req *req, *subreq;
2201 struct cli_tcon_andx_state *state;
2206 uint16_t sec_mode = cli_state_security_mode(cli);
2210 req = tevent_req_create(mem_ctx, &state, struct cli_tcon_andx_state);
2217 cli->share = talloc_strdup(cli, share);
2222 /* in user level security don't send a password now */
2223 if (sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {
2226 } else if (pass == NULL) {
2227 DEBUG(1, ("Server not using user level security and no "
2228 "password supplied.\n"));
2232 if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) &&
2233 *pass && passlen != 24) {
2234 if (!lp_client_lanman_auth()) {
2235 DEBUG(1, ("Server requested LANMAN password "
2236 "(share-level security) but "
2237 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2242 * Non-encrypted passwords - convert to DOS codepage before
2245 SMBencrypt(pass, cli->secblob.data, p24);
2247 pass = (const char *)p24;
2249 if((sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL
2250 |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE))
2254 if (!lp_client_plaintext_auth() && (*pass)) {
2255 DEBUG(1, ("Server requested plaintext "
2257 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2262 * Non-encrypted passwords - convert to DOS codepage
2265 tmp_pass = talloc_array(talloc_tos(), uint8, 0);
2266 if (tevent_req_nomem(tmp_pass, req)) {
2267 return tevent_req_post(req, ev);
2269 tmp_pass = trans2_bytes_push_str(tmp_pass,
2270 false, /* always DOS */
2274 if (tevent_req_nomem(tmp_pass, req)) {
2275 return tevent_req_post(req, ev);
2277 pass = (const char *)tmp_pass;
2278 passlen = talloc_get_size(tmp_pass);
2282 SCVAL(vwv+0, 0, 0xFF);
2285 SSVAL(vwv+2, 0, TCONX_FLAG_EXTENDED_RESPONSE);
2286 SSVAL(vwv+3, 0, passlen);
2288 if (passlen && pass) {
2289 bytes = (uint8_t *)talloc_memdup(state, pass, passlen);
2291 bytes = talloc_array(state, uint8_t, 0);
2297 tmp = talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
2298 cli_state_remote_name(cli), share);
2303 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), tmp, strlen(tmp)+1,
2308 * Add the devicetype
2310 tmp = talloc_strdup_upper(talloc_tos(), dev);
2315 bytes = smb_bytes_push_str(bytes, false, tmp, strlen(tmp)+1, NULL);
2318 if (bytes == NULL) {
2323 state->bytes.iov_base = (void *)bytes;
2324 state->bytes.iov_len = talloc_get_size(bytes);
2326 subreq = cli_smb_req_create(state, ev, cli, SMBtconX, 0, 4, vwv,
2328 if (subreq == NULL) {
2332 tevent_req_set_callback(subreq, cli_tcon_andx_done, req);
2337 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
2338 return tevent_req_post(req, ev);
2341 struct tevent_req *cli_tcon_andx_send(TALLOC_CTX *mem_ctx,
2342 struct event_context *ev,
2343 struct cli_state *cli,
2344 const char *share, const char *dev,
2345 const char *pass, int passlen)
2347 struct tevent_req *req, *subreq;
2350 req = cli_tcon_andx_create(mem_ctx, ev, cli, share, dev, pass, passlen,
2355 if (subreq == NULL) {
2358 status = cli_smb_req_send(subreq);
2359 if (!NT_STATUS_IS_OK(status)) {
2360 tevent_req_nterror(req, status);
2361 return tevent_req_post(req, ev);
2366 static void cli_tcon_andx_done(struct tevent_req *subreq)
2368 struct tevent_req *req = tevent_req_callback_data(
2369 subreq, struct tevent_req);
2370 struct cli_tcon_andx_state *state = tevent_req_data(
2371 req, struct cli_tcon_andx_state);
2372 struct cli_state *cli = state->cli;
2381 status = cli_smb_recv(subreq, state, &in, 0, &wct, &vwv,
2382 &num_bytes, &bytes);
2383 TALLOC_FREE(subreq);
2384 if (!NT_STATUS_IS_OK(status)) {
2385 tevent_req_nterror(req, status);
2392 if (clistr_pull_talloc(cli,
2394 SVAL(inbuf, smb_flg2),
2398 STR_TERMINATE|STR_ASCII) == -1) {
2399 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2403 cli->dev = talloc_strdup(cli, "");
2404 if (cli->dev == NULL) {
2405 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2410 if ((cli_state_protocol(cli) >= PROTOCOL_NT1) && (num_bytes == 3)) {
2411 /* almost certainly win95 - enable bug fixes */
2416 * Make sure that we have the optional support 16-bit field. WCT > 2.
2417 * Avoids issues when connecting to Win9x boxes sharing files
2420 cli->dfsroot = false;
2422 if ((wct > 2) && (cli_state_protocol(cli) >= PROTOCOL_LANMAN2)) {
2423 cli->dfsroot = ((SVAL(vwv+2, 0) & SMB_SHARE_IN_DFS) != 0);
2426 cli->smb1.tid = SVAL(inbuf,smb_tid);
2427 tevent_req_done(req);
2430 NTSTATUS cli_tcon_andx_recv(struct tevent_req *req)
2432 return tevent_req_simple_recv_ntstatus(req);
2435 NTSTATUS cli_tcon_andx(struct cli_state *cli, const char *share,
2436 const char *dev, const char *pass, int passlen)
2438 TALLOC_CTX *frame = talloc_stackframe();
2439 struct event_context *ev;
2440 struct tevent_req *req;
2441 NTSTATUS status = NT_STATUS_OK;
2443 if (cli_has_async_calls(cli)) {
2445 * Can't use sync call while an async call is in flight
2447 status = NT_STATUS_INVALID_PARAMETER;
2451 ev = event_context_init(frame);
2453 status = NT_STATUS_NO_MEMORY;
2457 req = cli_tcon_andx_send(frame, ev, cli, share, dev, pass, passlen);
2459 status = NT_STATUS_NO_MEMORY;
2463 if (!tevent_req_poll(req, ev)) {
2464 status = map_nt_error_from_unix(errno);
2468 status = cli_tcon_andx_recv(req);
2474 /****************************************************************************
2475 Send a tree disconnect.
2476 ****************************************************************************/
2478 struct cli_tdis_state {
2479 struct cli_state *cli;
2482 static void cli_tdis_done(struct tevent_req *subreq);
2484 struct tevent_req *cli_tdis_send(TALLOC_CTX *mem_ctx,
2485 struct tevent_context *ev,
2486 struct cli_state *cli)
2488 struct tevent_req *req, *subreq;
2489 struct cli_tdis_state *state;
2491 req = tevent_req_create(mem_ctx, &state, struct cli_tdis_state);
2497 subreq = cli_smb_send(state, ev, cli, SMBtdis, 0, 0, NULL, 0, NULL);
2498 if (tevent_req_nomem(subreq, req)) {
2499 return tevent_req_post(req, ev);
2501 tevent_req_set_callback(subreq, cli_tdis_done, req);
2505 static void cli_tdis_done(struct tevent_req *subreq)
2507 struct tevent_req *req = tevent_req_callback_data(
2508 subreq, struct tevent_req);
2509 struct cli_tdis_state *state = tevent_req_data(
2510 req, struct cli_tdis_state);
2513 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
2514 TALLOC_FREE(subreq);
2515 if (!NT_STATUS_IS_OK(status)) {
2516 tevent_req_nterror(req, status);
2519 state->cli->smb1.tid = UINT16_MAX;
2520 tevent_req_done(req);
2523 NTSTATUS cli_tdis_recv(struct tevent_req *req)
2525 return tevent_req_simple_recv_ntstatus(req);
2528 NTSTATUS cli_tdis(struct cli_state *cli)
2530 struct tevent_context *ev;
2531 struct tevent_req *req;
2532 NTSTATUS status = NT_STATUS_NO_MEMORY;
2534 if (cli_has_async_calls(cli)) {
2535 return NT_STATUS_INVALID_PARAMETER;
2537 ev = tevent_context_init(talloc_tos());
2541 req = cli_tdis_send(ev, ev, cli);
2545 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2548 status = cli_tdis_recv(req);
2554 /****************************************************************************
2555 Send a negprot command.
2556 ****************************************************************************/
2558 struct cli_negprot_state {
2559 struct cli_state *cli;
2562 static void cli_negprot_done(struct tevent_req *subreq);
2564 struct tevent_req *cli_negprot_send(TALLOC_CTX *mem_ctx,
2565 struct event_context *ev,
2566 struct cli_state *cli)
2568 struct tevent_req *req, *subreq;
2569 struct cli_negprot_state *state;
2570 uint8_t *bytes = NULL;
2573 req = tevent_req_create(mem_ctx, &state, struct cli_negprot_state);
2579 if (cli_state_protocol(cli) < PROTOCOL_NT1)
2580 cli->use_spnego = False;
2582 /* setup the protocol strings */
2583 for (numprots=0; numprots < ARRAY_SIZE(prots); numprots++) {
2585 if (prots[numprots].prot > cli_state_protocol(cli)) {
2588 bytes = (uint8_t *)talloc_append_blob(
2589 state, bytes, data_blob_const(&c, sizeof(c)));
2590 if (tevent_req_nomem(bytes, req)) {
2591 return tevent_req_post(req, ev);
2593 bytes = smb_bytes_push_str(bytes, false,
2594 prots[numprots].name,
2595 strlen(prots[numprots].name)+1,
2597 if (tevent_req_nomem(bytes, req)) {
2598 return tevent_req_post(req, ev);
2602 subreq = cli_smb_send(state, ev, cli, SMBnegprot, 0, 0, NULL,
2603 talloc_get_size(bytes), bytes);
2605 if (tevent_req_nomem(subreq, req)) {
2606 return tevent_req_post(req, ev);
2608 tevent_req_set_callback(subreq, cli_negprot_done, req);
2612 static void cli_negprot_done(struct tevent_req *subreq)
2614 struct tevent_req *req = tevent_req_callback_data(
2615 subreq, struct tevent_req);
2616 struct cli_negprot_state *state = tevent_req_data(
2617 req, struct cli_negprot_state);
2618 struct cli_state *cli = state->cli;
2627 status = cli_smb_recv(subreq, state, &inbuf, 1, &wct, &vwv,
2628 &num_bytes, &bytes);
2629 TALLOC_FREE(subreq);
2630 if (!NT_STATUS_IS_OK(status)) {
2631 tevent_req_nterror(req, status);
2635 protnum = SVAL(vwv, 0);
2637 if ((protnum >= ARRAY_SIZE(prots))
2638 || (prots[protnum].prot > cli_state_protocol(cli))) {
2639 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2643 cli->protocol = prots[protnum].prot;
2645 if ((cli_state_protocol(cli) < PROTOCOL_NT1) &&
2646 client_is_signing_mandatory(cli)) {
2647 DEBUG(0,("cli_negprot: SMB signing is mandatory and the selected protocol level doesn't support it.\n"));
2648 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
2652 if (cli_state_protocol(cli) >= PROTOCOL_NT1) {
2654 const char *client_signing = NULL;
2655 bool server_mandatory;
2656 bool server_allowed;
2657 const char *server_signing = NULL;
2661 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2666 cli->sec_mode = CVAL(vwv + 1, 0);
2667 cli->max_mux = SVAL(vwv + 1, 1);
2668 cli->max_xmit = IVAL(vwv + 3, 1);
2669 cli->sesskey = IVAL(vwv + 7, 1);
2670 cli->serverzone = SVALS(vwv + 15, 1);
2671 cli->serverzone *= 60;
2672 /* this time arrives in real GMT */
2673 ts = interpret_long_date(((char *)(vwv+11))+1);
2674 cli->servertime = ts.tv_sec;
2675 cli->secblob = data_blob(bytes, num_bytes);
2676 cli->capabilities = IVAL(vwv + 9, 1);
2677 if (cli_state_capabilities(cli) & CAP_RAW_MODE) {
2678 cli->readbraw_supported = True;
2679 cli->writebraw_supported = True;
2681 /* work out if they sent us a workgroup */
2682 if (!(cli_state_capabilities(cli) & CAP_EXTENDED_SECURITY) &&
2683 smb_buflen(inbuf) > 8) {
2685 status = smb_bytes_talloc_string(
2686 cli, (char *)inbuf, &cli->server_domain,
2687 bytes + 8, num_bytes - 8, &ret);
2688 if (tevent_req_nterror(req, status)) {
2693 client_signing = "disabled";
2694 if (client_is_signing_allowed(cli)) {
2695 client_signing = "allowed";
2697 if (client_is_signing_mandatory(cli)) {
2698 client_signing = "required";
2701 server_signing = "not supported";
2702 if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) {
2703 server_signing = "supported";
2704 server_allowed = true;
2706 if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) {
2707 server_signing = "required";
2708 server_mandatory = true;
2711 ok = cli_set_signing_negotiated(cli,
2715 DEBUG(1,("cli_negprot: SMB signing is required, "
2716 "but client[%s] and server[%s] mismatch\n",
2717 client_signing, server_signing));
2718 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
2722 } else if (cli_state_protocol(cli) >= PROTOCOL_LANMAN1) {
2724 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2728 cli->use_spnego = False;
2729 cli->sec_mode = SVAL(vwv + 1, 0);
2730 cli->max_xmit = SVAL(vwv + 2, 0);
2731 cli->max_mux = SVAL(vwv + 3, 0);
2732 cli->sesskey = IVAL(vwv + 6, 0);
2733 cli->serverzone = SVALS(vwv + 10, 0);
2734 cli->serverzone *= 60;
2735 /* this time is converted to GMT by make_unix_date */
2736 cli->servertime = make_unix_date(
2737 (char *)(vwv + 8), cli->serverzone);
2738 cli->readbraw_supported = ((SVAL(vwv + 5, 0) & 0x1) != 0);
2739 cli->writebraw_supported = ((SVAL(vwv + 5, 0) & 0x2) != 0);
2740 cli->secblob = data_blob(bytes, num_bytes);
2742 /* the old core protocol */
2743 cli->use_spnego = False;
2745 cli->serverzone = get_time_zone(time(NULL));
2746 cli->max_xmit = 1024;
2750 if (cli->max_xmit < 1024) {
2751 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2755 if (cli->max_mux < 1) {
2756 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
2760 cli->max_xmit = MIN(cli->max_xmit, CLI_BUFFER_SIZE);
2762 /* a way to force ascii SMB */
2763 if (cli->force_ascii) {
2764 cli->capabilities &= ~CAP_UNICODE;
2767 tevent_req_done(req);
2770 NTSTATUS cli_negprot_recv(struct tevent_req *req)
2772 return tevent_req_simple_recv_ntstatus(req);
2775 NTSTATUS cli_negprot(struct cli_state *cli)
2777 TALLOC_CTX *frame = talloc_stackframe();
2778 struct event_context *ev;
2779 struct tevent_req *req;
2780 NTSTATUS status = NT_STATUS_OK;
2782 if (cli_has_async_calls(cli)) {
2784 * Can't use sync call while an async call is in flight
2786 status = NT_STATUS_INVALID_PARAMETER;
2790 ev = event_context_init(frame);
2792 status = NT_STATUS_NO_MEMORY;
2796 req = cli_negprot_send(frame, ev, cli);
2798 status = NT_STATUS_NO_MEMORY;
2802 if (!tevent_req_poll(req, ev)) {
2803 status = map_nt_error_from_unix(errno);
2807 status = cli_negprot_recv(req);
2813 static NTSTATUS cli_connect_sock(const char *host, int name_type,
2814 const struct sockaddr_storage *pss,
2815 const char *myname, uint16_t port,
2816 int sec_timeout, int *pfd, uint16_t *pport)
2818 TALLOC_CTX *frame = talloc_stackframe();
2820 unsigned int i, num_addrs;
2821 const char **called_names;
2822 const char **calling_names;
2827 prog = getenv("LIBSMB_PROG");
2829 fd = sock_exec(prog);
2831 return map_nt_error_from_unix(errno);
2837 if ((pss == NULL) || is_zero_addr(pss)) {
2838 struct sockaddr_storage *addrs;
2839 status = resolve_name_list(talloc_tos(), host, name_type,
2840 &addrs, &num_addrs);
2841 if (!NT_STATUS_IS_OK(status)) {
2849 called_names = talloc_array(talloc_tos(), const char *, num_addrs);
2850 if (called_names == NULL) {
2851 status = NT_STATUS_NO_MEMORY;
2854 called_types = talloc_array(talloc_tos(), int, num_addrs);
2855 if (called_types == NULL) {
2856 status = NT_STATUS_NO_MEMORY;
2859 calling_names = talloc_array(talloc_tos(), const char *, num_addrs);
2860 if (calling_names == NULL) {
2861 status = NT_STATUS_NO_MEMORY;
2864 for (i=0; i<num_addrs; i++) {
2865 called_names[i] = host;
2866 called_types[i] = name_type;
2867 calling_names[i] = myname;
2869 status = smbsock_any_connect(pss, called_names, called_types,
2870 calling_names, NULL, num_addrs, port,
2871 sec_timeout, &fd, NULL, &port);
2872 if (!NT_STATUS_IS_OK(status)) {
2875 set_socket_options(fd, lp_socket_options());
2879 status = NT_STATUS_OK;
2885 NTSTATUS cli_connect_nb(const char *host, const struct sockaddr_storage *dest_ss,
2886 uint16_t port, int name_type, const char *myname,
2887 int signing_state, int flags, struct cli_state **pcli)
2889 TALLOC_CTX *frame = talloc_stackframe();
2890 struct cli_state *cli;
2891 NTSTATUS status = NT_STATUS_NO_MEMORY;
2896 desthost = talloc_strdup(talloc_tos(), host);
2897 if (desthost == NULL) {
2901 p = strchr(host, '#');
2903 name_type = strtol(p+1, NULL, 16);
2904 host = talloc_strndup(talloc_tos(), host, p - host);
2910 status = cli_connect_sock(host, name_type, dest_ss, myname, port,
2912 if (!NT_STATUS_IS_OK(status)) {
2916 cli = cli_state_create(NULL, fd, desthost, NULL, signing_state, flags);
2922 status = NT_STATUS_OK;
2929 establishes a connection to after the negprot.
2930 @param output_cli A fully initialised cli structure, non-null only on success
2931 @param dest_host The netbios name of the remote host
2932 @param dest_ss (optional) The the destination IP, NULL for name based lookup
2933 @param port (optional) The destination port (0 for default)
2935 NTSTATUS cli_start_connection(struct cli_state **output_cli,
2936 const char *my_name,
2937 const char *dest_host,
2938 const struct sockaddr_storage *dest_ss, int port,
2939 int signing_state, int flags)
2942 struct cli_state *cli;
2944 nt_status = cli_connect_nb(dest_host, dest_ss, port, 0x20, my_name,
2945 signing_state, flags, &cli);
2946 if (!NT_STATUS_IS_OK(nt_status)) {
2947 DEBUG(10, ("cli_connect_nb failed: %s\n",
2948 nt_errstr(nt_status)));
2952 nt_status = cli_negprot(cli);
2953 if (!NT_STATUS_IS_OK(nt_status)) {
2954 DEBUG(1, ("failed negprot: %s\n", nt_errstr(nt_status)));
2960 return NT_STATUS_OK;
2965 establishes a connection right up to doing tconX, password specified.
2966 @param output_cli A fully initialised cli structure, non-null only on success
2967 @param dest_host The netbios name of the remote host
2968 @param dest_ip (optional) The the destination IP, NULL for name based lookup
2969 @param port (optional) The destination port (0 for default)
2970 @param service (optional) The share to make the connection to. Should be 'unqualified' in any way.
2971 @param service_type The 'type' of serivice.
2972 @param user Username, unix string
2973 @param domain User's domain
2974 @param password User's password, unencrypted unix string.
2977 NTSTATUS cli_full_connection(struct cli_state **output_cli,
2978 const char *my_name,
2979 const char *dest_host,
2980 const struct sockaddr_storage *dest_ss, int port,
2981 const char *service, const char *service_type,
2982 const char *user, const char *domain,
2983 const char *password, int flags,
2987 struct cli_state *cli = NULL;
2988 int pw_len = password ? strlen(password)+1 : 0;
2992 if (password == NULL) {
2996 nt_status = cli_start_connection(&cli, my_name, dest_host,
2997 dest_ss, port, signing_state,
3000 if (!NT_STATUS_IS_OK(nt_status)) {
3004 nt_status = cli_session_setup(cli, user, password, pw_len, password,
3006 if (!NT_STATUS_IS_OK(nt_status)) {
3008 if (!(flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)) {
3009 DEBUG(1,("failed session setup with %s\n",
3010 nt_errstr(nt_status)));
3015 nt_status = cli_session_setup(cli, "", "", 0, "", 0, domain);
3016 if (!NT_STATUS_IS_OK(nt_status)) {
3017 DEBUG(1,("anonymous failed session setup with %s\n",
3018 nt_errstr(nt_status)));
3025 nt_status = cli_tcon_andx(cli, service, service_type, password,
3027 if (!NT_STATUS_IS_OK(nt_status)) {
3028 DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status)));
3030 if (NT_STATUS_IS_OK(nt_status)) {
3031 nt_status = NT_STATUS_UNSUCCESSFUL;
3037 nt_status = cli_init_creds(cli, user, domain, password);
3038 if (!NT_STATUS_IS_OK(nt_status)) {
3044 return NT_STATUS_OK;
3047 /****************************************************************************
3048 Send an old style tcon.
3049 ****************************************************************************/
3050 NTSTATUS cli_raw_tcon(struct cli_state *cli,
3051 const char *service, const char *pass, const char *dev,
3052 uint16 *max_xmit, uint16 *tid)
3054 struct tevent_req *req;
3059 if (!lp_client_plaintext_auth() && (*pass)) {
3060 DEBUG(1, ("Server requested plaintext password but 'client "
3061 "plaintext auth' is disabled\n"));
3062 return NT_STATUS_ACCESS_DENIED;
3065 bytes = talloc_array(talloc_tos(), uint8_t, 0);
3066 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3067 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
3068 service, strlen(service)+1, NULL);
3069 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3070 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
3071 pass, strlen(pass)+1, NULL);
3072 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
3073 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
3074 dev, strlen(dev)+1, NULL);
3076 status = cli_smb(talloc_tos(), cli, SMBtcon, 0, 0, NULL,
3077 talloc_get_size(bytes), bytes, &req,
3078 2, NULL, &ret_vwv, NULL, NULL);
3079 if (!NT_STATUS_IS_OK(status)) {
3083 *max_xmit = SVAL(ret_vwv + 0, 0);
3084 *tid = SVAL(ret_vwv + 1, 0);
3086 return NT_STATUS_OK;
3089 /* Return a cli_state pointing at the IPC$ share for the given server */
3091 struct cli_state *get_ipc_connect(char *server,
3092 struct sockaddr_storage *server_ss,
3093 const struct user_auth_info *user_info)
3095 struct cli_state *cli;
3097 uint32_t flags = CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
3099 if (user_info->use_kerberos) {
3100 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
3103 nt_status = cli_full_connection(&cli, NULL, server, server_ss, 0, "IPC$", "IPC",
3104 user_info->username ? user_info->username : "",
3106 user_info->password ? user_info->password : "",
3110 if (NT_STATUS_IS_OK(nt_status)) {
3112 } else if (is_ipaddress(server)) {
3113 /* windows 9* needs a correct NMB name for connections */
3114 fstring remote_name;
3116 if (name_status_find("*", 0, 0, server_ss, remote_name)) {
3117 cli = get_ipc_connect(remote_name, server_ss, user_info);
3126 * Given the IP address of a master browser on the network, return its
3127 * workgroup and connect to it.
3129 * This function is provided to allow additional processing beyond what
3130 * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
3131 * browsers and obtain each master browsers' list of domains (in case the
3132 * first master browser is recently on the network and has not yet
3133 * synchronized with other master browsers and therefore does not yet have the
3134 * entire network browse list)
3137 struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx,
3138 struct sockaddr_storage *mb_ip,
3139 const struct user_auth_info *user_info,
3140 char **pp_workgroup_out)
3142 char addr[INET6_ADDRSTRLEN];
3144 struct cli_state *cli;
3145 struct sockaddr_storage server_ss;
3147 *pp_workgroup_out = NULL;
3149 print_sockaddr(addr, sizeof(addr), mb_ip);
3150 DEBUG(99, ("Looking up name of master browser %s\n",
3154 * Do a name status query to find out the name of the master browser.
3155 * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
3156 * master browser will not respond to a wildcard query (or, at least,
3157 * an NT4 server acting as the domain master browser will not).
3159 * We might be able to use ONLY the query on MSBROWSE, but that's not
3160 * yet been tested with all Windows versions, so until it is, leave
3161 * the original wildcard query as the first choice and fall back to
3162 * MSBROWSE if the wildcard query fails.
3164 if (!name_status_find("*", 0, 0x1d, mb_ip, name) &&
3165 !name_status_find(MSBROWSE, 1, 0x1d, mb_ip, name)) {
3167 DEBUG(99, ("Could not retrieve name status for %s\n",
3172 if (!find_master_ip(name, &server_ss)) {
3173 DEBUG(99, ("Could not find master ip for %s\n", name));
3177 *pp_workgroup_out = talloc_strdup(ctx, name);
3179 DEBUG(4, ("found master browser %s, %s\n", name, addr));
3181 print_sockaddr(addr, sizeof(addr), &server_ss);
3182 cli = get_ipc_connect(addr, &server_ss, user_info);
3188 * Return the IP address and workgroup of a master browser on the network, and
3192 struct cli_state *get_ipc_connect_master_ip_bcast(TALLOC_CTX *ctx,
3193 const struct user_auth_info *user_info,
3194 char **pp_workgroup_out)
3196 struct sockaddr_storage *ip_list;
3197 struct cli_state *cli;
3201 *pp_workgroup_out = NULL;
3203 DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
3205 /* Go looking for workgroups by broadcasting on the local network */
3207 status = name_resolve_bcast(MSBROWSE, 1, talloc_tos(),
3209 if (!NT_STATUS_IS_OK(status)) {
3210 DEBUG(99, ("No master browsers responded: %s\n",
3211 nt_errstr(status)));
3215 for (i = 0; i < count; i++) {
3216 char addr[INET6_ADDRSTRLEN];
3217 print_sockaddr(addr, sizeof(addr), &ip_list[i]);
3218 DEBUG(99, ("Found master browser %s\n", addr));
3220 cli = get_ipc_connect_master_ip(ctx, &ip_list[i],
3221 user_info, pp_workgroup_out);