PEP8: fix E251: unexpected spaces around keyword / parameter equals
[amitay/samba.git] / source4 / dsdb / tests / python / password_lockout_base.py
index 514a5aa57714d865f27e6fc5bf099868610feaed..aee267958be5aa817786c8bebc78bfa0b5e86f8e 100644 (file)
@@ -1,3 +1,4 @@
+from __future__ import print_function
 import samba
 
 from samba.auth import system_session
@@ -13,10 +14,11 @@ import samba.tests
 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])
 
@@ -25,15 +27,6 @@ class BasePasswordTestCase(samba.tests.TestCase):
 
         return self.samr.OpenUser(self.samr_domain, security.SEC_FLAG_MAXIMUM_ALLOWED, rid)
 
-    def _reset_samr(self, res):
-
-        # Now reset the lockout, by removing ACB_AUTOLOCK (which removes the lock, despite being a generated attribute)
-        samr_user = self._open_samr_user(res)
-        acb_info = self.samr.QueryUserInfo(samr_user, 16)
-        acb_info.acct_flags &= ~samr.ACB_AUTOLOCK
-        self.samr.SetUserInfo(samr_user, 16, acb_info)
-        self.samr.Close(samr_user)
-
     def _check_attribute(self, res, name, value):
         if value is None:
             self.assertTrue(name not in res[0],
@@ -51,8 +44,8 @@ class BasePasswordTestCase(samba.tests.TestCase):
 
         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],
@@ -63,7 +56,7 @@ class BasePasswordTestCase(samba.tests.TestCase):
                         (name, res[0][name], res[0].dn))
 
 
-        print  "%s = '%s'" % (name, res[0][name][0])
+        print("%s = '%s'" % (name, res[0][name][0]))
 
         if mode == "present":
             return
@@ -93,6 +86,16 @@ 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,
@@ -103,12 +106,13 @@ class BasePasswordTestCase(samba.tests.TestCase):
                        userAccountControl=None,
                        msDSUserAccountControlComputed=None,
                        effective_bad_password_count=None,
-                       msg=None):
-        print '-=' * 36
+                       msg=None,
+                       badPwdCountOnly=False):
+        print('-=' * 36)
         if msg is not None:
