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 "rpc_client/rpc_client.h"
26 #include "../libcli/auth/libcli_auth.h"
27 #include "../librpc/gen_ndr/ndr_samr_c.h"
28 #include "rpc_client/cli_samr.h"
29 #include "../lib/crypto/arcfour.h"
30 #include "rpc_client/init_lsa.h"
32 /* User change password */
34 NTSTATUS
dcerpc_samr_chgpasswd_user(struct dcerpc_binding_handle
*h
,
36 struct policy_handle
*user_handle
,
37 const char *newpassword
,
38 const char *oldpassword
,
42 struct samr_Password hash1
, hash2
, hash3
, hash4
, hash5
, hash6
;
44 uchar old_nt_hash
[16];
45 uchar old_lm_hash
[16];
46 uchar new_nt_hash
[16];
47 uchar new_lm_hash
[16];
49 ZERO_STRUCT(old_nt_hash
);
50 ZERO_STRUCT(old_lm_hash
);
51 ZERO_STRUCT(new_nt_hash
);
52 ZERO_STRUCT(new_lm_hash
);
54 DEBUG(10,("rpccli_samr_chgpasswd_user\n"));
56 E_md4hash(oldpassword
, old_nt_hash
);
57 E_md4hash(newpassword
, new_nt_hash
);
59 E_deshash(oldpassword
, old_lm_hash
);
60 E_deshash(newpassword
, new_lm_hash
);
62 E_old_pw_hash(new_lm_hash
, old_lm_hash
, hash1
.hash
);
63 E_old_pw_hash(old_lm_hash
, new_lm_hash
, hash2
.hash
);
64 E_old_pw_hash(new_nt_hash
, old_nt_hash
, hash3
.hash
);
65 E_old_pw_hash(old_nt_hash
, new_nt_hash
, hash4
.hash
);
66 E_old_pw_hash(old_lm_hash
, new_nt_hash
, hash5
.hash
);
67 E_old_pw_hash(old_nt_hash
, new_lm_hash
, hash6
.hash
);
69 status
= dcerpc_samr_ChangePasswordUser(h
,
87 NTSTATUS
rpccli_samr_chgpasswd_user(struct rpc_pipe_client
*cli
,
89 struct policy_handle
*user_handle
,
90 const char *newpassword
,
91 const char *oldpassword
)
94 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
96 status
= dcerpc_samr_chgpasswd_user(cli
->binding_handle
,
102 if (!NT_STATUS_IS_OK(status
)) {
109 /* User change password */
111 NTSTATUS
dcerpc_samr_chgpasswd_user2(struct dcerpc_binding_handle
*h
,
113 const char *srv_name_slash
,
114 const char *username
,
115 const char *newpassword
,
116 const char *oldpassword
,
120 struct samr_CryptPassword new_nt_password
;
121 struct samr_CryptPassword new_lm_password
;
122 struct samr_Password old_nt_hash_enc
;
123 struct samr_Password old_lanman_hash_enc
;
125 uint8_t old_nt_hash
[16];
126 uint8_t old_lanman_hash
[16];
127 uint8_t new_nt_hash
[16];
128 uint8_t new_lanman_hash
[16];
129 struct lsa_String server
, account
;
131 DEBUG(10,("rpccli_samr_chgpasswd_user2\n"));
133 init_lsa_String(&server
, srv_name_slash
);
134 init_lsa_String(&account
, username
);
136 /* Calculate the MD4 hash (NT compatible) of the password */
137 E_md4hash(oldpassword
, old_nt_hash
);
138 E_md4hash(newpassword
, new_nt_hash
);
140 if (lp_client_lanman_auth() &&
141 E_deshash(newpassword
, new_lanman_hash
) &&
142 E_deshash(oldpassword
, old_lanman_hash
)) {
143 /* E_deshash returns false for 'long' passwords (> 14
144 DOS chars). This allows us to match Win2k, which
145 does not store a LM hash for these passwords (which
146 would reduce the effective password length to 14) */
148 encode_pw_buffer(new_lm_password
.data
, newpassword
, STR_UNICODE
);
150 arcfour_crypt(new_lm_password
.data
, old_nt_hash
, 516);
151 E_old_pw_hash(new_nt_hash
, old_lanman_hash
, old_lanman_hash_enc
.hash
);
153 ZERO_STRUCT(new_lm_password
);
154 ZERO_STRUCT(old_lanman_hash_enc
);
157 encode_pw_buffer(new_nt_password
.data
, newpassword
, STR_UNICODE
);
159 arcfour_crypt(new_nt_password
.data
, old_nt_hash
, 516);
160 E_old_pw_hash(new_nt_hash
, old_nt_hash
, old_nt_hash_enc
.hash
);
162 status
= dcerpc_samr_ChangePasswordUser2(h
,
170 &old_lanman_hash_enc
,
176 NTSTATUS
rpccli_samr_chgpasswd_user2(struct rpc_pipe_client
*cli
,
178 const char *username
,
179 const char *newpassword
,
180 const char *oldpassword
)
183 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
185 status
= dcerpc_samr_chgpasswd_user2(cli
->binding_handle
,
192 if (!NT_STATUS_IS_OK(status
)) {
199 /* User change password given blobs */
201 NTSTATUS
dcerpc_samr_chng_pswd_auth_crap(struct dcerpc_binding_handle
*h
,
203 const char *srv_name_slash
,
204 const char *username
,
205 DATA_BLOB new_nt_password_blob
,
206 DATA_BLOB old_nt_hash_enc_blob
,
207 DATA_BLOB new_lm_password_blob
,
208 DATA_BLOB old_lm_hash_enc_blob
,
212 struct samr_CryptPassword new_nt_password
;
213 struct samr_CryptPassword new_lm_password
;
214 struct samr_Password old_nt_hash_enc
;
215 struct samr_Password old_lm_hash_enc
;
216 struct lsa_String server
, account
;
218 DEBUG(10,("rpccli_samr_chng_pswd_auth_crap\n"));
220 ZERO_STRUCT(new_nt_password
);
221 ZERO_STRUCT(new_lm_password
);
222 ZERO_STRUCT(old_nt_hash_enc
);
223 ZERO_STRUCT(old_lm_hash_enc
);
225 init_lsa_String(&server
, srv_name_slash
);
226 init_lsa_String(&account
, username
);
228 if (new_nt_password_blob
.data
&& new_nt_password_blob
.length
>= 516) {
229 memcpy(&new_nt_password
.data
, new_nt_password_blob
.data
, 516);
232 if (new_lm_password_blob
.data
&& new_lm_password_blob
.length
>= 516) {
233 memcpy(&new_lm_password
.data
, new_lm_password_blob
.data
, 516);
236 if (old_nt_hash_enc_blob
.data
&& old_nt_hash_enc_blob
.length
>= 16) {
237 memcpy(&old_nt_hash_enc
.hash
, old_nt_hash_enc_blob
.data
, 16);
240 if (old_lm_hash_enc_blob
.data
&& old_lm_hash_enc_blob
.length
>= 16) {
241 memcpy(&old_lm_hash_enc
.hash
, old_lm_hash_enc_blob
.data
, 16);
244 status
= dcerpc_samr_ChangePasswordUser2(h
,
258 NTSTATUS
rpccli_samr_chng_pswd_auth_crap(struct rpc_pipe_client
*cli
,
260 const char *username
,
261 DATA_BLOB new_nt_password_blob
,
262 DATA_BLOB old_nt_hash_enc_blob
,
263 DATA_BLOB new_lm_password_blob
,
264 DATA_BLOB old_lm_hash_enc_blob
)
267 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
269 status
= dcerpc_samr_chng_pswd_auth_crap(cli
->binding_handle
,
273 new_nt_password_blob
,
274 old_nt_hash_enc_blob
,
275 new_lm_password_blob
,
276 old_lm_hash_enc_blob
,
278 if (!NT_STATUS_IS_OK(status
)) {
285 /* change password 3 */
287 NTSTATUS
dcerpc_samr_chgpasswd_user3(struct dcerpc_binding_handle
*h
,
289 const char *srv_name_slash
,
290 const char *username
,
291 const char *newpassword
,
292 const char *oldpassword
,
293 struct samr_DomInfo1
**dominfo1
,
294 struct userPwdChangeFailureInformation
**reject
,
299 struct samr_CryptPassword new_nt_password
;
300 struct samr_CryptPassword new_lm_password
;
301 struct samr_Password old_nt_hash_enc
;
302 struct samr_Password old_lanman_hash_enc
;
304 uint8_t old_nt_hash
[16];
305 uint8_t old_lanman_hash
[16];
306 uint8_t new_nt_hash
[16];
307 uint8_t new_lanman_hash
[16];
309 struct lsa_String server
, account
;
311 DEBUG(10,("rpccli_samr_chgpasswd_user3\n"));
313 init_lsa_String(&server
, srv_name_slash
);
314 init_lsa_String(&account
, username
);
316 /* Calculate the MD4 hash (NT compatible) of the password */
317 E_md4hash(oldpassword
, old_nt_hash
);
318 E_md4hash(newpassword
, new_nt_hash
);
320 if (lp_client_lanman_auth() &&
321 E_deshash(newpassword
, new_lanman_hash
) &&
322 E_deshash(oldpassword
, old_lanman_hash
)) {
323 /* E_deshash returns false for 'long' passwords (> 14
324 DOS chars). This allows us to match Win2k, which
325 does not store a LM hash for these passwords (which
326 would reduce the effective password length to 14) */
328 encode_pw_buffer(new_lm_password
.data
, newpassword
, STR_UNICODE
);
330 arcfour_crypt(new_lm_password
.data
, old_nt_hash
, 516);
331 E_old_pw_hash(new_nt_hash
, old_lanman_hash
, old_lanman_hash_enc
.hash
);
333 ZERO_STRUCT(new_lm_password
);
334 ZERO_STRUCT(old_lanman_hash_enc
);
337 encode_pw_buffer(new_nt_password
.data
, newpassword
, STR_UNICODE
);
339 arcfour_crypt(new_nt_password
.data
, old_nt_hash
, 516);
340 E_old_pw_hash(new_nt_hash
, old_nt_hash
, old_nt_hash_enc
.hash
);
342 status
= dcerpc_samr_ChangePasswordUser3(h
,
350 &old_lanman_hash_enc
,
359 NTSTATUS
rpccli_samr_chgpasswd_user3(struct rpc_pipe_client
*cli
,
361 const char *username
,
362 const char *newpassword
,
363 const char *oldpassword
,
364 struct samr_DomInfo1
**dominfo1
,
365 struct userPwdChangeFailureInformation
**reject
)
368 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
370 status
= dcerpc_samr_chgpasswd_user3(cli
->binding_handle
,
379 if (!NT_STATUS_IS_OK(status
)) {
386 /* This function returns the bizzare set of (max_entries, max_size) required
387 for the QueryDisplayInfo RPC to actually work against a domain controller
388 with large (10k and higher) numbers of users. These values were
389 obtained by inspection using ethereal and NT4 running User Manager. */
391 void dcerpc_get_query_dispinfo_params(int loop_count
,
392 uint32_t *max_entries
,
412 default: /* loop_count >= 4 */
419 NTSTATUS
dcerpc_try_samr_connects(struct dcerpc_binding_handle
*h
,
421 const char *srv_name_slash
,
422 uint32_t access_mask
,
423 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
= dcerpc_samr_Connect5(h
,
446 if (NT_STATUS_IS_OK(status
) && NT_STATUS_IS_OK(*presult
)) {
450 status
= dcerpc_samr_Connect4(h
,
457 if (NT_STATUS_IS_OK(status
) && NT_STATUS_IS_OK(*presult
)) {
461 status
= dcerpc_samr_Connect2(h
,
471 NTSTATUS
rpccli_try_samr_connects(struct rpc_pipe_client
*cli
,
473 uint32_t access_mask
,
474 struct policy_handle
*connect_pol
)
477 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
479 status
= dcerpc_try_samr_connects(cli
->binding_handle
,
485 if (!NT_STATUS_IS_OK(status
)) {
492 /* vim: set ts=8 sw=8 noet cindent: */