Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ipa: ipa_pwpolicy update pwpolicy module #7723

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
minor_changes:
- ipa_pwpolicy - update module to support ``maxrepeat``, ``maxsequence``, ``dictcheck``, ``usercheck``, ``gracelimit`` parameters in FreeIPA password policies (https://github.com/ansible-collections/community.general/pull/7723).
- ipa_pwpolicy - refactor module and exchange a sequence ``if`` statements with a ``for`` loop (https://github.com/ansible-collections/community.general/pull/7723).
89 changes: 68 additions & 21 deletions plugins/modules/ipa_pwpolicy.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,26 @@
lockouttime:
description: Period (in seconds) for which users are locked out.
type: str
gracelimit:
description: Maximum number of LDAP logins after password expiration.
type: int
version_added: 8.2.0
maxrepeat:
description: Maximum number of allowed same consecutive characters in the new password.
type: int
version_added: 8.2.0
maxsequence:
description: Maximum length of monotonic character sequences in the new password. An example of a monotonic sequence of length 5 is V(12345).
type: int
version_added: 8.2.0
dictcheck:
description: Check whether the password (with possible modifications) matches a word in a dictionary (using cracklib).
type: bool
version_added: 8.2.0
usercheck:
description: Check whether the password (with possible modifications) contains the user name in some form (if the name has > 3 characters).
type: bool
version_added: 8.2.0
extends_documentation_fragment:
- community.general.ipa.documentation
- community.general.attributes
Expand Down Expand Up @@ -93,9 +113,15 @@
historylength: '16'
minclasses: '4'
priority: '10'
minlength: '6'
maxfailcount: '4'
failinterval: '600'
lockouttime: '1200'
gracelimit: 3
maxrepeat: 3
maxsequence: 3
dictcheck: true
usercheck: true
ipa_host: ipa.example.com
ipa_user: admin
ipa_pass: topsecret
Expand Down Expand Up @@ -159,26 +185,35 @@ def pwpolicy_del(self, name):

def get_pwpolicy_dict(maxpwdlife=None, minpwdlife=None, historylength=None, minclasses=None,
minlength=None, priority=None, maxfailcount=None, failinterval=None,
lockouttime=None):
lockouttime=None, gracelimit=None, maxrepeat=None, maxsequence=None, dictcheck=None, usercheck=None):
pwpolicy = {}
if maxpwdlife is not None:
pwpolicy['krbmaxpwdlife'] = maxpwdlife
if minpwdlife is not None:
pwpolicy['krbminpwdlife'] = minpwdlife
if historylength is not None:
pwpolicy['krbpwdhistorylength'] = historylength
if minclasses is not None:
pwpolicy['krbpwdmindiffchars'] = minclasses
if minlength is not None:
pwpolicy['krbpwdminlength'] = minlength
if priority is not None:
pwpolicy['cospriority'] = priority
if maxfailcount is not None:
pwpolicy['krbpwdmaxfailure'] = maxfailcount
if failinterval is not None:
pwpolicy['krbpwdfailurecountinterval'] = failinterval
if lockouttime is not None:
pwpolicy['krbpwdlockoutduration'] = lockouttime
pwpolicy_options = {
'krbmaxpwdlife': maxpwdlife,
'krbminpwdlife': minpwdlife,
'krbpwdhistorylength': historylength,
'krbpwdmindiffchars': minclasses,
'krbpwdminlength': minlength,
'cospriority': priority,
'krbpwdmaxfailure': maxfailcount,
'krbpwdfailurecountinterval': failinterval,
'krbpwdlockoutduration': lockouttime,
'passwordgracelimit': gracelimit,
'ipapwdmaxrepeat': maxrepeat,
'ipapwdmaxsequence': maxsequence,
}

pwpolicy_boolean_options = {
'ipapwddictcheck': dictcheck,
'ipapwdusercheck': usercheck,
}

for option, value in pwpolicy_options.items():
if value is not None:
pwpolicy[option] = to_native(value)

for option, value in pwpolicy_boolean_options.items():
if value is not None:
pwpolicy[option] = bool(value)

return pwpolicy

Expand All @@ -199,7 +234,13 @@ def ensure(module, client):
priority=module.params.get('priority'),
maxfailcount=module.params.get('maxfailcount'),
failinterval=module.params.get('failinterval'),
lockouttime=module.params.get('lockouttime'))
lockouttime=module.params.get('lockouttime'),
gracelimit=module.params.get('gracelimit'),
maxrepeat=module.params.get('maxrepeat'),
maxsequence=module.params.get('maxsequence'),
dictcheck=module.params.get('dictcheck'),
usercheck=module.params.get('usercheck'),
)

ipa_pwpolicy = client.pwpolicy_find(name=name)

