[SCM] Samba Shared Repository - branch master updated
Andrew Bartlett
abartlet at samba.org
Sat Jun 24 07:19:02 UTC 2023
The branch, master has been updated
via a75378e3542 s4:kdc: translate sdb_entry->old[er]_keys into hdb_add_history_key()
via d4007b0ef9f s4:dsdb/tests: also verify too old, older password interaction with badPwdCount
via 28cf6c70676 s4:dsdb/tests: Test Kerberos login with old password fails (but badPwdCount=0)
via 370ba4ad527 s4:kdc: handle passwords from the history in hdb_samba4_auth_status()
from 4a8cfe1650a vfs: Remove "sbuf" from readdir_fn()
https://git.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit a75378e354286d095d82f644d645768345cd00fb
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Feb 7 19:32:08 2022 +0100
s4:kdc: translate sdb_entry->old[er]_keys into hdb_add_history_key()
It means that using the old or older password no longer
changes badPwdCount for Kerberos authentication.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14054
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
Autobuild-User(master): Andrew Bartlett <abartlet at samba.org>
Autobuild-Date(master): Sat Jun 24 07:18:03 UTC 2023 on atb-devel-224
commit d4007b0ef9f745a4881588ef1b8185d6b53025ee
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri Jun 23 13:42:31 2023 +0200
s4:dsdb/tests: also verify too old, older password interaction with badPwdCount
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14054
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 28cf6c706760894b7c0c65d4f5307d333d194154
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri Feb 25 05:16:36 2022 +0100
s4:dsdb/tests: Test Kerberos login with old password fails (but badPwdCount=0)
This demonstrates the pre-authentication failures with passwords from
the password history don't incremend badPwdCount, similar to the
NTLMSSP and simple bind cases. But it's still an interactive logon,
which doesn't use 'old password allowed period'.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14054
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 370ba4ad527b67555f69c2bc4b92effe0cc7169d
Author: Stefan Metzmacher <metze at samba.org>
Date: Thu Feb 17 07:12:10 2022 +0100
s4:kdc: handle passwords from the history in hdb_samba4_auth_status()
This is important in order to prevent ACCOUNT_LOCKED_OUT
with cached credentials.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14054
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
-----------------------------------------------------------------------
Summary of changes:
selftest/knownfail_mit_kdc | 5 ++
source4/dsdb/tests/python/login_basics.py | 97 ++++++++++++++++++++++++++++---
source4/kdc/hdb-samba4.c | 11 ++++
source4/kdc/sdb_to_hdb.c | 45 ++++++++++++++
4 files changed, 149 insertions(+), 9 deletions(-)
Changeset truncated at 500 lines:
diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc
index 9c5b76cac5a..8196f4f4d6b 100644
--- a/selftest/knownfail_mit_kdc
+++ b/selftest/knownfail_mit_kdc
@@ -2221,3 +2221,8 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_
^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_bad_pwd_allowed_from_user_deny.ad_dc
^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_denied_no_fast.ad_dc
^samba.tests.krb5.authn_policy_tests.samba.tests.krb5.authn_policy_tests.AuthnPolicyTests.test_authn_policy_tgt_lifetime_min.ad_dc
+#
+# MIT does not support password history in order to avoid badPwdCount changes
+# with the last password, see https://bugzilla.samba.org/show_bug.cgi?id=14054
+#
+^samba4.ldap.login_basics.python.*.__main__.BasicUserAuthTests.test_login_basics_krb5
diff --git a/source4/dsdb/tests/python/login_basics.py b/source4/dsdb/tests/python/login_basics.py
index b186e723f39..babe04879b1 100755
--- a/source4/dsdb/tests/python/login_basics.py
+++ b/source4/dsdb/tests/python/login_basics.py
@@ -122,7 +122,7 @@ class BasicUserAuthTests(BasePasswordTestCase):
lastLogon = int(res[0]["lastLogon"][0])
# check that the user can change its password
- new_password = "thatsAcomplPASS2"
+ too_old_password = "thatsAcomplTooOldPass1!"
user_ldb.modify_ldif("""
dn: %s
changetype: modify
@@ -130,28 +130,74 @@ delete: userPassword
userPassword: %s
add: userPassword
userPassword: %s
-""" % (userdn, userpass, new_password))
+""" % (userdn, userpass, too_old_password))
+
+ # change the password again
+ older_password = "thatsAcomplOlderPass1!"
+ user_ldb.modify_ldif("""
+dn: %s
+changetype: modify
+delete: userPassword
+userPassword: %s
+add: userPassword
+userPassword: %s
+""" % (userdn, too_old_password, older_password))
+
+ # change the password again
+ old_password = "thatsAcomplOldPass1!"
+ user_ldb.modify_ldif("""
+dn: %s
+changetype: modify
+delete: userPassword
+userPassword: %s
+add: userPassword
+userPassword: %s
+""" % (userdn, older_password, old_password))
+
+ # change the password once more
+ new_password = "thatsAcomplNewPass1!"
+ user_ldb.modify_ldif("""
+dn: %s
+changetype: modify
+delete: userPassword
+userPassword: %s
+add: userPassword
+userPassword: %s
+""" % (userdn, old_password, new_password))
# discard the old creds (i.e. get rid of our valid Kerberos ticket)
del test_creds
test_creds = self.insta_creds(creds)
- test_creds.set_password(userpass)
+ test_creds.set_password(older_password)
+
+ self.assertLoginFailure(ldap_url, test_creds, self.lp)
+ res = self._check_account(userdn,
+ badPwdCount=0,
+ badPasswordTime=badPasswordTime,
+ logonCount=logonCount,
+ lastLogon=lastLogon,
+ lastLogonTimestamp=lastLogonTimestamp,
+ userAccountControl=UF_NORMAL_ACCOUNT,
+ msDSUserAccountControlComputed=0,
+ msg='Test with older password fails (but badPwdCount=0)')
+
+ del test_creds
+ test_creds = self.insta_creds(creds)
+ test_creds.set_password(old_password)
# for Kerberos, logging in with the old password fails
if creds.get_kerberos_state() == MUST_USE_KERBEROS:
self.assertLoginFailure(ldap_url, test_creds, self.lp)
- info_msg = 'Test Kerberos login with old password fails'
- expectBadPwdTime = ("greater", badPasswordTime)
+ info_msg = 'Test Kerberos login with old password fails (but badPwdCount=0)'
res = self._check_account(userdn,
- badPwdCount=1,
- badPasswordTime=expectBadPwdTime,
+ badPwdCount=0,
+ badPasswordTime=badPasswordTime,
logonCount=logonCount,
lastLogon=lastLogon,
lastLogonTimestamp=lastLogonTimestamp,
userAccountControl=UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0,
msg=info_msg)
- badPasswordTime = int(res[0]["badPasswordTime"][0])
else:
# for NTLM, logging in with the old password succeeds
user_ldb = self.assertLoginSuccess(ldap_url, test_creds, self.lp)
@@ -168,8 +214,10 @@ userPassword: %s
userAccountControl=UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0,
msg=info_msg)
+ logonCount = int(res[0]["logonCount"][0])
+ lastLogon = int(res[0]["lastLogon"][0])
- # check logging in with the new password succeeds
+ # check logging in with the correct password succeeds
test_creds.set_password(new_password)
user_ldb = self.assertLoginSuccess(ldap_url, test_creds, self.lp)
res = self._check_account(userdn,
@@ -181,6 +229,37 @@ userPassword: %s
userAccountControl=UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0,
msg='Test login with new password succeeds')
+ logonCount = int(res[0]["logonCount"][0])
+ lastLogon = int(res[0]["lastLogon"][0])
+
+ del test_creds
+ test_creds = self.insta_creds(creds)
+ test_creds.set_password(too_old_password)
+
+ self.assertLoginFailure(ldap_url, test_creds, self.lp)
+ res = self._check_account(userdn,
+ badPwdCount=1,
+ badPasswordTime=("greater", badPasswordTime),
+ logonCount=logonCount,
+ lastLogon=lastLogon,
+ lastLogonTimestamp=lastLogonTimestamp,
+ userAccountControl=UF_NORMAL_ACCOUNT,
+ msDSUserAccountControlComputed=0,
+ msg='Test login with too old password fails')
+ badPasswordTime = int(res[0]["badPasswordTime"][0])
+
+ # check logging in with the correct password succeeds
+ test_creds.set_password(new_password)
+ user_ldb = self.assertLoginSuccess(ldap_url, test_creds, self.lp)
+ res = self._check_account(userdn,
+ badPwdCount=0,
+ badPasswordTime=badPasswordTime,
+ logonCount=(logoncount_relation, logonCount),
+ lastLogon=('greater', lastLogon),
+ lastLogonTimestamp=lastLogonTimestamp,
+ userAccountControl=UF_NORMAL_ACCOUNT,
+ msDSUserAccountControlComputed=0,
+ msg='Test login with new password succeeds again')
def test_login_basics_krb5(self):
self._test_login_basics(self.lockout1krb5_creds)
diff --git a/source4/kdc/hdb-samba4.c b/source4/kdc/hdb-samba4.c
index 90e52f60cef..c176a84eb5b 100644
--- a/source4/kdc/hdb-samba4.c
+++ b/source4/kdc/hdb-samba4.c
@@ -846,6 +846,17 @@ static krb5_error_code hdb_samba4_audit(krb5_context context,
status = NT_STATUS_WRONG_PASSWORD;
}
rwdc_fallback = kdc_db_ctx->rodc;
+ } else if (hdb_auth_status == KDC_AUTH_EVENT_HISTORIC_LONG_TERM_KEY) {
+ /*
+ * The pre-authentication succeeds with a password
+ * from the password history, so we don't
+ * update the badPwdCount, but still return
+ * PREAUTH_FAILED and need to forward to
+ * a RWDC in order to produce an autoritative
+ * response for the client.
+ */
+ status = NT_STATUS_WRONG_PASSWORD;
+ rwdc_fallback = kdc_db_ctx->rodc;
} else if (hdb_auth_status == KDC_AUTH_EVENT_CLIENT_LOCKED_OUT) {
edata_status = status = NT_STATUS_ACCOUNT_LOCKED_OUT;
rwdc_fallback = kdc_db_ctx->rodc;
diff --git a/source4/kdc/sdb_to_hdb.c b/source4/kdc/sdb_to_hdb.c
index 994a52d7d44..93d2f3f5980 100644
--- a/source4/kdc/sdb_to_hdb.c
+++ b/source4/kdc/sdb_to_hdb.c
@@ -147,6 +147,31 @@ static int sdb_keys_to_Keys(const struct sdb_keys *s, Keys *h)
return 0;
}
+static int sdb_keys_to_HistKeys(krb5_context context,
+ const struct sdb_keys *s,
+ krb5_kvno kvno,
+ hdb_entry *h)
+{
+ unsigned int i;
+
+ for (i = 0; i < s->len; i++) {
+ Key k = { 0, };
+ int ret;
+
+ ret = sdb_key_to_Key(&s->val[i], &k);
+ if (ret != 0) {
+ return ENOMEM;
+ }
+ ret = hdb_add_history_key(context, h, kvno, &k);
+ free_Key(&k);
+ if (ret != 0) {
+ return ENOMEM;
+ }
+ }
+
+ return 0;
+}
+
static int sdb_event_to_Event(krb5_context context,
const struct sdb_event *s, Event *h)
{
@@ -192,6 +217,26 @@ int sdb_entry_to_hdb_entry(krb5_context context,
goto error;
}
+ if (h->kvno > 1) {
+ rc = sdb_keys_to_HistKeys(context,
+ &s->old_keys,
+ h->kvno - 1,
+ h);
+ if (rc != 0) {
+ goto error;
+ }
+ }
+
+ if (h->kvno > 2) {
+ rc = sdb_keys_to_HistKeys(context,
+ &s->older_keys,
+ h->kvno - 2,
+ h);
+ if (rc != 0) {
+ goto error;
+ }
+ }
+
rc = sdb_event_to_Event(context,
&s->created_by,
&h->created_by);
--
Samba Shared Repository
More information about the samba-cvs
mailing list