mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2024-12-24 08:00:02 -06:00
Use kerberos password policy.
This lets the KDC count password failures and can lock out accounts for a period of time. This only works for KDC >= 1.8. There currently is no way to unlock a locked account across a replica. MIT Kerberos 1.9 is adding support for doing so. Once that is available unlock will be added. The concept of a "global" password policy has changed. When we were managing the policy using the IPA password plugin it was smart enough to search up the tree looking for a policy. The KDC is not so smart and relies on the krbpwdpolicyreference to find the policy. For this reason every user entry requires this attribute. I've created a new global_policy entry to store the default password policy. All users point at this now. The group policy works the same and can override this setting. As a result the special "GLOBAL" name has been replaced with global_policy. This policy works like any other and is the default if a name is not provided on the command-line. ticket 51
This commit is contained in:
parent
aff2816d20
commit
813dfe5013
@ -120,6 +120,12 @@ attributetypes: ( 2.16.840.1.113719.1.301.4.32.1 NAME 'krbPwdMinDiffChars' EQUAL
|
||||
attributetypes: ( 2.16.840.1.113719.1.301.4.33.1 NAME 'krbPwdMinLength' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE)
|
||||
##### Number of previous versions of passwords that are stored
|
||||
attributetypes: ( 2.16.840.1.113719.1.301.4.34.1 NAME 'krbPwdHistoryLength' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE)
|
||||
##### Number of consecutive pre-authentication failures before lockout
|
||||
attributetypes: ( 1.3.6.1.4.1.5322.21.2.1 NAME 'krbPwdMaxFailure' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE)
|
||||
##### Period after which bad preauthentication count will be reset
|
||||
attributetypes: ( 1.3.6.1.4.1.5322.21.2.2 NAME 'krbPwdFailureCountInterval' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE)
|
||||
##### Period in which lockout is enforced
|
||||
attributetypes: ( 1.3.6.1.4.1.5322.21.2.3 NAME 'krbPwdLockoutDuration' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE)
|
||||
##### FDN pointing to a Kerberos Password Policy object
|
||||
attributetypes: ( 2.16.840.1.113719.1.301.4.36.1 NAME 'krbPwdPolicyReference' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE)
|
||||
##### The time at which the principal's password expires
|
||||
@ -289,7 +295,7 @@ objectClasses: ( 2.16.840.1.113719.1.301.6.13.1 NAME 'krbAdmService' SUP ( krbSe
|
||||
##### can be applied to principals when they are created.
|
||||
##### These policy attributes will be in effect, when the Kerberos
|
||||
##### passwords are different from users' passwords (UP).
|
||||
objectClasses: ( 2.16.840.1.113719.1.301.6.14.1 NAME 'krbPwdPolicy' SUP top MUST ( cn ) MAY ( krbMaxPwdLife $ krbMinPwdLife $ krbPwdMinDiffChars $ krbPwdMinLength $ krbPwdHistoryLength ) )
|
||||
objectClasses: ( 2.16.840.1.113719.1.301.6.14.1 NAME 'krbPwdPolicy' SUP top MUST ( cn ) MAY ( krbMaxPwdLife $ krbMinPwdLife $ krbPwdMinDiffChars $ krbPwdMinLength $ krbPwdHistoryLength $ krbPwdMaxFailure $ krbPwdFailureCountInterval $ krbPwdLockoutDuration ) )
|
||||
##### The krbTicketPolicyAux holds Kerberos ticket policy attributes.
|
||||
##### This class can be attached to a principal object or realm object.
|
||||
objectClasses: ( 2.16.840.1.113719.1.301.6.16.1 NAME 'krbTicketPolicyAux' AUXILIARY MAY ( krbTicketFlags $ krbMaxTicketLife $ krbMaxRenewableAge ) )
|
||||
|
@ -15,6 +15,7 @@ app_DATA = \
|
||||
default-aci.ldif \
|
||||
default-hbac.ldif \
|
||||
default-keytypes.ldif \
|
||||
default-pwpolicy.ldif \
|
||||
delegation.ldif \
|
||||
dns.ldif \
|
||||
kerberos.ldif \
|
||||
|
@ -2,13 +2,7 @@ dn: cn=accounts,$SUFFIX
|
||||
changetype: add
|
||||
objectClass: top
|
||||
objectClass: nsContainer
|
||||
objectClass: krbPwdPolicy
|
||||
cn: accounts
|
||||
krbMinPwdLife: 3600
|
||||
krbPwdMinDiffChars: 0
|
||||
krbPwdMinLength: 8
|
||||
krbPwdHistoryLength: 0
|
||||
krbMaxPwdLife: 7776000
|
||||
|
||||
dn: cn=users,cn=accounts,$SUFFIX
|
||||
changetype: add
|
||||
@ -271,5 +265,5 @@ objectClass: ldapsubentry
|
||||
objectClass: cosSuperDefinition
|
||||
objectClass: cosClassicDefinition
|
||||
cosTemplateDn: cn=cosTemplates,cn=accounts,$SUFFIX
|
||||
cosAttribute: krbPwdPolicyReference
|
||||
cosAttribute: krbPwdPolicyReference override
|
||||
cosSpecifier: memberOf
|
||||
|
14
install/share/default-pwpolicy.ldif
Normal file
14
install/share/default-pwpolicy.ldif
Normal file
@ -0,0 +1,14 @@
|
||||
dn: cn=global_policy,cn=$REALM,cn=kerberos,$SUFFIX
|
||||
changetype: add
|
||||
objectClass: top
|
||||
objectClass: nsContainer
|
||||
objectClass: krbPwdPolicy
|
||||
krbMinPwdLife: 3600
|
||||
krbPwdMinDiffChars: 0
|
||||
krbPwdMinLength: 8
|
||||
krbPwdHistoryLength: 0
|
||||
krbMaxPwdLife: 7776000
|
||||
krbPwdMaxFailure: 3
|
||||
krbPwdFailureCountInterval: 60
|
||||
krbPwdLockoutDuration: 10
|
||||
|
@ -63,6 +63,7 @@ from ipalib import api
|
||||
from ipalib import Int, Str
|
||||
from ipalib.plugins.baseldap import *
|
||||
from ipalib import _
|
||||
from ipapython.ipautil import run
|
||||
|
||||
class cosentry(LDAPObject):
|
||||
"""
|
||||
@ -154,8 +155,7 @@ class cosentry_find(LDAPSearch):
|
||||
api.register(cosentry_find)
|
||||
|
||||
|
||||
GLOBAL_POLICY_NAME = u'GLOBAL'
|
||||
|
||||
global_policy_dn = 'cn=global_policy,cn=%s,cn=kerberos,%s' % (api.env.realm, api.env.basedn)
|
||||
|
||||
class pwpolicy(LDAPObject):
|
||||
"""
|
||||
@ -168,7 +168,37 @@ class pwpolicy(LDAPObject):
|
||||
default_attributes = [
|
||||
'cn', 'cospriority', 'krbmaxpwdlife', 'krbminpwdlife',
|
||||
'krbpwdhistorylength', 'krbpwdmindiffchars', 'krbpwdminlength',
|
||||
'krbpwdmaxfailure', 'krbpwdfailurecountinterval',
|
||||
'krbpwdlockoutduration',
|
||||
]
|
||||
has_lockout = False
|
||||
lockout_params = ()
|
||||
(stdout, stderr, rc) = run(['klist', '-V'], raiseonerr=False)
|
||||
if rc == 0:
|
||||
if stdout.find('version 1.8') > -1:
|
||||
has_lockout = True
|
||||
|
||||
if has_lockout:
|
||||
lockout_params = (
|
||||
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,
|
||||
),
|
||||
)
|
||||
|
||||
label = _('Password Policy')
|
||||
|
||||
@ -216,14 +246,14 @@ class pwpolicy(LDAPObject):
|
||||
doc=_('Priority of the policy (higher number means lower priority'),
|
||||
minvalue=0,
|
||||
),
|
||||
)
|
||||
) + lockout_params
|
||||
|
||||
def get_dn(self, *keys, **options):
|
||||
if keys[-1] is not None:
|
||||
return self.backend.make_dn_from_attr(
|
||||
self.primary_key.name, keys[-1], self.container_dn
|
||||
)
|
||||
return self.api.env.container_accounts
|
||||
return global_policy_dn
|
||||
|
||||
def convert_time_for_output(self, entry_attrs, **options):
|
||||
# Convert seconds to hours and days for displaying to user
|
||||
@ -348,8 +378,6 @@ class pwpolicy_mod(LDAPUpdate):
|
||||
if not options.get('raw', False):
|
||||
if options.get('cospriority') is not None:
|
||||
entry_attrs['cospriority'] = [unicode(options['cospriority'])]
|
||||
if keys[-1] is None:
|
||||
entry_attrs['cn'] = GLOBAL_POLICY_NAME
|
||||
self.obj.convert_time_for_output(entry_attrs, **options)
|
||||
return dn
|
||||
|
||||
@ -394,8 +422,6 @@ class pwpolicy_show(LDAPRetrieve):
|
||||
entry_attrs['cospriority'] = cos_entry['cospriority']
|
||||
except errors.NotFound:
|
||||
pass
|
||||
else:
|
||||
entry_attrs['cn'] = GLOBAL_POLICY_NAME
|
||||
self.obj.convert_time_for_output(entry_attrs, **options)
|
||||
return dn
|
||||
|
||||
@ -418,13 +444,6 @@ class pwpolicy_find(LDAPSearch):
|
||||
except errors.NotFound:
|
||||
pass
|
||||
self.obj.convert_time_for_output(e[1], **options)
|
||||
if not args[-1]:
|
||||
global_entry = self.api.Command.pwpolicy_show(
|
||||
all=options.get('all', False), raw=options.get('raw', False)
|
||||
)['result']
|
||||
dn = global_entry['dn']
|
||||
del global_entry['dn']
|
||||
entries.insert(0, (dn, global_entry))
|
||||
|
||||
api.register(pwpolicy_find)
|
||||
|
||||
|
@ -177,6 +177,7 @@ class user_add(LDAPCreate):
|
||||
home_dir = '%s/%s' % (homes_root, keys[-1])
|
||||
home_dir = home_dir.replace('//', '/').rstrip('/')
|
||||
entry_attrs['homedirectory'] = home_dir
|
||||
entry_attrs.setdefault('krbpwdpolicyreference', 'cn=global_policy,cn=%s,cn=kerberos,%s' % (api.env.realm, api.env.basedn))
|
||||
|
||||
if ldap.has_upg():
|
||||
# User Private Groups - uidNumber == gidNumber
|
||||
|
@ -169,6 +169,7 @@ class KrbInstance(service.Service):
|
||||
self.step("adding default ACIs", self.__add_default_acis)
|
||||
self.step("configuring KDC", self.__create_instance)
|
||||
self.step("adding default keytypes", self.__add_default_keytypes)
|
||||
self.step("adding default password policy", self.__add_default_pwpolicy)
|
||||
self.step("creating a keytab for the directory", self.__create_ds_keytab)
|
||||
self.step("creating a keytab for the machine", self.__create_host_keytab)
|
||||
self.step("exporting the kadmin keytab", self.__export_kadmin_changepw_keytab)
|
||||
@ -303,6 +304,9 @@ class KrbInstance(service.Service):
|
||||
def __add_default_keytypes(self):
|
||||
self._ldap_mod("default-keytypes.ldif", self.sub_dict)
|
||||
|
||||
def __add_default_pwpolicy(self):
|
||||
self._ldap_mod("default-pwpolicy.ldif", self.sub_dict)
|
||||
|
||||
def __create_replica_instance(self):
|
||||
self.__create_instance(replica=True)
|
||||
|
||||
|
@ -335,8 +335,8 @@ class test_group(Declarative):
|
||||
'gidnumber': [fuzzy_digits],
|
||||
'cn': [u'admins'],
|
||||
'description': [u'Account administrators group'],
|
||||
'memberof_rolegroup': [u'replicaadmin'],
|
||||
'memberof_taskgroup': [u'managereplica', u'deletereplica'],
|
||||
'memberof_rolegroup': [u'hostadmin', u'replicaadmin'],
|
||||
'memberof_taskgroup': [u'addhosts', u'removehosts', u'modifyhosts', u'manage_host_keytab', u'enroll_host', u'managereplica', u'deletereplica'],
|
||||
},
|
||||
{
|
||||
'dn': u'cn=ipausers,cn=groups,cn=accounts,%s' % api.env.basedn,
|
||||
|
@ -150,7 +150,8 @@ class test_user(Declarative):
|
||||
'uidnumber': [fuzzy_digits],
|
||||
'gidnumber': [fuzzy_digits],
|
||||
'ipauniqueid': [fuzzy_uuid],
|
||||
'mepmanagedentry': [u'cn=%s,cn=groups,cn=accounts,%s' % (user1, api.env.basedn)]
|
||||
'mepmanagedentry': [u'cn=%s,cn=groups,cn=accounts,%s' % (user1, api.env.basedn)],
|
||||
'krbpwdpolicyreference': [u'cn=global_policy,cn=%s,cn=kerberos,%s' % (api.env.realm, api.env.basedn)],
|
||||
},
|
||||
],
|
||||
summary=u'1 user matched',
|
||||
@ -197,8 +198,8 @@ class test_user(Declarative):
|
||||
sn=[u'Administrator'],
|
||||
uid=[u'admin'],
|
||||
memberof_group=[u'admins'],
|
||||
memberof_rolegroup=[u'replicaadmin'],
|
||||
memberof_taskgroup=[u'managereplica', u'deletereplica'],
|
||||
memberof_rolegroup=[u'hostadmin', u'replicaadmin'],
|
||||
memberof_taskgroup=[u'addhosts', u'removehosts', u'modifyhosts', u'manage_host_keytab', u'enroll_host', u'managereplica', u'deletereplica'],
|
||||
),
|
||||
dict(
|
||||
dn=u'uid=tuser1,cn=users,cn=accounts,' + api.env.basedn,
|
||||
@ -231,8 +232,8 @@ class test_user(Declarative):
|
||||
sn=[u'Administrator'],
|
||||
uid=[u'admin'],
|
||||
memberof_group=[u'admins'],
|
||||
memberof_rolegroup=[u'replicaadmin'],
|
||||
memberof_taskgroup=[u'managereplica', u'deletereplica'],
|
||||
memberof_rolegroup=[u'hostadmin', u'replicaadmin'],
|
||||
memberof_taskgroup=[u'addhosts', u'removehosts', u'modifyhosts', u'manage_host_keytab', u'enroll_host', u'managereplica', u'deletereplica'],
|
||||
),
|
||||
],
|
||||
summary=u'1 user matched',
|
||||
|
Loading…
Reference in New Issue
Block a user