Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
# Authors: # Pavel Zuna <pzuna@redhat.com> # Martin Kosek <mkosek@redhat.com> # # Copyright (C) 2010 Red Hat # see file 'COPYING' for use and warranty information # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>.
Password policy
A password policy sets limitations on IPA passwords, including maximum lifetime, minimum lifetime, the number of passwords to save in history, the number of character classes required (for stronger passwords) and the minimum password length.
By default there is a single, global policy for all users. You can also create a password policy to apply to a group. Each user is only subject to one password policy, either the group policy or the global policy. A group policy stands alone; it is not a super-set of the global policy plus custom settings.
Each group password policy requires a unique priority setting. If a user is in multiple groups that have password policies, this priority determines which password policy is applied. A lower value indicates a higher priority policy.
Group password policies are automatically removed when the groups they are associated with are removed.
EXAMPLES:
Modify the global policy: ipa pwpolicy-mod --minlength=10
Add a new group password policy: ipa pwpolicy-add --maxlife=90 --minlife=1 --history=10 --minclasses=3 --minlength=8 --priority=10 localadmins
Display the global password policy: ipa pwpolicy-show
Display a group password policy: ipa pwpolicy-show localadmins
Display the policy that would be applied to a given user: ipa pwpolicy-show --user=tuser1
Modify a group password policy: ipa pwpolicy-mod --minclasses=2 localadmins """)
""" Class of Service object used for linking policies with groups """
Str('cn', primary_key=True), DNParam('krbpwdpolicyreference'), Int('cospriority', minvalue=0), )
'priority must be a unique value (%(prio)d already used by %(gname)s)' )
'cn', group_dn, DN(self.container_dn, api.env.basedn) )
cospriority=options['cospriority'] )['result'] DN(entries[0]['cn'][0])) name='priority', error=self.priority_not_unique_msg % { 'prio': options['cospriority'], 'gname': group_name, } )
# check for existence of the group
assert isinstance(dn, DN) new_cospriority = options.get('cospriority') if new_cospriority is not None: cos_entry = self.api.Command.cosentry_show(keys[-1])['result'] old_cospriority = int(cos_entry['cospriority'][0])
# check uniqueness only when the new priority differs if old_cospriority != new_cospriority: self.obj.check_priority_uniqueness(*keys, **options) return dn
""" Password Policy object """ 'cn', 'cospriority', 'krbmaxpwdlife', 'krbminpwdlife', 'krbpwdhistorylength', 'krbpwdmindiffchars', 'krbpwdminlength', 'krbpwdmaxfailure', 'krbpwdfailurecountinterval', 'krbpwdlockoutduration', ]
Int('krbpwdmaxfailure?', cli_name='maxfail', label=_('Max failures'), doc=_('Consecutive failures before lockout'), minvalue=0, ), Int('krbpwdfailurecountinterval?', cli_name='failinterval', label=_('Failure reset interval'), doc=_('Period after which failure count will be reset (seconds)'), minvalue=0, ), Int('krbpwdlockoutduration?', cli_name='lockouttime', label=_('Lockout duration'), doc=_('Period for which lockout is enforced (seconds)'), minvalue=0, ), )
Str('cn?', cli_name='group', label=_('Group'), doc=_('Manage password policy for specific group'), primary_key=True, ), Int('krbmaxpwdlife?', cli_name='maxlife', label=_('Max lifetime (days)'), doc=_('Maximum password lifetime (in days)'), minvalue=0, ), Int('krbminpwdlife?', cli_name='minlife', label=_('Min lifetime (hours)'), doc=_('Minimum password lifetime (in hours)'), minvalue=0, ), Int('krbpwdhistorylength?', cli_name='history', label=_('History size'), doc=_('Password history size'), minvalue=0, ), Int('krbpwdmindiffchars?', cli_name='minclasses', label=_('Character classes'), doc=_('Minimum number of character classes'), minvalue=0, maxvalue=5, ), Int('krbpwdminlength?', cli_name='minlength', label=_('Min length'), doc=_('Minimum length of password'), minvalue=0, ), Int('cospriority', cli_name='priority', label=_('Priority'), doc=_('Priority of the policy (higher number means lower priority'), minvalue=0, flags=('virtual_attribute',), ), ) + lockout_params
self.primary_key.name, keys[-1], DN(self.container_dn, api.env.basedn) )
# Convert seconds to hours and days for displaying to user int(entry_attrs['krbmaxpwdlife'][0]) / 86400 ) int(entry_attrs['krbminpwdlife'][0]) / 3600 )
# Convert hours and days to seconds for writing to LDAP
""" Ensure that the maximum lifetime is greater than the minimum. If there is no minimum lifetime set then don't return an error. """ all=True, )['result'] minlife = int(existing_entry['krbminpwdlife'][0]) * 3600
raise errors.ValidationError( name='maxlife', error=_('Maximum password life must be greater than minimum.'), )
pwpolicy_name, rights=rights, all=rights )['result'] entry['attributelevelrights']['cospriority'] = \ cos_entry['attributelevelrights']['cospriority']
keys[-1], krbpwdpolicyreference=dn, cospriority=options.get('cospriority') )
# attribute rights are not allowed for pwpolicy_add
attribute=True, required=True, multivalue=True )
name='group', error=_('cannot delete global password policy') )
except errors.NotFound: pass
if keys[-1] is None: raise errors.ValidationError( name='priority', error=_('priority cannot be set on global policy') ) try: self.api.Command.cosentry_mod( keys[-1], cospriority=options['cospriority'] ) except errors.EmptyModlist, e: if len(entry_attrs) == 1: # cospriority only was passed raise e else: setattr(context, 'cosupdate', True)
if call_func.func_name == 'update_entry': if isinstance(exc, errors.EmptyModlist): entry_attrs = call_args[1] cosupdate = getattr(context, 'cosupdate') if not entry_attrs or cosupdate: return raise exc
Str('user?', label=_('User'), doc=_('Display effective policy for a specific user'), ), )
user_entry = self.api.Command.user_show( options['user'], all=True )['result'] if 'krbpwdpolicyreference' in user_entry: return user_entry.get('krbpwdpolicyreference', [dn])[0]
# this command does custom sorting in post_callback
"""Key for sorting password policies
returns a pair: (is_global, priority) """ # global policy will be always last in the output else: # policies with higher priority (lower number) will be at the # beginning of the list except KeyError: # if cospriority is not present in the entry, rather return 0 # than crash cospriority = 0
# When pkey_only flag is on, entries should contain only a cn. # Add a cospriority attribute that will be used for sorting. # Attribute rights are not allowed for pwpolicy_find.
# do custom entry sorting by its cospriority
# remove cospriority that was used for sorting
|