-            print  "\033[01;32m %s \033[00m\n" % msg
+            print("\033[01;32m %s \033[00m\n" % msg)
         attrs = [
-           "objectSid",
+            "objectSid",
            "badPwdCount",
            "badPasswordTime",
            "lastLogon",
@@ -126,17 +130,18 @@ class BasePasswordTestCase(samba.tests.TestCase):
         res = self.ldb.search(dn, scope=SCOPE_BASE, attrs=attrs)
         self.assertTrue(len(res) == 1)
         self._check_attribute(res, "badPwdCount", badPwdCount)
-        self._check_attribute(res, "badPasswordTime", badPasswordTime)
-        self._check_attribute(res, "logonCount", logonCount)
-        self._check_attribute(res, "lastLogon", lastLogon)
-        self._check_attribute(res, "lastLogonTimestamp", lastLogonTimestamp)
         self._check_attribute(res, "lockoutTime", lockoutTime)
-        self._check_attribute(res, "userAccountControl", userAccountControl)
-        self._check_attribute(res, "msDS-User-Account-Control-Computed",
-                              msDSUserAccountControlComputed)
+        self._check_attribute(res, "badPasswordTime", badPasswordTime)
+        if not badPwdCountOnly:
+            self._check_attribute(res, "logonCount", logonCount)
+            self._check_attribute(res, "lastLogon", lastLogon)
+            self._check_attribute(res, "lastLogonTimestamp", lastLogonTimestamp)
+            self._check_attribute(res, "userAccountControl", userAccountControl)
+            self._check_attribute(res, "msDS-User-Account-Control-Computed",
+                                  msDSUserAccountControlComputed)
 
-        lastLogon = int(res[0]["lastLogon"][0])
-        logonCount = int(res[0]["logonCount"][0])
+            lastLogon = int(res[0]["lastLogon"][0])
+            logonCount = int(res[0]["logonCount"][0])
 
         samr_user = self._open_samr_user(res)
         uinfo3 = self.samr.QueryUserInfo(samr_user, 3)
@@ -146,16 +151,21 @@ class BasePasswordTestCase(samba.tests.TestCase):
         self.samr.Close(samr_user)
 
         expected_acb_info = 0
-        if userAccountControl & dsdb.UF_NORMAL_ACCOUNT:
-            expected_acb_info |= samr.ACB_NORMAL
-        if userAccountControl & dsdb.UF_ACCOUNTDISABLE:
-            expected_acb_info |= samr.ACB_DISABLED
-        if userAccountControl & dsdb.UF_PASSWD_NOTREQD:
-            expected_acb_info |= samr.ACB_PWNOTREQ
-        if msDSUserAccountControlComputed & dsdb.UF_LOCKOUT:
-            expected_acb_info |= samr.ACB_AUTOLOCK
-        if msDSUserAccountControlComputed & dsdb.UF_PASSWORD_EXPIRED:
-            expected_acb_info |= samr.ACB_PW_EXPIRED
+        if not badPwdCountOnly:
+            if userAccountControl & dsdb.UF_NORMAL_ACCOUNT:
+                expected_acb_info |= samr.ACB_NORMAL
+            if userAccountControl & dsdb.UF_ACCOUNTDISABLE:
+                expected_acb_info |= samr.ACB_DISABLED
+            if userAccountControl & dsdb.UF_PASSWD_NOTREQD:
+                expected_acb_info |= samr.ACB_PWNOTREQ
+            if msDSUserAccountControlComputed & dsdb.UF_LOCKOUT:
+                expected_acb_info |= samr.ACB_AUTOLOCK
+            if msDSUserAccountControlComputed & dsdb.UF_PASSWORD_EXPIRED:
+                expected_acb_info |= samr.ACB_PW_EXPIRED
+
+            self.assertEquals(uinfo3.acct_flags, expected_acb_info)
+            self.assertEquals(uinfo3.last_logon, lastLogon)
+            self.assertEquals(uinfo3.logon_count, logonCount)
 
         expected_bad_password_count = 0
         if badPwdCount is not None:
@@ -163,22 +173,21 @@ class BasePasswordTestCase(samba.tests.TestCase):
         if effective_bad_password_count is None:
             effective_bad_password_count = expected_bad_password_count
 
-        self.assertEquals(uinfo3.acct_flags, expected_acb_info)
         self.assertEquals(uinfo3.bad_password_count, expected_bad_password_count)
-        self.assertEquals(uinfo3.last_logon, lastLogon)
-        self.assertEquals(uinfo3.logon_count, logonCount)
 
-        self.assertEquals(uinfo5.acct_flags, expected_acb_info)
-        self.assertEquals(uinfo5.bad_password_count, effective_bad_password_count)
-        self.assertEquals(uinfo5.last_logon, lastLogon)
-        self.assertEquals(uinfo5.logon_count, logonCount)
+        if not badPwdCountOnly:
+            self.assertEquals(uinfo5.acct_flags, expected_acb_info)
+            self.assertEquals(uinfo5.bad_password_count, effective_bad_password_count)
+            self.assertEquals(uinfo5.last_logon, lastLogon)
+            self.assertEquals(uinfo5.logon_count, logonCount)
 
-        self.assertEquals(uinfo16.acct_flags, expected_acb_info)
+            self.assertEquals(uinfo16.acct_flags, expected_acb_info)
+
+            self.assertEquals(uinfo21.acct_flags, expected_acb_info)
+            self.assertEquals(uinfo21.bad_password_count, effective_bad_password_count)
+            self.assertEquals(uinfo21.last_logon, lastLogon)
+            self.assertEquals(uinfo21.logon_count, logonCount)
 
-        self.assertEquals(uinfo21.acct_flags, expected_acb_info)
-        self.assertEquals(uinfo21.bad_password_count, effective_bad_password_count)
-        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.
@@ -190,6 +199,20 @@ class BasePasswordTestCase(samba.tests.TestCase):
         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()
@@ -220,14 +243,16 @@ userPassword: """ + userpass + """
         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)
 
         # Fail once to get a badPasswordTime
         try:
             ldb = SamDB(url=self.host_url, credentials=fail_creds, lp=self.lp)
             self.fail()
