diff --git a/python/samba/tests/samba_tool/user.py b/python/samba/tests/samba_tool/user.py index 22f76333ae2..07eb09b24d5 100644 --- a/python/samba/tests/samba_tool/user.py +++ b/python/samba/tests/samba_tool/user.py @@ -800,6 +800,47 @@ sAMAccountName: %s self._check_posix_user(user) self.runsubcmd("user", "delete", user["name"]) + # Test: samba-tool user unlock + # This test does not verify that the command unlocks the user, it just + # tests the command itself. The unlock test, which unlocks locked users, + # is located in the 'samba4.ldap.password_lockout' test in + # source4/dsdb/tests/python/password_lockout.py + def test_unlock(self): + + # try to unlock a nonexistent user, this should fail + nonexistentusername = "userdoesnotexist" + (result, out, err) = self.runsubcmd( + "user", "unlock", nonexistentusername) + self.assertCmdFail(result, "Ensure that unlock nonexistent user fails") + self.assertIn("Failed to unlock user '%s'" % nonexistentusername, err) + self.assertIn("Unable to find user", err) + + # try to unlock with insufficient permissions, this should fail + unprivileged_username = "unprivilegedunlockuser" + unlocktest_username = "usertounlock" + + self.runsubcmd("user", "add", unprivileged_username, "Passw0rd") + self.runsubcmd("user", "add", unlocktest_username, "Passw0rd") + + (result, out, err) = self.runsubcmd( + "user", "unlock", unlocktest_username, + "-H", "ldap://%s" % os.environ["DC_SERVER"], + "-U%s%%%s" % (unprivileged_username, + "Passw0rd")) + self.assertCmdFail(result, "Fail with LDAP_INSUFFICIENT_ACCESS_RIGHTS") + self.assertIn("Failed to unlock user '%s'" % unlocktest_username, err) + self.assertIn("LDAP error 50 LDAP_INSUFFICIENT_ACCESS_RIGHTS", err) + + self.runsubcmd("user", "delete", unprivileged_username) + self.runsubcmd("user", "delete", unlocktest_username) + + # run unlock against test users + for user in self.users: + (result, out, err) = self.runsubcmd( + "user", "unlock", user["name"]) + self.assertCmdSuccess(result, out, err, "Error running user unlock") + self.assertEqual(err, "", "Shouldn't be any error messages") + def _randomUser(self, base={}): """create a user with random attribute values, you can specify base attributes""" user = { diff --git a/source4/dsdb/tests/python/password_lockout.py b/source4/dsdb/tests/python/password_lockout.py index cbe15c33742..445944862b8 100755 --- a/source4/dsdb/tests/python/password_lockout.py +++ b/source4/dsdb/tests/python/password_lockout.py @@ -17,6 +17,7 @@ sys.path.insert(0, "bin/python") import samba from samba.tests.subunitrun import TestProgram, SubunitOptions +from samba.netcmd.main import cmd_sambatool import samba.getopt as options @@ -133,6 +134,17 @@ replace: lockoutTime lockoutTime: 0 """) + def _reset_samba_tool(self, res): + username = res[0]["sAMAccountName"][0] + + cmd = cmd_sambatool.subcommands['user'].subcommands['unlock'] + result = cmd._run("samba-tool user unlock", + username, + "-H%s" % host_url, + "-U%s%%%s" % (global_creds.get_username(), + global_creds.get_password())) + self.assertEqual(result, None) + def _reset_ldap_userAccountControl(self, res): self.assertTrue("userAccountControl" in res[0]) self.assertTrue("msDS-User-Account-Control-Computed" in res[0]) @@ -157,6 +169,8 @@ userAccountControl: %d self._reset_ldap_lockoutTime(res) elif method == "samr": self._reset_samr(res) + elif method == "samba-tool": + self._reset_samba_tool(res) else: self.assertTrue(False, msg="Invalid reset method[%s]" % method) @@ -635,6 +649,12 @@ userPassword: thatsAcomplPASS2XYZ "samr", initial_lastlogon_relation='greater') + # just test "samba-tool user unlock" command once + def test_userPassword_lockout_with_clear_change_krb5_ldap_samba_tool(self): + self._test_userPassword_lockout_with_clear_change(self.lockout1krb5_creds, + self.lockout2krb5_ldb, + "samba-tool") + def test_multiple_logon_krb5(self): self._test_multiple_logon(self.lockout1krb5_creds) diff --git a/source4/dsdb/tests/python/password_lockout_base.py b/source4/dsdb/tests/python/password_lockout_base.py index 17ae807faf6..0f9617da1e6 100644 --- a/source4/dsdb/tests/python/password_lockout_base.py +++ b/source4/dsdb/tests/python/password_lockout_base.py @@ -113,6 +113,7 @@ class BasePasswordTestCase(PasswordTestCase): print("\033[01;32m %s \033[00m\n" % msg) attrs = [ "objectSid", + "sAMAccountName", "badPwdCount", "badPasswordTime", "lastLogon",