diff options
author | Chong.Lu@windriver.com <Chong.Lu@windriver.com> | 2014-06-13 14:12:54 +0800 |
---|---|---|
committer | Martin Jansa <Martin.Jansa@gmail.com> | 2014-06-21 19:22:24 +0200 |
commit | 3d5d8c6d0f21de60dc84610a4d47da2d8c062901 (patch) | |
tree | e549f5d8e529f58bbdd6e440b7dddb1651fba583 /meta-oe/recipes-connectivity/samba | |
parent | 33a45cf6529243764bc383ee6c8ece00c7792e8b (diff) | |
download | meta-openembedded-3d5d8c6d0f21de60dc84610a4d47da2d8c062901.tar.gz |
samba: Security Advisory - CVE-2013-4496
Samba 3.x before 3.6.23, 4.0.x before 4.0.16, and 4.1.x before 4.1.6
does not enforce the password-guessing protection mechanism for all
interfaces, which makes it easier for remote attackers to obtain access
via brute-force ChangePasswordUser2 (1) SAMR or (2) RAP attempts.
http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2013-4496
Signed-off-by: Yue Tao <Yue.Tao@windriver.com>
Signed-off-by: Chong Lu <Chong.Lu@windriver.com>
Signed-off-by: Martin Jansa <Martin.Jansa@gmail.com>
Diffstat (limited to 'meta-oe/recipes-connectivity/samba')
-rw-r--r-- | meta-oe/recipes-connectivity/samba/samba/samba-3.6.22-CVE-2013-4496.patch | 966 | ||||
-rw-r--r-- | meta-oe/recipes-connectivity/samba/samba_3.6.8.bb | 1 |
2 files changed, 967 insertions, 0 deletions
diff --git a/meta-oe/recipes-connectivity/samba/samba/samba-3.6.22-CVE-2013-4496.patch b/meta-oe/recipes-connectivity/samba/samba/samba-3.6.22-CVE-2013-4496.patch new file mode 100644 index 000000000..c190a6c50 --- /dev/null +++ b/meta-oe/recipes-connectivity/samba/samba/samba-3.6.22-CVE-2013-4496.patch | |||
@@ -0,0 +1,966 @@ | |||
1 | Upstream-Status: Backport | ||
2 | |||
3 | From 25066eb31d6608075b5993b0d19b3e0843cdadeb Mon Sep 17 00:00:00 2001 | ||
4 | From: Andrew Bartlett <abartlet@samba.org> | ||
5 | Date: Fri, 1 Nov 2013 14:55:44 +1300 | ||
6 | Subject: [PATCH 1/3] CVE-2013-4496:s3-samr: Block attempts to crack passwords | ||
7 | via repeated password changes | ||
8 | |||
9 | Bug: https://bugzilla.samba.org/show_bug.cgi?id=10245 | ||
10 | |||
11 | Signed-off-by: Andrew Bartlett <abartlet@samba.org> | ||
12 | Signed-off-by: Stefan Metzmacher <metze@samba.org> | ||
13 | Signed-off-by: Jeremy Allison <jra@samba.org> | ||
14 | Reviewed-by: Stefan Metzmacher <metze@samba.org> | ||
15 | Reviewed-by: Jeremy Allison <jra@samba.org> | ||
16 | Reviewed-by: Andreas Schneider <asn@samba.org> | ||
17 | --- | ||
18 | source3/rpc_server/samr/srv_samr_chgpasswd.c | 55 ++++++++++++++++ | ||
19 | source3/rpc_server/samr/srv_samr_nt.c | 90 +++++++++++++++++++++----- | ||
20 | 2 files changed, 129 insertions(+), 16 deletions(-) | ||
21 | |||
22 | diff --git a/source3/rpc_server/samr/srv_samr_chgpasswd.c b/source3/rpc_server/samr/srv_samr_chgpasswd.c | ||
23 | index 0b4b25b..59905be 100644 | ||
24 | --- a/source3/rpc_server/samr/srv_samr_chgpasswd.c | ||
25 | +++ b/source3/rpc_server/samr/srv_samr_chgpasswd.c | ||
26 | @@ -1106,6 +1106,8 @@ NTSTATUS pass_oem_change(char *user, const char *rhost, | ||
27 | struct samu *sampass = NULL; | ||
28 | NTSTATUS nt_status; | ||
29 | bool ret = false; | ||
30 | + bool updated_badpw = false; | ||
31 | + NTSTATUS update_login_attempts_status; | ||
32 | |||
33 | if (!(sampass = samu_new(NULL))) { | ||
34 | return NT_STATUS_NO_MEMORY; | ||
35 | @@ -1121,6 +1123,13 @@ NTSTATUS pass_oem_change(char *user, const char *rhost, | ||
36 | return NT_STATUS_NO_SUCH_USER; | ||
37 | } | ||
38 | |||
39 | + /* Quit if the account was locked out. */ | ||
40 | + if (pdb_get_acct_ctrl(sampass) & ACB_AUTOLOCK) { | ||
41 | + DEBUG(3,("check_sam_security: Account for user %s was locked out.\n", user)); | ||
42 | + TALLOC_FREE(sampass); | ||
43 | + return NT_STATUS_ACCOUNT_LOCKED_OUT; | ||
44 | + } | ||
45 | + | ||
46 | nt_status = check_oem_password(user, | ||
47 | password_encrypted_with_lm_hash, | ||
48 | old_lm_hash_encrypted, | ||
49 | @@ -1129,6 +1138,52 @@ NTSTATUS pass_oem_change(char *user, const char *rhost, | ||
50 | sampass, | ||
51 | &new_passwd); | ||
52 | |||
53 | + /* | ||
54 | + * Notify passdb backend of login success/failure. If not | ||
55 | + * NT_STATUS_OK the backend doesn't like the login | ||
56 | + */ | ||
57 | + update_login_attempts_status = pdb_update_login_attempts(sampass, | ||
58 | + NT_STATUS_IS_OK(nt_status)); | ||
59 | + | ||
60 | + if (!NT_STATUS_IS_OK(nt_status)) { | ||
61 | + bool increment_bad_pw_count = false; | ||
62 | + | ||
63 | + if (NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD) && | ||
64 | + (pdb_get_acct_ctrl(sampass) & ACB_NORMAL) && | ||
65 | + NT_STATUS_IS_OK(update_login_attempts_status)) | ||
66 | + { | ||
67 | + increment_bad_pw_count = true; | ||
68 | + } | ||
69 | + | ||
70 | + if (increment_bad_pw_count) { | ||
71 | + pdb_increment_bad_password_count(sampass); | ||
72 | + updated_badpw = true; | ||
73 | + } else { | ||
74 | + pdb_update_bad_password_count(sampass, | ||
75 | + &updated_badpw); | ||
76 | + } | ||
77 | + } else { | ||
78 | + | ||
79 | + if ((pdb_get_acct_ctrl(sampass) & ACB_NORMAL) && | ||
80 | + (pdb_get_bad_password_count(sampass) > 0)){ | ||
81 | + pdb_set_bad_password_count(sampass, 0, PDB_CHANGED); | ||
82 | + pdb_set_bad_password_time(sampass, 0, PDB_CHANGED); | ||
83 | + updated_badpw = true; | ||
84 | + } | ||
85 | + } | ||
86 | + | ||
87 | + if (updated_badpw) { | ||
88 | + NTSTATUS update_status; | ||
89 | + become_root(); | ||
90 | + update_status = pdb_update_sam_account(sampass); | ||
91 | + unbecome_root(); | ||
92 | + | ||
93 | + if (!NT_STATUS_IS_OK(update_status)) { | ||
94 | + DEBUG(1, ("Failed to modify entry: %s\n", | ||
95 | + nt_errstr(update_status))); | ||
96 | + } | ||
97 | + } | ||
98 | + | ||
99 | if (!NT_STATUS_IS_OK(nt_status)) { | ||
100 | TALLOC_FREE(sampass); | ||
101 | return nt_status; | ||
102 | diff --git a/source3/rpc_server/samr/srv_samr_nt.c b/source3/rpc_server/samr/srv_samr_nt.c | ||
103 | index 78ef1ba..3241b97 100644 | ||
104 | --- a/source3/rpc_server/samr/srv_samr_nt.c | ||
105 | +++ b/source3/rpc_server/samr/srv_samr_nt.c | ||
106 | @@ -1715,9 +1715,11 @@ NTSTATUS _samr_ChangePasswordUser(struct pipes_struct *p, | ||
107 | NTSTATUS status; | ||
108 | bool ret = false; | ||
109 | struct samr_user_info *uinfo; | ||
110 | - struct samu *pwd; | ||
111 | + struct samu *pwd = NULL; | ||
112 | struct samr_Password new_lmPwdHash, new_ntPwdHash, checkHash; | ||
113 | struct samr_Password lm_pwd, nt_pwd; | ||
114 | + bool updated_badpw = false; | ||
115 | + NTSTATUS update_login_attempts_status; | ||
116 | |||
117 | uinfo = policy_handle_find(p, r->in.user_handle, | ||
118 | SAMR_USER_ACCESS_SET_PASSWORD, NULL, | ||
119 | @@ -1729,6 +1731,15 @@ NTSTATUS _samr_ChangePasswordUser(struct pipes_struct *p, | ||
120 | DEBUG(5,("_samr_ChangePasswordUser: sid:%s\n", | ||
121 | sid_string_dbg(&uinfo->sid))); | ||
122 | |||
123 | + /* basic sanity checking on parameters. Do this before any database ops */ | ||
124 | + if (!r->in.lm_present || !r->in.nt_present || | ||
125 | + !r->in.old_lm_crypted || !r->in.new_lm_crypted || | ||
126 | + !r->in.old_nt_crypted || !r->in.new_nt_crypted) { | ||
127 | + /* we should really handle a change with lm not | ||
128 | + present */ | ||
129 | + return NT_STATUS_INVALID_PARAMETER_MIX; | ||
130 | + } | ||
131 | + | ||
132 | if (!(pwd = samu_new(NULL))) { | ||
133 | return NT_STATUS_NO_MEMORY; | ||
134 | } | ||
135 | @@ -1742,6 +1753,14 @@ NTSTATUS _samr_ChangePasswordUser(struct pipes_struct *p, | ||
136 | return NT_STATUS_WRONG_PASSWORD; | ||
137 | } | ||
138 | |||
139 | + /* Quit if the account was locked out. */ | ||
140 | + if (pdb_get_acct_ctrl(pwd) & ACB_AUTOLOCK) { | ||
141 | + DEBUG(3, ("Account for user %s was locked out.\n", | ||
142 | + pdb_get_username(pwd))); | ||
143 | + status = NT_STATUS_ACCOUNT_LOCKED_OUT; | ||
144 | + goto out; | ||
145 | + } | ||
146 | + | ||
147 | { | ||
148 | const uint8_t *lm_pass, *nt_pass; | ||
149 | |||
150 | @@ -1750,29 +1769,19 @@ NTSTATUS _samr_ChangePasswordUser(struct pipes_struct *p, | ||
151 | |||
152 | if (!lm_pass || !nt_pass) { | ||
153 | status = NT_STATUS_WRONG_PASSWORD; | ||
154 | - goto out; | ||
155 | + goto update_login; | ||
156 | } | ||
157 | |||
158 | memcpy(&lm_pwd.hash, lm_pass, sizeof(lm_pwd.hash)); | ||
159 | memcpy(&nt_pwd.hash, nt_pass, sizeof(nt_pwd.hash)); | ||
160 | } | ||
161 | |||
162 | - /* basic sanity checking on parameters. Do this before any database ops */ | ||
163 | - if (!r->in.lm_present || !r->in.nt_present || | ||
164 | - !r->in.old_lm_crypted || !r->in.new_lm_crypted || | ||
165 | - !r->in.old_nt_crypted || !r->in.new_nt_crypted) { | ||
166 | - /* we should really handle a change with lm not | ||
167 | - present */ | ||
168 | - status = NT_STATUS_INVALID_PARAMETER_MIX; | ||
169 | - goto out; | ||
170 | - } | ||
171 | - | ||
172 | /* decrypt and check the new lm hash */ | ||
173 | D_P16(lm_pwd.hash, r->in.new_lm_crypted->hash, new_lmPwdHash.hash); | ||
174 | D_P16(new_lmPwdHash.hash, r->in.old_lm_crypted->hash, checkHash.hash); | ||
175 | if (memcmp(checkHash.hash, lm_pwd.hash, 16) != 0) { | ||
176 | status = NT_STATUS_WRONG_PASSWORD; | ||
177 | - goto out; | ||
178 | + goto update_login; | ||
179 | } | ||
180 | |||
181 | /* decrypt and check the new nt hash */ | ||
182 | @@ -1780,7 +1789,7 @@ NTSTATUS _samr_ChangePasswordUser(struct pipes_struct *p, | ||
183 | D_P16(new_ntPwdHash.hash, r->in.old_nt_crypted->hash, checkHash.hash); | ||
184 | if (memcmp(checkHash.hash, nt_pwd.hash, 16) != 0) { | ||
185 | status = NT_STATUS_WRONG_PASSWORD; | ||
186 | - goto out; | ||
187 | + goto update_login; | ||
188 | } | ||
189 | |||
190 | /* The NT Cross is not required by Win2k3 R2, but if present | ||
191 | @@ -1789,7 +1798,7 @@ NTSTATUS _samr_ChangePasswordUser(struct pipes_struct *p, | ||
192 | D_P16(lm_pwd.hash, r->in.nt_cross->hash, checkHash.hash); | ||
193 | if (memcmp(checkHash.hash, new_ntPwdHash.hash, 16) != 0) { | ||
194 | status = NT_STATUS_WRONG_PASSWORD; | ||
195 | - goto out; | ||
196 | + goto update_login; | ||
197 | } | ||
198 | } | ||
199 | |||
200 | @@ -1799,7 +1808,7 @@ NTSTATUS _samr_ChangePasswordUser(struct pipes_struct *p, | ||
201 | D_P16(nt_pwd.hash, r->in.lm_cross->hash, checkHash.hash); | ||
202 | if (memcmp(checkHash.hash, new_lmPwdHash.hash, 16) != 0) { | ||
203 | status = NT_STATUS_WRONG_PASSWORD; | ||
204 | - goto out; | ||
205 | + goto update_login; | ||
206 | } | ||
207 | } | ||
208 | |||
209 | @@ -1810,6 +1819,55 @@ NTSTATUS _samr_ChangePasswordUser(struct pipes_struct *p, | ||
210 | } | ||
211 | |||
212 | status = pdb_update_sam_account(pwd); | ||
213 | + | ||
214 | +update_login: | ||
215 | + | ||
216 | + /* | ||
217 | + * Notify passdb backend of login success/failure. If not | ||
218 | + * NT_STATUS_OK the backend doesn't like the login | ||
219 | + */ | ||
220 | + update_login_attempts_status = pdb_update_login_attempts(pwd, | ||
221 | + NT_STATUS_IS_OK(status)); | ||
222 | + | ||
223 | + if (!NT_STATUS_IS_OK(status)) { | ||
224 | + bool increment_bad_pw_count = false; | ||
225 | + | ||
226 | + if (NT_STATUS_EQUAL(status,NT_STATUS_WRONG_PASSWORD) && | ||
227 | + (pdb_get_acct_ctrl(pwd) & ACB_NORMAL) && | ||
228 | + NT_STATUS_IS_OK(update_login_attempts_status)) | ||
229 | + { | ||
230 | + increment_bad_pw_count = true; | ||
231 | + } | ||
232 | + | ||
233 | + if (increment_bad_pw_count) { | ||
234 | + pdb_increment_bad_password_count(pwd); | ||
235 | + updated_badpw = true; | ||
236 | + } else { | ||
237 | + pdb_update_bad_password_count(pwd, | ||
238 | + &updated_badpw); | ||
239 | + } | ||
240 | + } else { | ||
241 | + | ||
242 | + if ((pdb_get_acct_ctrl(pwd) & ACB_NORMAL) && | ||
243 | + (pdb_get_bad_password_count(pwd) > 0)){ | ||
244 | + pdb_set_bad_password_count(pwd, 0, PDB_CHANGED); | ||
245 | + pdb_set_bad_password_time(pwd, 0, PDB_CHANGED); | ||
246 | + updated_badpw = true; | ||
247 | + } | ||
248 | + } | ||
249 | + | ||
250 | + if (updated_badpw) { | ||
251 | + NTSTATUS update_status; | ||
252 | + become_root(); | ||
253 | + update_status = pdb_update_sam_account(pwd); | ||
254 | + unbecome_root(); | ||
255 | + | ||
256 | + if (!NT_STATUS_IS_OK(update_status)) { | ||
257 | + DEBUG(1, ("Failed to modify entry: %s\n", | ||
258 | + nt_errstr(update_status))); | ||
259 | + } | ||
260 | + } | ||
261 | + | ||
262 | out: | ||
263 | TALLOC_FREE(pwd); | ||
264 | |||
265 | -- | ||
266 | 1.7.9.5 | ||
267 | |||
268 | |||
269 | From 059da248cf69a3b0ef29836f49367b938fb1cbda Mon Sep 17 00:00:00 2001 | ||
270 | From: Stefan Metzmacher <metze@samba.org> | ||
271 | Date: Tue, 5 Nov 2013 14:04:20 +0100 | ||
272 | Subject: [PATCH 2/3] CVE-2013-4496:s3:auth: fix memory leak in the | ||
273 | ACCOUNT_LOCKED_OUT case. | ||
274 | |||
275 | Bug: https://bugzilla.samba.org/show_bug.cgi?id=10245 | ||
276 | |||
277 | Signed-off-by: Stefan Metzmacher <metze@samba.org> | ||
278 | Reviewed-by: Jeremy Allison <jra@samba.org> | ||
279 | Signed-off-by: Andrew Bartlett <abartlet@samba.org> | ||
280 | Reviewed-by: Andreas Schneider <asn@samba.org> | ||
281 | --- | ||
282 | source3/auth/check_samsec.c | 1 + | ||
283 | 1 file changed, 1 insertion(+) | ||
284 | |||
285 | diff --git a/source3/auth/check_samsec.c b/source3/auth/check_samsec.c | ||
286 | index f918dc0..e2c42d6 100644 | ||
287 | --- a/source3/auth/check_samsec.c | ||
288 | +++ b/source3/auth/check_samsec.c | ||
289 | @@ -408,6 +408,7 @@ NTSTATUS check_sam_security(const DATA_BLOB *challenge, | ||
290 | /* Quit if the account was locked out. */ | ||
291 | if (pdb_get_acct_ctrl(sampass) & ACB_AUTOLOCK) { | ||
292 | DEBUG(3,("check_sam_security: Account for user %s was locked out.\n", username)); | ||
293 | + TALLOC_FREE(sampass); | ||
294 | return NT_STATUS_ACCOUNT_LOCKED_OUT; | ||
295 | } | ||
296 | |||
297 | -- | ||
298 | 1.7.9.5 | ||
299 | |||
300 | |||
301 | From 27f982ef33a1238ae48d7a38d608dd23ebde61ae Mon Sep 17 00:00:00 2001 | ||
302 | From: Andrew Bartlett <abartlet@samba.org> | ||
303 | Date: Tue, 5 Nov 2013 16:16:46 +1300 | ||
304 | Subject: [PATCH 3/3] CVE-2013-4496:samr: Remove ChangePasswordUser | ||
305 | |||
306 | This old password change mechanism does not provide the plaintext to | ||
307 | validate against password complexity, and it is not used by modern | ||
308 | clients. | ||
309 | |||
310 | The missing features in both implementations (by design) were: | ||
311 | |||
312 | - the password complexity checks (no plaintext) | ||
313 | - the minimum password length (no plaintext) | ||
314 | |||
315 | Additionally, the source3 version did not check: | ||
316 | |||
317 | - the minimum password age | ||
318 | - pdb_get_pass_can_change() which checks the security | ||
319 | descriptor for the 'user cannot change password' setting. | ||
320 | - the password history | ||
321 | - the output of the 'passwd program' if 'unix passwd sync = yes'. | ||
322 | |||
323 | Finally, the mechanism was almost useless, as it was incorrectly | ||
324 | only made available to administrative users with permission | ||
325 | to reset the password. It is removed here so that it is not | ||
326 | mistakenly reinstated in the future. | ||
327 | |||
328 | Andrew Bartlett | ||
329 | |||
330 | Bug: https://bugzilla.samba.org/show_bug.cgi?id=10245 | ||
331 | |||
332 | Signed-off-by: Andrew Bartlett <abartlet@samba.org> | ||
333 | Reviewed-by: Andreas Schneider <asn@samba.org> | ||
334 | Reviewed-by: Stefan Metzmacher <metze@samba.org> | ||
335 | --- | ||
336 | source3/rpc_server/samr/srv_samr_nt.c | 169 +------------------- | ||
337 | source3/smbd/lanman.c | 254 ------------------------------- | ||
338 | source4/rpc_server/samr/samr_password.c | 126 +-------------- | ||
339 | source4/torture/rpc/samr.c | 12 +- | ||
340 | 4 files changed, 24 insertions(+), 537 deletions(-) | ||
341 | |||
342 | diff --git a/source3/rpc_server/samr/srv_samr_nt.c b/source3/rpc_server/samr/srv_samr_nt.c | ||
343 | index 3241b97..2519a3f 100644 | ||
344 | --- a/source3/rpc_server/samr/srv_samr_nt.c | ||
345 | +++ b/source3/rpc_server/samr/srv_samr_nt.c | ||
346 | @@ -1706,172 +1706,19 @@ NTSTATUS _samr_LookupNames(struct pipes_struct *p, | ||
347 | } | ||
348 | |||
349 | /**************************************************************** | ||
350 | - _samr_ChangePasswordUser | ||
351 | + _samr_ChangePasswordUser. | ||
352 | + | ||
353 | + So old it is just not worth implementing | ||
354 | + because it does not supply a plaintext and so we can't do password | ||
355 | + complexity checking and cannot update other services that use a | ||
356 | + plaintext password via passwd chat/pam password change/ldap password | ||
357 | + sync. | ||
358 | ****************************************************************/ | ||
359 | |||
360 | NTSTATUS _samr_ChangePasswordUser(struct pipes_struct *p, | ||
361 | struct samr_ChangePasswordUser *r) | ||
362 | { | ||
363 | - NTSTATUS status; | ||
364 | - bool ret = false; | ||
365 | - struct samr_user_info *uinfo; | ||
366 | - struct samu *pwd = NULL; | ||
367 | - struct samr_Password new_lmPwdHash, new_ntPwdHash, checkHash; | ||
368 | - struct samr_Password lm_pwd, nt_pwd; | ||
369 | - bool updated_badpw = false; | ||
370 | - NTSTATUS update_login_attempts_status; | ||
371 | - | ||
372 | - uinfo = policy_handle_find(p, r->in.user_handle, | ||
373 | - SAMR_USER_ACCESS_SET_PASSWORD, NULL, | ||
374 | - struct samr_user_info, &status); | ||
375 | - if (!NT_STATUS_IS_OK(status)) { | ||
376 | - return status; | ||
377 | - } | ||
378 | - | ||
379 | - DEBUG(5,("_samr_ChangePasswordUser: sid:%s\n", | ||
380 | - sid_string_dbg(&uinfo->sid))); | ||
381 | - | ||
382 | - /* basic sanity checking on parameters. Do this before any database ops */ | ||
383 | - if (!r->in.lm_present || !r->in.nt_present || | ||
384 | - !r->in.old_lm_crypted || !r->in.new_lm_crypted || | ||
385 | - !r->in.old_nt_crypted || !r->in.new_nt_crypted) { | ||
386 | - /* we should really handle a change with lm not | ||
387 | - present */ | ||
388 | - return NT_STATUS_INVALID_PARAMETER_MIX; | ||
389 | - } | ||
390 | - | ||
391 | - if (!(pwd = samu_new(NULL))) { | ||
392 | - return NT_STATUS_NO_MEMORY; | ||
393 | - } | ||
394 | - | ||
395 | - become_root(); | ||
396 | - ret = pdb_getsampwsid(pwd, &uinfo->sid); | ||
397 | - unbecome_root(); | ||
398 | - | ||
399 | - if (!ret) { | ||
400 | - TALLOC_FREE(pwd); | ||
401 | - return NT_STATUS_WRONG_PASSWORD; | ||
402 | - } | ||
403 | - | ||
404 | - /* Quit if the account was locked out. */ | ||
405 | - if (pdb_get_acct_ctrl(pwd) & ACB_AUTOLOCK) { | ||
406 | - DEBUG(3, ("Account for user %s was locked out.\n", | ||
407 | - pdb_get_username(pwd))); | ||
408 | - status = NT_STATUS_ACCOUNT_LOCKED_OUT; | ||
409 | - goto out; | ||
410 | - } | ||
411 | - | ||
412 | - { | ||
413 | - const uint8_t *lm_pass, *nt_pass; | ||
414 | - | ||
415 | - lm_pass = pdb_get_lanman_passwd(pwd); | ||
416 | - nt_pass = pdb_get_nt_passwd(pwd); | ||
417 | - | ||
418 | - if (!lm_pass || !nt_pass) { | ||
419 | - status = NT_STATUS_WRONG_PASSWORD; | ||
420 | - goto update_login; | ||
421 | - } | ||
422 | - | ||
423 | - memcpy(&lm_pwd.hash, lm_pass, sizeof(lm_pwd.hash)); | ||
424 | - memcpy(&nt_pwd.hash, nt_pass, sizeof(nt_pwd.hash)); | ||
425 | - } | ||
426 | - | ||
427 | - /* decrypt and check the new lm hash */ | ||
428 | - D_P16(lm_pwd.hash, r->in.new_lm_crypted->hash, new_lmPwdHash.hash); | ||
429 | - D_P16(new_lmPwdHash.hash, r->in.old_lm_crypted->hash, checkHash.hash); | ||
430 | - if (memcmp(checkHash.hash, lm_pwd.hash, 16) != 0) { | ||
431 | - status = NT_STATUS_WRONG_PASSWORD; | ||
432 | - goto update_login; | ||
433 | - } | ||
434 | - | ||
435 | - /* decrypt and check the new nt hash */ | ||
436 | - D_P16(nt_pwd.hash, r->in.new_nt_crypted->hash, new_ntPwdHash.hash); | ||
437 | - D_P16(new_ntPwdHash.hash, r->in.old_nt_crypted->hash, checkHash.hash); | ||
438 | - if (memcmp(checkHash.hash, nt_pwd.hash, 16) != 0) { | ||
439 | - status = NT_STATUS_WRONG_PASSWORD; | ||
440 | - goto update_login; | ||
441 | - } | ||
442 | - | ||
443 | - /* The NT Cross is not required by Win2k3 R2, but if present | ||
444 | - check the nt cross hash */ | ||
445 | - if (r->in.cross1_present && r->in.nt_cross) { | ||
446 | - D_P16(lm_pwd.hash, r->in.nt_cross->hash, checkHash.hash); | ||
447 | - if (memcmp(checkHash.hash, new_ntPwdHash.hash, 16) != 0) { | ||
448 | - status = NT_STATUS_WRONG_PASSWORD; | ||
449 | - goto update_login; | ||
450 | - } | ||
451 | - } | ||
452 | - | ||
453 | - /* The LM Cross is not required by Win2k3 R2, but if present | ||
454 | - check the lm cross hash */ | ||
455 | - if (r->in.cross2_present && r->in.lm_cross) { | ||
456 | - D_P16(nt_pwd.hash, r->in.lm_cross->hash, checkHash.hash); | ||
457 | - if (memcmp(checkHash.hash, new_lmPwdHash.hash, 16) != 0) { | ||
458 | - status = NT_STATUS_WRONG_PASSWORD; | ||
459 | - goto update_login; | ||
460 | - } | ||
461 | - } | ||
462 | - | ||
463 | - if (!pdb_set_nt_passwd(pwd, new_ntPwdHash.hash, PDB_CHANGED) || | ||
464 | - !pdb_set_lanman_passwd(pwd, new_lmPwdHash.hash, PDB_CHANGED)) { | ||
465 | - status = NT_STATUS_ACCESS_DENIED; | ||
466 | - goto out; | ||
467 | - } | ||
468 | - | ||
469 | - status = pdb_update_sam_account(pwd); | ||
470 | - | ||
471 | -update_login: | ||
472 | - | ||
473 | - /* | ||
474 | - * Notify passdb backend of login success/failure. If not | ||
475 | - * NT_STATUS_OK the backend doesn't like the login | ||
476 | - */ | ||
477 | - update_login_attempts_status = pdb_update_login_attempts(pwd, | ||
478 | - NT_STATUS_IS_OK(status)); | ||
479 | - | ||
480 | - if (!NT_STATUS_IS_OK(status)) { | ||
481 | - bool increment_bad_pw_count = false; | ||
482 | - | ||
483 | - if (NT_STATUS_EQUAL(status,NT_STATUS_WRONG_PASSWORD) && | ||
484 | - (pdb_get_acct_ctrl(pwd) & ACB_NORMAL) && | ||
485 | - NT_STATUS_IS_OK(update_login_attempts_status)) | ||
486 | - { | ||
487 | - increment_bad_pw_count = true; | ||
488 | - } | ||
489 | - | ||
490 | - if (increment_bad_pw_count) { | ||
491 | - pdb_increment_bad_password_count(pwd); | ||
492 | - updated_badpw = true; | ||
493 | - } else { | ||
494 | - pdb_update_bad_password_count(pwd, | ||
495 | - &updated_badpw); | ||
496 | - } | ||
497 | - } else { | ||
498 | - | ||
499 | - if ((pdb_get_acct_ctrl(pwd) & ACB_NORMAL) && | ||
500 | - (pdb_get_bad_password_count(pwd) > 0)){ | ||
501 | - pdb_set_bad_password_count(pwd, 0, PDB_CHANGED); | ||
502 | - pdb_set_bad_password_time(pwd, 0, PDB_CHANGED); | ||
503 | - updated_badpw = true; | ||
504 | - } | ||
505 | - } | ||
506 | - | ||
507 | - if (updated_badpw) { | ||
508 | - NTSTATUS update_status; | ||
509 | - become_root(); | ||
510 | - update_status = pdb_update_sam_account(pwd); | ||
511 | - unbecome_root(); | ||
512 | - | ||
513 | - if (!NT_STATUS_IS_OK(update_status)) { | ||
514 | - DEBUG(1, ("Failed to modify entry: %s\n", | ||
515 | - nt_errstr(update_status))); | ||
516 | - } | ||
517 | - } | ||
518 | - | ||
519 | - out: | ||
520 | - TALLOC_FREE(pwd); | ||
521 | - | ||
522 | - return status; | ||
523 | + return NT_STATUS_NOT_IMPLEMENTED; | ||
524 | } | ||
525 | |||
526 | /******************************************************************* | ||
527 | diff --git a/source3/smbd/lanman.c b/source3/smbd/lanman.c | ||
528 | index aef12df..3b4ec65 100644 | ||
529 | --- a/source3/smbd/lanman.c | ||
530 | +++ b/source3/smbd/lanman.c | ||
531 | @@ -2947,259 +2947,6 @@ static bool api_NetRemoteTOD(struct smbd_server_connection *sconn, | ||
532 | } | ||
533 | |||
534 | /**************************************************************************** | ||
535 | - Set the user password. | ||
536 | -*****************************************************************************/ | ||
537 | - | ||
538 | -static bool api_SetUserPassword(struct smbd_server_connection *sconn, | ||
539 | - connection_struct *conn,uint16 vuid, | ||
540 | - char *param, int tpscnt, | ||
541 | - char *data, int tdscnt, | ||
542 | - int mdrcnt,int mprcnt, | ||
543 | - char **rdata,char **rparam, | ||
544 | - int *rdata_len,int *rparam_len) | ||
545 | -{ | ||
546 | - char *np = get_safe_str_ptr(param,tpscnt,param,2); | ||
547 | - char *p = NULL; | ||
548 | - fstring user; | ||
549 | - fstring pass1,pass2; | ||
550 | - TALLOC_CTX *mem_ctx = talloc_tos(); | ||
551 | - NTSTATUS status, result; | ||
552 | - struct rpc_pipe_client *cli = NULL; | ||
553 | - struct policy_handle connect_handle, domain_handle, user_handle; | ||
554 | - struct lsa_String domain_name; | ||
555 | - struct dom_sid2 *domain_sid; | ||
556 | - struct lsa_String names; | ||
557 | - struct samr_Ids rids; | ||
558 | - struct samr_Ids types; | ||
559 | - struct samr_Password old_lm_hash; | ||
560 | - struct samr_Password new_lm_hash; | ||
561 | - int errcode = NERR_badpass; | ||
562 | - uint32_t rid; | ||
563 | - int encrypted; | ||
564 | - int min_pwd_length; | ||
565 | - struct dcerpc_binding_handle *b = NULL; | ||
566 | - | ||
567 | - /* Skip 2 strings. */ | ||
568 | - p = skip_string(param,tpscnt,np); | ||
569 | - p = skip_string(param,tpscnt,p); | ||
570 | - | ||
571 | - if (!np || !p) { | ||
572 | - return False; | ||
573 | - } | ||
574 | - | ||
575 | - /* Do we have a string ? */ | ||
576 | - if (skip_string(param,tpscnt,p) == NULL) { | ||
577 | - return False; | ||
578 | - } | ||
579 | - pull_ascii_fstring(user,p); | ||
580 | - | ||
581 | - p = skip_string(param,tpscnt,p); | ||
582 | - if (!p) { | ||
583 | - return False; | ||
584 | - } | ||
585 | - | ||
586 | - memset(pass1,'\0',sizeof(pass1)); | ||
587 | - memset(pass2,'\0',sizeof(pass2)); | ||
588 | - /* | ||
589 | - * We use 31 here not 32 as we're checking | ||
590 | - * the last byte we want to access is safe. | ||
591 | - */ | ||
592 | - if (!is_offset_safe(param,tpscnt,p,31)) { | ||
593 | - return False; | ||
594 | - } | ||
595 | - memcpy(pass1,p,16); | ||
596 | - memcpy(pass2,p+16,16); | ||
597 | - | ||
598 | - encrypted = get_safe_SVAL(param,tpscnt,p+32,0,-1); | ||
599 | - if (encrypted == -1) { | ||
600 | - errcode = W_ERROR_V(WERR_INVALID_PARAM); | ||
601 | - goto out; | ||
602 | - } | ||
603 | - | ||
604 | - min_pwd_length = get_safe_SVAL(param,tpscnt,p+34,0,-1); | ||
605 | - if (min_pwd_length == -1) { | ||
606 | - errcode = W_ERROR_V(WERR_INVALID_PARAM); | ||
607 | - goto out; | ||
608 | - } | ||
609 | - | ||
610 | - *rparam_len = 4; | ||
611 | - *rparam = smb_realloc_limit(*rparam,*rparam_len); | ||
612 | - if (!*rparam) { | ||
613 | - return False; | ||
614 | - } | ||
615 | - | ||
616 | - *rdata_len = 0; | ||
617 | - | ||
618 | - DEBUG(3,("Set password for <%s> (encrypted: %d, min_pwd_length: %d)\n", | ||
619 | - user, encrypted, min_pwd_length)); | ||
620 | - | ||
621 | - ZERO_STRUCT(connect_handle); | ||
622 | - ZERO_STRUCT(domain_handle); | ||
623 | - ZERO_STRUCT(user_handle); | ||
624 | - | ||
625 | - status = rpc_pipe_open_interface(mem_ctx, &ndr_table_samr.syntax_id, | ||
626 | - conn->session_info, | ||
627 | - &conn->sconn->client_id, | ||
628 | - conn->sconn->msg_ctx, | ||
629 | - &cli); | ||
630 | - if (!NT_STATUS_IS_OK(status)) { | ||
631 | - DEBUG(0,("api_SetUserPassword: could not connect to samr: %s\n", | ||
632 | - nt_errstr(status))); | ||
633 | - errcode = W_ERROR_V(ntstatus_to_werror(status)); | ||
634 | - goto out; | ||
635 | - } | ||
636 | - | ||
637 | - b = cli->binding_handle; | ||
638 | - | ||
639 | - status = dcerpc_samr_Connect2(b, mem_ctx, | ||
640 | - global_myname(), | ||
641 | - SAMR_ACCESS_CONNECT_TO_SERVER | | ||
642 | - SAMR_ACCESS_ENUM_DOMAINS | | ||
643 | - SAMR_ACCESS_LOOKUP_DOMAIN, | ||
644 | - &connect_handle, | ||
645 | - &result); | ||
646 | - if (!NT_STATUS_IS_OK(status)) { | ||
647 | - errcode = W_ERROR_V(ntstatus_to_werror(status)); | ||
648 | - goto out; | ||
649 | - } | ||
650 | - if (!NT_STATUS_IS_OK(result)) { | ||
651 | - errcode = W_ERROR_V(ntstatus_to_werror(result)); | ||
652 | - goto out; | ||
653 | - } | ||
654 | - | ||
655 | - init_lsa_String(&domain_name, get_global_sam_name()); | ||
656 | - | ||
657 | - status = dcerpc_samr_LookupDomain(b, mem_ctx, | ||
658 | - &connect_handle, | ||
659 | - &domain_name, | ||
660 | - &domain_sid, | ||
661 | - &result); | ||
662 | - if (!NT_STATUS_IS_OK(status)) { | ||
663 | - errcode = W_ERROR_V(ntstatus_to_werror(status)); | ||
664 | - goto out; | ||
665 | - } | ||
666 | - if (!NT_STATUS_IS_OK(result)) { | ||
667 | - errcode = W_ERROR_V(ntstatus_to_werror(result)); | ||
668 | - goto out; | ||
669 | - } | ||
670 | - | ||
671 | - status = dcerpc_samr_OpenDomain(b, mem_ctx, | ||
672 | - &connect_handle, | ||
673 | - SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, | ||
674 | - domain_sid, | ||
675 | - &domain_handle, | ||
676 | - &result); | ||
677 | - if (!NT_STATUS_IS_OK(status)) { | ||
678 | - errcode = W_ERROR_V(ntstatus_to_werror(status)); | ||
679 | - goto out; | ||
680 | - } | ||
681 | - if (!NT_STATUS_IS_OK(result)) { | ||
682 | - errcode = W_ERROR_V(ntstatus_to_werror(result)); | ||
683 | - goto out; | ||
684 | - } | ||
685 | - | ||
686 | - init_lsa_String(&names, user); | ||
687 | - | ||
688 | - status = dcerpc_samr_LookupNames(b, mem_ctx, | ||
689 | - &domain_handle, | ||
690 | - 1, | ||
691 | - &names, | ||
692 | - &rids, | ||
693 | - &types, | ||
694 | - &result); | ||
695 | - if (!NT_STATUS_IS_OK(status)) { | ||
696 | - errcode = W_ERROR_V(ntstatus_to_werror(status)); | ||
697 | - goto out; | ||
698 | - } | ||
699 | - if (!NT_STATUS_IS_OK(result)) { | ||
700 | - errcode = W_ERROR_V(ntstatus_to_werror(result)); | ||
701 | - goto out; | ||
702 | - } | ||
703 | - | ||
704 | - if (rids.count != 1) { | ||
705 | - errcode = W_ERROR_V(WERR_NO_SUCH_USER); | ||
706 | - goto out; | ||
707 | - } | ||
708 | - if (rids.count != types.count) { | ||
709 | - errcode = W_ERROR_V(WERR_INVALID_PARAM); | ||
710 | - goto out; | ||
711 | - } | ||
712 | - if (types.ids[0] != SID_NAME_USER) { | ||
713 | - errcode = W_ERROR_V(WERR_INVALID_PARAM); | ||
714 | - goto out; | ||
715 | - } | ||
716 | - | ||
717 | - rid = rids.ids[0]; | ||
718 | - | ||
719 | - status = dcerpc_samr_OpenUser(b, mem_ctx, | ||
720 | - &domain_handle, | ||
721 | - SAMR_USER_ACCESS_CHANGE_PASSWORD, | ||
722 | - rid, | ||
723 | - &user_handle, | ||
724 | - &result); | ||
725 | - if (!NT_STATUS_IS_OK(status)) { | ||
726 | - errcode = W_ERROR_V(ntstatus_to_werror(status)); | ||
727 | - goto out; | ||
728 | - } | ||
729 | - if (!NT_STATUS_IS_OK(result)) { | ||
730 | - errcode = W_ERROR_V(ntstatus_to_werror(result)); | ||
731 | - goto out; | ||
732 | - } | ||
733 | - | ||
734 | - if (encrypted == 0) { | ||
735 | - E_deshash(pass1, old_lm_hash.hash); | ||
736 | - E_deshash(pass2, new_lm_hash.hash); | ||
737 | - } else { | ||
738 | - ZERO_STRUCT(old_lm_hash); | ||
739 | - ZERO_STRUCT(new_lm_hash); | ||
740 | - memcpy(old_lm_hash.hash, pass1, MIN(strlen(pass1), 16)); | ||
741 | - memcpy(new_lm_hash.hash, pass1, MIN(strlen(pass2), 16)); | ||
742 | - } | ||
743 | - | ||
744 | - status = dcerpc_samr_ChangePasswordUser(b, mem_ctx, | ||
745 | - &user_handle, | ||
746 | - true, /* lm_present */ | ||
747 | - &old_lm_hash, | ||
748 | - &new_lm_hash, | ||
749 | - false, /* nt_present */ | ||
750 | - NULL, /* old_nt_crypted */ | ||
751 | - NULL, /* new_nt_crypted */ | ||
752 | - false, /* cross1_present */ | ||
753 | - NULL, /* nt_cross */ | ||
754 | - false, /* cross2_present */ | ||
755 | - NULL, /* lm_cross */ | ||
756 | - &result); | ||
757 | - if (!NT_STATUS_IS_OK(status)) { | ||
758 | - errcode = W_ERROR_V(ntstatus_to_werror(status)); | ||
759 | - goto out; | ||
760 | - } | ||
761 | - if (!NT_STATUS_IS_OK(result)) { | ||
762 | - errcode = W_ERROR_V(ntstatus_to_werror(result)); | ||
763 | - goto out; | ||
764 | - } | ||
765 | - | ||
766 | - errcode = NERR_Success; | ||
767 | - out: | ||
768 | - | ||
769 | - if (b && is_valid_policy_hnd(&user_handle)) { | ||
770 | - dcerpc_samr_Close(b, mem_ctx, &user_handle, &result); | ||
771 | - } | ||
772 | - if (b && is_valid_policy_hnd(&domain_handle)) { | ||
773 | - dcerpc_samr_Close(b, mem_ctx, &domain_handle, &result); | ||
774 | - } | ||
775 | - if (b && is_valid_policy_hnd(&connect_handle)) { | ||
776 | - dcerpc_samr_Close(b, mem_ctx, &connect_handle, &result); | ||
777 | - } | ||
778 | - | ||
779 | - memset((char *)pass1,'\0',sizeof(fstring)); | ||
780 | - memset((char *)pass2,'\0',sizeof(fstring)); | ||
781 | - | ||
782 | - SSVAL(*rparam,0,errcode); | ||
783 | - SSVAL(*rparam,2,0); /* converter word */ | ||
784 | - return(True); | ||
785 | -} | ||
786 | - | ||
787 | -/**************************************************************************** | ||
788 | Set the user password (SamOEM version - gets plaintext). | ||
789 | ****************************************************************************/ | ||
790 | |||
791 | @@ -5790,7 +5537,6 @@ static const struct { | ||
792 | {"NetServerEnum2", RAP_NetServerEnum2, api_RNetServerEnum2}, /* anon OK */ | ||
793 | {"NetServerEnum3", RAP_NetServerEnum3, api_RNetServerEnum3}, /* anon OK */ | ||
794 | {"WAccessGetUserPerms",RAP_WAccessGetUserPerms,api_WAccessGetUserPerms}, | ||
795 | - {"SetUserPassword", RAP_WUserPasswordSet2, api_SetUserPassword}, | ||
796 | {"WWkstaUserLogon", RAP_WWkstaUserLogon, api_WWkstaUserLogon}, | ||
797 | {"PrintJobInfo", RAP_WPrintJobSetInfo, api_PrintJobInfo}, | ||
798 | {"WPrintDriverEnum", RAP_WPrintDriverEnum, api_WPrintDriverEnum}, | ||
799 | diff --git a/source4/rpc_server/samr/samr_password.c b/source4/rpc_server/samr/samr_password.c | ||
800 | index ee13a11..e618740 100644 | ||
801 | --- a/source4/rpc_server/samr/samr_password.c | ||
802 | +++ b/source4/rpc_server/samr/samr_password.c | ||
803 | @@ -32,131 +32,17 @@ | ||
804 | |||
805 | /* | ||
806 | samr_ChangePasswordUser | ||
807 | + | ||
808 | + So old it is just not worth implementing | ||
809 | + because it does not supply a plaintext and so we can't do password | ||
810 | + complexity checking and cannot update all the other password hashes. | ||
811 | + | ||
812 | */ | ||
813 | NTSTATUS dcesrv_samr_ChangePasswordUser(struct dcesrv_call_state *dce_call, | ||
814 | TALLOC_CTX *mem_ctx, | ||
815 | struct samr_ChangePasswordUser *r) | ||
816 | { | ||
817 | - struct dcesrv_handle *h; | ||
818 | - struct samr_account_state *a_state; | ||
819 | - struct ldb_context *sam_ctx; | ||
820 | - struct ldb_message **res; | ||
821 | - int ret; | ||
822 | - struct samr_Password new_lmPwdHash, new_ntPwdHash, checkHash; | ||
823 | - struct samr_Password *lm_pwd, *nt_pwd; | ||
824 | - NTSTATUS status = NT_STATUS_OK; | ||
825 | - const char * const attrs[] = { "dBCSPwd", "unicodePwd" , NULL }; | ||
826 | - | ||
827 | - DCESRV_PULL_HANDLE(h, r->in.user_handle, SAMR_HANDLE_USER); | ||
828 | - | ||
829 | - a_state = h->data; | ||
830 | - | ||
831 | - /* basic sanity checking on parameters. Do this before any database ops */ | ||
832 | - if (!r->in.lm_present || !r->in.nt_present || | ||
833 | - !r->in.old_lm_crypted || !r->in.new_lm_crypted || | ||
834 | - !r->in.old_nt_crypted || !r->in.new_nt_crypted) { | ||
835 | - /* we should really handle a change with lm not | ||
836 | - present */ | ||
837 | - return NT_STATUS_INVALID_PARAMETER_MIX; | ||
838 | - } | ||
839 | - | ||
840 | - /* Connect to a SAMDB with system privileges for fetching the old pw | ||
841 | - * hashes. */ | ||
842 | - sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, | ||
843 | - dce_call->conn->dce_ctx->lp_ctx, | ||
844 | - system_session(dce_call->conn->dce_ctx->lp_ctx), 0); | ||
845 | - if (sam_ctx == NULL) { | ||
846 | - return NT_STATUS_INVALID_SYSTEM_SERVICE; | ||
847 | - } | ||
848 | - | ||
849 | - /* fetch the old hashes */ | ||
850 | - ret = gendb_search_dn(sam_ctx, mem_ctx, | ||
851 | - a_state->account_dn, &res, attrs); | ||
852 | - if (ret != 1) { | ||
853 | - return NT_STATUS_WRONG_PASSWORD; | ||
854 | - } | ||
855 | - | ||
856 | - status = samdb_result_passwords(mem_ctx, | ||
857 | - dce_call->conn->dce_ctx->lp_ctx, | ||
858 | - res[0], &lm_pwd, &nt_pwd); | ||
859 | - if (!NT_STATUS_IS_OK(status) || !nt_pwd) { | ||
860 | - return NT_STATUS_WRONG_PASSWORD; | ||
861 | - } | ||
862 | - | ||
863 | - /* decrypt and check the new lm hash */ | ||
864 | - if (lm_pwd) { | ||
865 | - D_P16(lm_pwd->hash, r->in.new_lm_crypted->hash, new_lmPwdHash.hash); | ||
866 | - D_P16(new_lmPwdHash.hash, r->in.old_lm_crypted->hash, checkHash.hash); | ||
867 | - if (memcmp(checkHash.hash, lm_pwd, 16) != 0) { | ||
868 | - return NT_STATUS_WRONG_PASSWORD; | ||
869 | - } | ||
870 | - } | ||
871 | - | ||
872 | - /* decrypt and check the new nt hash */ | ||
873 | - D_P16(nt_pwd->hash, r->in.new_nt_crypted->hash, new_ntPwdHash.hash); | ||
874 | - D_P16(new_ntPwdHash.hash, r->in.old_nt_crypted->hash, checkHash.hash); | ||
875 | - if (memcmp(checkHash.hash, nt_pwd, 16) != 0) { | ||
876 | - return NT_STATUS_WRONG_PASSWORD; | ||
877 | - } | ||
878 | - | ||
879 | - /* The NT Cross is not required by Win2k3 R2, but if present | ||
880 | - check the nt cross hash */ | ||
881 | - if (r->in.cross1_present && r->in.nt_cross && lm_pwd) { | ||
882 | - D_P16(lm_pwd->hash, r->in.nt_cross->hash, checkHash.hash); | ||
883 | - if (memcmp(checkHash.hash, new_ntPwdHash.hash, 16) != 0) { | ||
884 | - return NT_STATUS_WRONG_PASSWORD; | ||
885 | - } | ||
886 | - } | ||
887 | - | ||
888 | - /* The LM Cross is not required by Win2k3 R2, but if present | ||
889 | - check the lm cross hash */ | ||
890 | - if (r->in.cross2_present && r->in.lm_cross && lm_pwd) { | ||
891 | - D_P16(nt_pwd->hash, r->in.lm_cross->hash, checkHash.hash); | ||
892 | - if (memcmp(checkHash.hash, new_lmPwdHash.hash, 16) != 0) { | ||
893 | - return NT_STATUS_WRONG_PASSWORD; | ||
894 | - } | ||
895 | - } | ||
896 | - | ||
897 | - /* Start a SAM with user privileges for the password change */ | ||
898 | - sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, | ||
899 | - dce_call->conn->dce_ctx->lp_ctx, | ||
900 | - dce_call->conn->auth_state.session_info, 0); | ||
901 | - if (sam_ctx == NULL) { | ||
902 | - return NT_STATUS_INVALID_SYSTEM_SERVICE; | ||
903 | - } | ||
904 | - | ||
905 | - /* Start transaction */ | ||
906 | - ret = ldb_transaction_start(sam_ctx); | ||
907 | - if (ret != LDB_SUCCESS) { | ||
908 | - DEBUG(1, ("Failed to start transaction: %s\n", ldb_errstring(sam_ctx))); | ||
909 | - return NT_STATUS_TRANSACTION_ABORTED; | ||
910 | - } | ||
911 | - | ||
912 | - /* Performs the password modification. We pass the old hashes read out | ||
913 | - * from the database since they were already checked against the user- | ||
914 | - * provided ones. */ | ||
915 | - status = samdb_set_password(sam_ctx, mem_ctx, | ||
916 | - a_state->account_dn, | ||
917 | - a_state->domain_state->domain_dn, | ||
918 | - NULL, &new_lmPwdHash, &new_ntPwdHash, | ||
919 | - lm_pwd, nt_pwd, /* this is a user password change */ | ||
920 | - NULL, | ||
921 | - NULL); | ||
922 | - if (!NT_STATUS_IS_OK(status)) { | ||
923 | - ldb_transaction_cancel(sam_ctx); | ||
924 | - return status; | ||
925 | - } | ||
926 | - | ||
927 | - /* And this confirms it in a transaction commit */ | ||
928 | - ret = ldb_transaction_commit(sam_ctx); | ||
929 | - if (ret != LDB_SUCCESS) { | ||
930 | - DEBUG(1,("Failed to commit transaction to change password on %s: %s\n", | ||
931 | - ldb_dn_get_linearized(a_state->account_dn), | ||
932 | - ldb_errstring(sam_ctx))); | ||
933 | - return NT_STATUS_TRANSACTION_ABORTED; | ||
934 | - } | ||
935 | - | ||
936 | - return NT_STATUS_OK; | ||
937 | + return NT_STATUS_NOT_IMPLEMENTED; | ||
938 | } | ||
939 | |||
940 | /* | ||
941 | diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c | ||
942 | index 7d9a1e2..adfc5d4 100644 | ||
943 | --- a/source4/torture/rpc/samr.c | ||
944 | +++ b/source4/torture/rpc/samr.c | ||
945 | @@ -1728,8 +1728,16 @@ static bool test_ChangePasswordUser(struct dcerpc_binding_handle *b, | ||
946 | |||
947 | torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, &r), | ||
948 | "ChangePasswordUser failed"); | ||
949 | - torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_WRONG_PASSWORD, | ||
950 | - "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash"); | ||
951 | + | ||
952 | + /* Do not proceed if this call has been removed */ | ||
953 | + if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_IMPLEMENTED)) { | ||
954 | + return true; | ||
955 | + } | ||
956 | + | ||
957 | + if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) { | ||
958 | + torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_WRONG_PASSWORD, | ||
959 | + "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash"); | ||
960 | + } | ||
961 | |||
962 | /* Unbreak the LM hash */ | ||
963 | hash1.hash[0]--; | ||
964 | -- | ||
965 | 1.7.9.5 | ||
966 | |||
diff --git a/meta-oe/recipes-connectivity/samba/samba_3.6.8.bb b/meta-oe/recipes-connectivity/samba/samba_3.6.8.bb index 20b609de5..f80e41ed0 100644 --- a/meta-oe/recipes-connectivity/samba/samba_3.6.8.bb +++ b/meta-oe/recipes-connectivity/samba/samba_3.6.8.bb | |||
@@ -30,6 +30,7 @@ SRC_URI += "\ | |||
30 | file://configure-disable-getaddrinfo-cross.patch;patchdir=.. \ | 30 | file://configure-disable-getaddrinfo-cross.patch;patchdir=.. \ |
31 | file://configure-disable-core_pattern-cross-check.patch;patchdir=.. \ | 31 | file://configure-disable-core_pattern-cross-check.patch;patchdir=.. \ |
32 | file://configure-libunwind.patch;patchdir=.. \ | 32 | file://configure-libunwind.patch;patchdir=.. \ |
33 | file://samba-3.6.22-CVE-2013-4496.patch;patchdir=.. \ | ||
33 | " | 34 | " |
34 | SRC_URI[md5sum] = "fbb245863eeef2fffe172df779a217be" | 35 | SRC_URI[md5sum] = "fbb245863eeef2fffe172df779a217be" |
35 | SRC_URI[sha256sum] = "4f5a171a8d902c6b4f822ed875c51eb8339196d9ccf0ecd7f6521c966b3514de" | 36 | SRC_URI[sha256sum] = "4f5a171a8d902c6b4f822ed875c51eb8339196d9ccf0ecd7f6521c966b3514de" |