-        except LdbError, (num, msg):
+        except LdbError as e:
+            (num, msg) = e.args
             self.assertEquals(num, ERR_INVALID_CREDENTIALS)
 
         # Succeed to reset everything to 0
@@ -235,190 +260,12 @@ userPassword: """ + userpass + """
 
         return ldb
 
-    def _testing_add_user(self, creds, lockOutObservationWindow=0):
-        username = creds.get_username()
-        userpass = creds.get_password()
-        userdn = "cn=%s,cn=users,%s" % (username, self.base_dn)
-
-        use_kerberos = creds.get_kerberos_state()
-        if use_kerberos == MUST_USE_KERBEROS:
-            logoncount_relation = 'greater'
-            lastlogon_relation = 'greater'
-        else:
-            logoncount_relation = 'equal'
-            if lockOutObservationWindow == 0:
-                lastlogon_relation = 'greater'
-            else:
-                lastlogon_relation = 'equal'
-
-        delete_force(self.ldb, userdn)
-        self.ldb.add({
-             "dn": userdn,
-             "objectclass": "user",
-             "sAMAccountName": username})
-
-        self.addCleanup(delete_force, self.ldb, userdn)
-
-        res = self._check_account(userdn,
-                                  badPwdCount=0,
-                                  badPasswordTime=0,
-                                  logonCount=0,
-                                  lastLogon=0,
-                                  lastLogonTimestamp=('absent', None),
-                                  userAccountControl=
-                                    dsdb.UF_NORMAL_ACCOUNT |
-                                    dsdb.UF_ACCOUNTDISABLE |
-                                    dsdb.UF_PASSWD_NOTREQD,
-                                  msDSUserAccountControlComputed=
-                                    dsdb.UF_PASSWORD_EXPIRED)
-
-        # SAMR doesn't have any impact if dsdb.UF_LOCKOUT isn't present.
-        # It doesn't create "lockoutTime" = 0.
-        self._reset_samr(res)
-
-        res = self._check_account(userdn,
-                                  badPwdCount=0,
-                                  badPasswordTime=0,
-                                  logonCount=0,
-                                  lastLogon=0,
-                                  lastLogonTimestamp=('absent', None),
-                                  userAccountControl=
-                                    dsdb.UF_NORMAL_ACCOUNT |
-                                    dsdb.UF_ACCOUNTDISABLE |
-                                    dsdb.UF_PASSWD_NOTREQD,
-                                  msDSUserAccountControlComputed=
-                                    dsdb.UF_PASSWORD_EXPIRED)
-
-        # Tests a password change when we don't have any password yet with a
-        # wrong old password
-        try:
-            self.ldb.modify_ldif("""
-dn: """ + userdn + """
-changetype: modify
-delete: userPassword
-userPassword: noPassword
-add: userPassword
-userPassword: thatsAcomplPASS2
-""")
-            self.fail()
-        except LdbError, (num, msg):
-            self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
-            # Windows (2008 at least) seems to have some small bug here: it
-            # returns "0000056A" on longer (always wrong) previous passwords.
-            self.assertTrue('00000056' in msg, msg)
-
-        res = self._check_account(userdn,
-                                  badPwdCount=1,
-                                  badPasswordTime=("greater", 0),
-                                  logonCount=0,
-                                  lastLogon=0,
-                                  lastLogonTimestamp=('absent', None),
-                                  userAccountControl=
-                                    dsdb.UF_NORMAL_ACCOUNT |
-                                    dsdb.UF_ACCOUNTDISABLE |
-                                    dsdb.UF_PASSWD_NOTREQD,
-                                  msDSUserAccountControlComputed=
-                                    dsdb.UF_PASSWORD_EXPIRED)
-        badPwdCount = int(res[0]["badPwdCount"][0])
-        badPasswordTime = int(res[0]["badPasswordTime"][0])
-
-        # Sets the initial user password with a "special" password change
-        # I think that this internally is a password set operation and it can
-        # only be performed by someone which has password set privileges on the
-        # account (at least in s4 we do handle it like that).
-        self.ldb.modify_ldif("""
-dn: """ + userdn + """
-changetype: modify
-delete: userPassword
-add: userPassword
-userPassword: """ + userpass + """
-""")
-
-        res = self._check_account(userdn,
-                                  badPwdCount=badPwdCount,
-                                  badPasswordTime=badPasswordTime,
-                                  logonCount=0,
-                                  lastLogon=0,
-                                  lastLogonTimestamp=('absent', None),
-                                  userAccountControl=
-                                    dsdb.UF_NORMAL_ACCOUNT |
-                                    dsdb.UF_ACCOUNTDISABLE |
-                                    dsdb.UF_PASSWD_NOTREQD,
-                                  msDSUserAccountControlComputed=0)
-
-        # Enables the user account
-        self.ldb.enable_account("(sAMAccountName=%s)" % username)
-
-        res = self._check_account(userdn,
-                                  badPwdCount=badPwdCount,
-                                  badPasswordTime=badPasswordTime,
-                                  logonCount=0,
-                                  lastLogon=0,
-                                  lastLogonTimestamp=('absent', None),
-                                  userAccountControl=
-                                    dsdb.UF_NORMAL_ACCOUNT,
-                                  msDSUserAccountControlComputed=0)
-        if lockOutObservationWindow != 0:
-            time.sleep(lockOutObservationWindow + 1)
-            effective_bad_password_count = 0
-        else:
-            effective_bad_password_count = badPwdCount
-
-        res = self._check_account(userdn,
-                                  badPwdCount=badPwdCount,
-                                  effective_bad_password_count=effective_bad_password_count,
-                                  badPasswordTime=badPasswordTime,
-                                  logonCount=0,
-                                  lastLogon=0,
-                                  lastLogonTimestamp=('absent', None),
-                                  userAccountControl=
-                                    dsdb.UF_NORMAL_ACCOUNT,
-                                  msDSUserAccountControlComputed=0)
-
-        ldb = SamDB(url=self.host_url, credentials=creds, lp=self.lp)
-
-        if lockOutObservationWindow == 0:
-            badPwdCount = 0
-            effective_bad_password_count = 0
-        if use_kerberos == MUST_USE_KERBEROS:
-            badPwdCount = 0
-            effective_bad_password_count = 0
-
-        res = self._check_account(userdn,
-                                  badPwdCount=badPwdCount,
-                                  effective_bad_password_count=effective_bad_password_count,
-                                  badPasswordTime=badPasswordTime,
-                                  logonCount=(logoncount_relation, 0),
-                                  lastLogon=(lastlogon_relation, 0),
-                                  lastLogonTimestamp=('greater', badPasswordTime),
-                                  userAccountControl=
-                                    dsdb.UF_NORMAL_ACCOUNT,
-                                  msDSUserAccountControlComputed=0)
-
-        logonCount = int(res[0]["logonCount"][0])
-        lastLogon = int(res[0]["lastLogon"][0])
-        lastLogonTimestamp = int(res[0]["lastLogonTimestamp"][0])
-        if lastlogon_relation == 'greater':
-            self.assertGreater(lastLogon, badPasswordTime)
-            self.assertGreaterEqual(lastLogon, lastLogonTimestamp)
-
-        res = self._check_account(userdn,
-                                  badPwdCount=badPwdCount,
-                                  effective_bad_password_count=effective_bad_password_count,
-                                  badPasswordTime=badPasswordTime,
-                                  logonCount=logonCount,
-                                  lastLogon=lastLogon,
-                                  lastLogonTimestamp=lastLogonTimestamp,
-                                  userAccountControl=
-                                    dsdb.UF_NORMAL_ACCOUNT,
-                                  msDSUserAccountControlComputed=0)
-        return ldb
-
     def assertLoginFailure(self, url, creds, lp, errno=ERR_INVALID_CREDENTIALS):
         try:
             ldb = SamDB(url=url, credentials=creds, lp=lp)
             self.fail("Login unexpectedly succeeded")
