Add comment explaining the previous fix.
[Samba.git] / source / rpc_client / cli_samr.c
blobfd4fbfc9f41e87977b2c90c2b33b704e2538380f
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"
26 /* User change password */
28 NTSTATUS rpccli_samr_chgpasswd_user(struct rpc_pipe_client *cli,
29 TALLOC_CTX *mem_ctx,
30 const char *username,
31 const char *newpassword,
32 const char *oldpassword)
34 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
35 struct samr_CryptPassword new_nt_password;
36 struct samr_CryptPassword new_lm_password;
37 struct samr_Password old_nt_hash_enc;
38 struct samr_Password old_lanman_hash_enc;
40 uchar old_nt_hash[16];
41 uchar old_lanman_hash[16];
42 uchar new_nt_hash[16];
43 uchar new_lanman_hash[16];
44 struct lsa_String server, account;
46 DEBUG(10,("rpccli_samr_chgpasswd_user\n"));
48 init_lsa_String(&server, cli->cli->srv_name_slash);
49 init_lsa_String(&account, username);
51 /* Calculate the MD4 hash (NT compatible) of the password */
52 E_md4hash(oldpassword, old_nt_hash);
53 E_md4hash(newpassword, new_nt_hash);
55 if (lp_client_lanman_auth() &&
56 E_deshash(newpassword, new_lanman_hash) &&
57 E_deshash(oldpassword, old_lanman_hash)) {
58 /* E_deshash returns false for 'long' passwords (> 14
59 DOS chars). This allows us to match Win2k, which
60 does not store a LM hash for these passwords (which
61 would reduce the effective password length to 14) */
63 encode_pw_buffer(new_lm_password.data, newpassword, STR_UNICODE);
65 SamOEMhash(new_lm_password.data, old_nt_hash, 516);
66 E_old_pw_hash(new_nt_hash, old_lanman_hash, old_lanman_hash_enc.hash);
67 } else {
68 ZERO_STRUCT(new_lm_password);
69 ZERO_STRUCT(old_lanman_hash_enc);
72 encode_pw_buffer(new_nt_password.data, newpassword, STR_UNICODE);
74 SamOEMhash(new_nt_password.data, old_nt_hash, 516);
75 E_old_pw_hash(new_nt_hash, old_nt_hash, old_nt_hash_enc.hash);
77 result = rpccli_samr_ChangePasswordUser2(cli, mem_ctx,
78 &server,
79 &account,
80 &new_nt_password,
81 &old_nt_hash_enc,
82 true,
83 &new_lm_password,
84 &old_lanman_hash_enc);
86 return result;
89 /* User change password given blobs */
91 NTSTATUS rpccli_samr_chng_pswd_auth_crap(struct rpc_pipe_client *cli,
92 TALLOC_CTX *mem_ctx,
93 const char *username,
94 DATA_BLOB new_nt_password_blob,
95 DATA_BLOB old_nt_hash_enc_blob,
96 DATA_BLOB new_lm_password_blob,
97 DATA_BLOB old_lm_hash_enc_blob)
99 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
100 struct samr_CryptPassword new_nt_password;
101 struct samr_CryptPassword new_lm_password;
102 struct samr_Password old_nt_hash_enc;
103 struct samr_Password old_lm_hash_enc;
104 struct lsa_String server, account;
106 DEBUG(10,("rpccli_samr_chng_pswd_auth_crap\n"));
108 init_lsa_String(&server, cli->cli->srv_name_slash);
109 init_lsa_String(&account, username);
111 memcpy(&new_nt_password.data, new_nt_password_blob.data, 516);
112 memcpy(&new_lm_password.data, new_lm_password_blob.data, 516);
113 memcpy(&old_nt_hash_enc.hash, old_nt_hash_enc_blob.data, 16);
114 memcpy(&old_lm_hash_enc.hash, old_lm_hash_enc_blob.data, 16);
116 result = rpccli_samr_ChangePasswordUser2(cli, mem_ctx,
117 &server,
118 &account,
119 &new_nt_password,
120 &old_nt_hash_enc,
121 true,
122 &new_lm_password,
123 &old_lm_hash_enc);
124 return result;
128 /* change password 3 */
130 NTSTATUS rpccli_samr_chgpasswd3(struct rpc_pipe_client *cli,
131 TALLOC_CTX *mem_ctx,
132 const char *username,
133 const char *newpassword,
134 const char *oldpassword,
135 struct samr_DomInfo1 **dominfo1,
136 struct samr_ChangeReject **reject)
138 NTSTATUS status;
140 struct samr_CryptPassword new_nt_password;
141 struct samr_CryptPassword new_lm_password;
142 struct samr_Password old_nt_hash_enc;
143 struct samr_Password old_lanman_hash_enc;
145 uchar old_nt_hash[16];
146 uchar old_lanman_hash[16];
147 uchar new_nt_hash[16];
148 uchar new_lanman_hash[16];
150 struct lsa_String server, account;
152 DEBUG(10,("rpccli_samr_chgpasswd_user3\n"));
154 init_lsa_String(&server, cli->cli->srv_name_slash);
155 init_lsa_String(&account, username);
157 /* Calculate the MD4 hash (NT compatible) of the password */
158 E_md4hash(oldpassword, old_nt_hash);
159 E_md4hash(newpassword, new_nt_hash);
161 if (lp_client_lanman_auth() &&
162 E_deshash(newpassword, new_lanman_hash) &&
163 E_deshash(oldpassword, old_lanman_hash)) {
164 /* E_deshash returns false for 'long' passwords (> 14
165 DOS chars). This allows us to match Win2k, which
166 does not store a LM hash for these passwords (which
167 would reduce the effective password length to 14) */
169 encode_pw_buffer(new_lm_password.data, newpassword, STR_UNICODE);
171 SamOEMhash(new_lm_password.data, old_nt_hash, 516);
172 E_old_pw_hash(new_nt_hash, old_lanman_hash, old_lanman_hash_enc.hash);
173 } else {
174 ZERO_STRUCT(new_lm_password);
175 ZERO_STRUCT(old_lanman_hash_enc);
178 encode_pw_buffer(new_nt_password.data, newpassword, STR_UNICODE);
180 SamOEMhash(new_nt_password.data, old_nt_hash, 516);
181 E_old_pw_hash(new_nt_hash, old_nt_hash, old_nt_hash_enc.hash);
183 status = rpccli_samr_ChangePasswordUser3(cli, mem_ctx,
184 &server,
185 &account,
186 &new_nt_password,
187 &old_nt_hash_enc,
188 true,
189 &new_lm_password,
190 &old_lanman_hash_enc,
191 NULL,
192 dominfo1,
193 reject);
194 return status;
197 /* This function returns the bizzare set of (max_entries, max_size) required
198 for the QueryDisplayInfo RPC to actually work against a domain controller
199 with large (10k and higher) numbers of users. These values were
200 obtained by inspection using ethereal and NT4 running User Manager. */
202 void get_query_dispinfo_params(int loop_count, uint32 *max_entries,
203 uint32 *max_size)
205 switch(loop_count) {
206 case 0:
207 *max_entries = 512;
208 *max_size = 16383;
209 break;
210 case 1:
211 *max_entries = 1024;
212 *max_size = 32766;
213 break;
214 case 2:
215 *max_entries = 2048;
216 *max_size = 65532;
217 break;
218 case 3:
219 *max_entries = 4096;
220 *max_size = 131064;
221 break;
222 default: /* loop_count >= 4 */
223 *max_entries = 4096;
224 *max_size = 131071;
225 break;
229 NTSTATUS rpccli_try_samr_connects(struct rpc_pipe_client *cli,
230 TALLOC_CTX *mem_ctx,
231 uint32_t access_mask,
232 POLICY_HND *connect_pol)
234 NTSTATUS status;
235 union samr_ConnectInfo info_in, info_out;
236 struct samr_ConnectInfo1 info1;
237 uint32_t lvl_out = 0;
239 ZERO_STRUCT(info1);
241 info1.client_version = SAMR_CONNECT_W2K;
242 info_in.info1 = info1;
244 status = rpccli_samr_Connect5(cli, mem_ctx,
245 cli->cli->srv_name_slash,
246 access_mask,
248 &info_in,
249 &lvl_out,
250 &info_out,
251 connect_pol);
252 if (NT_STATUS_IS_OK(status)) {
253 return status;
256 status = rpccli_samr_Connect4(cli, mem_ctx,
257 cli->cli->srv_name_slash,
258 SAMR_CONNECT_W2K,
259 access_mask,
260 connect_pol);
261 if (NT_STATUS_IS_OK(status)) {
262 return status;
265 status = rpccli_samr_Connect2(cli, mem_ctx,
266 cli->cli->srv_name_slash,
267 access_mask,
268 connect_pol);
269 return status;