Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : Authentication utility functions
4 : Copyright (C) Andrew Tridgell 1992-1998
5 : Copyright (C) Andrew Bartlett 2001
6 : Copyright (C) Jeremy Allison 2000-2001
7 : Copyright (C) Rafal Szczesniak 2002
8 : Copyright (C) Stefan Metzmacher 2005
9 :
10 : This program is free software; you can redistribute it and/or modify
11 : it under the terms of the GNU General Public License as published by
12 : the Free Software Foundation; either version 3 of the License, or
13 : (at your option) any later version.
14 :
15 : This program is distributed in the hope that it will be useful,
16 : but WITHOUT ANY WARRANTY; without even the implied warranty of
17 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 : GNU General Public License for more details.
19 :
20 : You should have received a copy of the GNU General Public License
21 : along with this program. If not, see <http://www.gnu.org/licenses/>.
22 : */
23 :
24 : #include "includes.h"
25 : #include "auth/auth.h"
26 : #include "libcli/auth/libcli_auth.h"
27 : #include "param/param.h"
28 : #include "auth/ntlm/auth_proto.h"
29 : #include "librpc/gen_ndr/drsuapi.h"
30 : #include "dsdb/samdb/samdb.h"
31 : #include "lib/crypto/gnutls_helpers.h"
32 :
33 : #undef DBGC_CLASS
34 : #define DBGC_CLASS DBGC_AUTH
35 :
36 : /****************************************************************************
37 : Create an auth_usersupplied_data structure after appropriate mapping.
38 : ****************************************************************************/
39 :
40 2024 : NTSTATUS encrypt_user_info(TALLOC_CTX *mem_ctx, struct auth4_context *auth_context,
41 : enum auth_password_state to_state,
42 : const struct auth_usersupplied_info *user_info_in,
43 : const struct auth_usersupplied_info **user_info_encrypted)
44 : {
45 6 : int rc;
46 6 : NTSTATUS nt_status;
47 6 : struct auth_usersupplied_info *user_info_temp;
48 2024 : switch (to_state) {
49 1452 : case AUTH_PASSWORD_RESPONSE:
50 1452 : switch (user_info_in->password_state) {
51 8 : case AUTH_PASSWORD_PLAIN:
52 : {
53 0 : const struct auth_usersupplied_info *user_info_temp2;
54 8 : nt_status = encrypt_user_info(mem_ctx, auth_context,
55 : AUTH_PASSWORD_HASH,
56 : user_info_in, &user_info_temp2);
57 8 : if (!NT_STATUS_IS_OK(nt_status)) {
58 0 : return nt_status;
59 : }
60 8 : user_info_in = user_info_temp2;
61 :
62 0 : FALL_THROUGH;
63 : }
64 : case AUTH_PASSWORD_HASH:
65 : {
66 0 : uint8_t chal[8];
67 0 : DATA_BLOB chall_blob;
68 8 : user_info_temp = talloc_zero(mem_ctx, struct auth_usersupplied_info);
69 8 : if (!user_info_temp) {
70 0 : return NT_STATUS_NO_MEMORY;
71 : }
72 8 : if (!talloc_reference(user_info_temp, user_info_in)) {
73 0 : return NT_STATUS_NO_MEMORY;
74 : }
75 8 : *user_info_temp = *user_info_in;
76 8 : user_info_temp->password_state = to_state;
77 :
78 8 : nt_status = auth_get_challenge(auth_context, chal);
79 8 : if (!NT_STATUS_IS_OK(nt_status)) {
80 0 : return nt_status;
81 : }
82 :
83 8 : chall_blob = data_blob_talloc(mem_ctx, chal, 8);
84 8 : if (lpcfg_client_ntlmv2_auth(auth_context->lp_ctx)) {
85 8 : DATA_BLOB names_blob = NTLMv2_generate_names_blob(mem_ctx, lpcfg_netbios_name(auth_context->lp_ctx), lpcfg_workgroup(auth_context->lp_ctx));
86 0 : DATA_BLOB lmv2_response, ntlmv2_response, lmv2_session_key, ntlmv2_session_key;
87 :
88 8 : if (!SMBNTLMv2encrypt_hash(user_info_temp,
89 8 : user_info_in->client.account_name,
90 8 : user_info_in->client.domain_name,
91 8 : user_info_in->password.hash.nt->hash,
92 : &chall_blob,
93 : NULL, /* server_timestamp */
94 : &names_blob,
95 : &lmv2_response, &ntlmv2_response,
96 : &lmv2_session_key, &ntlmv2_session_key)) {
97 0 : data_blob_free(&names_blob);
98 0 : return NT_STATUS_NO_MEMORY;
99 : }
100 8 : data_blob_free(&names_blob);
101 8 : user_info_temp->password.response.lanman = lmv2_response;
102 8 : user_info_temp->password.response.nt = ntlmv2_response;
103 :
104 8 : data_blob_free(&lmv2_session_key);
105 8 : data_blob_free(&ntlmv2_session_key);
106 : } else {
107 0 : DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, 24);
108 0 : rc = SMBOWFencrypt(user_info_in->password.hash.nt->hash, chal, blob.data);
109 0 : if (rc != 0) {
110 0 : return gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
111 : }
112 0 : user_info_temp->password.response.nt = blob;
113 0 : if (lpcfg_client_lanman_auth(auth_context->lp_ctx) && user_info_in->password.hash.lanman) {
114 0 : DATA_BLOB lm_blob = data_blob_talloc(mem_ctx, NULL, 24);
115 0 : rc = SMBOWFencrypt(user_info_in->password.hash.lanman->hash, chal, blob.data);
116 0 : if (rc != 0) {
117 0 : return gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
118 : }
119 0 : user_info_temp->password.response.lanman = lm_blob;
120 : } else {
121 : /* if not sending the LM password, send the NT password twice */
122 0 : user_info_temp->password.response.lanman = user_info_temp->password.response.nt;
123 : }
124 : }
125 :
126 8 : user_info_in = user_info_temp;
127 :
128 0 : FALL_THROUGH;
129 : }
130 : case AUTH_PASSWORD_RESPONSE:
131 1452 : *user_info_encrypted = user_info_in;
132 : }
133 1446 : break;
134 572 : case AUTH_PASSWORD_HASH:
135 : {
136 572 : switch (user_info_in->password_state) {
137 452 : case AUTH_PASSWORD_PLAIN:
138 : {
139 0 : struct samr_Password lanman;
140 0 : struct samr_Password nt;
141 :
142 452 : user_info_temp = talloc_zero(mem_ctx, struct auth_usersupplied_info);
143 452 : if (!user_info_temp) {
144 0 : return NT_STATUS_NO_MEMORY;
145 : }
146 452 : if (!talloc_reference(user_info_temp, user_info_in)) {
147 0 : return NT_STATUS_NO_MEMORY;
148 : }
149 452 : *user_info_temp = *user_info_in;
150 452 : user_info_temp->password_state = to_state;
151 :
152 452 : if (E_deshash(user_info_in->password.plaintext, lanman.hash)) {
153 123 : user_info_temp->password.hash.lanman = talloc(user_info_temp,
154 : struct samr_Password);
155 123 : *user_info_temp->password.hash.lanman = lanman;
156 : } else {
157 329 : user_info_temp->password.hash.lanman = NULL;
158 : }
159 :
160 452 : E_md4hash(user_info_in->password.plaintext, nt.hash);
161 452 : user_info_temp->password.hash.nt = talloc(user_info_temp,
162 : struct samr_Password);
163 452 : *user_info_temp->password.hash.nt = nt;
164 :
165 452 : user_info_in = user_info_temp;
166 :
167 0 : FALL_THROUGH;
168 : }
169 : case AUTH_PASSWORD_HASH:
170 572 : *user_info_encrypted = user_info_in;
171 572 : break;
172 0 : default:
173 0 : return NT_STATUS_INVALID_PARAMETER;
174 : break;
175 : }
176 572 : break;
177 : }
178 0 : default:
179 0 : return NT_STATUS_INVALID_PARAMETER;
180 : }
181 :
182 2024 : return NT_STATUS_OK;
183 : }
|