from samba.tests import delete_force
from samba.dcerpc import security, samr
from samba.ndr import ndr_unpack
+from samba.tests.password_test import PasswordTestCase
import time
-class BasePasswordTestCase(samba.tests.TestCase):
+
+class BasePasswordTestCase(PasswordTestCase):
def _open_samr_user(self, res):
self.assertTrue("objectSid" in res[0])
if mode == "absent":
self.assertFalse(name in res[0],
- msg="attr[%s] not missing on dn[%s]" %
- (name, res[0].dn))
+ msg="attr[%s] not missing on dn[%s]" %
+ (name, res[0].dn))
return
self.assertTrue(name in res[0],
msg="attr[%s]=%r on dn[%s]" %
(name, res[0][name], res[0].dn))
-
print("%s = '%s'" % (name, res[0][name][0]))
if mode == "present":
logonCount=0,
lastLogon=0,
lastLogonTimestamp=("absent", None),
- userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0)
def _check_account(self, dn,
if msg is not None:
print("\033[01;32m %s \033[00m\n" % msg)
attrs = [
- "objectSid",
+ "objectSid",
"badPwdCount",
"badPasswordTime",
"lastLogon",
self.assertEquals(uinfo21.last_logon, lastLogon)
self.assertEquals(uinfo21.logon_count, logonCount)
-
# check LDAP again and make sure the samr.QueryUserInfo
# doesn't have any impact.
res2 = self.ldb.search(dn, scope=SCOPE_BASE, attrs=attrs)
time.sleep(0.01)
return res
+ def update_lockout_settings(self, threshold, duration, observation_window):
+ """Updates the global user lockout settings"""
+ m = Message()
+ m.dn = Dn(self.ldb, self.base_dn)
+ account_lockout_duration_ticks = -int(duration * (1e7))
+ m["lockoutDuration"] = MessageElement(str(account_lockout_duration_ticks),
+ FLAG_MOD_REPLACE, "lockoutDuration")
+ m["lockoutThreshold"] = MessageElement(str(threshold),
+ FLAG_MOD_REPLACE, "lockoutThreshold")
+ lockout_observation_window_ticks = -int(observation_window * (1e7))
+ m["lockOutObservationWindow"] = MessageElement(str(lockout_observation_window_ticks),
+ FLAG_MOD_REPLACE, "lockOutObservationWindow")
+ self.ldb.modify(m)
+
def _readd_user(self, creds, lockOutObservationWindow=0):
username = creds.get_username()
userpass = creds.get_password()
use_kerberos = creds.get_kerberos_state()
fail_creds = self.insta_creds(self.template_creds,
username=username,
- userpass=userpass+"X",
+ userpass=userpass + "X",
kerberos_state=use_kerberos)
self._check_account_initial(userdn)
self.template_creds.set_gensec_features(self.global_creds.get_gensec_features())
self.template_creds.set_kerberos_state(self.global_creds.get_kerberos_state())
-
# Gets back the basedn
base_dn = self.ldb.domain_dn()
# Gets back the configuration basedn
configuration_dn = self.ldb.get_config_basedn().get_linearized()
- # Get the old "dSHeuristics" if it was set
- dsheuristics = self.ldb.get_dsheuristics()
-
- # Reset the "dSHeuristics" as they were before
- self.addCleanup(self.ldb.set_dsheuristics, dsheuristics)
-
res = self.ldb.search(base_dn,
- scope=SCOPE_BASE, attrs=["lockoutDuration", "lockOutObservationWindow", "lockoutThreshold"])
+ scope=SCOPE_BASE, attrs=["lockoutDuration", "lockOutObservationWindow", "lockoutThreshold"])
if "lockoutDuration" in res[0]:
lockoutDuration = res[0]["lockoutDuration"][0]
lockoutThreshold: """ + str(lockoutThreshold) + """
""")
- m = Message()
- m.dn = Dn(self.ldb, base_dn)
-
- self.account_lockout_duration = 2
- account_lockout_duration_ticks = -int(self.account_lockout_duration * (1e7))
-
- m["lockoutDuration"] = MessageElement(str(account_lockout_duration_ticks),
- FLAG_MOD_REPLACE, "lockoutDuration")
-
- account_lockout_threshold = 3
- m["lockoutThreshold"] = MessageElement(str(account_lockout_threshold),
- FLAG_MOD_REPLACE, "lockoutThreshold")
-
- self.lockout_observation_window = 2
- lockout_observation_window_ticks = -int(self.lockout_observation_window * (1e7))
-
- m["lockOutObservationWindow"] = MessageElement(str(lockout_observation_window_ticks),
- FLAG_MOD_REPLACE, "lockOutObservationWindow")
-
- self.ldb.modify(m)
-
- # Set the "dSHeuristics" to activate the correct "userPassword" behaviour
- self.ldb.set_dsheuristics("000000001")
-
- # Get the old "minPwdAge"
- minPwdAge = self.ldb.get_minPwdAge()
-
- # Reset the "minPwdAge" as it was before
- self.addCleanup(self.ldb.set_minPwdAge, minPwdAge)
-
- # Set it temporarely to "0"
- self.ldb.set_minPwdAge("0")
-
self.base_dn = self.ldb.domain_dn()
+ self.account_lockout_duration = 3
+ self.lockout_observation_window = 3
+ self.update_lockout_settings(threshold=3,
+ duration=self.account_lockout_duration,
+ observation_window=self.lockout_observation_window)
+
+ # update DC to allow password changes for the duration of this test
+ self.allow_password_changes()
self.domain_sid = security.dom_sid(self.ldb.get_domain_sid())
self.samr = samr.samr("ncacn_ip_tcp:%s[seal]" % self.host, self.lp, self.global_creds)
logonCount=(logoncount_relation, 0),
lastLogon=("greater", 0),
lastLogonTimestamp=("greater", 0),
- userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0)
badPasswordTime = int(res[0]["badPasswordTime"][0])
logonCount = int(res[0]["logonCount"][0])
print(firstLogon)
print(lastLogonTimestamp)
-
self.assertGreater(lastLogon, badPasswordTime)
self.assertGreaterEqual(lastLogon, lastLogonTimestamp)
logonCount=logonCount,
lastLogon=lastLogon,
lastLogonTimestamp=lastLogonTimestamp,
- userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0,
msg='lastlogontimestamp with wrong password')
badPasswordTime = int(res[0]["badPasswordTime"][0])
logonCount=(logoncount_relation, logonCount),
lastLogon=('greater', lastLogon),
lastLogonTimestamp=lastLogonTimestamp,
- userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0,
msg='LLTimestamp is updated to lastlogon')
logonCount=logonCount,
lastLogon=lastLogon,
lastLogonTimestamp=lastLogonTimestamp,
- userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0)
badPasswordTime = int(res[0]["badPasswordTime"][0])
logonCount=logonCount,
lastLogon=lastLogon,
lastLogonTimestamp=lastLogonTimestamp,
- userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0)
badPasswordTime = int(res[0]["badPasswordTime"][0])
lastLogon=lastLogon,
lastLogonTimestamp=lastLogonTimestamp,
lockoutTime=("greater", badPasswordTime),
- userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=dsdb.UF_LOCKOUT)
badPasswordTime = int(res[0]["badPasswordTime"][0])
lockoutTime = int(res[0]["lockoutTime"][0])
lastLogon=lastLogon,
lastLogonTimestamp=lastLogonTimestamp,
lockoutTime=lockoutTime,
- userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=dsdb.UF_LOCKOUT)
# The wrong password
lastLogon=lastLogon,
lastLogonTimestamp=lastLogonTimestamp,
lockoutTime=lockoutTime,
- userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=dsdb.UF_LOCKOUT)
# The correct password, but we are locked out
lastLogon=lastLogon,
lastLogonTimestamp=lastLogonTimestamp,
lockoutTime=lockoutTime,
- userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=dsdb.UF_LOCKOUT)
# wait for the lockout to end
lockoutTime=lockoutTime,
lastLogon=lastLogon,
lastLogonTimestamp=lastLogonTimestamp,
- userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0)
# The correct password after letting the timeout expire
lastLogon=(lastlogon_relation, lastLogon),
lastLogonTimestamp=lastLogonTimestamp,
lockoutTime=0,
- userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0,
msg="lastLogon is way off")
lockoutTime=0,
lastLogon=lastLogon,
lastLogonTimestamp=lastLogonTimestamp,
- userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0)
badPasswordTime = int(res[0]["badPasswordTime"][0])
lockoutTime=0,
lastLogon=lastLogon,
lastLogonTimestamp=lastLogonTimestamp,
- userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0)
badPasswordTime = int(res[0]["badPasswordTime"][0])
lockoutTime=0,
lastLogon=lastLogon,
lastLogonTimestamp=lastLogonTimestamp,
- userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0)
# The wrong password
lockoutTime=0,
lastLogon=lastLogon,
lastLogonTimestamp=lastLogonTimestamp,
- userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0)
badPasswordTime = int(res[0]["badPasswordTime"][0])
lockoutTime=0,
lastLogon=("greater", lastLogon),
lastLogonTimestamp=lastLogonTimestamp,
- userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0)
def _test_multiple_logon(self, creds):
logonCount=(logoncount_relation, 0),
lastLogon=("greater", 0),
lastLogonTimestamp=("greater", 0),
- userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0)
badPasswordTime = int(res[0]["badPasswordTime"][0])
logonCount = int(res[0]["logonCount"][0])
logonCount=(logoncount_relation, logonCount),
lastLogon=(lastlogon_relation, lastLogon),
lastLogonTimestamp=lastLogonTimestamp,
- userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0,
msg=("second logon, firstlogon was %s" %
firstLogon))
-
lastLogon = int(res[0]["lastLogon"][0])
time.sleep(1)
logonCount=(logoncount_relation, logonCount),
lastLogon=(lastlogon_relation, lastLogon),
lastLogonTimestamp=lastLogonTimestamp,
- userAccountControl=
- dsdb.UF_NORMAL_ACCOUNT,
+ userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0)