-        except LdbError, (num, msg):
+        except LdbError as e1:
+            (num, msg) = e1.args
             if errno is not None:
                 self.assertEquals(num, errno, ("Login failed in the wrong way"
                                                "(got err %d, expected %d)" %
@@ -439,21 +286,14 @@ userPassword: """ + userpass + """
         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]
@@ -481,69 +321,39 @@ replace: lockoutThreshold
 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)
         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.addCleanup(self.delete_ldb_connections)
+
         # (Re)adds the test user accounts
         self.lockout1krb5_creds = self.insta_creds(self.template_creds,
                                                    username="lockout1krb5",
                                                    userpass="thatsAcomplPASS0",
                                                    kerberos_state=MUST_USE_KERBEROS)
         self.lockout1krb5_ldb = self._readd_user(self.lockout1krb5_creds)
-        self.lockout2krb5_creds = self.insta_creds(self.template_creds,
-                                                   username="lockout2krb5",
-                                                   userpass="thatsAcomplPASS0",
-                                                   kerberos_state=MUST_USE_KERBEROS)
-        self.lockout2krb5_ldb = self._readd_user(self.lockout2krb5_creds,
-                                                 lockOutObservationWindow=self.lockout_observation_window)
         self.lockout1ntlm_creds = self.insta_creds(self.template_creds,
                                                    username="lockout1ntlm",
                                                    userpass="thatsAcomplPASS0",
                                                    kerberos_state=DONT_USE_KERBEROS)
         self.lockout1ntlm_ldb = self._readd_user(self.lockout1ntlm_creds)
