summaryrefslogtreecommitdiffstats
path: root/meta-oe/recipes-connectivity/samba
diff options
context:
space:
mode:
authorChong.Lu@windriver.com <Chong.Lu@windriver.com>2014-06-13 14:12:54 +0800
committerMartin Jansa <Martin.Jansa@gmail.com>2014-06-21 19:22:24 +0200
commit3d5d8c6d0f21de60dc84610a4d47da2d8c062901 (patch)
treee549f5d8e529f58bbdd6e440b7dddb1651fba583 /meta-oe/recipes-connectivity/samba
parent33a45cf6529243764bc383ee6c8ece00c7792e8b (diff)
downloadmeta-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.patch966
-rw-r--r--meta-oe/recipes-connectivity/samba/samba_3.6.8.bb1
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 @@
1Upstream-Status: Backport
2
3From 25066eb31d6608075b5993b0d19b3e0843cdadeb Mon Sep 17 00:00:00 2001
4From: Andrew Bartlett <abartlet@samba.org>
5Date: Fri, 1 Nov 2013 14:55:44 +1300
6Subject: [PATCH 1/3] CVE-2013-4496:s3-samr: Block attempts to crack passwords
7 via repeated password changes
8
9Bug: https://bugzilla.samba.org/show_bug.cgi?id=10245
10
11Signed-off-by: Andrew Bartlett <abartlet@samba.org>
12Signed-off-by: Stefan Metzmacher <metze@samba.org>
13Signed-off-by: Jeremy Allison <jra@samba.org>
14Reviewed-by: Stefan Metzmacher <metze@samba.org>
15Reviewed-by: Jeremy Allison <jra@samba.org>
16Reviewed-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
22diff --git a/source3/rpc_server/samr/srv_samr_chgpasswd.c b/source3/rpc_server/samr/srv_samr_chgpasswd.c
23index 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;
102diff --git a/source3/rpc_server/samr/srv_samr_nt.c b/source3/rpc_server/samr/srv_samr_nt.c
103index 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--
2661.7.9.5
267
268
269From 059da248cf69a3b0ef29836f49367b938fb1cbda Mon Sep 17 00:00:00 2001
270From: Stefan Metzmacher <metze@samba.org>
271Date: Tue, 5 Nov 2013 14:04:20 +0100
272Subject: [PATCH 2/3] CVE-2013-4496:s3:auth: fix memory leak in the
273 ACCOUNT_LOCKED_OUT case.
274
275Bug: https://bugzilla.samba.org/show_bug.cgi?id=10245
276
277Signed-off-by: Stefan Metzmacher <metze@samba.org>
278Reviewed-by: Jeremy Allison <jra@samba.org>
279Signed-off-by: Andrew Bartlett <abartlet@samba.org>
280Reviewed-by: Andreas Schneider <asn@samba.org>
281---
282 source3/auth/check_samsec.c | 1 +
283 1 file changed, 1 insertion(+)
284
285diff --git a/source3/auth/check_samsec.c b/source3/auth/check_samsec.c
286index 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--
2981.7.9.5
299
300
301From 27f982ef33a1238ae48d7a38d608dd23ebde61ae Mon Sep 17 00:00:00 2001
302From: Andrew Bartlett <abartlet@samba.org>
303Date: Tue, 5 Nov 2013 16:16:46 +1300
304Subject: [PATCH 3/3] CVE-2013-4496:samr: Remove ChangePasswordUser
305
306This old password change mechanism does not provide the plaintext to
307validate against password complexity, and it is not used by modern
308clients.
309
310The missing features in both implementations (by design) were:
311
312 - the password complexity checks (no plaintext)
313 - the minimum password length (no plaintext)
314
315Additionally, 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
323Finally, the mechanism was almost useless, as it was incorrectly
324only made available to administrative users with permission
325to reset the password. It is removed here so that it is not
326mistakenly reinstated in the future.
327
328Andrew Bartlett
329
330Bug: https://bugzilla.samba.org/show_bug.cgi?id=10245
331
332Signed-off-by: Andrew Bartlett <abartlet@samba.org>
333Reviewed-by: Andreas Schneider <asn@samba.org>
334Reviewed-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
342diff --git a/source3/rpc_server/samr/srv_samr_nt.c b/source3/rpc_server/samr/srv_samr_nt.c
343index 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 /*******************************************************************
527diff --git a/source3/smbd/lanman.c b/source3/smbd/lanman.c
528index 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},
799diff --git a/source4/rpc_server/samr/samr_password.c b/source4/rpc_server/samr/samr_password.c
800index 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 /*
941diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c
942index 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--
9651.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"
34SRC_URI[md5sum] = "fbb245863eeef2fffe172df779a217be" 35SRC_URI[md5sum] = "fbb245863eeef2fffe172df779a217be"
35SRC_URI[sha256sum] = "4f5a171a8d902c6b4f822ed875c51eb8339196d9ccf0ecd7f6521c966b3514de" 36SRC_URI[sha256sum] = "4f5a171a8d902c6b4f822ed875c51eb8339196d9ccf0ecd7f6521c966b3514de"