ndr: Another try to support the build on non-IPv6 systems
[Samba.git] / source3 / rpc_client / cli_samr.c
blob7f5e6fca4a92725aa15b92b7190f3939cfe6ec24
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"
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 rpccli_samr_chgpasswd_user(struct rpc_pipe_client *cli,
34 TALLOC_CTX *mem_ctx,
35 struct policy_handle *user_handle,
36 const char *newpassword,
37 const char *oldpassword)
39 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
40 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
42 uchar old_nt_hash[16];
43 uchar old_lm_hash[16];
44 uchar new_nt_hash[16];
45 uchar new_lm_hash[16];
47 ZERO_STRUCT(old_nt_hash);
48 ZERO_STRUCT(old_lm_hash);
49 ZERO_STRUCT(new_nt_hash);
50 ZERO_STRUCT(new_lm_hash);
52 DEBUG(10,("rpccli_samr_chgpasswd_user\n"));
54 E_md4hash(oldpassword, old_nt_hash);
55 E_md4hash(newpassword, new_nt_hash);
57 E_deshash(oldpassword, old_lm_hash);
58 E_deshash(newpassword, new_lm_hash);
60 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
61 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
62 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
63 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
64 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
65 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
67 result = rpccli_samr_ChangePasswordUser(cli, mem_ctx,
68 user_handle,
69 true,
70 &hash1,
71 &hash2,
72 true,
73 &hash3,
74 &hash4,
75 true,
76 &hash5,
77 true,
78 &hash6);
80 return result;
84 /* User change password */
86 NTSTATUS rpccli_samr_chgpasswd_user2(struct rpc_pipe_client *cli,
87 TALLOC_CTX *mem_ctx,
88 const char *username,
89 const char *newpassword,
90 const char *oldpassword)
92 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
93 struct samr_CryptPassword new_nt_password;
94 struct samr_CryptPassword new_lm_password;
95 struct samr_Password old_nt_hash_enc;
96 struct samr_Password old_lanman_hash_enc;
98 uchar old_nt_hash[16];
99 uchar old_lanman_hash[16];
100 uchar new_nt_hash[16];
101 uchar new_lanman_hash[16];
102 struct lsa_String server, account;
104 DEBUG(10,("rpccli_samr_chgpasswd_user2\n"));
106 init_lsa_String(&server, cli->srv_name_slash);
107 init_lsa_String(&account, username);
109 /* Calculate the MD4 hash (NT compatible) of the password */
110 E_md4hash(oldpassword, old_nt_hash);
111 E_md4hash(newpassword, new_nt_hash);
113 if (lp_client_lanman_auth() &&
114 E_deshash(newpassword, new_lanman_hash) &&
115 E_deshash(oldpassword, old_lanman_hash)) {
116 /* E_deshash returns false for 'long' passwords (> 14
117 DOS chars). This allows us to match Win2k, which
118 does not store a LM hash for these passwords (which
119 would reduce the effective password length to 14) */
121 encode_pw_buffer(new_lm_password.data, newpassword, STR_UNICODE);
123 arcfour_crypt(new_lm_password.data, old_nt_hash, 516);
124 E_old_pw_hash(new_nt_hash, old_lanman_hash, old_lanman_hash_enc.hash);
125 } else {
126 ZERO_STRUCT(new_lm_password);
127 ZERO_STRUCT(old_lanman_hash_enc);
130 encode_pw_buffer(new_nt_password.data, newpassword, STR_UNICODE);
132 arcfour_crypt(new_nt_password.data, old_nt_hash, 516);
133 E_old_pw_hash(new_nt_hash, old_nt_hash, old_nt_hash_enc.hash);
135 result = rpccli_samr_ChangePasswordUser2(cli, mem_ctx,
136 &server,
137 &account,
138 &new_nt_password,
139 &old_nt_hash_enc,
140 true,
141 &new_lm_password,
142 &old_lanman_hash_enc);
144 return result;
147 /* User change password given blobs */
149 NTSTATUS rpccli_samr_chng_pswd_auth_crap(struct rpc_pipe_client *cli,
150 TALLOC_CTX *mem_ctx,
151 const char *username,
152 DATA_BLOB new_nt_password_blob,
153 DATA_BLOB old_nt_hash_enc_blob,
154 DATA_BLOB new_lm_password_blob,
155 DATA_BLOB old_lm_hash_enc_blob)
157 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
158 struct samr_CryptPassword new_nt_password;
159 struct samr_CryptPassword new_lm_password;
160 struct samr_Password old_nt_hash_enc;
161 struct samr_Password old_lm_hash_enc;
162 struct lsa_String server, account;
164 DEBUG(10,("rpccli_samr_chng_pswd_auth_crap\n"));
166 init_lsa_String(&server, cli->srv_name_slash);
167 init_lsa_String(&account, username);
169 if (new_nt_password_blob.length > 0) {
170 memcpy(&new_nt_password.data, new_nt_password_blob.data, 516);
171 } else {
172 ZERO_STRUCT(new_nt_password_blob);
175 if (new_lm_password_blob.length > 0) {
176 memcpy(&new_lm_password.data, new_lm_password_blob.data, 516);
177 } else {
178 ZERO_STRUCT(new_lm_password);
181 if (old_nt_hash_enc_blob.length > 0) {
182 memcpy(&old_nt_hash_enc.hash, old_nt_hash_enc_blob.data, 16);
183 } else {
184 ZERO_STRUCT(old_nt_hash_enc);
187 if (old_lm_hash_enc_blob.length > 0) {
188 memcpy(&old_lm_hash_enc.hash, old_lm_hash_enc_blob.data, 16);
189 } else {
190 ZERO_STRUCT(old_lm_hash_enc);
193 result = rpccli_samr_ChangePasswordUser2(cli, mem_ctx,
194 &server,
195 &account,
196 &new_nt_password,
197 &old_nt_hash_enc,
198 true,
199 &new_lm_password,
200 &old_lm_hash_enc);
201 return result;
205 /* change password 3 */
207 NTSTATUS rpccli_samr_chgpasswd_user3(struct rpc_pipe_client *cli,
208 TALLOC_CTX *mem_ctx,
209 const char *username,
210 const char *newpassword,
211 const char *oldpassword,
212 struct samr_DomInfo1 **dominfo1,
213 struct userPwdChangeFailureInformation **reject)
215 NTSTATUS status;
217 struct samr_CryptPassword new_nt_password;
218 struct samr_CryptPassword new_lm_password;
219 struct samr_Password old_nt_hash_enc;
220 struct samr_Password old_lanman_hash_enc;
222 uchar old_nt_hash[16];
223 uchar old_lanman_hash[16];
224 uchar new_nt_hash[16];
225 uchar new_lanman_hash[16];
227 struct lsa_String server, account;
229 DEBUG(10,("rpccli_samr_chgpasswd_user3\n"));
231 init_lsa_String(&server, cli->srv_name_slash);
232 init_lsa_String(&account, username);
234 /* Calculate the MD4 hash (NT compatible) of the password */
235 E_md4hash(oldpassword, old_nt_hash);
236 E_md4hash(newpassword, new_nt_hash);
238 if (lp_client_lanman_auth() &&
239 E_deshash(newpassword, new_lanman_hash) &&
240 E_deshash(oldpassword, old_lanman_hash)) {
241 /* E_deshash returns false for 'long' passwords (> 14
242 DOS chars). This allows us to match Win2k, which
243 does not store a LM hash for these passwords (which
244 would reduce the effective password length to 14) */
246 encode_pw_buffer(new_lm_password.data, newpassword, STR_UNICODE);
248 arcfour_crypt(new_lm_password.data, old_nt_hash, 516);
249 E_old_pw_hash(new_nt_hash, old_lanman_hash, old_lanman_hash_enc.hash);
250 } else {
251 ZERO_STRUCT(new_lm_password);
252 ZERO_STRUCT(old_lanman_hash_enc);
255 encode_pw_buffer(new_nt_password.data, newpassword, STR_UNICODE);
257 arcfour_crypt(new_nt_password.data, old_nt_hash, 516);
258 E_old_pw_hash(new_nt_hash, old_nt_hash, old_nt_hash_enc.hash);
260 status = rpccli_samr_ChangePasswordUser3(cli, mem_ctx,
261 &server,
262 &account,
263 &new_nt_password,
264 &old_nt_hash_enc,
265 true,
266 &new_lm_password,
267 &old_lanman_hash_enc,
268 NULL,
269 dominfo1,
270 reject);
271 return status;
274 /* This function returns the bizzare set of (max_entries, max_size) required
275 for the QueryDisplayInfo RPC to actually work against a domain controller
276 with large (10k and higher) numbers of users. These values were
277 obtained by inspection using ethereal and NT4 running User Manager. */
279 void get_query_dispinfo_params(int loop_count, uint32 *max_entries,
280 uint32 *max_size)
282 switch(loop_count) {
283 case 0:
284 *max_entries = 512;
285 *max_size = 16383;
286 break;
287 case 1:
288 *max_entries = 1024;
289 *max_size = 32766;
290 break;
291 case 2:
292 *max_entries = 2048;
293 *max_size = 65532;
294 break;
295 case 3:
296 *max_entries = 4096;
297 *max_size = 131064;
298 break;
299 default: /* loop_count >= 4 */
300 *max_entries = 4096;
301 *max_size = 131071;
302 break;
306 NTSTATUS rpccli_try_samr_connects(struct rpc_pipe_client *cli,
307 TALLOC_CTX *mem_ctx,
308 uint32_t access_mask,
309 struct policy_handle *connect_pol)
311 NTSTATUS status;
312 union samr_ConnectInfo info_in, info_out;
313 struct samr_ConnectInfo1 info1;
314 uint32_t lvl_out = 0;
316 ZERO_STRUCT(info1);
318 info1.client_version = SAMR_CONNECT_W2K;
319 info_in.info1 = info1;
321 status = rpccli_samr_Connect5(cli, mem_ctx,
322 cli->srv_name_slash,
323 access_mask,
325 &info_in,
326 &lvl_out,
327 &info_out,
328 connect_pol);
329 if (NT_STATUS_IS_OK(status)) {
330 return status;
333 status = rpccli_samr_Connect4(cli, mem_ctx,
334 cli->srv_name_slash,
335 SAMR_CONNECT_W2K,
336 access_mask,
337 connect_pol);
338 if (NT_STATUS_IS_OK(status)) {
339 return status;
342 status = rpccli_samr_Connect2(cli, mem_ctx,
343 cli->srv_name_slash,
344 access_mask,
345 connect_pol);
346 return status;