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 "auth_info.h"
26 #include "../libcli/auth/libcli_auth.h"
27 #include "../libcli/auth/spnego.h"
29 #include "../auth/ntlmssp/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"
35 #include "librpc/ndr/libndr.h"
36 #include "../libcli/smb/smbXcli_base.h"
39 #define STAR_SMBSERVER "*SMBSERVER"
41 /********************************************************
42 Utility function to ensure we always return at least
43 a valid char * pointer to an empty string for the
44 cli->server_os, cli->server_type and cli->server_domain
46 *******************************************************/
48 static NTSTATUS smb_bytes_talloc_string(TALLOC_CTX *mem_ctx,
55 *destlen = clistr_pull_talloc(mem_ctx,
63 return NT_STATUS_NO_MEMORY;
67 *dest = talloc_strdup(mem_ctx, "");
69 return NT_STATUS_NO_MEMORY;
76 * Set the user session key for a connection
77 * @param cli The cli structure to add it too
78 * @param session_key The session key used. (A copy of this is taken for the cli struct)
82 static void cli_set_session_key (struct cli_state *cli, const DATA_BLOB session_key)
84 cli->user_session_key = data_blob(session_key.data, session_key.length);
87 /****************************************************************************
88 Do an old lanman2 style session setup.
89 ****************************************************************************/
91 struct cli_session_setup_lanman2_state {
92 struct cli_state *cli;
97 static void cli_session_setup_lanman2_done(struct tevent_req *subreq);
99 static struct tevent_req *cli_session_setup_lanman2_send(
100 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
101 struct cli_state *cli, const char *user,
102 const char *pass, size_t passlen,
103 const char *workgroup)
105 struct tevent_req *req, *subreq;
106 struct cli_session_setup_lanman2_state *state;
107 DATA_BLOB lm_response = data_blob_null;
111 uint16_t sec_mode = smb1cli_conn_server_security_mode(cli->conn);
113 req = tevent_req_create(mem_ctx, &state,
114 struct cli_session_setup_lanman2_state);
123 * if in share level security then don't send a password now
125 if (!(sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) {
130 && (sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)
133 * Encrypted mode needed, and non encrypted password
136 lm_response = data_blob(NULL, 24);
137 if (tevent_req_nomem(lm_response.data, req)) {
138 return tevent_req_post(req, ev);
141 if (!SMBencrypt(pass, smb1cli_conn_server_challenge(cli->conn),
142 (uint8_t *)lm_response.data)) {
143 DEBUG(1, ("Password is > 14 chars in length, and is "
144 "therefore incompatible with Lanman "
145 "authentication\n"));
146 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
147 return tevent_req_post(req, ev);
149 } else if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)
152 * Encrypted mode needed, and encrypted password
155 lm_response = data_blob(pass, passlen);
156 if (tevent_req_nomem(lm_response.data, req)) {
157 return tevent_req_post(req, ev);
159 } else if (passlen > 0) {
161 size_t converted_size;
163 * Plaintext mode needed, assume plaintext supplied.
165 buf = talloc_array(talloc_tos(), uint8_t, 0);
166 buf = smb_bytes_push_str(buf, smbXcli_conn_use_unicode(cli->conn), pass, passlen+1,
168 if (tevent_req_nomem(buf, req)) {
169 return tevent_req_post(req, ev);
171 lm_response = data_blob(pass, passlen);
173 if (tevent_req_nomem(lm_response.data, req)) {
174 return tevent_req_post(req, ev);
178 SCVAL(vwv+0, 0, 0xff);
181 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
184 SIVAL(vwv+5, 0, smb1cli_conn_server_session_key(cli->conn));
185 SSVAL(vwv+7, 0, lm_response.length);
187 bytes = talloc_array(state, uint8_t, lm_response.length);
188 if (tevent_req_nomem(bytes, req)) {
189 return tevent_req_post(req, ev);
191 if (lm_response.length != 0) {
192 memcpy(bytes, lm_response.data, lm_response.length);
194 data_blob_free(&lm_response);
196 tmp = talloc_strdup_upper(talloc_tos(), user);
197 if (tevent_req_nomem(tmp, req)) {
198 return tevent_req_post(req, ev);
200 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), tmp, strlen(tmp)+1,
204 tmp = talloc_strdup_upper(talloc_tos(), workgroup);
205 if (tevent_req_nomem(tmp, req)) {
206 return tevent_req_post(req, ev);
208 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), tmp, strlen(tmp)+1,
210 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "Unix", 5, NULL);
211 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "Samba", 6, NULL);
213 if (tevent_req_nomem(bytes, req)) {
214 return tevent_req_post(req, ev);
217 subreq = cli_smb_send(state, ev, cli, SMBsesssetupX, 0, 10, vwv,
218 talloc_get_size(bytes), bytes);
219 if (tevent_req_nomem(subreq, req)) {
220 return tevent_req_post(req, ev);
222 tevent_req_set_callback(subreq, cli_session_setup_lanman2_done, req);
226 static void cli_session_setup_lanman2_done(struct tevent_req *subreq)
228 struct tevent_req *req = tevent_req_callback_data(
229 subreq, struct tevent_req);
230 struct cli_session_setup_lanman2_state *state = tevent_req_data(
231 req, struct cli_session_setup_lanman2_state);
232 struct cli_state *cli = state->cli;
243 status = cli_smb_recv(subreq, state, &in, 3, &wct, &vwv,
246 if (!NT_STATUS_IS_OK(status)) {
247 tevent_req_nterror(req, status);
251 inhdr = in + NBT_HDR_SIZE;
254 cli_state_set_uid(state->cli, SVAL(inhdr, HDR_UID));
255 cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0);
257 status = smb_bytes_talloc_string(cli,
264 if (!NT_STATUS_IS_OK(status)) {
265 tevent_req_nterror(req, status);
270 status = smb_bytes_talloc_string(cli,
277 if (!NT_STATUS_IS_OK(status)) {
278 tevent_req_nterror(req, status);
283 status = smb_bytes_talloc_string(cli,
290 if (!NT_STATUS_IS_OK(status)) {
291 tevent_req_nterror(req, status);
296 status = cli_set_username(cli, state->user);
297 if (tevent_req_nterror(req, status)) {
300 tevent_req_done(req);
303 static NTSTATUS cli_session_setup_lanman2_recv(struct tevent_req *req)
305 return tevent_req_simple_recv_ntstatus(req);
308 static NTSTATUS cli_session_setup_lanman2(struct cli_state *cli, const char *user,
309 const char *pass, size_t passlen,
310 const char *workgroup)
312 TALLOC_CTX *frame = talloc_stackframe();
313 struct event_context *ev;
314 struct tevent_req *req;
315 NTSTATUS status = NT_STATUS_NO_MEMORY;
317 if (smbXcli_conn_has_async_calls(cli->conn)) {
319 * Can't use sync call while an async call is in flight
321 status = NT_STATUS_INVALID_PARAMETER;
324 ev = event_context_init(frame);
328 req = cli_session_setup_lanman2_send(frame, ev, cli, user, pass, passlen,
333 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
336 status = cli_session_setup_lanman2_recv(req);
342 /****************************************************************************
343 Work out suitable capabilities to offer the server.
344 ****************************************************************************/
346 static uint32_t cli_session_setup_capabilities(struct cli_state *cli,
347 uint32_t sesssetup_capabilities)
349 uint32_t client_capabilities = smb1cli_conn_capabilities(cli->conn);
352 * We only send capabilities based on the mask for:
353 * - client only flags
354 * - flags used in both directions
356 * We do not echo the server only flags.
358 client_capabilities &= (SMB_CAP_BOTH_MASK | SMB_CAP_CLIENT_MASK);
361 * Session Setup specific flags CAP_DYNAMIC_REAUTH
362 * and CAP_EXTENDED_SECURITY are passed by the caller.
363 * We need that in order to do guest logins even if
364 * CAP_EXTENDED_SECURITY is negotiated.
366 client_capabilities &= ~(CAP_DYNAMIC_REAUTH|CAP_EXTENDED_SECURITY);
367 sesssetup_capabilities &= (CAP_DYNAMIC_REAUTH|CAP_EXTENDED_SECURITY);
368 client_capabilities |= sesssetup_capabilities;
370 return client_capabilities;
373 /****************************************************************************
374 Do a NT1 guest session setup.
375 ****************************************************************************/
377 struct cli_session_setup_guest_state {
378 struct cli_state *cli;
383 static void cli_session_setup_guest_done(struct tevent_req *subreq);
385 struct tevent_req *cli_session_setup_guest_create(TALLOC_CTX *mem_ctx,
386 struct event_context *ev,
387 struct cli_state *cli,
388 struct tevent_req **psmbreq)
390 struct tevent_req *req, *subreq;
391 struct cli_session_setup_guest_state *state;
395 req = tevent_req_create(mem_ctx, &state,
396 struct cli_session_setup_guest_state);
403 SCVAL(vwv+0, 0, 0xFF);
406 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
408 SSVAL(vwv+4, 0, cli_state_get_vc_num(cli));
409 SIVAL(vwv+5, 0, smb1cli_conn_server_session_key(cli->conn));
414 SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli, 0));
416 bytes = talloc_array(state, uint8_t, 0);
418 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "", 1, /* username */
420 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "", 1, /* workgroup */
422 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "Unix", 5, NULL);
423 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "Samba", 6, NULL);
430 state->bytes.iov_base = (void *)bytes;
431 state->bytes.iov_len = talloc_get_size(bytes);
433 subreq = cli_smb_req_create(state, ev, cli, SMBsesssetupX, 0, 13, vwv,
435 if (subreq == NULL) {
439 tevent_req_set_callback(subreq, cli_session_setup_guest_done, req);
444 struct tevent_req *cli_session_setup_guest_send(TALLOC_CTX *mem_ctx,
445 struct event_context *ev,
446 struct cli_state *cli)
448 struct tevent_req *req, *subreq;
451 req = cli_session_setup_guest_create(mem_ctx, ev, cli, &subreq);
456 status = smb1cli_req_chain_submit(&subreq, 1);
457 if (NT_STATUS_IS_OK(status)) {
458 tevent_req_nterror(req, status);
459 return tevent_req_post(req, ev);
464 static void cli_session_setup_guest_done(struct tevent_req *subreq)
466 struct tevent_req *req = tevent_req_callback_data(
467 subreq, struct tevent_req);
468 struct cli_session_setup_guest_state *state = tevent_req_data(
469 req, struct cli_session_setup_guest_state);
470 struct cli_state *cli = state->cli;
481 status = cli_smb_recv(subreq, state, &in, 3, &wct, &vwv,
484 if (!NT_STATUS_IS_OK(status)) {
485 tevent_req_nterror(req, status);
489 inhdr = in + NBT_HDR_SIZE;
492 cli_state_set_uid(state->cli, SVAL(inhdr, HDR_UID));
493 cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0);
495 status = smb_bytes_talloc_string(cli,
502 if (!NT_STATUS_IS_OK(status)) {
503 tevent_req_nterror(req, status);
508 status = smb_bytes_talloc_string(cli,
515 if (!NT_STATUS_IS_OK(status)) {
516 tevent_req_nterror(req, status);
521 status = smb_bytes_talloc_string(cli,
528 if (!NT_STATUS_IS_OK(status)) {
529 tevent_req_nterror(req, status);
534 status = cli_set_username(cli, "");
535 if (!NT_STATUS_IS_OK(status)) {
536 tevent_req_nterror(req, status);
539 tevent_req_done(req);
542 NTSTATUS cli_session_setup_guest_recv(struct tevent_req *req)
544 return tevent_req_simple_recv_ntstatus(req);
547 static NTSTATUS cli_session_setup_guest(struct cli_state *cli)
549 TALLOC_CTX *frame = talloc_stackframe();
550 struct event_context *ev;
551 struct tevent_req *req;
552 NTSTATUS status = NT_STATUS_OK;
554 if (smbXcli_conn_has_async_calls(cli->conn)) {
556 * Can't use sync call while an async call is in flight
558 status = NT_STATUS_INVALID_PARAMETER;
562 ev = event_context_init(frame);
564 status = NT_STATUS_NO_MEMORY;
568 req = cli_session_setup_guest_send(frame, ev, cli);
570 status = NT_STATUS_NO_MEMORY;
574 if (!tevent_req_poll(req, ev)) {
575 status = map_nt_error_from_unix(errno);
579 status = cli_session_setup_guest_recv(req);
585 /****************************************************************************
586 Do a NT1 plaintext session setup.
587 ****************************************************************************/
589 struct cli_session_setup_plain_state {
590 struct cli_state *cli;
595 static void cli_session_setup_plain_done(struct tevent_req *subreq);
597 static struct tevent_req *cli_session_setup_plain_send(
598 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
599 struct cli_state *cli,
600 const char *user, const char *pass, const char *workgroup)
602 struct tevent_req *req, *subreq;
603 struct cli_session_setup_plain_state *state;
609 req = tevent_req_create(mem_ctx, &state,
610 struct cli_session_setup_plain_state);
618 SCVAL(vwv+0, 0, 0xff);
621 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
623 SSVAL(vwv+4, 0, cli_state_get_vc_num(cli));
624 SIVAL(vwv+5, 0, smb1cli_conn_server_session_key(cli->conn));
629 SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli, 0));
631 bytes = talloc_array(state, uint8_t, 0);
632 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), pass, strlen(pass)+1,
634 if (tevent_req_nomem(bytes, req)) {
635 return tevent_req_post(req, ev);
637 SSVAL(vwv + (smbXcli_conn_use_unicode(cli->conn) ? 8 : 7), 0, passlen);
639 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
640 user, strlen(user)+1, NULL);
641 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
642 workgroup, strlen(workgroup)+1, NULL);
643 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
646 version = talloc_asprintf(talloc_tos(), "Samba %s",
647 samba_version_string());
648 if (tevent_req_nomem(version, req)){
649 return tevent_req_post(req, ev);
651 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
652 version, strlen(version)+1, NULL);
653 TALLOC_FREE(version);
655 if (tevent_req_nomem(bytes, req)) {
656 return tevent_req_post(req, ev);
659 subreq = cli_smb_send(state, ev, cli, SMBsesssetupX, 0, 13, vwv,
660 talloc_get_size(bytes), bytes);
661 if (tevent_req_nomem(subreq, req)) {
662 return tevent_req_post(req, ev);
664 tevent_req_set_callback(subreq, cli_session_setup_plain_done, req);
668 static void cli_session_setup_plain_done(struct tevent_req *subreq)
670 struct tevent_req *req = tevent_req_callback_data(
671 subreq, struct tevent_req);
672 struct cli_session_setup_plain_state *state = tevent_req_data(
673 req, struct cli_session_setup_plain_state);
674 struct cli_state *cli = state->cli;
685 status = cli_smb_recv(subreq, state, &in, 3, &wct, &vwv,
688 if (tevent_req_nterror(req, status)) {
692 inhdr = in + NBT_HDR_SIZE;
695 cli_state_set_uid(state->cli, SVAL(inhdr, HDR_UID));
696 cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0);
698 status = smb_bytes_talloc_string(cli,
705 if (!NT_STATUS_IS_OK(status)) {
706 tevent_req_nterror(req, status);
711 status = smb_bytes_talloc_string(cli,
718 if (!NT_STATUS_IS_OK(status)) {
719 tevent_req_nterror(req, status);
724 status = smb_bytes_talloc_string(cli,
731 if (!NT_STATUS_IS_OK(status)) {
732 tevent_req_nterror(req, status);
737 status = cli_set_username(cli, state->user);
738 if (tevent_req_nterror(req, status)) {
742 tevent_req_done(req);
745 static NTSTATUS cli_session_setup_plain_recv(struct tevent_req *req)
747 return tevent_req_simple_recv_ntstatus(req);
750 static NTSTATUS cli_session_setup_plain(struct cli_state *cli,
751 const char *user, const char *pass,
752 const char *workgroup)
754 TALLOC_CTX *frame = talloc_stackframe();
755 struct event_context *ev;
756 struct tevent_req *req;
757 NTSTATUS status = NT_STATUS_NO_MEMORY;
759 if (smbXcli_conn_has_async_calls(cli->conn)) {
761 * Can't use sync call while an async call is in flight
763 status = NT_STATUS_INVALID_PARAMETER;
766 ev = event_context_init(frame);
770 req = cli_session_setup_plain_send(frame, ev, cli, user, pass,
775 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
778 status = cli_session_setup_plain_recv(req);
784 /****************************************************************************
785 do a NT1 NTLM/LM encrypted session setup - for when extended security
787 @param cli client state to create do session setup on
789 @param pass *either* cleartext password (passlen !=24) or LM response.
790 @param ntpass NT response, implies ntpasslen >=24, implies pass is not clear
791 @param workgroup The user's domain.
792 ****************************************************************************/
794 struct cli_session_setup_nt1_state {
795 struct cli_state *cli;
798 DATA_BLOB session_key;
802 static void cli_session_setup_nt1_done(struct tevent_req *subreq);
804 static struct tevent_req *cli_session_setup_nt1_send(
805 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
806 struct cli_state *cli, const char *user,
807 const char *pass, size_t passlen,
808 const char *ntpass, size_t ntpasslen,
809 const char *workgroup)
811 struct tevent_req *req, *subreq;
812 struct cli_session_setup_nt1_state *state;
813 DATA_BLOB lm_response = data_blob_null;
814 DATA_BLOB nt_response = data_blob_null;
815 DATA_BLOB session_key = data_blob_null;
818 char *workgroup_upper;
820 req = tevent_req_create(mem_ctx, &state,
821 struct cli_session_setup_nt1_state);
830 /* do nothing - guest login */
831 } else if (passlen != 24) {
832 if (lp_client_ntlmv2_auth()) {
833 DATA_BLOB server_chal;
834 DATA_BLOB names_blob;
837 data_blob_const(smb1cli_conn_server_challenge(cli->conn),
841 * note that the 'workgroup' here is a best
842 * guess - we don't know the server's domain
843 * at this point. Windows clients also don't
846 names_blob = NTLMv2_generate_names_blob(
847 NULL, NULL, workgroup);
849 if (tevent_req_nomem(names_blob.data, req)) {
850 return tevent_req_post(req, ev);
853 if (!SMBNTLMv2encrypt(NULL, user, workgroup, pass,
854 &server_chal, &names_blob,
855 &lm_response, &nt_response,
856 NULL, &session_key)) {
857 data_blob_free(&names_blob);
859 req, NT_STATUS_ACCESS_DENIED);
860 return tevent_req_post(req, ev);
862 data_blob_free(&names_blob);
866 E_md4hash(pass, nt_hash);
869 nt_response = data_blob_null;
871 nt_response = data_blob(NULL, 24);
872 if (tevent_req_nomem(nt_response.data, req)) {
873 return tevent_req_post(req, ev);
876 SMBNTencrypt(pass, smb1cli_conn_server_challenge(cli->conn),
879 /* non encrypted password supplied. Ignore ntpass. */
880 if (lp_client_lanman_auth()) {
882 lm_response = data_blob(NULL, 24);
883 if (tevent_req_nomem(lm_response.data, req)) {
884 return tevent_req_post(req, ev);
887 if (!SMBencrypt(pass,
888 smb1cli_conn_server_challenge(cli->conn),
891 * Oops, the LM response is
892 * invalid, just put the NT
893 * response there instead
895 data_blob_free(&lm_response);
896 lm_response = data_blob(
902 * LM disabled, place NT# in LM field
905 lm_response = data_blob(
906 nt_response.data, nt_response.length);
909 if (tevent_req_nomem(lm_response.data, req)) {
910 return tevent_req_post(req, ev);
913 session_key = data_blob(NULL, 16);
914 if (tevent_req_nomem(session_key.data, req)) {
915 return tevent_req_post(req, ev);
918 E_deshash(pass, session_key.data);
919 memset(&session_key.data[8], '\0', 8);
921 SMBsesskeygen_ntv1(nt_hash, session_key.data);
925 /* pre-encrypted password supplied. Only used for
926 security=server, can't do
927 signing because we don't have original key */
929 lm_response = data_blob(pass, passlen);
930 if (tevent_req_nomem(lm_response.data, req)) {
931 return tevent_req_post(req, ev);
934 nt_response = data_blob(ntpass, ntpasslen);
935 if (tevent_req_nomem(nt_response.data, req)) {
936 return tevent_req_post(req, ev);
941 state->response = data_blob_talloc(
942 state, lm_response.data, lm_response.length);
944 state->response = data_blob_talloc(
945 state, nt_response.data, nt_response.length);
947 if (tevent_req_nomem(state->response.data, req)) {
948 return tevent_req_post(req, ev);
951 if (session_key.data) {
952 state->session_key = data_blob_talloc(
953 state, session_key.data, session_key.length);
954 if (tevent_req_nomem(state->session_key.data, req)) {
955 return tevent_req_post(req, ev);
958 data_blob_free(&session_key);
960 SCVAL(vwv+0, 0, 0xff);
963 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
965 SSVAL(vwv+4, 0, cli_state_get_vc_num(cli));
966 SIVAL(vwv+5, 0, smb1cli_conn_server_session_key(cli->conn));
967 SSVAL(vwv+7, 0, lm_response.length);
968 SSVAL(vwv+8, 0, nt_response.length);
971 SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli, 0));
973 bytes = talloc_array(state, uint8_t,
974 lm_response.length + nt_response.length);
975 if (tevent_req_nomem(bytes, req)) {
976 return tevent_req_post(req, ev);
978 if (lm_response.length != 0) {
979 memcpy(bytes, lm_response.data, lm_response.length);
981 if (nt_response.length != 0) {
982 memcpy(bytes + lm_response.length,
983 nt_response.data, nt_response.length);
985 data_blob_free(&lm_response);
986 data_blob_free(&nt_response);
988 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
989 user, strlen(user)+1, NULL);
992 * Upper case here might help some NTLMv2 implementations
994 workgroup_upper = talloc_strdup_upper(talloc_tos(), workgroup);
995 if (tevent_req_nomem(workgroup_upper, req)) {
996 return tevent_req_post(req, ev);
998 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
999 workgroup_upper, strlen(workgroup_upper)+1,
1001 TALLOC_FREE(workgroup_upper);
1003 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "Unix", 5, NULL);
1004 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "Samba", 6, NULL);
1005 if (tevent_req_nomem(bytes, req)) {
1006 return tevent_req_post(req, ev);
1009 subreq = cli_smb_send(state, ev, cli, SMBsesssetupX, 0, 13, vwv,
1010 talloc_get_size(bytes), bytes);
1011 if (tevent_req_nomem(subreq, req)) {
1012 return tevent_req_post(req, ev);
1014 tevent_req_set_callback(subreq, cli_session_setup_nt1_done, req);
1018 static void cli_session_setup_nt1_done(struct tevent_req *subreq)
1020 struct tevent_req *req = tevent_req_callback_data(
1021 subreq, struct tevent_req);
1022 struct cli_session_setup_nt1_state *state = tevent_req_data(
1023 req, struct cli_session_setup_nt1_state);
1024 struct cli_state *cli = state->cli;
1035 status = cli_smb_recv(subreq, state, &in, 3, &wct, &vwv,
1036 &num_bytes, &bytes);
1037 TALLOC_FREE(subreq);
1038 if (!NT_STATUS_IS_OK(status)) {
1039 tevent_req_nterror(req, status);
1043 inhdr = in + NBT_HDR_SIZE;
1046 cli_state_set_uid(state->cli, SVAL(inhdr, HDR_UID));
1047 cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0);
1049 status = smb_bytes_talloc_string(cli,
1055 if (!NT_STATUS_IS_OK(status)) {
1056 tevent_req_nterror(req, status);
1061 status = smb_bytes_talloc_string(cli,
1067 if (!NT_STATUS_IS_OK(status)) {
1068 tevent_req_nterror(req, status);
1073 status = smb_bytes_talloc_string(cli,
1075 &cli->server_domain,
1079 if (!NT_STATUS_IS_OK(status)) {
1080 tevent_req_nterror(req, status);
1085 status = cli_set_username(cli, state->user);
1086 if (tevent_req_nterror(req, status)) {
1089 if (smb1cli_conn_activate_signing(cli->conn, state->session_key, state->response)
1090 && !smb1cli_conn_check_signing(cli->conn, (uint8_t *)in, 1)) {
1091 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1094 if (state->session_key.data) {
1095 struct smbXcli_session *session = state->cli->smb1.session;
1097 /* Have plaintext orginal */
1098 cli_set_session_key(cli, state->session_key);
1100 status = smb1cli_session_set_session_key(session,
1101 state->session_key);
1102 if (tevent_req_nterror(req, status)) {
1106 tevent_req_done(req);
1109 static NTSTATUS cli_session_setup_nt1_recv(struct tevent_req *req)
1111 return tevent_req_simple_recv_ntstatus(req);
1114 static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user,
1115 const char *pass, size_t passlen,
1116 const char *ntpass, size_t ntpasslen,
1117 const char *workgroup)
1119 TALLOC_CTX *frame = talloc_stackframe();
1120 struct event_context *ev;
1121 struct tevent_req *req;
1122 NTSTATUS status = NT_STATUS_NO_MEMORY;
1124 if (smbXcli_conn_has_async_calls(cli->conn)) {
1126 * Can't use sync call while an async call is in flight
1128 status = NT_STATUS_INVALID_PARAMETER;
1131 ev = event_context_init(frame);
1135 req = cli_session_setup_nt1_send(frame, ev, cli, user, pass, passlen,
1136 ntpass, ntpasslen, workgroup);
1140 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1143 status = cli_session_setup_nt1_recv(req);
1149 /* The following is calculated from :
1151 * (smb_wcnt * 2) = 24 (smb_wcnt == 12 in cli_session_setup_blob_send() )
1152 * (strlen("Unix") + 1 + strlen("Samba") + 1) * 2 = 22 (unicode strings at
1156 #define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22)
1158 struct cli_sesssetup_blob_state {
1159 struct tevent_context *ev;
1160 struct cli_state *cli;
1162 uint16_t max_blob_size;
1166 DATA_BLOB smb2_blob;
1167 struct iovec *recv_iov;
1174 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state *state,
1175 struct tevent_req **psubreq);
1176 static void cli_sesssetup_blob_done(struct tevent_req *subreq);
1178 static struct tevent_req *cli_sesssetup_blob_send(TALLOC_CTX *mem_ctx,
1179 struct tevent_context *ev,
1180 struct cli_state *cli,
1183 struct tevent_req *req, *subreq;
1184 struct cli_sesssetup_blob_state *state;
1185 uint32_t usable_space;
1187 req = tevent_req_create(mem_ctx, &state,
1188 struct cli_sesssetup_blob_state);
1196 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
1197 usable_space = UINT16_MAX;
1199 usable_space = cli_state_available_size(cli,
1200 BASE_SESSSETUP_BLOB_PACKET_SIZE);
1203 if (usable_space == 0) {
1204 DEBUG(1, ("cli_session_setup_blob: cli->max_xmit too small "
1205 "(not possible to send %u bytes)\n",
1206 BASE_SESSSETUP_BLOB_PACKET_SIZE + 1));
1207 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1208 return tevent_req_post(req, ev);
1210 state->max_blob_size = MIN(usable_space, 0xFFFF);
1212 if (!cli_sesssetup_blob_next(state, &subreq)) {
1213 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1214 return tevent_req_post(req, ev);
1216 tevent_req_set_callback(subreq, cli_sesssetup_blob_done, req);
1220 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state *state,
1221 struct tevent_req **psubreq)
1223 struct tevent_req *subreq;
1226 thistime = MIN(state->blob.length, state->max_blob_size);
1228 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
1230 state->smb2_blob.data = state->blob.data;
1231 state->smb2_blob.length = thistime;
1233 state->blob.data += thistime;
1234 state->blob.length -= thistime;
1236 subreq = smb2cli_session_setup_send(state, state->ev,
1238 state->cli->timeout,
1239 state->cli->smb2.session,
1241 SMB2_CAP_DFS, /* in_capabilities */
1243 0, /* in_previous_session_id */
1245 if (subreq == NULL) {
1252 SCVAL(state->vwv+0, 0, 0xFF);
1253 SCVAL(state->vwv+0, 1, 0);
1254 SSVAL(state->vwv+1, 0, 0);
1255 SSVAL(state->vwv+2, 0, CLI_BUFFER_SIZE);
1256 SSVAL(state->vwv+3, 0, 2);
1257 SSVAL(state->vwv+4, 0, 1);
1258 SIVAL(state->vwv+5, 0, 0);
1260 SSVAL(state->vwv+7, 0, thistime);
1262 SSVAL(state->vwv+8, 0, 0);
1263 SSVAL(state->vwv+9, 0, 0);
1264 SIVAL(state->vwv+10, 0,
1265 cli_session_setup_capabilities(state->cli, CAP_EXTENDED_SECURITY));
1267 state->buf = (uint8_t *)talloc_memdup(state, state->blob.data,
1269 if (state->buf == NULL) {
1272 state->blob.data += thistime;
1273 state->blob.length -= thistime;
1275 state->buf = smb_bytes_push_str(state->buf, smbXcli_conn_use_unicode(state->cli->conn),
1277 state->buf = smb_bytes_push_str(state->buf, smbXcli_conn_use_unicode(state->cli->conn),
1279 if (state->buf == NULL) {
1282 subreq = cli_smb_send(state, state->ev, state->cli, SMBsesssetupX, 0,
1284 talloc_get_size(state->buf), state->buf);
1285 if (subreq == NULL) {
1292 static void cli_sesssetup_blob_done(struct tevent_req *subreq)
1294 struct tevent_req *req = tevent_req_callback_data(
1295 subreq, struct tevent_req);
1296 struct cli_sesssetup_blob_state *state = tevent_req_data(
1297 req, struct cli_sesssetup_blob_state);
1298 struct cli_state *cli = state->cli;
1305 uint16_t blob_length;
1310 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
1311 status = smb2cli_session_setup_recv(subreq, state,
1315 status = cli_smb_recv(subreq, state, &in, 4, &wct, &vwv,
1316 &num_bytes, &bytes);
1317 TALLOC_FREE(state->buf);
1319 TALLOC_FREE(subreq);
1320 if (!NT_STATUS_IS_OK(status)
1321 && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1322 tevent_req_nterror(req, status);
1326 state->status = status;
1328 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
1333 inhdr = in + NBT_HDR_SIZE;
1334 cli_state_set_uid(state->cli, SVAL(inhdr, HDR_UID));
1335 cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0);
1337 blob_length = SVAL(vwv+3, 0);
1338 if (blob_length > num_bytes) {
1339 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1342 state->ret_blob = data_blob_const(bytes, blob_length);
1344 p = bytes + blob_length;
1346 status = smb_bytes_talloc_string(cli,
1353 if (!NT_STATUS_IS_OK(status)) {
1354 tevent_req_nterror(req, status);
1359 status = smb_bytes_talloc_string(cli,
1366 if (!NT_STATUS_IS_OK(status)) {
1367 tevent_req_nterror(req, status);
1372 status = smb_bytes_talloc_string(cli,
1374 &cli->server_domain,
1379 if (!NT_STATUS_IS_OK(status)) {
1380 tevent_req_nterror(req, status);
1386 if (state->blob.length != 0) {
1390 if (!cli_sesssetup_blob_next(state, &subreq)) {
1391 tevent_req_oom(req);
1394 tevent_req_set_callback(subreq, cli_sesssetup_blob_done, req);
1397 tevent_req_done(req);
1400 static NTSTATUS cli_sesssetup_blob_recv(struct tevent_req *req,
1401 TALLOC_CTX *mem_ctx,
1404 struct iovec **precv_iov)
1406 struct cli_sesssetup_blob_state *state = tevent_req_data(
1407 req, struct cli_sesssetup_blob_state);
1410 struct iovec *recv_iov;
1412 if (tevent_req_is_nterror(req, &status)) {
1413 TALLOC_FREE(state->cli->smb2.session);
1414 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
1418 inbuf = talloc_move(mem_ctx, &state->inbuf);
1419 recv_iov = talloc_move(mem_ctx, &state->recv_iov);
1420 if (pblob != NULL) {
1421 *pblob = state->ret_blob;
1423 if (pinbuf != NULL) {
1426 if (precv_iov != NULL) {
1427 *precv_iov = recv_iov;
1429 /* could be NT_STATUS_MORE_PROCESSING_REQUIRED */
1430 return state->status;
1435 /****************************************************************************
1436 Use in-memory credentials cache
1437 ****************************************************************************/
1439 static void use_in_memory_ccache(void) {
1440 setenv(KRB5_ENV_CCNAME, "MEMORY:cliconnect", 1);
1443 /****************************************************************************
1444 Do a spnego/kerberos encrypted session setup.
1445 ****************************************************************************/
1447 struct cli_session_setup_kerberos_state {
1448 struct cli_state *cli;
1449 DATA_BLOB negTokenTarg;
1450 DATA_BLOB session_key_krb5;
1451 ADS_STATUS ads_status;
1454 static void cli_session_setup_kerberos_done(struct tevent_req *subreq);
1456 static struct tevent_req *cli_session_setup_kerberos_send(
1457 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
1458 const char *principal)
1460 struct tevent_req *req, *subreq;
1461 struct cli_session_setup_kerberos_state *state;
1464 DEBUG(2,("Doing kerberos session setup\n"));
1466 req = tevent_req_create(mem_ctx, &state,
1467 struct cli_session_setup_kerberos_state);
1472 state->ads_status = ADS_SUCCESS;
1475 * Ok, this is cheating: spnego_gen_krb5_negTokenInit can block if
1476 * we have to acquire a ticket. To be fixed later :-)
1478 rc = spnego_gen_krb5_negTokenInit(state, principal, 0, &state->negTokenTarg,
1479 &state->session_key_krb5, 0, NULL);
1481 DEBUG(1, ("cli_session_setup_kerberos: "
1482 "spnego_gen_krb5_negTokenInit failed: %s\n",
1483 error_message(rc)));
1484 state->ads_status = ADS_ERROR_KRB5(rc);
1485 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
1486 return tevent_req_post(req, ev);
1490 file_save("negTokenTarg.dat", state->negTokenTarg.data,
1491 state->negTokenTarg.length);
1494 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
1495 state->cli->smb2.session = smbXcli_session_create(cli,
1497 if (tevent_req_nomem(state->cli->smb2.session, req)) {
1498 return tevent_req_post(req, ev);
1502 subreq = cli_sesssetup_blob_send(state, ev, cli, state->negTokenTarg);
1503 if (tevent_req_nomem(subreq, req)) {
1504 return tevent_req_post(req, ev);
1506 tevent_req_set_callback(subreq, cli_session_setup_kerberos_done, req);
1510 static void cli_session_setup_kerberos_done(struct tevent_req *subreq)
1512 struct tevent_req *req = tevent_req_callback_data(
1513 subreq, struct tevent_req);
1514 struct cli_session_setup_kerberos_state *state = tevent_req_data(
1515 req, struct cli_session_setup_kerberos_state);
1516 uint8_t *inbuf = NULL;
1517 struct iovec *recv_iov = NULL;
1520 status = cli_sesssetup_blob_recv(subreq, state,
1521 NULL, &inbuf, &recv_iov);
1522 TALLOC_FREE(subreq);
1523 if (!NT_STATUS_IS_OK(status)) {
1524 tevent_req_nterror(req, status);
1528 cli_set_session_key(state->cli, state->session_key_krb5);
1530 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
1531 struct smbXcli_session *session = state->cli->smb2.session;
1532 status = smb2cli_session_set_session_key(session,
1533 state->session_key_krb5,
1535 if (tevent_req_nterror(req, status)) {
1539 struct smbXcli_session *session = state->cli->smb1.session;
1541 status = smb1cli_session_set_session_key(session,
1542 state->session_key_krb5);
1543 if (tevent_req_nterror(req, status)) {
1547 if (smb1cli_conn_activate_signing(state->cli->conn, state->session_key_krb5,
1549 && !smb1cli_conn_check_signing(state->cli->conn, inbuf, 1)) {
1550 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1555 tevent_req_done(req);
1558 static ADS_STATUS cli_session_setup_kerberos_recv(struct tevent_req *req)
1560 struct cli_session_setup_kerberos_state *state = tevent_req_data(
1561 req, struct cli_session_setup_kerberos_state);
1564 if (tevent_req_is_nterror(req, &status)) {
1565 return ADS_ERROR_NT(status);
1567 return state->ads_status;
1570 static ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli,
1571 const char *principal)
1573 struct tevent_context *ev;
1574 struct tevent_req *req;
1575 ADS_STATUS status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1577 if (smbXcli_conn_has_async_calls(cli->conn)) {
1578 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1580 ev = tevent_context_init(talloc_tos());
1584 req = cli_session_setup_kerberos_send(ev, ev, cli, principal);
1588 if (!tevent_req_poll(req, ev)) {
1589 status = ADS_ERROR_SYSTEM(errno);
1592 status = cli_session_setup_kerberos_recv(req);
1597 #endif /* HAVE_KRB5 */
1599 /****************************************************************************
1600 Do a spnego/NTLMSSP encrypted session setup.
1601 ****************************************************************************/
1603 struct cli_session_setup_ntlmssp_state {
1604 struct tevent_context *ev;
1605 struct cli_state *cli;
1606 struct ntlmssp_state *ntlmssp_state;
1611 static int cli_session_setup_ntlmssp_state_destructor(
1612 struct cli_session_setup_ntlmssp_state *state)
1614 if (state->ntlmssp_state != NULL) {
1615 TALLOC_FREE(state->ntlmssp_state);
1620 static void cli_session_setup_ntlmssp_done(struct tevent_req *req);
1622 static struct tevent_req *cli_session_setup_ntlmssp_send(
1623 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
1624 const char *user, const char *pass, const char *domain)
1626 struct tevent_req *req, *subreq;
1627 struct cli_session_setup_ntlmssp_state *state;
1630 const char *OIDs_ntlm[] = {OID_NTLMSSP, NULL};
1632 req = tevent_req_create(mem_ctx, &state,
1633 struct cli_session_setup_ntlmssp_state);
1641 state->ntlmssp_state = NULL;
1642 talloc_set_destructor(
1643 state, cli_session_setup_ntlmssp_state_destructor);
1645 status = ntlmssp_client_start(state,
1648 lp_client_ntlmv2_auth(),
1649 &state->ntlmssp_state);
1650 if (!NT_STATUS_IS_OK(status)) {
1653 ntlmssp_want_feature(state->ntlmssp_state,
1654 NTLMSSP_FEATURE_SESSION_KEY);
1655 if (cli->use_ccache) {
1656 ntlmssp_want_feature(state->ntlmssp_state,
1657 NTLMSSP_FEATURE_CCACHE);
1659 status = ntlmssp_set_username(state->ntlmssp_state, user);
1660 if (!NT_STATUS_IS_OK(status)) {
1663 status = ntlmssp_set_domain(state->ntlmssp_state, domain);
1664 if (!NT_STATUS_IS_OK(status)) {
1667 if (cli->pw_nt_hash) {
1668 status = ntlmssp_set_password_hash(state->ntlmssp_state, pass);
1670 status = ntlmssp_set_password(state->ntlmssp_state, pass);
1672 if (!NT_STATUS_IS_OK(status)) {
1675 status = ntlmssp_update(state->ntlmssp_state, data_blob_null,
1677 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1681 state->blob_out = spnego_gen_negTokenInit(state, OIDs_ntlm, &blob_out, NULL);
1682 data_blob_free(&blob_out);
1684 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
1685 state->cli->smb2.session = smbXcli_session_create(cli,
1687 if (tevent_req_nomem(state->cli->smb2.session, req)) {
1688 return tevent_req_post(req, ev);
1692 subreq = cli_sesssetup_blob_send(state, ev, cli, state->blob_out);
1693 if (tevent_req_nomem(subreq, req)) {
1694 return tevent_req_post(req, ev);
1696 tevent_req_set_callback(subreq, cli_session_setup_ntlmssp_done, req);
1699 tevent_req_nterror(req, status);
1700 return tevent_req_post(req, ev);
1703 static void cli_session_setup_ntlmssp_done(struct tevent_req *subreq)
1705 struct tevent_req *req = tevent_req_callback_data(
1706 subreq, struct tevent_req);
1707 struct cli_session_setup_ntlmssp_state *state = tevent_req_data(
1708 req, struct cli_session_setup_ntlmssp_state);
1709 DATA_BLOB blob_in, msg_in, blob_out;
1710 uint8_t *inbuf = NULL;
1711 struct iovec *recv_iov = NULL;
1715 status = cli_sesssetup_blob_recv(subreq, talloc_tos(), &blob_in,
1717 TALLOC_FREE(subreq);
1718 data_blob_free(&state->blob_out);
1720 if (NT_STATUS_IS_OK(status)) {
1721 if (state->cli->server_domain[0] == '\0') {
1722 TALLOC_FREE(state->cli->server_domain);
1723 state->cli->server_domain = talloc_strdup(state->cli,
1724 state->ntlmssp_state->server.netbios_domain);
1725 if (state->cli->server_domain == NULL) {
1726 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1730 cli_set_session_key(
1731 state->cli, state->ntlmssp_state->session_key);
1733 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
1734 struct smbXcli_session *session = state->cli->smb2.session;
1736 if (ntlmssp_is_anonymous(state->ntlmssp_state)) {
1738 * Windows server does not set the
1739 * SMB2_SESSION_FLAG_IS_GUEST nor
1740 * SMB2_SESSION_FLAG_IS_NULL flag.
1742 * This fix makes sure we do not try
1743 * to verify a signature on the final
1744 * session setup response.
1746 TALLOC_FREE(state->ntlmssp_state);
1747 tevent_req_done(req);
1751 status = smb2cli_session_set_session_key(session,
1752 state->ntlmssp_state->session_key,
1754 if (tevent_req_nterror(req, status)) {
1758 struct smbXcli_session *session = state->cli->smb1.session;
1760 status = smb1cli_session_set_session_key(session,
1761 state->ntlmssp_state->session_key);
1762 if (tevent_req_nterror(req, status)) {
1766 if (smb1cli_conn_activate_signing(
1767 state->cli->conn, state->ntlmssp_state->session_key,
1769 && !smb1cli_conn_check_signing(state->cli->conn, inbuf, 1)) {
1770 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
1774 TALLOC_FREE(state->ntlmssp_state);
1775 tevent_req_done(req);
1778 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1779 tevent_req_nterror(req, status);
1783 if (blob_in.length == 0) {
1784 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
1788 if ((state->turn == 1)
1789 && NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1790 DATA_BLOB tmp_blob = data_blob_null;
1791 /* the server might give us back two challenges */
1792 parse_ret = spnego_parse_challenge(state, blob_in, &msg_in,
1794 data_blob_free(&tmp_blob);
1796 parse_ret = spnego_parse_auth_response(state, blob_in, status,
1797 OID_NTLMSSP, &msg_in);
1802 DEBUG(3,("Failed to parse auth response\n"));
1803 if (NT_STATUS_IS_OK(status)
1804 || NT_STATUS_EQUAL(status,
1805 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1807 req, NT_STATUS_INVALID_NETWORK_RESPONSE);
1812 status = ntlmssp_update(state->ntlmssp_state, msg_in, &blob_out);
1814 if (!NT_STATUS_IS_OK(status)
1815 && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1816 TALLOC_FREE(state->ntlmssp_state);
1817 tevent_req_nterror(req, status);
1821 state->blob_out = spnego_gen_auth(state, blob_out);
1822 if (tevent_req_nomem(state->blob_out.data, req)) {
1826 subreq = cli_sesssetup_blob_send(state, state->ev, state->cli,
1828 if (tevent_req_nomem(subreq, req)) {
1831 tevent_req_set_callback(subreq, cli_session_setup_ntlmssp_done, req);
1834 static NTSTATUS cli_session_setup_ntlmssp_recv(struct tevent_req *req)
1836 struct cli_session_setup_ntlmssp_state *state = tevent_req_data(
1837 req, struct cli_session_setup_ntlmssp_state);
1840 if (tevent_req_is_nterror(req, &status)) {
1841 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
1844 return NT_STATUS_OK;
1847 static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli,
1852 struct tevent_context *ev;
1853 struct tevent_req *req;
1854 NTSTATUS status = NT_STATUS_NO_MEMORY;
1856 if (smbXcli_conn_has_async_calls(cli->conn)) {
1857 return NT_STATUS_INVALID_PARAMETER;
1859 ev = tevent_context_init(talloc_tos());
1863 req = cli_session_setup_ntlmssp_send(ev, ev, cli, user, pass, domain);
1867 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1870 status = cli_session_setup_ntlmssp_recv(req);
1876 /****************************************************************************
1877 Do a spnego encrypted session setup.
1879 user_domain: The shortname of the domain the user/machine is a member of.
1880 dest_realm: The realm we're connecting to, if NULL we use our default realm.
1881 ****************************************************************************/
1883 static ADS_STATUS cli_session_setup_spnego(struct cli_state *cli,
1886 const char *user_domain,
1887 const char * dest_realm)
1889 char *principal = NULL;
1890 char *OIDs[ASN1_MAX_OIDS];
1892 const DATA_BLOB *server_blob;
1893 DATA_BLOB blob = data_blob_null;
1894 const char *p = NULL;
1895 char *account = NULL;
1898 server_blob = smbXcli_conn_server_gss_blob(cli->conn);
1900 blob = data_blob(server_blob->data, server_blob->length);
1903 DEBUG(3,("Doing spnego session setup (blob length=%lu)\n", (unsigned long)blob.length));
1905 /* the server might not even do spnego */
1906 if (blob.length == 0) {
1907 DEBUG(3,("server didn't supply a full spnego negprot\n"));
1912 file_save("negprot.dat", cli->secblob.data, cli->secblob.length);
1915 /* The server sent us the first part of the SPNEGO exchange in the
1916 * negprot reply. It is WRONG to depend on the principal sent in the
1917 * negprot reply, but right now we do it. If we don't receive one,
1918 * we try to best guess, then fall back to NTLM. */
1919 if (!spnego_parse_negTokenInit(talloc_tos(), blob, OIDs, &principal, NULL) ||
1921 data_blob_free(&blob);
1922 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1924 data_blob_free(&blob);
1926 /* make sure the server understands kerberos */
1927 for (i=0;OIDs[i];i++) {
1929 DEBUG(3,("got OID=%s\n", OIDs[i]));
1931 DEBUGADD(3,("got OID=%s\n", OIDs[i]));
1932 if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0 ||
1933 strcmp(OIDs[i], OID_KERBEROS5) == 0) {
1934 cli->got_kerberos_mechanism = True;
1936 talloc_free(OIDs[i]);
1939 DEBUG(3,("got principal=%s\n", principal ? principal : "<null>"));
1941 status = cli_set_username(cli, user);
1942 if (!NT_STATUS_IS_OK(status)) {
1943 TALLOC_FREE(principal);
1944 return ADS_ERROR_NT(status);
1948 /* If password is set we reauthenticate to kerberos server
1949 * and do not store results */
1951 if (user && *user && cli->got_kerberos_mechanism && cli->use_kerberos) {
1953 const char *remote_name = smbXcli_conn_remote_name(cli->conn);
1955 if (pass && *pass) {
1958 use_in_memory_ccache();
1959 ret = kerberos_kinit_password(user, pass, 0 /* no time correction for now */, NULL);
1962 TALLOC_FREE(principal);
1963 DEBUG(0, ("Kinit failed: %s\n", error_message(ret)));
1964 if (cli->fallback_after_kerberos)
1966 return ADS_ERROR_KRB5(ret);
1970 /* We may not be allowed to use the server-supplied SPNEGO principal, or it may not have been supplied to us
1972 if (!lp_client_use_spnego_principal() || strequal(principal, ADS_IGNORE_PRINCIPAL)) {
1973 TALLOC_FREE(principal);
1976 if (principal == NULL &&
1977 !is_ipaddress(remote_name) &&
1978 !strequal(STAR_SMBSERVER,
1980 DEBUG(3,("cli_session_setup_spnego: using target "
1981 "hostname not SPNEGO principal\n"));
1984 char *realm = strupper_talloc(talloc_tos(), dest_realm);
1986 principal = talloc_asprintf(talloc_tos(),
1993 principal = kerberos_get_principal_from_service_hostname(talloc_tos(),
2000 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
2002 DEBUG(3,("cli_session_setup_spnego: guessed "
2003 "server principal=%s\n",
2004 principal ? principal : "<null>"));
2008 rc = cli_session_setup_kerberos(cli, principal);
2009 if (ADS_ERR_OK(rc) || !cli->fallback_after_kerberos) {
2010 TALLOC_FREE(principal);
2017 TALLOC_FREE(principal);
2021 account = talloc_strdup(talloc_tos(), user);
2023 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
2026 /* when falling back to ntlmssp while authenticating with a machine
2027 * account strip off the realm - gd */
2029 if ((p = strchr_m(user, '@')) != NULL) {
2030 account[PTR_DIFF(p,user)] = '\0';
2033 return ADS_ERROR_NT(cli_session_setup_ntlmssp(cli, account, pass, user_domain));
2036 /****************************************************************************
2037 Send a session setup. The username and workgroup is in UNIX character
2038 format and must be converted to DOS codepage format before sending. If the
2039 password is in plaintext, the same should be done.
2040 ****************************************************************************/
2042 NTSTATUS cli_session_setup(struct cli_state *cli,
2044 const char *pass, int passlen,
2045 const char *ntpass, int ntpasslen,
2046 const char *workgroup)
2050 uint16_t sec_mode = smb1cli_conn_server_security_mode(cli->conn);
2053 user2 = talloc_strdup(talloc_tos(), user);
2055 user2 = talloc_strdup(talloc_tos(), "");
2057 if (user2 == NULL) {
2058 return NT_STATUS_NO_MEMORY;
2065 /* allow for workgroups as part of the username */
2066 if ((p=strchr_m(user2,'\\')) || (p=strchr_m(user2,'/')) ||
2067 (p=strchr_m(user2,*lp_winbind_separator()))) {
2074 if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_LANMAN1) {
2075 return NT_STATUS_OK;
2078 /* now work out what sort of session setup we are going to
2079 do. I have split this into separate functions to make the
2080 flow a bit easier to understand (tridge) */
2082 /* if its an older server then we have to use the older request format */
2084 if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_NT1) {
2085 if (!lp_client_lanman_auth() && passlen != 24 && (*pass)) {
2086 DEBUG(1, ("Server requested LM password but 'client lanman auth = no'"
2087 " or 'client ntlmv2 auth = yes'\n"));
2088 return NT_STATUS_ACCESS_DENIED;
2091 if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0 &&
2092 !lp_client_plaintext_auth() && (*pass)) {
2093 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
2094 " or 'client ntlmv2 auth = yes'\n"));
2095 return NT_STATUS_ACCESS_DENIED;
2098 return cli_session_setup_lanman2(cli, user, pass, passlen,
2102 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
2103 const char *remote_realm = cli_state_remote_realm(cli);
2104 ADS_STATUS status = cli_session_setup_spnego(cli, user, pass,
2107 if (!ADS_ERR_OK(status)) {
2108 DEBUG(3, ("SMB2-SPNEGO login failed: %s\n", ads_errstr(status)));
2109 return ads_ntstatus(status);
2111 return NT_STATUS_OK;
2114 /* if no user is supplied then we have to do an anonymous connection.
2115 passwords are ignored */
2117 if (!user || !*user)
2118 return cli_session_setup_guest(cli);
2120 /* if the server is share level then send a plaintext null
2121 password at this point. The password is sent in the tree
2124 if ((sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0)
2125 return cli_session_setup_plain(cli, user, "", workgroup);
2127 /* if the server doesn't support encryption then we have to use
2128 plaintext. The second password is ignored */
2130 if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) {
2131 if (!lp_client_plaintext_auth() && (*pass)) {
2132 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
2133 " or 'client ntlmv2 auth = yes'\n"));
2134 return NT_STATUS_ACCESS_DENIED;
2136 return cli_session_setup_plain(cli, user, pass, workgroup);
2139 /* if the server supports extended security then use SPNEGO */
2141 if (smb1cli_conn_capabilities(cli->conn) & CAP_EXTENDED_SECURITY) {
2142 const char *remote_realm = cli_state_remote_realm(cli);
2143 ADS_STATUS status = cli_session_setup_spnego(cli, user, pass,
2146 if (!ADS_ERR_OK(status)) {
2147 DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status)));
2148 return ads_ntstatus(status);
2153 /* otherwise do a NT1 style session setup */
2154 status = cli_session_setup_nt1(cli, user, pass, passlen,
2155 ntpass, ntpasslen, workgroup);
2156 if (!NT_STATUS_IS_OK(status)) {
2157 DEBUG(3,("cli_session_setup: NT1 session setup "
2158 "failed: %s\n", nt_errstr(status)));
2163 return NT_STATUS_OK;
2166 /****************************************************************************
2168 *****************************************************************************/
2170 struct cli_ulogoff_state {
2171 struct cli_state *cli;
2175 static void cli_ulogoff_done(struct tevent_req *subreq);
2177 struct tevent_req *cli_ulogoff_send(TALLOC_CTX *mem_ctx,
2178 struct tevent_context *ev,
2179 struct cli_state *cli)
2181 struct tevent_req *req, *subreq;
2182 struct cli_ulogoff_state *state;
2184 req = tevent_req_create(mem_ctx, &state, struct cli_ulogoff_state);
2190 SCVAL(state->vwv+0, 0, 0xFF);
2191 SCVAL(state->vwv+1, 0, 0);
2192 SSVAL(state->vwv+2, 0, 0);
2194 subreq = cli_smb_send(state, ev, cli, SMBulogoffX, 0, 2, state->vwv,
2196 if (tevent_req_nomem(subreq, req)) {
2197 return tevent_req_post(req, ev);
2199 tevent_req_set_callback(subreq, cli_ulogoff_done, req);
2203 static void cli_ulogoff_done(struct tevent_req *subreq)
2205 struct tevent_req *req = tevent_req_callback_data(
2206 subreq, struct tevent_req);
2207 struct cli_ulogoff_state *state = tevent_req_data(
2208 req, struct cli_ulogoff_state);
2211 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
2212 if (!NT_STATUS_IS_OK(status)) {
2213 tevent_req_nterror(req, status);
2216 cli_state_set_uid(state->cli, UID_FIELD_INVALID);
2217 tevent_req_done(req);
2220 NTSTATUS cli_ulogoff_recv(struct tevent_req *req)
2222 return tevent_req_simple_recv_ntstatus(req);
2225 NTSTATUS cli_ulogoff(struct cli_state *cli)
2227 struct tevent_context *ev;
2228 struct tevent_req *req;
2229 NTSTATUS status = NT_STATUS_NO_MEMORY;
2231 if (smbXcli_conn_has_async_calls(cli->conn)) {
2232 return NT_STATUS_INVALID_PARAMETER;
2234 ev = tevent_context_init(talloc_tos());
2238 req = cli_ulogoff_send(ev, ev, cli);
2242 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2245 status = cli_ulogoff_recv(req);
2251 /****************************************************************************
2253 ****************************************************************************/
2255 struct cli_tcon_andx_state {
2256 struct cli_state *cli;
2261 static void cli_tcon_andx_done(struct tevent_req *subreq);
2263 struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx,
2264 struct event_context *ev,
2265 struct cli_state *cli,
2266 const char *share, const char *dev,
2267 const char *pass, int passlen,
2268 struct tevent_req **psmbreq)
2270 struct tevent_req *req, *subreq;
2271 struct cli_tcon_andx_state *state;
2276 uint16_t sec_mode = smb1cli_conn_server_security_mode(cli->conn);
2280 req = tevent_req_create(mem_ctx, &state, struct cli_tcon_andx_state);
2287 cli->share = talloc_strdup(cli, share);
2292 /* in user level security don't send a password now */
2293 if (sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {
2296 } else if (pass == NULL) {
2297 DEBUG(1, ("Server not using user level security and no "
2298 "password supplied.\n"));
2302 if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) &&
2303 *pass && passlen != 24) {
2304 if (!lp_client_lanman_auth()) {
2305 DEBUG(1, ("Server requested LANMAN password "
2306 "(share-level security) but "
2307 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
2312 * Non-encrypted passwords - convert to DOS codepage before
2315 SMBencrypt(pass, smb1cli_conn_server_challenge(cli->conn), p24);
2317 pass = (const char *)p24;
2319 if((sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL
2320 |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE))
2324 if (!lp_client_plaintext_auth() && (*pass)) {
2325 DEBUG(1, ("Server requested PLAINTEXT "
2327 "'client plaintext auth = no' or 'client ntlmv2 auth = yes'\n"));
2332 * Non-encrypted passwords - convert to DOS codepage
2335 tmp_pass = talloc_array(talloc_tos(), uint8, 0);
2336 if (tevent_req_nomem(tmp_pass, req)) {
2337 return tevent_req_post(req, ev);
2339 tmp_pass = trans2_bytes_push_str(tmp_pass,
2340 false, /* always DOS */
2344 if (tevent_req_nomem(tmp_pass, req)) {
2345 return tevent_req_post(req, ev);
2347 pass = (const char *)tmp_pass;
2348 passlen = talloc_get_size(tmp_pass);
2352 SCVAL(vwv+0, 0, 0xFF);
2355 SSVAL(vwv+2, 0, TCONX_FLAG_EXTENDED_RESPONSE);
2356 SSVAL(vwv+3, 0, passlen);
2358 if (passlen && pass) {
2359 bytes = (uint8_t *)talloc_memdup(state, pass, passlen);
2361 bytes = talloc_array(state, uint8_t, 0);
2367 tmp = talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
2368 smbXcli_conn_remote_name(cli->conn), share);
2373 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), tmp, strlen(tmp)+1,
2378 * Add the devicetype
2380 tmp = talloc_strdup_upper(talloc_tos(), dev);
2385 bytes = smb_bytes_push_str(bytes, false, tmp, strlen(tmp)+1, NULL);
2388 if (bytes == NULL) {
2393 state->bytes.iov_base = (void *)bytes;
2394 state->bytes.iov_len = talloc_get_size(bytes);
2396 subreq = cli_smb_req_create(state, ev, cli, SMBtconX, 0, 4, vwv,
2398 if (subreq == NULL) {
2402 tevent_req_set_callback(subreq, cli_tcon_andx_done, req);
2407 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
2408 return tevent_req_post(req, ev);
2411 struct tevent_req *cli_tcon_andx_send(TALLOC_CTX *mem_ctx,
2412 struct event_context *ev,
2413 struct cli_state *cli,
2414 const char *share, const char *dev,
2415 const char *pass, int passlen)
2417 struct tevent_req *req, *subreq;
2420 req = cli_tcon_andx_create(mem_ctx, ev, cli, share, dev, pass, passlen,
2425 if (subreq == NULL) {
2428 status = smb1cli_req_chain_submit(&subreq, 1);
2429 if (!NT_STATUS_IS_OK(status)) {
2430 tevent_req_nterror(req, status);
2431 return tevent_req_post(req, ev);
2436 static void cli_tcon_andx_done(struct tevent_req *subreq)
2438 struct tevent_req *req = tevent_req_callback_data(
2439 subreq, struct tevent_req);
2440 struct cli_tcon_andx_state *state = tevent_req_data(
2441 req, struct cli_tcon_andx_state);
2442 struct cli_state *cli = state->cli;
2451 status = cli_smb_recv(subreq, state, &in, 0, &wct, &vwv,
2452 &num_bytes, &bytes);
2453 TALLOC_FREE(subreq);
2454 if (!NT_STATUS_IS_OK(status)) {
2455 tevent_req_nterror(req, status);
2459 inhdr = in + NBT_HDR_SIZE;
2462 if (clistr_pull_talloc(cli,
2463 (const char *)inhdr,
2464 SVAL(inhdr, HDR_FLG2),
2468 STR_TERMINATE|STR_ASCII) == -1) {
2469 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2473 cli->dev = talloc_strdup(cli, "");
2474 if (cli->dev == NULL) {
2475 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
2480 if ((smbXcli_conn_protocol(cli->conn) >= PROTOCOL_NT1) && (num_bytes == 3)) {
2481 /* almost certainly win95 - enable bug fixes */
2486 * Make sure that we have the optional support 16-bit field. WCT > 2.
2487 * Avoids issues when connecting to Win9x boxes sharing files
2490 cli->dfsroot = false;
2492 if ((wct > 2) && (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_LANMAN2)) {
2493 cli->dfsroot = ((SVAL(vwv+2, 0) & SMB_SHARE_IN_DFS) != 0);
2496 cli_state_set_tid(cli, SVAL(inhdr, HDR_TID));
2497 tevent_req_done(req);
2500 NTSTATUS cli_tcon_andx_recv(struct tevent_req *req)
2502 return tevent_req_simple_recv_ntstatus(req);
2505 NTSTATUS cli_tcon_andx(struct cli_state *cli, const char *share,
2506 const char *dev, const char *pass, int passlen)
2508 TALLOC_CTX *frame = talloc_stackframe();
2509 struct event_context *ev;
2510 struct tevent_req *req;
2511 NTSTATUS status = NT_STATUS_OK;
2513 if (smbXcli_conn_has_async_calls(cli->conn)) {
2515 * Can't use sync call while an async call is in flight
2517 status = NT_STATUS_INVALID_PARAMETER;
2521 ev = event_context_init(frame);
2523 status = NT_STATUS_NO_MEMORY;
2527 req = cli_tcon_andx_send(frame, ev, cli, share, dev, pass, passlen);
2529 status = NT_STATUS_NO_MEMORY;
2533 if (!tevent_req_poll(req, ev)) {
2534 status = map_nt_error_from_unix(errno);
2538 status = cli_tcon_andx_recv(req);
2544 NTSTATUS cli_tree_connect(struct cli_state *cli, const char *share,
2545 const char *dev, const char *pass, int passlen)
2548 uint16_t max_xmit = 0;
2551 cli->share = talloc_strdup(cli, share);
2553 return NT_STATUS_NO_MEMORY;
2556 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
2557 return smb2cli_tcon(cli, share);
2560 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_LANMAN1) {
2561 return cli_tcon_andx(cli, share, dev, pass, passlen);
2564 status = cli_raw_tcon(cli, share, pass, dev, &max_xmit, &tid);
2565 if (!NT_STATUS_IS_OK(status)) {
2569 cli_state_set_tid(cli, tid);
2571 return NT_STATUS_OK;
2574 /****************************************************************************
2575 Send a tree disconnect.
2576 ****************************************************************************/
2578 struct cli_tdis_state {
2579 struct cli_state *cli;
2582 static void cli_tdis_done(struct tevent_req *subreq);
2584 struct tevent_req *cli_tdis_send(TALLOC_CTX *mem_ctx,
2585 struct tevent_context *ev,
2586 struct cli_state *cli)
2588 struct tevent_req *req, *subreq;
2589 struct cli_tdis_state *state;
2591 req = tevent_req_create(mem_ctx, &state, struct cli_tdis_state);
2597 subreq = cli_smb_send(state, ev, cli, SMBtdis, 0, 0, NULL, 0, NULL);
2598 if (tevent_req_nomem(subreq, req)) {
2599 return tevent_req_post(req, ev);
2601 tevent_req_set_callback(subreq, cli_tdis_done, req);
2605 static void cli_tdis_done(struct tevent_req *subreq)
2607 struct tevent_req *req = tevent_req_callback_data(
2608 subreq, struct tevent_req);
2609 struct cli_tdis_state *state = tevent_req_data(
2610 req, struct cli_tdis_state);
2613 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
2614 TALLOC_FREE(subreq);
2615 if (!NT_STATUS_IS_OK(status)) {
2616 tevent_req_nterror(req, status);
2619 cli_state_set_tid(state->cli, UINT16_MAX);
2620 tevent_req_done(req);
2623 NTSTATUS cli_tdis_recv(struct tevent_req *req)
2625 return tevent_req_simple_recv_ntstatus(req);
2628 NTSTATUS cli_tdis(struct cli_state *cli)
2630 struct tevent_context *ev;
2631 struct tevent_req *req;
2632 NTSTATUS status = NT_STATUS_NO_MEMORY;
2634 if (smbXcli_conn_has_async_calls(cli->conn)) {
2635 return NT_STATUS_INVALID_PARAMETER;
2637 ev = tevent_context_init(talloc_tos());
2641 req = cli_tdis_send(ev, ev, cli);
2645 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2648 status = cli_tdis_recv(req);
2654 static NTSTATUS cli_connect_sock(const char *host, int name_type,
2655 const struct sockaddr_storage *pss,
2656 const char *myname, uint16_t port,
2657 int sec_timeout, int *pfd, uint16_t *pport)
2659 TALLOC_CTX *frame = talloc_stackframe();
2661 unsigned int i, num_addrs;
2662 const char **called_names;
2663 const char **calling_names;
2668 prog = getenv("LIBSMB_PROG");
2670 fd = sock_exec(prog);
2672 return map_nt_error_from_unix(errno);
2678 if ((pss == NULL) || is_zero_addr(pss)) {
2679 struct sockaddr_storage *addrs;
2680 status = resolve_name_list(talloc_tos(), host, name_type,
2681 &addrs, &num_addrs);
2682 if (!NT_STATUS_IS_OK(status)) {
2690 called_names = talloc_array(talloc_tos(), const char *, num_addrs);
2691 if (called_names == NULL) {
2692 status = NT_STATUS_NO_MEMORY;
2695 called_types = talloc_array(talloc_tos(), int, num_addrs);
2696 if (called_types == NULL) {
2697 status = NT_STATUS_NO_MEMORY;
2700 calling_names = talloc_array(talloc_tos(), const char *, num_addrs);
2701 if (calling_names == NULL) {
2702 status = NT_STATUS_NO_MEMORY;
2705 for (i=0; i<num_addrs; i++) {
2706 called_names[i] = host;
2707 called_types[i] = name_type;
2708 calling_names[i] = myname;
2710 status = smbsock_any_connect(pss, called_names, called_types,
2711 calling_names, NULL, num_addrs, port,
2712 sec_timeout, &fd, NULL, &port);
2713 if (!NT_STATUS_IS_OK(status)) {
2716 set_socket_options(fd, lp_socket_options());
2720 status = NT_STATUS_OK;
2726 NTSTATUS cli_connect_nb(const char *host, const struct sockaddr_storage *dest_ss,
2727 uint16_t port, int name_type, const char *myname,
2728 int signing_state, int flags, struct cli_state **pcli)
2730 TALLOC_CTX *frame = talloc_stackframe();
2731 struct cli_state *cli;
2732 NTSTATUS status = NT_STATUS_NO_MEMORY;
2737 desthost = talloc_strdup(talloc_tos(), host);
2738 if (desthost == NULL) {
2742 p = strchr(host, '#');
2744 name_type = strtol(p+1, NULL, 16);
2745 host = talloc_strndup(talloc_tos(), host, p - host);
2751 status = cli_connect_sock(host, name_type, dest_ss, myname, port,
2753 if (!NT_STATUS_IS_OK(status)) {
2757 cli = cli_state_create(NULL, fd, desthost, NULL, signing_state, flags);
2765 status = NT_STATUS_OK;
2772 establishes a connection to after the negprot.
2773 @param output_cli A fully initialised cli structure, non-null only on success
2774 @param dest_host The netbios name of the remote host
2775 @param dest_ss (optional) The the destination IP, NULL for name based lookup
2776 @param port (optional) The destination port (0 for default)
2778 NTSTATUS cli_start_connection(struct cli_state **output_cli,
2779 const char *my_name,
2780 const char *dest_host,
2781 const struct sockaddr_storage *dest_ss, int port,
2782 int signing_state, int flags)
2785 struct cli_state *cli;
2787 nt_status = cli_connect_nb(dest_host, dest_ss, port, 0x20, my_name,
2788 signing_state, flags, &cli);
2789 if (!NT_STATUS_IS_OK(nt_status)) {
2790 DEBUG(10, ("cli_connect_nb failed: %s\n",
2791 nt_errstr(nt_status)));
2795 nt_status = smbXcli_negprot(cli->conn, cli->timeout, PROTOCOL_CORE,
2797 if (!NT_STATUS_IS_OK(nt_status)) {
2798 DEBUG(1, ("failed negprot: %s\n", nt_errstr(nt_status)));
2804 return NT_STATUS_OK;
2809 establishes a connection right up to doing tconX, password specified.
2810 @param output_cli A fully initialised cli structure, non-null only on success
2811 @param dest_host The netbios name of the remote host
2812 @param dest_ip (optional) The the destination IP, NULL for name based lookup
2813 @param port (optional) The destination port (0 for default)
2814 @param service (optional) The share to make the connection to. Should be 'unqualified' in any way.
2815 @param service_type The 'type' of serivice.
2816 @param user Username, unix string
2817 @param domain User's domain
2818 @param password User's password, unencrypted unix string.
2821 NTSTATUS cli_full_connection(struct cli_state **output_cli,
2822 const char *my_name,
2823 const char *dest_host,
2824 const struct sockaddr_storage *dest_ss, int port,
2825 const char *service, const char *service_type,
2826 const char *user, const char *domain,
2827 const char *password, int flags,
2831 struct cli_state *cli = NULL;
2832 int pw_len = password ? strlen(password)+1 : 0;
2836 if (password == NULL) {
2840 nt_status = cli_start_connection(&cli, my_name, dest_host,
2841 dest_ss, port, signing_state,
2844 if (!NT_STATUS_IS_OK(nt_status)) {
2848 nt_status = cli_session_setup(cli, user, password, pw_len, password,
2850 if (!NT_STATUS_IS_OK(nt_status)) {
2852 if (!(flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)) {
2853 DEBUG(1,("failed session setup with %s\n",
2854 nt_errstr(nt_status)));
2859 nt_status = cli_session_setup(cli, "", "", 0, "", 0, domain);
2860 if (!NT_STATUS_IS_OK(nt_status)) {
2861 DEBUG(1,("anonymous failed session setup with %s\n",
2862 nt_errstr(nt_status)));
2869 nt_status = cli_tree_connect(cli, service, service_type,
2871 if (!NT_STATUS_IS_OK(nt_status)) {
2872 DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status)));
2874 if (NT_STATUS_IS_OK(nt_status)) {
2875 nt_status = NT_STATUS_UNSUCCESSFUL;
2881 nt_status = cli_init_creds(cli, user, domain, password);
2882 if (!NT_STATUS_IS_OK(nt_status)) {
2888 return NT_STATUS_OK;
2891 /****************************************************************************
2892 Send an old style tcon.
2893 ****************************************************************************/
2894 NTSTATUS cli_raw_tcon(struct cli_state *cli,
2895 const char *service, const char *pass, const char *dev,
2896 uint16 *max_xmit, uint16 *tid)
2898 struct tevent_req *req;
2903 if (!lp_client_plaintext_auth() && (*pass)) {
2904 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
2905 " or 'client ntlmv2 auth = yes'\n"));
2906 return NT_STATUS_ACCESS_DENIED;
2909 bytes = talloc_array(talloc_tos(), uint8_t, 0);
2910 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
2911 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
2912 service, strlen(service)+1, NULL);
2913 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
2914 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
2915 pass, strlen(pass)+1, NULL);
2916 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
2917 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
2918 dev, strlen(dev)+1, NULL);
2920 status = cli_smb(talloc_tos(), cli, SMBtcon, 0, 0, NULL,
2921 talloc_get_size(bytes), bytes, &req,
2922 2, NULL, &ret_vwv, NULL, NULL);
2923 if (!NT_STATUS_IS_OK(status)) {
2927 *max_xmit = SVAL(ret_vwv + 0, 0);
2928 *tid = SVAL(ret_vwv + 1, 0);
2930 return NT_STATUS_OK;
2933 /* Return a cli_state pointing at the IPC$ share for the given server */
2935 struct cli_state *get_ipc_connect(char *server,
2936 struct sockaddr_storage *server_ss,
2937 const struct user_auth_info *user_info)
2939 struct cli_state *cli;
2941 uint32_t flags = CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
2943 if (user_info->use_kerberos) {
2944 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
2947 nt_status = cli_full_connection(&cli, NULL, server, server_ss, 0, "IPC$", "IPC",
2948 user_info->username ? user_info->username : "",
2950 user_info->password ? user_info->password : "",
2952 SMB_SIGNING_DEFAULT);
2954 if (NT_STATUS_IS_OK(nt_status)) {
2956 } else if (is_ipaddress(server)) {
2957 /* windows 9* needs a correct NMB name for connections */
2958 fstring remote_name;
2960 if (name_status_find("*", 0, 0, server_ss, remote_name)) {
2961 cli = get_ipc_connect(remote_name, server_ss, user_info);
2970 * Given the IP address of a master browser on the network, return its
2971 * workgroup and connect to it.
2973 * This function is provided to allow additional processing beyond what
2974 * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
2975 * browsers and obtain each master browsers' list of domains (in case the
2976 * first master browser is recently on the network and has not yet
2977 * synchronized with other master browsers and therefore does not yet have the
2978 * entire network browse list)
2981 struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx,
2982 struct sockaddr_storage *mb_ip,
2983 const struct user_auth_info *user_info,
2984 char **pp_workgroup_out)
2986 char addr[INET6_ADDRSTRLEN];
2988 struct cli_state *cli;
2989 struct sockaddr_storage server_ss;
2991 *pp_workgroup_out = NULL;
2993 print_sockaddr(addr, sizeof(addr), mb_ip);
2994 DEBUG(99, ("Looking up name of master browser %s\n",
2998 * Do a name status query to find out the name of the master browser.
2999 * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
3000 * master browser will not respond to a wildcard query (or, at least,
3001 * an NT4 server acting as the domain master browser will not).
3003 * We might be able to use ONLY the query on MSBROWSE, but that's not
3004 * yet been tested with all Windows versions, so until it is, leave
3005 * the original wildcard query as the first choice and fall back to
3006 * MSBROWSE if the wildcard query fails.
3008 if (!name_status_find("*", 0, 0x1d, mb_ip, name) &&
3009 !name_status_find(MSBROWSE, 1, 0x1d, mb_ip, name)) {
3011 DEBUG(99, ("Could not retrieve name status for %s\n",
3016 if (!find_master_ip(name, &server_ss)) {
3017 DEBUG(99, ("Could not find master ip for %s\n", name));
3021 *pp_workgroup_out = talloc_strdup(ctx, name);
3023 DEBUG(4, ("found master browser %s, %s\n", name, addr));
3025 print_sockaddr(addr, sizeof(addr), &server_ss);
3026 cli = get_ipc_connect(addr, &server_ss, user_info);
3032 * Return the IP address and workgroup of a master browser on the network, and
3036 struct cli_state *get_ipc_connect_master_ip_bcast(TALLOC_CTX *ctx,
3037 const struct user_auth_info *user_info,
3038 char **pp_workgroup_out)
3040 struct sockaddr_storage *ip_list;
3041 struct cli_state *cli;
3045 *pp_workgroup_out = NULL;
3047 DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
3049 /* Go looking for workgroups by broadcasting on the local network */
3051 status = name_resolve_bcast(MSBROWSE, 1, talloc_tos(),
3053 if (!NT_STATUS_IS_OK(status)) {
3054 DEBUG(99, ("No master browsers responded: %s\n",
3055 nt_errstr(status)));
3059 for (i = 0; i < count; i++) {
3060 char addr[INET6_ADDRSTRLEN];
3061 print_sockaddr(addr, sizeof(addr), &ip_list[i]);
3062 DEBUG(99, ("Found master browser %s\n", addr));
3064 cli = get_ipc_connect_master_ip(ctx, &ip_list[i],
3065 user_info, pp_workgroup_out);