s4-ldb: cope better with corruption of tdb records
[Samba/aatanasov.git] / source3 / rpc_client / cli_samr.c
blob5a0dff296595dc80855440002683053bc0e48dd7
1 /*
2 Unix SMB/CIFS implementation.
3 RPC pipe client
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/>.
24 #include "includes.h"
25 #include "../libcli/auth/libcli_auth.h"
27 /* User change password */
29 NTSTATUS rpccli_samr_chgpasswd_user(struct rpc_pipe_client *cli,
30 TALLOC_CTX *mem_ctx,
31 struct policy_handle *user_handle,
32 const char *newpassword,
33 const char *oldpassword)
35 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
36 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
38 uchar old_nt_hash[16];
39 uchar old_lm_hash[16];
40 uchar new_nt_hash[16];
41 uchar new_lm_hash[16];
43 ZERO_STRUCT(old_nt_hash);
44 ZERO_STRUCT(old_lm_hash);
45 ZERO_STRUCT(new_nt_hash);
46 ZERO_STRUCT(new_lm_hash);
48 DEBUG(10,("rpccli_samr_chgpasswd_user\n"));
50 E_md4hash(oldpassword, old_nt_hash);
51 E_md4hash(newpassword, new_nt_hash);
53 E_deshash(oldpassword, old_lm_hash);
54 E_deshash(newpassword, new_lm_hash);
56 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
57 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
58 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
59 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
60 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
61 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
63 result = rpccli_samr_ChangePasswordUser(cli, mem_ctx,
64 user_handle,
65 true,
66 &hash1,
67 &hash2,
68 true,
69 &hash3,
70 &hash4,
71 true,
72 &hash5,
73 true,
74 &hash6);
76 return result;
80 /* User change password */
82 NTSTATUS rpccli_samr_chgpasswd_user2(struct rpc_pipe_client *cli,
83 TALLOC_CTX *mem_ctx,
84 const char *username,
85 const char *newpassword,
86 const char *oldpassword)
88 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
89 struct samr_CryptPassword new_nt_password;
90 struct samr_CryptPassword new_lm_password;
91 struct samr_Password old_nt_hash_enc;
92 struct samr_Password old_lanman_hash_enc;
94 uchar old_nt_hash[16];
95 uchar old_lanman_hash[16];
96 uchar new_nt_hash[16];
97 uchar new_lanman_hash[16];
98 struct lsa_String server, account;
100 DEBUG(10,("rpccli_samr_chgpasswd_user2\n"));
102 init_lsa_String(&server, cli->srv_name_slash);
103 init_lsa_String(&account, username);
105 /* Calculate the MD4 hash (NT compatible) of the password */
106 E_md4hash(oldpassword, old_nt_hash);
107 E_md4hash(newpassword, new_nt_hash);
109 if (lp_client_lanman_auth() &&
110 E_deshash(newpassword, new_lanman_hash) &&
111 E_deshash(oldpassword, old_lanman_hash)) {
112 /* E_deshash returns false for 'long' passwords (> 14
113 DOS chars). This allows us to match Win2k, which
114 does not store a LM hash for these passwords (which
115 would reduce the effective password length to 14) */
117 encode_pw_buffer(new_lm_password.data, newpassword, STR_UNICODE);
119 arcfour_crypt(new_lm_password.data, old_nt_hash, 516);
120 E_old_pw_hash(new_nt_hash, old_lanman_hash, old_lanman_hash_enc.hash);
121 } else {
122 ZERO_STRUCT(new_lm_password);
123 ZERO_STRUCT(old_lanman_hash_enc);
126 encode_pw_buffer(new_nt_password.data, newpassword, STR_UNICODE);
128 arcfour_crypt(new_nt_password.data, old_nt_hash, 516);
129 E_old_pw_hash(new_nt_hash, old_nt_hash, old_nt_hash_enc.hash);
131 result = rpccli_samr_ChangePasswordUser2(cli, mem_ctx,
132 &server,
133 &account,
134 &new_nt_password,
135 &old_nt_hash_enc,
136 true,
137 &new_lm_password,
138 &old_lanman_hash_enc);
140 return result;
143 /* User change password given blobs */
145 NTSTATUS rpccli_samr_chng_pswd_auth_crap(struct rpc_pipe_client *cli,
146 TALLOC_CTX *mem_ctx,
147 const char *username,
148 DATA_BLOB new_nt_password_blob,
149 DATA_BLOB old_nt_hash_enc_blob,
150 DATA_BLOB new_lm_password_blob,
151 DATA_BLOB old_lm_hash_enc_blob)
153 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
154 struct samr_CryptPassword new_nt_password;
155 struct samr_CryptPassword new_lm_password;
156 struct samr_Password old_nt_hash_enc;
157 struct samr_Password old_lm_hash_enc;
158 struct lsa_String server, account;
160 DEBUG(10,("rpccli_samr_chng_pswd_auth_crap\n"));
162 init_lsa_String(&server, cli->srv_name_slash);
163 init_lsa_String(&account, username);
165 memcpy(&new_nt_password.data, new_nt_password_blob.data, 516);
166 memcpy(&new_lm_password.data, new_lm_password_blob.data, 516);
167 memcpy(&old_nt_hash_enc.hash, old_nt_hash_enc_blob.data, 16);
168 memcpy(&old_lm_hash_enc.hash, old_lm_hash_enc_blob.data, 16);
170 result = rpccli_samr_ChangePasswordUser2(cli, mem_ctx,
171 &server,
172 &account,
173 &new_nt_password,
174 &old_nt_hash_enc,
175 true,
176 &new_lm_password,
177 &old_lm_hash_enc);
178 return result;
182 /* change password 3 */
184 NTSTATUS rpccli_samr_chgpasswd_user3(struct rpc_pipe_client *cli,
185 TALLOC_CTX *mem_ctx,
186 const char *username,
187 const char *newpassword,
188 const char *oldpassword,
189 struct samr_DomInfo1 **dominfo1,
190 struct samr_ChangeReject **reject)
192 NTSTATUS status;
194 struct samr_CryptPassword new_nt_password;
195 struct samr_CryptPassword new_lm_password;
196 struct samr_Password old_nt_hash_enc;
197 struct samr_Password old_lanman_hash_enc;
199 uchar old_nt_hash[16];
200 uchar old_lanman_hash[16];
201 uchar new_nt_hash[16];
202 uchar new_lanman_hash[16];
204 struct lsa_String server, account;
206 DEBUG(10,("rpccli_samr_chgpasswd_user3\n"));
208 init_lsa_String(&server, cli->srv_name_slash);
209 init_lsa_String(&account, username);
211 /* Calculate the MD4 hash (NT compatible) of the password */
212 E_md4hash(oldpassword, old_nt_hash);
213 E_md4hash(newpassword, new_nt_hash);
215 if (lp_client_lanman_auth() &&
216 E_deshash(newpassword, new_lanman_hash) &&
217 E_deshash(oldpassword, old_lanman_hash)) {
218 /* E_deshash returns false for 'long' passwords (> 14
219 DOS chars). This allows us to match Win2k, which
220 does not store a LM hash for these passwords (which
221 would reduce the effective password length to 14) */
223 encode_pw_buffer(new_lm_password.data, newpassword, STR_UNICODE);
225 arcfour_crypt(new_lm_password.data, old_nt_hash, 516);
226 E_old_pw_hash(new_nt_hash, old_lanman_hash, old_lanman_hash_enc.hash);
227 } else {
228 ZERO_STRUCT(new_lm_password);
229 ZERO_STRUCT(old_lanman_hash_enc);
232 encode_pw_buffer(new_nt_password.data, newpassword, STR_UNICODE);
234 arcfour_crypt(new_nt_password.data, old_nt_hash, 516);
235 E_old_pw_hash(new_nt_hash, old_nt_hash, old_nt_hash_enc.hash);
237 status = rpccli_samr_ChangePasswordUser3(cli, mem_ctx,
238 &server,
239 &account,
240 &new_nt_password,
241 &old_nt_hash_enc,
242 true,
243 &new_lm_password,
244 &old_lanman_hash_enc,
245 NULL,
246 dominfo1,
247 reject);
248 return status;
251 /* This function returns the bizzare set of (max_entries, max_size) required
252 for the QueryDisplayInfo RPC to actually work against a domain controller
253 with large (10k and higher) numbers of users. These values were
254 obtained by inspection using ethereal and NT4 running User Manager. */
256 void get_query_dispinfo_params(int loop_count, uint32 *max_entries,
257 uint32 *max_size)
259 switch(loop_count) {
260 case 0:
261 *max_entries = 512;
262 *max_size = 16383;
263 break;
264 case 1:
265 *max_entries = 1024;
266 *max_size = 32766;
267 break;
268 case 2:
269 *max_entries = 2048;
270 *max_size = 65532;
271 break;
272 case 3:
273 *max_entries = 4096;
274 *max_size = 131064;
275 break;
276 default: /* loop_count >= 4 */
277 *max_entries = 4096;
278 *max_size = 131071;
279 break;
283 NTSTATUS rpccli_try_samr_connects(struct rpc_pipe_client *cli,
284 TALLOC_CTX *mem_ctx,
285 uint32_t access_mask,
286 struct policy_handle *connect_pol)
288 NTSTATUS status;
289 union samr_ConnectInfo info_in, info_out;
290 struct samr_ConnectInfo1 info1;
291 uint32_t lvl_out = 0;
293 ZERO_STRUCT(info1);
295 info1.client_version = SAMR_CONNECT_W2K;
296 info_in.info1 = info1;
298 status = rpccli_samr_Connect5(cli, mem_ctx,
299 cli->srv_name_slash,
300 access_mask,
302 &info_in,
303 &lvl_out,
304 &info_out,
305 connect_pol);
306 if (NT_STATUS_IS_OK(status)) {
307 return status;
310 status = rpccli_samr_Connect4(cli, mem_ctx,
311 cli->srv_name_slash,
312 SAMR_CONNECT_W2K,
313 access_mask,
314 connect_pol);
315 if (NT_STATUS_IS_OK(status)) {
316 return status;
319 status = rpccli_samr_Connect2(cli, mem_ctx,
320 cli->srv_name_slash,
321 access_mask,
322 connect_pol);
323 return status;