-        self.lockout2ntlm_creds = self.insta_creds(self.template_creds,
-                                                   username="lockout2ntlm",
-                                                   userpass="thatsAcomplPASS0",
-                                                   kerberos_state=DONT_USE_KERBEROS)
-        self.lockout2ntlm_ldb = self._readd_user(self.lockout2ntlm_creds,
-                                                 lockOutObservationWindow=self.lockout_observation_window)
+
+    def delete_ldb_connections(self):
+        del self.lockout1krb5_ldb
+        del self.lockout1ntlm_ldb
+        del self.ldb
 
     def tearDown(self):
         super(BasePasswordTestCase, self).tearDown()
@@ -558,11 +368,11 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
         if use_kerberos == MUST_USE_KERBEROS:
             logoncount_relation = 'greater'
             lastlogon_relation = 'greater'
-            print "Performs a lockout attempt against LDAP using Kerberos"
+            print("Performs a lockout attempt against LDAP using Kerberos")
         else:
             logoncount_relation = 'equal'
             lastlogon_relation = 'equal'
-            print "Performs a lockout attempt against LDAP using NTLM"
+            print("Performs a lockout attempt against LDAP using NTLM")
 
         # Change password on a connection as another user
         res = self._check_account(userdn,
@@ -571,16 +381,15 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
                                   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])
         lastLogon = int(res[0]["lastLogon"][0])
         firstLogon = lastLogon
         lastLogonTimestamp = int(res[0]["lastLogonTimestamp"][0])
-        print firstLogon
-        print lastLogonTimestamp
+        print(firstLogon)
+        print(lastLogonTimestamp)
 
 
         self.assertGreater(lastLogon, badPasswordTime)
@@ -602,8 +411,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
                                   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])
@@ -621,8 +429,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
                                   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')
 
@@ -642,8 +449,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
                                   logonCount=logonCount,
                                   lastLogon=lastLogon,
                                   lastLogonTimestamp=lastLogonTimestamp,
