password_lockout: Tests against RODC (once preloaded)
authorGarming Sam <garming@catalyst.net.nz>
Thu, 6 Apr 2017 04:26:26 +0000 (16:26 +1200)
committerGarming Sam <garming@samba.org>
Thu, 13 Apr 2017 05:29:17 +0000 (07:29 +0200)
In this scenario, both the login server and the verification server are
the RODC. This tests that a user is locked out correctly once the
lockout limit is reached and they are also unlocked correctly when the
lockout time period expires.

Signed-off-by: Garming Sam <garming@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
selftest/knownfail
source4/dsdb/tests/python/password_lockout_base.py
source4/dsdb/tests/python/rodc_rwdc.py

index 2cc9c70f1d60224714cf27e67e29f15a5d7bcaa1..bd3268e4bebb94eaff5a70e9db5878e45a7820f8 100644 (file)
 # We currently don't send referrals for LDAP modify of non-replicated attrs
 ^samba4.ldap.rodc.python\(rodc\).__main__.RodcTests.test_modify_nonreplicated.*
 ^samba4.ldap.rodc_rwdc.python.*.__main__.RodcRwdcTests.test_change_password_reveal_on_demand_kerberos
+^samba4.ldap.rodc_rwdc.python\(rodc\).__main__.RodcRwdcTests.test_login_lockout_.*
index d066d58c90367a3aad78c871e76f3e41358bc00f..190cedf1a197b064ff81cd10f4a7bd5e76ebf215 100644 (file)
@@ -84,6 +84,17 @@ class BasePasswordTestCase(samba.tests.TestCase):
             return
         self.assertEqual(mode, not mode, "Invalid Mode[%s]" % mode)
 
+    def _check_account_initial(self, userdn):
+        self._check_account(userdn,
+                            badPwdCount=0,
+                            badPasswordTime=0,
+                            logonCount=0,
+                            lastLogon=0,
+                            lastLogonTimestamp=("absent", None),
+                            userAccountControl=
+                            dsdb.UF_NORMAL_ACCOUNT,
+                            msDSUserAccountControlComputed=0)
+
     def _check_account(self, dn,
                        badPwdCount=None,
                        badPasswordTime=None,
@@ -213,6 +224,7 @@ userPassword: """ + userpass + """
                                       username=username,
                                       userpass=userpass+"X",
                                       kerberos_state=use_kerberos)
+        self._check_account_initial(userdn)
 
         # Fail once to get a badPasswordTime
         try:
index 9c05c49e6f39fea481c8434c3c9d8e2db1ea77d2..f0910c9e9c1cf1d793ad7406a2f6bf1930f29930 100644 (file)
@@ -24,7 +24,10 @@ from samba.auth import system_session
 from samba.samdb import SamDB
 from samba.credentials import Credentials, DONT_USE_KERBEROS, MUST_USE_KERBEROS
 from samba import gensec, dsdb
+from ldb import SCOPE_BASE, LdbError, ERR_INVALID_CREDENTIALS
+from samba.dcerpc import security, samr
 
+import password_lockout_base
 
 def passwd_encode(pw):
     return base64.b64encode(('"%s"' % pw).encode('utf-16-le'))
@@ -111,7 +114,7 @@ def get_server_ref_from_samdb(samdb):
 
 
 
-class RodcRwdcTests(samba.tests.TestCase):
+class RodcRwdcTests(password_lockout_base.BasePasswordTestCase):
     counter = itertools.count(1).next
 
     def force_replication(self, base=None):
@@ -140,6 +143,10 @@ class RodcRwdcTests(samba.tests.TestCase):
             print stderr
             raise RodcRwdcTestException()
 
+    def _check_account_initial(self, dn):
+        self.force_replication()
+        return super(RodcRwdcTests, self)._check_account_initial(dn)
+
     def tearDown(self):
         super(RodcRwdcTests, self).tearDown()
         self.rwdc_db.set_dsheuristics(self.rwdc_dsheuristics)
@@ -147,13 +154,30 @@ class RodcRwdcTests(samba.tests.TestCase):
         set_auto_replication(RWDC, True)
 
     def setUp(self):
-        super(RodcRwdcTests, self).setUp()
         self.rodc_db = SamDB('ldap://%s' % RODC, credentials=CREDS,
                              session_info=system_session(LP), lp=LP)
 
         self.rwdc_db = SamDB('ldap://%s' % RWDC, credentials=CREDS,
                              session_info=system_session(LP), lp=LP)
 
