Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Issue 3061 - RFE - Add password policy debug log level
Description: Added new logging level (1048576) for password policy debugging where the failure message, entry dn, and pwd policy is recorded (it's either the global policy or the DN of the local policy). relates: #3061 Reviewed by: firstyear & spichugi(Thanks!!)
- Loading branch information
1 parent
fe383c0
commit a929745
Showing
13 changed files
with
324 additions
and
92 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
152 changes: 152 additions & 0 deletions
152
dirsrvtests/tests/suites/password/pwdPolicy_logging_test.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
import ldap | ||
import logging | ||
import pytest | ||
import os | ||
import time | ||
from lib389._constants import DEFAULT_SUFFIX, PASSWORD | ||
from lib389.topologies import topology_st as topo | ||
from lib389.pwpolicy import PwPolicyManager | ||
from lib389.idm.organizationalunit import OrganizationalUnits | ||
from lib389.idm.user import UserAccount, UserAccounts, TEST_USER_PROPERTIES | ||
from lib389.idm.domain import Domain | ||
|
||
log = logging.getLogger(__name__) | ||
|
||
LOCAL_RDN = 'ou=People' | ||
GLOBAL_RDN = 'ou=Global' | ||
LOCAL_BIND_DN ="uid=local_user,ou=people," + DEFAULT_SUFFIX | ||
GLOBAL_BIND_DN ="uid=global_user,ou=global," + DEFAULT_SUFFIX | ||
|
||
|
||
def create_entries(inst): | ||
# Create local user | ||
users = UserAccounts(inst, DEFAULT_SUFFIX, rdn=LOCAL_RDN) | ||
user_props = TEST_USER_PROPERTIES.copy() | ||
user_props.update({'uid': 'local_user', 'cn': 'local_user', 'userpassword': PASSWORD}) | ||
users.create(properties=user_props) | ||
|
||
# Create new OU | ||
ou_global = OrganizationalUnits(inst, DEFAULT_SUFFIX).create(properties={'ou': 'Global'}) | ||
|
||
# Create global user | ||
users = UserAccounts(inst, DEFAULT_SUFFIX, rdn=GLOBAL_RDN) | ||
user_props = TEST_USER_PROPERTIES.copy() | ||
user_props.update({'uid': 'global_user', 'cn': 'global_user', 'userpassword': PASSWORD}) | ||
users.create(properties=user_props) | ||
|
||
# Add aci | ||
aci = '(targetattr="*")(version 3.0; acl "pwp test"; allow (all) userdn="ldap:///self";)' | ||
suffix = Domain(inst, DEFAULT_SUFFIX) | ||
suffix.add('aci', aci) | ||
|
||
|
||
def create_policies(inst): | ||
# Configure subtree policy | ||
pwp = PwPolicyManager(inst) | ||
subtree_policy_props = { | ||
'passwordCheckSyntax': 'on', | ||
'passwordMinLength': '6', | ||
'passwordChange': 'on', | ||
'passwordLockout': 'on', | ||
'passwordMaxFailure': '2', | ||
} | ||
pwp.create_subtree_policy(f'{LOCAL_RDN},{DEFAULT_SUFFIX}', subtree_policy_props) | ||
|
||
# Configure global policy | ||
inst.config.replace('nsslapd-pwpolicy-local', 'on') | ||
inst.config.replace('passwordCheckSyntax', 'on') | ||
inst.config.replace('passwordMinLength', '8') | ||
inst.config.replace('passwordChange', 'on') | ||
inst.config.replace('passwordLockout', 'on') | ||
inst.config.replace('passwordMaxFailure', '5') | ||
time.sleep(1) | ||
|
||
|
||
def test_debug_logging(topo): | ||
"""Enable password policy logging | ||
:id: cc152c65-94e0-4716-a77c-abdd2deec00d | ||
:setup: Standalone Instance | ||
:steps: | ||
1. Set password policy logging level | ||
2. Add database entries | ||
3. Configure local and global policies | ||
4. Test syntax checking on local policy | ||
5. Test syntax checking on global policy | ||
6. Test account lockout on local policy | ||
7. Test account lockout on global policy | ||
:expectedresults: | ||
1. Success | ||
2. Success | ||
3. Success | ||
4. Success | ||
5. Success | ||
6. Success | ||
7. Success | ||
""" | ||
|
||
inst = topo.standalone | ||
|
||
# Enable password policy debug logging | ||
inst.config.replace('nsslapd-errorlog-level', '1048576') | ||
|
||
# Create entries and password policies | ||
create_entries(inst) | ||
create_policies(inst) | ||
|
||
# Setup bind connections | ||
|
||
local_conn = UserAccounts(inst, DEFAULT_SUFFIX, rdn=LOCAL_RDN).get('local_user').bind(PASSWORD) | ||
local_user = UserAccount(local_conn, LOCAL_BIND_DN) | ||
global_conn = UserAccounts(inst, DEFAULT_SUFFIX, rdn=GLOBAL_RDN).get('global_user').bind(PASSWORD) | ||
global_user = UserAccount(global_conn, GLOBAL_BIND_DN) | ||
|
||
# Test syntax checking on local policy | ||
passwd_val = "passw" # len 5 which is less than configured 6 | ||
with pytest.raises(ldap.CONSTRAINT_VIOLATION): | ||
local_user.replace('userpassword', passwd_val) | ||
time.sleep(1) | ||
|
||
err_msg = "PWDPOLICY_DEBUG - invalid password syntax - password must be at least 6 characters long: Entry " + \ | ||
"\\(uid=local_user,ou=people,dc=example,dc=com\\) Policy \\(cn=" | ||
assert inst.searchErrorsLog(err_msg) | ||
|
||
# Test syntax checking on global policy | ||
passwd_val = "passwod" # len 7 which is less than configured 8 | ||
with pytest.raises(ldap.CONSTRAINT_VIOLATION): | ||
global_user.replace('userpassword', passwd_val) | ||
time.sleep(1) | ||
|
||
err_msg = "PWDPOLICY_DEBUG - invalid password syntax - password must be at least 8 characters long: Entry " + \ | ||
"\\(uid=global_user,ou=global,dc=example,dc=com\\) Policy \\(Global\\)" | ||
assert inst.searchErrorsLog(err_msg) | ||
|
||
# Test account lock is logging for local policy | ||
for i in range(2): | ||
with pytest.raises(ldap.INVALID_CREDENTIALS): | ||
local_user.bind("bad") | ||
with pytest.raises(ldap.CONSTRAINT_VIOLATION): | ||
local_user.bind("bad") | ||
|
||
err_msg = "PWDPOLICY_DEBUG - Account is locked: Entry " + \ | ||
"\\(uid=local_user,ou=people,dc=example,dc=com\\) Policy \\(cn=" | ||
assert inst.searchErrorsLog(err_msg) | ||
|
||
# Test account lock is logging for global policy | ||
for i in range(5): | ||
with pytest.raises(ldap.INVALID_CREDENTIALS): | ||
global_user.bind("bad") | ||
with pytest.raises(ldap.CONSTRAINT_VIOLATION): | ||
global_user.bind("bad") | ||
|
||
err_msg = "PWDPOLICY_DEBUG - Account is locked: Entry " + \ | ||
"\\(uid=global_user,ou=global,dc=example,dc=com\\) Policy \\(Global\\)" | ||
assert inst.searchErrorsLog(err_msg) | ||
|
||
|
||
if __name__ == '__main__': | ||
# Run isolated | ||
# -s for DEBUG mode | ||
CURRENT_FILE = os.path.realpath(__file__) | ||
pytest.main(["-s", CURRENT_FILE]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.