Expand Down Expand Up @@ -236,7 +277,13 @@ def main():
priority=dict(type='str'),
maxfailcount=dict(type='str'),
failinterval=dict(type='str'),
lockouttime=dict(type='str'))
lockouttime=dict(type='str'),
gracelimit=dict(type='int'),
maxrepeat=dict(type='int'),
maxsequence=dict(type='int'),
dictcheck=dict(type='bool'),
usercheck=dict(type='bool'),
)

module = AnsibleModule(argument_spec=argument_spec,
supports_check_mode=True)
Expand Down
123 changes: 109 additions & 14 deletions tests/unit/plugins/modules/test_ipa_pwpolicy.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,12 @@ def test_add(self):
'minlength': '16',
'maxfailcount': '6',
'failinterval': '60',
'lockouttime': '600'
'lockouttime': '600',
'gracelimit': 3,
'maxrepeat': 3,
'maxsequence': 3,
'dictcheck': True,
'usercheck': True,
}
return_value = {}
mock_calls = (
Expand All @@ -124,7 +129,12 @@ def test_add(self):
'krbpwdminlength': '16',
'krbpwdmaxfailure': '6',
'krbpwdfailurecountinterval': '60',
'krbpwdlockoutduration': '600'
'krbpwdlockoutduration': '600',
'passwordgracelimit': '3',
'ipapwdmaxrepeat': '3',
'ipapwdmaxsequence': '3',
'ipapwddictcheck': True,
'ipapwdusercheck': True,
}
}
)
Expand All @@ -145,7 +155,12 @@ def test_aliases(self):
'minlength': '16',
'maxfailcount': '6',
'failinterval': '60',
'lockouttime': '600'
'lockouttime': '600',
'gracelimit': 3,
'maxrepeat': 3,
'maxsequence': 3,
'dictcheck': True,
'usercheck': True,
}
return_value = {}
mock_calls = (
Expand All @@ -169,7 +184,12 @@ def test_aliases(self):
'krbpwdminlength': '16',
'krbpwdmaxfailure': '6',
'krbpwdfailurecountinterval': '60',
'krbpwdlockoutduration': '600'
'krbpwdlockoutduration': '600',
'passwordgracelimit': '3',
'ipapwdmaxrepeat': '3',
'ipapwdmaxsequence': '3',
'ipapwddictcheck': True,
'ipapwdusercheck': True,
}
}
)
Expand All @@ -190,7 +210,12 @@ def test_mod_different_args(self):
'minlength': '12',
'maxfailcount': '8',
'failinterval': '60',
'lockouttime': '600'
'lockouttime': '600',
'gracelimit': 3,
'maxrepeat': 3,
'maxsequence': 3,
'dictcheck': True,
'usercheck': True,
}
return_value = {
'cn': ['sysops'],
Expand All @@ -203,6 +228,11 @@ def test_mod_different_args(self):
'krbpwdmaxfailure': ['6'],
'krbpwdfailurecountinterval': ['60'],
'krbpwdlockoutduration': ['600'],
'passwordgracelimit': ['3'],
'ipapwdmaxrepeat': ['3'],
'ipapwdmaxsequence': ['3'],
'ipapwddictcheck': [True],
'ipapwdusercheck': [True],
'dn': 'cn=sysops,cn=EXAMPLE.COM,cn=kerberos,dc=example,dc=com',
'objectclass': ['top', 'nscontainer', 'krbpwdpolicy']
}
Expand All @@ -227,7 +257,12 @@ def test_mod_different_args(self):
'krbpwdminlength': '12',
'krbpwdmaxfailure': '8',
'krbpwdfailurecountinterval': '60',
'krbpwdlockoutduration': '600'
'krbpwdlockoutduration': '600',
'passwordgracelimit': '3',
'ipapwdmaxrepeat': '3',
'ipapwdmaxsequence': '3',
'ipapwddictcheck': True,
'ipapwdusercheck': True,
}
}
)
Expand All @@ -248,7 +283,12 @@ def test_mod_missing_args(self):
'minlength': '16',
'maxfailcount': '6',
'failinterval': '60',
'lockouttime': '600'
'lockouttime': '600',
'gracelimit': 3,
'maxrepeat': 3,
'maxsequence': 3,
'dictcheck': True,
'usercheck': True,
}
return_value = {
'cn': ['sysops'],
Expand Down Expand Up @@ -281,7 +321,12 @@ def test_mod_missing_args(self):
'krbpwdminlength': '16',
'krbpwdmaxfailure': '6',
'krbpwdfailurecountinterval': '60',
'krbpwdlockoutduration': '600'
'krbpwdlockoutduration': '600',
'passwordgracelimit': '3',
'ipapwdmaxrepeat': '3',
'ipapwdmaxsequence': '3',
'ipapwddictcheck': True,
'ipapwdusercheck': True,
}
}
)
Expand Down Expand Up @@ -342,7 +387,12 @@ def test_no_change(self):
'minlength': '16',
'maxfailcount': '6',
'failinterval': '60',
'lockouttime': '600'
'lockouttime': '600',
'gracelimit': 3,
'maxrepeat': 3,
'maxsequence': 3,
'dictcheck': True,
'usercheck': True,
}
return_value = {
'cn': ['admins'],
Expand All @@ -355,6 +405,11 @@ def test_no_change(self):
'krbpwdmaxfailure': ['6'],
'krbpwdfailurecountinterval': ['60'],
'krbpwdlockoutduration': ['600'],
'passwordgracelimit': ['3'],
'ipapwdmaxrepeat': ['3'],
'ipapwdmaxsequence': ['3'],
'ipapwddictcheck': [True],
'ipapwdusercheck': [True],
'dn': 'cn=admins,cn=EXAMPLE.COM,cn=kerberos,dc=example,dc=com',
'objectclass': ['top', 'nscontainer', 'krbpwdpolicy']
}
Expand Down Expand Up @@ -409,7 +464,12 @@ def test_global(self):
'minlength': '12',
'maxfailcount': '8',
'failinterval': '60',
'lockouttime': '600'
'lockouttime': '600',
'gracelimit': 3,
'maxrepeat': 3,
'maxsequence': 3,
'dictcheck': True,
'usercheck': True,
}
return_value = {
'cn': ['global_policy'],
Expand All @@ -420,6 +480,11 @@ def test_global(self):
'krbpwdmaxfailure': ['6'],
'krbpwdfailurecountinterval': ['60'],
'krbpwdlockoutduration': ['600'],
'passwordgracelimit': ['3'],
'ipapwdmaxrepeat': ['3'],
'ipapwdmaxsequence': ['3'],
'ipapwddictcheck': [True],
'ipapwdusercheck': [True],
'dn': 'cn=global_policy,cn=EXAMPLE.COM,cn=kerberos,dc=example,dc=com',
'objectclass': ['top', 'nscontainer', 'krbpwdpolicy']
}
Expand All @@ -443,7 +508,12 @@ def test_global(self):
'krbpwdminlength': '12',
'krbpwdmaxfailure': '8',
'krbpwdfailurecountinterval': '60',
'krbpwdlockoutduration': '600'
'krbpwdlockoutduration': '600',
'passwordgracelimit': '3',
'ipapwdmaxrepeat': '3',
'ipapwdmaxsequence': '3',
'ipapwddictcheck': True,
'ipapwdusercheck': True,
}
}
)
Expand All @@ -461,7 +531,12 @@ def test_global_no_change(self):
'minlength': '16',
'maxfailcount': '6',
'failinterval': '60',
'lockouttime': '600'
'lockouttime': '600',
'gracelimit': 3,
'maxrepeat': 3,
'maxsequence': 3,
'dictcheck': True,
'usercheck': True,
}
return_value = {
'cn': ['global_policy'],
Expand All @@ -473,6 +548,11 @@ def test_global_no_change(self):
'krbpwdmaxfailure': ['6'],
'krbpwdfailurecountinterval': ['60'],
'krbpwdlockoutduration': ['600'],
'passwordgracelimit': ['3'],
'ipapwdmaxrepeat': ['3'],
'ipapwdmaxsequence': ['3'],
'ipapwddictcheck': [True],
'ipapwdusercheck': [True],
'dn': 'cn=global_policy,cn=EXAMPLE.COM,cn=kerberos,dc=example,dc=com',
'objectclass': ['top', 'nscontainer', 'krbpwdpolicy']
}
Expand Down Expand Up @@ -504,7 +584,12 @@ def test_check_add(self):
'minlength': '16',
'maxfailcount': '6',
'failinterval': '60',
'lockouttime': '600'
'lockouttime': '600',
'gracelimit': 3,
'maxrepeat': 3,
'maxsequence': 3,
'dictcheck': True,
'usercheck': True,
}
return_value = {}
mock_calls = [
Expand Down Expand Up @@ -535,7 +620,12 @@ def test_check_mod(self):
'minlength': '12',
'maxfailcount': '8',
'failinterval': '60',
'lockouttime': '600'
'lockouttime': '600',
'gracelimit': 3,
'maxrepeat': 3,
'maxsequence': 3,
'dictcheck': True,
'usercheck': True,
}
return_value = {
'cn': ['sysops'],
Expand All @@ -548,6 +638,11 @@ def test_check_mod(self):
'krbpwdmaxfailure': ['6'],
'krbpwdfailurecountinterval': ['60'],
'krbpwdlockoutduration': ['600'],
'passwordgracelimit': ['3'],
'ipapwdmaxrepeat': ['3'],
'ipapwdmaxsequence': ['3'],
'ipapwddictcheck': [True],
'ipapwdusercheck': [True],
'dn': 'cn=sysops,cn=EXAMPLE.COM,cn=kerberos,dc=example,dc=com',
'objectclass': ['top', 'nscontainer', 'krbpwdpolicy']
}
Expand Down