-                                  userAccountControl=
-                                    dsdb.UF_NORMAL_ACCOUNT,
+                                  userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
                                   msDSUserAccountControlComputed=0)
         badPasswordTime = int(res[0]["badPasswordTime"][0])
 
@@ -654,7 +460,8 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
             ldb_lockout = SamDB(url=self.host_url, credentials=creds_lockout, lp=self.lp)
             self.fail()
 
-        except LdbError, (num, msg):
+        except LdbError as e2:
+            (num, msg) = e2.args
             self.assertEquals(num, ERR_INVALID_CREDENTIALS)
 
         res = self._check_account(userdn,
@@ -663,12 +470,11 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
                                   logonCount=logonCount,
                                   lastLogon=lastLogon,
                                   lastLogonTimestamp=lastLogonTimestamp,
-                                  userAccountControl=
-                                    dsdb.UF_NORMAL_ACCOUNT,
+                                  userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
                                   msDSUserAccountControlComputed=0)
         badPasswordTime = int(res[0]["badPasswordTime"][0])
 
-        print "two failed password change"
+        print("two failed password change")
 
         # The wrong password
         creds_lockout.set_password("thatsAcomplPASS1x")
@@ -677,7 +483,8 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
             ldb_lockout = SamDB(url=self.host_url, credentials=creds_lockout, lp=self.lp)
             self.fail()
 
-        except LdbError, (num, msg):
+        except LdbError as e3:
+            (num, msg) = e3.args
             self.assertEquals(num, ERR_INVALID_CREDENTIALS)
 
         res = self._check_account(userdn,
@@ -687,8 +494,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
                                   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])
@@ -698,7 +504,8 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
         try:
             ldb_lockout = SamDB(url=self.host_url, credentials=creds_lockout, lp=self.lp)
             self.fail()
-        except LdbError, (num, msg):
+        except LdbError as e4:
+            (num, msg) = e4.args
             self.assertEquals(num, ERR_INVALID_CREDENTIALS)
 
         res = self._check_account(userdn,
@@ -708,8 +515,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
                                   lastLogon=lastLogon,
                                   lastLogonTimestamp=lastLogonTimestamp,
                                   lockoutTime=lockoutTime,
-                                  userAccountControl=
-                                    dsdb.UF_NORMAL_ACCOUNT,
+                                  userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
                                   msDSUserAccountControlComputed=dsdb.UF_LOCKOUT)
 
         # The wrong password
@@ -717,7 +523,8 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
         try:
             ldb_lockout = SamDB(url=self.host_url, credentials=creds_lockout, lp=self.lp)
             self.fail()