+        # Define variables for BasePasswordTestCase
+        self.lp = LP
+        self.global_creds = CREDS
+        self.host = RWDC
+        self.host_url = 'ldap://%s' % RWDC
+        self.ldb = SamDB(url='ldap://%s' % RWDC, session_info=system_session(self.lp),
+                         credentials=self.global_creds, lp=self.lp)
+
+        super(RodcRwdcTests, self).setUp()
+        self.host = RODC
+        self.host_url = 'ldap://%s' % RODC
+        self.ldb = SamDB(url='ldap://%s' % RODC, session_info=system_session(self.lp),
+                         credentials=self.global_creds, lp=self.lp)
+
+        self.samr = samr.samr("ncacn_ip_tcp:%s[seal]" % self.host, self.lp, self.global_creds)
+        self.samr_handle = self.samr.Connect2(None, security.SEC_FLAG_MAXIMUM_ALLOWED)
+        self.samr_domain = self.samr.OpenDomain(self.samr_handle, security.SEC_FLAG_MAXIMUM_ALLOWED, self.domain_sid)
+
         self.base_dn = self.rwdc_db.domain_dn()
 
         root = self.rodc_db.search(base='', scope=ldb.SCOPE_BASE,
@@ -548,6 +572,112 @@ class RodcRwdcTests(samba.tests.TestCase):
         CREDS.set_kerberos_state(MUST_USE_KERBEROS)
         self._test_ldap_change_password_reveal_on_demand()
 
+    def test_login_lockout_krb5(self):
+        username = self.lockout1krb5_creds.get_username()
+        userpass = self.lockout1krb5_creds.get_password()
+        userdn = "cn=%s,cn=users,%s" % (username, self.base_dn)
+
+        preload_rodc_user(userdn)
+
+        use_kerberos = self.lockout1krb5_creds.get_kerberos_state()
+        fail_creds = self.insta_creds(self.template_creds,
+                                      username=username,
+                                      userpass=userpass+"X",
+                                      kerberos_state=use_kerberos)
+
+        try:
+            ldb = SamDB(url=self.host_url, credentials=fail_creds, lp=self.lp)
+            self.fail()
+        except LdbError, (num, msg):
+            self.assertEquals(num, ERR_INVALID_CREDENTIALS)
+
+        # Succeed to reset everything to 0
+        success_creds = self.insta_creds(self.template_creds,
+                                         username=username,
+                                         userpass=userpass,
+                                         kerberos_state=use_kerberos)
+
+        ldb = SamDB(url=self.host_url, credentials=success_creds, lp=self.lp)
+
+        self._test_login_lockout(self.lockout1krb5_creds)
+
+    def test_login_lockout_ntlm(self):
+        username = self.lockout1ntlm_creds.get_username()
+        userpass = self.lockout1ntlm_creds.get_password()
+        userdn = "cn=%s,cn=users,%s" % (username, self.base_dn)
+
+        preload_rodc_user(userdn)
+
+        use_kerberos = self.lockout1ntlm_creds.get_kerberos_state()
+        fail_creds = self.insta_creds(self.template_creds,
+                                      username=username,
+                                      userpass=userpass+"X",
+                                      kerberos_state=use_kerberos)
+
+        try:
+            ldb = SamDB(url=self.host_url, credentials=fail_creds, lp=self.lp)
+            self.fail()
+        except LdbError, (num, msg):
+            self.assertEquals(num, ERR_INVALID_CREDENTIALS)
+
+        # Succeed to reset everything to 0
+        ldb = SamDB(url=self.host_url, credentials=self.lockout1ntlm_creds, lp=self.lp)
+
+        self._test_login_lockout(self.lockout1ntlm_creds)
+
+    def test_multiple_logon_krb5(self):
+        username = self.lockout1krb5_creds.get_username()
+        userpass = self.lockout1krb5_creds.get_password()
+        userdn = "cn=%s,cn=users,%s" % (username, self.base_dn)
+
+        preload_rodc_user(userdn)
+
+        use_kerberos = self.lockout1krb5_creds.get_kerberos_state()
+        fail_creds = self.insta_creds(self.template_creds,
+                                      username=username,
+                                      userpass=userpass+"X",
+                                      kerberos_state=use_kerberos)
+
+        try:
+            ldb = SamDB(url=self.host_url, credentials=fail_creds, lp=self.lp)
+            self.fail()
+        except LdbError, (num, msg):
+            self.assertEquals(num, ERR_INVALID_CREDENTIALS)
+
+        # Succeed to reset everything to 0
+        success_creds = self.insta_creds(self.template_creds,
+                                         username=username,
+                                         userpass=userpass,
+                                         kerberos_state=use_kerberos)
+
+        ldb = SamDB(url=self.host_url, credentials=success_creds, lp=self.lp)
+
+        self._test_multiple_logon(self.lockout1krb5_creds)
+
+    def test_multiple_logon_ntlm(self):
+        username = self.lockout1ntlm_creds.get_username()
+        userdn = "cn=%s,cn=users,%s" % (username, self.base_dn)
+        userpass = self.lockout1ntlm_creds.get_password()
+
+        preload_rodc_user(userdn)
+
+        use_kerberos = self.lockout1ntlm_creds.get_kerberos_state()
+        fail_creds = self.insta_creds(self.template_creds,
+                                      username=username,
+                                      userpass=userpass+"X",
+                                      kerberos_state=use_kerberos)
+
+        try:
+            ldb = SamDB(url=self.host_url, credentials=fail_creds, lp=self.lp)
+            self.fail()
+        except LdbError, (num, msg):
+            self.assertEquals(num, ERR_INVALID_CREDENTIALS)
+
+        # Succeed to reset everything to 0
+        ldb = SamDB(url=self.host_url, credentials=self.lockout1ntlm_creds, lp=self.lp)
+
+        self._test_multiple_logon(self.lockout1ntlm_creds)
+
 def main():
     global RODC, RWDC, CREDS, LP
     parser = optparse.OptionParser(