Fix bug #7528 - Solaris with NIS autohome.
[Samba.git] / source3 / rpc_client / cli_samr.c
blob936f3bb88c24e6e192689fe2fdf3ee0d6979bd56
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"
28 /* User change password */
30 NTSTATUS rpccli_samr_chgpasswd_user(struct rpc_pipe_client *cli,
31 TALLOC_CTX *mem_ctx,
32 struct policy_handle *user_handle,
33 const char *newpassword,
34 const char *oldpassword)
36 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
37 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
39 uchar old_nt_hash[16];
40 uchar old_lm_hash[16];
41 uchar new_nt_hash[16];
42 uchar new_lm_hash[16];
44 ZERO_STRUCT(old_nt_hash);
45 ZERO_STRUCT(old_lm_hash);
46 ZERO_STRUCT(new_nt_hash);
47 ZERO_STRUCT(new_lm_hash);
49 DEBUG(10,("rpccli_samr_chgpasswd_user\n"));
51 E_md4hash(oldpassword, old_nt_hash);
52 E_md4hash(newpassword, new_nt_hash);
54 E_deshash(oldpassword, old_lm_hash);
55 E_deshash(newpassword, new_lm_hash);
57 E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
58 E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
59 E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
60 E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
61 E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
62 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
64 result = rpccli_samr_ChangePasswordUser(cli, mem_ctx,
65 user_handle,
66 true,
67 &hash1,
68 &hash2,
69 true,
70 &hash3,
71 &hash4,
72 true,
73 &hash5,
74 true,
75 &hash6);
77 return result;
81 /* User change password */
83 NTSTATUS rpccli_samr_chgpasswd_user2(struct rpc_pipe_client *cli,
84 TALLOC_CTX *mem_ctx,
85 const char *username,
86 const char *newpassword,
87 const char *oldpassword)
89 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
90 struct samr_CryptPassword new_nt_password;
91 struct samr_CryptPassword new_lm_password;
92 struct samr_Password old_nt_hash_enc;
93 struct samr_Password old_lanman_hash_enc;
95 uchar old_nt_hash[16];
96 uchar old_lanman_hash[16];
97 uchar new_nt_hash[16];
98 uchar new_lanman_hash[16];
99 struct lsa_String server, account;
101 DEBUG(10,("rpccli_samr_chgpasswd_user2\n"));
103 init_lsa_String(&server, cli->srv_name_slash);
104 init_lsa_String(&account, username);
106 /* Calculate the MD4 hash (NT compatible) of the password */
107 E_md4hash(oldpassword, old_nt_hash);
108 E_md4hash(newpassword, new_nt_hash);
110 if (lp_client_lanman_auth() &&
111 E_deshash(newpassword, new_lanman_hash) &&
112 E_deshash(oldpassword, old_lanman_hash)) {
113 /* E_deshash returns false for 'long' passwords (> 14
114 DOS chars). This allows us to match Win2k, which
115 does not store a LM hash for these passwords (which
116 would reduce the effective password length to 14) */
118 encode_pw_buffer(new_lm_password.data, newpassword, STR_UNICODE);
120 arcfour_crypt(new_lm_password.data, old_nt_hash, 516);
121 E_old_pw_hash(new_nt_hash, old_lanman_hash, old_lanman_hash_enc.hash);
122 } else {
123 ZERO_STRUCT(new_lm_password);
124 ZERO_STRUCT(old_lanman_hash_enc);
127 encode_pw_buffer(new_nt_password.data, newpassword, STR_UNICODE);
129 arcfour_crypt(new_nt_password.data, old_nt_hash, 516);
130 E_old_pw_hash(new_nt_hash, old_nt_hash, old_nt_hash_enc.hash);
132 result = rpccli_samr_ChangePasswordUser2(cli, mem_ctx,
133 &server,
134 &account,
135 &new_nt_password,
136 &old_nt_hash_enc,
137 true,
138 &new_lm_password,
139 &old_lanman_hash_enc);
141 return result;
144 /* User change password given blobs */
146 NTSTATUS rpccli_samr_chng_pswd_auth_crap(struct rpc_pipe_client *cli,
147 TALLOC_CTX *mem_ctx,
148 const char *username,
149 DATA_BLOB new_nt_password_blob,
150 DATA_BLOB old_nt_hash_enc_blob,
151 DATA_BLOB new_lm_password_blob,
152 DATA_BLOB old_lm_hash_enc_blob)
154 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
155 struct samr_CryptPassword new_nt_password;
156 struct samr_CryptPassword new_lm_password;
157 struct samr_Password old_nt_hash_enc;
158 struct samr_Password old_lm_hash_enc;
159 struct lsa_String server, account;
161 ZERO_STRUCT(new_nt_password);
162 ZERO_STRUCT(new_lm_password);
163 ZERO_STRUCT(old_nt_hash_enc);
164 ZERO_STRUCT(old_lm_hash_enc);
166 DEBUG(10,("rpccli_samr_chng_pswd_auth_crap\n"));
168 init_lsa_String(&server, cli->srv_name_slash);
169 init_lsa_String(&account, username);
171 if (new_nt_password_blob.data && new_nt_password_blob.length >= 516) {
172 memcpy(&new_nt_password.data, new_nt_password_blob.data, 516);
174 if (new_lm_password_blob.data && new_lm_password_blob.length >= 516) {
175 memcpy(&new_lm_password.data, new_lm_password_blob.data, 516);
177 if (old_nt_hash_enc_blob.data && old_nt_hash_enc_blob.length >= 16) {
178 memcpy(&old_nt_hash_enc.hash, old_nt_hash_enc_blob.data, 16);
180 if (old_lm_hash_enc_blob.data && old_lm_hash_enc_blob.length >= 16) {
181 memcpy(&old_lm_hash_enc.hash, old_lm_hash_enc_blob.data, 16);
184 result = rpccli_samr_ChangePasswordUser2(cli, mem_ctx,
185 &server,
186 &account,
187 &new_nt_password,
188 &old_nt_hash_enc,
189 true,
190 &new_lm_password,
191 &old_lm_hash_enc);
192 return result;
196 /* change password 3 */
198 NTSTATUS rpccli_samr_chgpasswd_user3(struct rpc_pipe_client *cli,
199 TALLOC_CTX *mem_ctx,
200 const char *username,
201 const char *newpassword,
202 const char *oldpassword,
203 struct samr_DomInfo1 **dominfo1,
204 struct samr_ChangeReject **reject)
206 NTSTATUS status;
208 struct samr_CryptPassword new_nt_password;
209 struct samr_CryptPassword new_lm_password;
210 struct samr_Password old_nt_hash_enc;
211 struct samr_Password old_lanman_hash_enc;
213 uchar old_nt_hash[16];
214 uchar old_lanman_hash[16];
215 uchar new_nt_hash[16];
216 uchar new_lanman_hash[16];
218 struct lsa_String server, account;
220 DEBUG(10,("rpccli_samr_chgpasswd_user3\n"));
222 init_lsa_String(&server, cli->srv_name_slash);
223 init_lsa_String(&account, username);
225 /* Calculate the MD4 hash (NT compatible) of the password */
226 E_md4hash(oldpassword, old_nt_hash);
227 E_md4hash(newpassword, new_nt_hash);
229 if (lp_client_lanman_auth() &&
230 E_deshash(newpassword, new_lanman_hash) &&
231 E_deshash(oldpassword, old_lanman_hash)) {
232 /* E_deshash returns false for 'long' passwords (> 14
233 DOS chars). This allows us to match Win2k, which
234 does not store a LM hash for these passwords (which
235 would reduce the effective password length to 14) */
237 encode_pw_buffer(new_lm_password.data, newpassword, STR_UNICODE);
239 arcfour_crypt(new_lm_password.data, old_nt_hash, 516);
240 E_old_pw_hash(new_nt_hash, old_lanman_hash, old_lanman_hash_enc.hash);
241 } else {
242 ZERO_STRUCT(new_lm_password);
243 ZERO_STRUCT(old_lanman_hash_enc);
246 encode_pw_buffer(new_nt_password.data, newpassword, STR_UNICODE);
248 arcfour_crypt(new_nt_password.data, old_nt_hash, 516);
249 E_old_pw_hash(new_nt_hash, old_nt_hash, old_nt_hash_enc.hash);
251 status = rpccli_samr_ChangePasswordUser3(cli, mem_ctx,
252 &server,
253 &account,
254 &new_nt_password,
255 &old_nt_hash_enc,
256 true,
257 &new_lm_password,
258 &old_lanman_hash_enc,
259 NULL,
260 dominfo1,
261 reject);
262 return status;
265 /* This function returns the bizzare set of (max_entries, max_size) required
266 for the QueryDisplayInfo RPC to actually work against a domain controller
267 with large (10k and higher) numbers of users. These values were
268 obtained by inspection using ethereal and NT4 running User Manager. */
270 void get_query_dispinfo_params(int loop_count, uint32 *max_entries,
271 uint32 *max_size)
273 switch(loop_count) {
274 case 0:
275 *max_entries = 512;
276 *max_size = 16383;
277 break;
278 case 1:
279 *max_entries = 1024;
280 *max_size = 32766;
281 break;
282 case 2:
283 *max_entries = 2048;
284 *max_size = 65532;
285 break;
286 case 3:
287 *max_entries = 4096;
288 *max_size = 131064;
289 break;
290 default: /* loop_count >= 4 */
291 *max_entries = 4096;
292 *max_size = 131071;
293 break;
297 NTSTATUS rpccli_try_samr_connects(struct rpc_pipe_client *cli,
298 TALLOC_CTX *mem_ctx,
299 uint32_t access_mask,
300 struct policy_handle *connect_pol)
302 NTSTATUS status;
303 union samr_ConnectInfo info_in, info_out;
304 struct samr_ConnectInfo1 info1;
305 uint32_t lvl_out = 0;
307 ZERO_STRUCT(info1);
309 info1.client_version = SAMR_CONNECT_W2K;
310 info_in.info1 = info1;
312 status = rpccli_samr_Connect5(cli, mem_ctx,
313 cli->srv_name_slash,
314 access_mask,
316 &info_in,
317 &lvl_out,
318 &info_out,
319 connect_pol);
320 if (NT_STATUS_IS_OK(status)) {
321 return status;
324 status = rpccli_samr_Connect4(cli, mem_ctx,
325 cli->srv_name_slash,
326 SAMR_CONNECT_W2K,
327 access_mask,
328 connect_pol);
329 if (NT_STATUS_IS_OK(status)) {
330 return status;
333 status = rpccli_samr_Connect2(cli, mem_ctx,
334 cli->srv_name_slash,
335 access_mask,
336 connect_pol);
337 return status;