-        except LdbError, (num, msg):
+        except LdbError as e5:
+            (num, msg) = e5.args
             self.assertEquals(num, ERR_INVALID_CREDENTIALS)
 
         res = self._check_account(userdn,
@@ -727,8 +534,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
                                   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
@@ -736,7 +542,8 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
         try:
             ldb_lockout = SamDB(url=self.host_url, credentials=creds_lockout, lp=self.lp)
             self.fail()
-        except LdbError, (num, msg):
+        except LdbError as e6:
+            (num, msg) = e6.args
             self.assertEquals(num, ERR_INVALID_CREDENTIALS)
 
         res = self._check_account(userdn,
@@ -746,13 +553,12 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
                                   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
         time.sleep(self.account_lockout_duration + 1)
-        print self.account_lockout_duration + 1
+        print(self.account_lockout_duration + 1)
 
         res = self._check_account(userdn,
                                   badPwdCount=3, effective_bad_password_count=0,
@@ -761,8 +567,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
                                   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
@@ -781,8 +586,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
                                   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")
 
@@ -794,7 +598,8 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
         try:
             ldb_lockout = SamDB(url=self.host_url, credentials=creds_lockout, lp=self.lp)
             self.fail()
-        except LdbError, (num, msg):
+        except LdbError as e7:
+            (num, msg) = e7.args
             self.assertEquals(num, ERR_INVALID_CREDENTIALS)
 
         res = self._check_account(userdn,
@@ -804,8 +609,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
                                   lockoutTime=0,
                                   lastLogon=lastLogon,
                                   lastLogonTimestamp=lastLogonTimestamp,
-                                  userAccountControl=
-                                    dsdb.UF_NORMAL_ACCOUNT,
+                                  userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
                                   msDSUserAccountControlComputed=0)
         badPasswordTime = int(res[0]["badPasswordTime"][0])
 
@@ -814,7 +618,8 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
         try:
             ldb_lockout = SamDB(url=self.host_url, credentials=creds_lockout, lp=self.lp)
             self.fail()
-        except LdbError, (num, msg):
+        except LdbError as e8:
+            (num, msg) = e8.args
             self.assertEquals(num, ERR_INVALID_CREDENTIALS)
 
         res = self._check_account(userdn,
@@ -824,8 +629,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
                                   lockoutTime=0,
                                   lastLogon=lastLogon,
                                   lastLogonTimestamp=lastLogonTimestamp,
-                                  userAccountControl=
-                                    dsdb.UF_NORMAL_ACCOUNT,
+                                  userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
                                   msDSUserAccountControlComputed=0)
         badPasswordTime = int(res[0]["badPasswordTime"][0])
 
@@ -838,8 +642,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
                                   lockoutTime=0,
                                   lastLogon=lastLogon,
                                   lastLogonTimestamp=lastLogonTimestamp,
-                                  userAccountControl=
-                                    dsdb.UF_NORMAL_ACCOUNT,
+                                  userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
                                   msDSUserAccountControlComputed=0)
 
         # The wrong password
@@ -847,7 +650,8 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
         try:
             ldb_lockout = SamDB(url=self.host_url, credentials=creds_lockout, lp=self.lp)
             self.fail()
-        except LdbError, (num, msg):
+        except LdbError as e9:
+            (num, msg) = e9.args
             self.assertEquals(num, ERR_INVALID_CREDENTIALS)
 
         res = self._check_account(userdn,
@@ -857,8 +661,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
                                   lockoutTime=0,
                                   lastLogon=lastLogon,
                                   lastLogonTimestamp=lastLogonTimestamp,
-                                  userAccountControl=
-                                    dsdb.UF_NORMAL_ACCOUNT,
+                                  userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
                                   msDSUserAccountControlComputed=0)
         badPasswordTime = int(res[0]["badPasswordTime"][0])
 
@@ -873,8 +676,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
                                   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):
@@ -891,11 +693,11 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
 
         use_kerberos = creds.get_kerberos_state()
         if use_kerberos == MUST_USE_KERBEROS:
-            print "Testing multiple logon with Kerberos"
+            print("Testing multiple logon with Kerberos")
             logoncount_relation = 'greater'
             lastlogon_relation = 'greater'
         else:
-            print "Testing multiple logon with NTLM"
+            print("Testing multiple logon with NTLM")
             logoncount_relation = 'equal'
             lastlogon_relation = 'equal'
 
@@ -907,15 +709,14 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
                                   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])
         lastLogon = int(res[0]["lastLogon"][0])
         lastLogonTimestamp = int(res[0]["lastLogonTimestamp"][0])
         firstLogon = lastLogon
-        print "last logon is %d" % lastLogon
+        print("last logon is %d" % lastLogon)
         self.assertGreater(lastLogon, badPasswordTime)
         self.assertGreaterEqual(lastLogon, lastLogonTimestamp)
 
@@ -928,8 +729,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
                                   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))
@@ -947,6 +747,5 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
                                   logonCount=(logoncount_relation, logonCount),
                                   lastLogon=(lastlogon_relation, lastLogon),
                                   lastLogonTimestamp=lastLogonTimestamp,
-                                  userAccountControl=
-                                    dsdb.UF_NORMAL_ACCOUNT,
+                                  userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
                                   msDSUserAccountControlComputed=0)