2 Unix SMB/CIFS implementation.
4 Copyright (C) Tim Potter 2000-2001,
5 Copyright (C) Andrew Tridgell 1992-1997,2000,
6 Copyright (C) Rafal Szczesniak 2002.
7 Copyright (C) Jeremy Allison 2005.
8 Copyright (C) Guenther Deschner 2008.
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.
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.
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/>.
25 #include "../libcli/auth/libcli_auth.h"
26 #include "../librpc/gen_ndr/cli_samr.h"
27 #include "rpc_client/cli_samr.h"
28 #include "../lib/crypto/arcfour.h"
29 #include "rpc_client/init_lsa.h"
31 /* User change password */
33 NTSTATUS dcerpc_samr_chgpasswd_user(struct dcerpc_binding_handle *h,
35 struct policy_handle *user_handle,
36 const char *newpassword,
37 const char *oldpassword,
41 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
43 uchar old_nt_hash[16];
44 uchar old_lm_hash[16];
45 uchar new_nt_hash[16];
46 uchar new_lm_hash[16];
48 ZERO_STRUCT(old_nt_hash);
49 ZERO_STRUCT(old_lm_hash);
50 ZERO_STRUCT(new_nt_hash);
51 ZERO_STRUCT(new_lm_hash);
53 DEBUG(10,("rpccli_samr_chgpasswd_user\n"));
55 E_md4hash(oldpassword, old_nt_hash);
56 E_md4hash(newpassword, new_nt_hash);
58 E_deshash(oldpassword, old_lm_hash);
59 E_deshash(newpassword, new_lm_hash);
61 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
62 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
63 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
64 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
65 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
66 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
68 status = dcerpc_samr_ChangePasswordUser(h,
86 NTSTATUS rpccli_samr_chgpasswd_user(struct rpc_pipe_client *cli,
88 struct policy_handle *user_handle,
89 const char *newpassword,
90 const char *oldpassword)
93 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
95 status = dcerpc_samr_chgpasswd_user(cli->binding_handle,
101 if (!NT_STATUS_IS_OK(status)) {
108 /* User change password */
110 NTSTATUS dcerpc_samr_chgpasswd_user2(struct dcerpc_binding_handle *h,
112 const char *srv_name_slash,
113 const char *username,
114 const char *newpassword,
115 const char *oldpassword,
119 struct samr_CryptPassword new_nt_password;
120 struct samr_CryptPassword new_lm_password;
121 struct samr_Password old_nt_hash_enc;
122 struct samr_Password old_lanman_hash_enc;
124 uint8_t old_nt_hash[16];
125 uint8_t old_lanman_hash[16];
126 uint8_t new_nt_hash[16];
127 uint8_t new_lanman_hash[16];
128 struct lsa_String server, account;
130 DEBUG(10,("rpccli_samr_chgpasswd_user2\n"));
132 init_lsa_String(&server, srv_name_slash);
133 init_lsa_String(&account, username);
135 /* Calculate the MD4 hash (NT compatible) of the password */
136 E_md4hash(oldpassword, old_nt_hash);
137 E_md4hash(newpassword, new_nt_hash);
139 if (lp_client_lanman_auth() &&
140 E_deshash(newpassword, new_lanman_hash) &&
141 E_deshash(oldpassword, old_lanman_hash)) {
142 /* E_deshash returns false for 'long' passwords (> 14
143 DOS chars). This allows us to match Win2k, which
144 does not store a LM hash for these passwords (which
145 would reduce the effective password length to 14) */
147 encode_pw_buffer(new_lm_password.data, newpassword, STR_UNICODE);
149 arcfour_crypt(new_lm_password.data, old_nt_hash, 516);
150 E_old_pw_hash(new_nt_hash, old_lanman_hash, old_lanman_hash_enc.hash);
152 ZERO_STRUCT(new_lm_password);
153 ZERO_STRUCT(old_lanman_hash_enc);
156 encode_pw_buffer(new_nt_password.data, newpassword, STR_UNICODE);
158 arcfour_crypt(new_nt_password.data, old_nt_hash, 516);
159 E_old_pw_hash(new_nt_hash, old_nt_hash, old_nt_hash_enc.hash);
161 status = dcerpc_samr_ChangePasswordUser2(h,
169 &old_lanman_hash_enc,
175 NTSTATUS rpccli_samr_chgpasswd_user2(struct rpc_pipe_client *cli,
177 const char *username,
178 const char *newpassword,
179 const char *oldpassword)
182 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
184 status = dcerpc_samr_chgpasswd_user2(cli->binding_handle,
191 if (!NT_STATUS_IS_OK(status)) {
198 /* User change password given blobs */
200 NTSTATUS dcerpc_samr_chng_pswd_auth_crap(struct dcerpc_binding_handle *h,
202 const char *srv_name_slash,
203 const char *username,
204 DATA_BLOB new_nt_password_blob,
205 DATA_BLOB old_nt_hash_enc_blob,
206 DATA_BLOB new_lm_password_blob,
207 DATA_BLOB old_lm_hash_enc_blob,
211 struct samr_CryptPassword new_nt_password;
212 struct samr_CryptPassword new_lm_password;
213 struct samr_Password old_nt_hash_enc;
214 struct samr_Password old_lm_hash_enc;
215 struct lsa_String server, account;
217 DEBUG(10,("rpccli_samr_chng_pswd_auth_crap\n"));
219 init_lsa_String(&server, srv_name_slash);
220 init_lsa_String(&account, username);
222 if (new_nt_password_blob.length > 0) {
223 memcpy(&new_nt_password.data, new_nt_password_blob.data, 516);
225 ZERO_STRUCT(new_nt_password_blob);
228 if (new_lm_password_blob.length > 0) {
229 memcpy(&new_lm_password.data, new_lm_password_blob.data, 516);
231 ZERO_STRUCT(new_lm_password);
234 if (old_nt_hash_enc_blob.length > 0) {
235 memcpy(&old_nt_hash_enc.hash, old_nt_hash_enc_blob.data, 16);
237 ZERO_STRUCT(old_nt_hash_enc);
240 if (old_lm_hash_enc_blob.length > 0) {
241 memcpy(&old_lm_hash_enc.hash, old_lm_hash_enc_blob.data, 16);
243 ZERO_STRUCT(old_lm_hash_enc);
246 status = dcerpc_samr_ChangePasswordUser2(h,
260 NTSTATUS rpccli_samr_chng_pswd_auth_crap(struct rpc_pipe_client *cli,
262 const char *username,
263 DATA_BLOB new_nt_password_blob,
264 DATA_BLOB old_nt_hash_enc_blob,
265 DATA_BLOB new_lm_password_blob,
266 DATA_BLOB old_lm_hash_enc_blob)
269 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
271 status = dcerpc_samr_chng_pswd_auth_crap(cli->binding_handle,
275 new_nt_password_blob,
276 old_nt_hash_enc_blob,
277 new_lm_password_blob,
278 old_lm_hash_enc_blob,
280 if (!NT_STATUS_IS_OK(status)) {
287 /* change password 3 */
289 NTSTATUS dcerpc_samr_chgpasswd_user3(struct dcerpc_binding_handle *h,
291 const char *srv_name_slash,
292 const char *username,
293 const char *newpassword,
294 const char *oldpassword,
295 struct samr_DomInfo1 **dominfo1,
296 struct userPwdChangeFailureInformation **reject,
301 struct samr_CryptPassword new_nt_password;
302 struct samr_CryptPassword new_lm_password;
303 struct samr_Password old_nt_hash_enc;
304 struct samr_Password old_lanman_hash_enc;
306 uint8_t old_nt_hash[16];
307 uint8_t old_lanman_hash[16];
308 uint8_t new_nt_hash[16];
309 uint8_t new_lanman_hash[16];
311 struct lsa_String server, account;
313 DEBUG(10,("rpccli_samr_chgpasswd_user3\n"));
315 init_lsa_String(&server, srv_name_slash);
316 init_lsa_String(&account, username);
318 /* Calculate the MD4 hash (NT compatible) of the password */
319 E_md4hash(oldpassword, old_nt_hash);
320 E_md4hash(newpassword, new_nt_hash);
322 if (lp_client_lanman_auth() &&
323 E_deshash(newpassword, new_lanman_hash) &&
324 E_deshash(oldpassword, old_lanman_hash)) {
325 /* E_deshash returns false for 'long' passwords (> 14
326 DOS chars). This allows us to match Win2k, which
327 does not store a LM hash for these passwords (which
328 would reduce the effective password length to 14) */
330 encode_pw_buffer(new_lm_password.data, newpassword, STR_UNICODE);
332 arcfour_crypt(new_lm_password.data, old_nt_hash, 516);
333 E_old_pw_hash(new_nt_hash, old_lanman_hash, old_lanman_hash_enc.hash);
335 ZERO_STRUCT(new_lm_password);
336 ZERO_STRUCT(old_lanman_hash_enc);
339 encode_pw_buffer(new_nt_password.data, newpassword, STR_UNICODE);
341 arcfour_crypt(new_nt_password.data, old_nt_hash, 516);
342 E_old_pw_hash(new_nt_hash, old_nt_hash, old_nt_hash_enc.hash);
344 status = dcerpc_samr_ChangePasswordUser3(h,
352 &old_lanman_hash_enc,
361 NTSTATUS rpccli_samr_chgpasswd_user3(struct rpc_pipe_client *cli,
363 const char *username,
364 const char *newpassword,
365 const char *oldpassword,
366 struct samr_DomInfo1 **dominfo1,
367 struct userPwdChangeFailureInformation **reject)
370 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
372 status = dcerpc_samr_chgpasswd_user3(cli->binding_handle,
381 if (!NT_STATUS_IS_OK(status)) {
388 /* This function returns the bizzare set of (max_entries, max_size) required
389 for the QueryDisplayInfo RPC to actually work against a domain controller
390 with large (10k and higher) numbers of users. These values were
391 obtained by inspection using ethereal and NT4 running User Manager. */
393 void dcerpc_get_query_dispinfo_params(int loop_count,
394 uint32_t *max_entries,
414 default: /* loop_count >= 4 */
421 NTSTATUS rpccli_try_samr_connects(struct rpc_pipe_client *cli,
423 uint32_t access_mask,
424 struct policy_handle *connect_pol)
427 union samr_ConnectInfo info_in, info_out;
428 struct samr_ConnectInfo1 info1;
429 uint32_t lvl_out = 0;
433 info1.client_version = SAMR_CONNECT_W2K;
434 info_in.info1 = info1;
436 status = rpccli_samr_Connect5(cli, mem_ctx,
444 if (NT_STATUS_IS_OK(status)) {
448 status = rpccli_samr_Connect4(cli, mem_ctx,
453 if (NT_STATUS_IS_OK(status)) {
457 status = rpccli_samr_Connect2(cli, mem_ctx,