URL: https://github.com/freeipa/freeipa/pull/621 Author: redhatrises Title: #621: Add --password-expiration to allow an admin to force a password change Action: synchronized
To pull the PR as Git branch: git remote add ghfreeipa https://github.com/freeipa/freeipa git fetch ghfreeipa pull/621/head:pr621 git checkout pr621
From c9e5553a7be43c9af9d8c74ba4487e0ceabcb557 Mon Sep 17 00:00:00 2001 From: Gabe <redhatri...@gmail.com> Date: Thu, 30 Mar 2017 18:21:47 -0600 Subject: [PATCH] Add --password-expiration to allow admin to force user password expiration - Allows an admin to easily force a user to expire their password forcing the user to change it immediately or at a specified time in the future --- ACI.txt | 2 +- API.txt | 18 ++++++++++++------ VERSION.m4 | 4 ++-- install/updates/20-aci.update | 6 ++++-- ipalib/parameters.py | 16 ++++++++++------ ipaserver/plugins/baseuser.py | 4 ++++ ipaserver/plugins/user.py | 2 +- 7 files changed, 34 insertions(+), 18 deletions(-) diff --git a/ACI.txt b/ACI.txt index 9c7996c..185812a 100644 --- a/ACI.txt +++ b/ACI.txt @@ -351,7 +351,7 @@ aci: (targetattr = "member")(target = "ldap:///cn=ipausers,cn=groups,cn=accounts dn: cn=users,cn=accounts,dc=ipa,dc=example aci: (targetfilter = "(objectclass=posixaccount)")(version 3.0;acl "permission:System: Add Users";allow (add) groupdn = "ldap:///cn=System: Add Users,cn=permissions,cn=pbac,dc=ipa,dc=example";) dn: cn=users,cn=accounts,dc=ipa,dc=example -aci: (targetattr = "krbprincipalkey || passwordhistory || sambalmpassword || sambantpassword || userpassword")(targetfilter = "(&(!(memberOf=cn=admins,cn=groups,cn=accounts,dc=ipa,dc=example))(objectclass=posixaccount))")(version 3.0;acl "permission:System: Change User password";allow (write) groupdn = "ldap:///cn=System: Change User password,cn=permissions,cn=pbac,dc=ipa,dc=example";) +aci: (targetattr = "krbpasswordexpiration || krbprincipalkey || passwordhistory || sambalmpassword || sambantpassword || userpassword")(targetfilter = "(&(!(memberOf=cn=admins,cn=groups,cn=accounts,dc=ipa,dc=example))(objectclass=posixaccount))")(version 3.0;acl "permission:System: Change User password";allow (write) groupdn = "ldap:///cn=System: Change User password,cn=permissions,cn=pbac,dc=ipa,dc=example";) dn: cn=users,cn=accounts,dc=ipa,dc=example aci: (targetattr = "ipacertmapdata || objectclass")(targetfilter = "(objectclass=posixaccount)")(version 3.0;acl "permission:System: Manage User Certificate Mappings";allow (write) groupdn = "ldap:///cn=System: Manage User Certificate Mappings,cn=permissions,cn=pbac,dc=ipa,dc=example";) dn: cn=users,cn=accounts,dc=ipa,dc=example diff --git a/API.txt b/API.txt index 7594157..7850538 100644 --- a/API.txt +++ b/API.txt @@ -4828,7 +4828,7 @@ output: Entry('result') output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>]) output: PrimaryKey('value') command: stageuser_add/1 -args: 1,44,3 +args: 1,45,3 arg: Str('uid', cli_name='login') option: Str('addattr*', cli_name='addattr') option: Flag('all', autofill=True, cli_name='all', default=False) @@ -4849,6 +4849,7 @@ option: Str('ipasshpubkey*', cli_name='sshpubkey') option: Str('ipatokenradiusconfiglink?', cli_name='radius') option: Str('ipatokenradiususername?', cli_name='radius_username') option: StrEnum('ipauserauthtype*', cli_name='user_auth_type', values=[u'password', u'radius', u'otp']) +option: DateTime('krbpasswordexpiration?', cli_name='password_expiration') option: DateTime('krbprincipalexpiration?', cli_name='principal_expiration') option: Principal('krbprincipalname*', autofill=True, cli_name='principal') option: Str('l?', cli_name='city') @@ -4933,7 +4934,7 @@ output: Output('result', type=[<type 'dict'>]) output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>]) output: ListOfPrimaryKeys('value') command: stageuser_find/1 -args: 1,53,4 +args: 1,54,4 arg: Str('criteria?') option: Flag('all', autofill=True, cli_name='all', default=False) option: Str('carlicense*', autofill=False) @@ -4956,6 +4957,7 @@ option: Str('initials?', autofill=False) option: Str('ipatokenradiusconfiglink?', autofill=False, cli_name='radius') option: Str('ipatokenradiususername?', autofill=False, cli_name='radius_username') option: StrEnum('ipauserauthtype*', autofill=False, cli_name='user_auth_type', values=[u'password', u'radius', u'otp']) +option: DateTime('krbpasswordexpiration?', autofill=False, cli_name='password_expiration') option: DateTime('krbprincipalexpiration?', autofill=False, cli_name='principal_expiration') option: Principal('krbprincipalname*', autofill=False, cli_name='principal') option: Str('l?', autofill=False, cli_name='city') @@ -4993,7 +4995,7 @@ output: ListOfEntries('result') output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>]) output: Output('truncated', type=[<type 'bool'>]) command: stageuser_mod/1 -args: 1,46,3 +args: 1,47,3 arg: Str('uid', cli_name='login') option: Str('addattr*', cli_name='addattr') option: Flag('all', autofill=True, cli_name='all', default=False) @@ -5014,6 +5016,7 @@ option: Str('ipasshpubkey*', autofill=False, cli_name='sshpubkey') option: Str('ipatokenradiusconfiglink?', autofill=False, cli_name='radius') option: Str('ipatokenradiususername?', autofill=False, cli_name='radius_username') option: StrEnum('ipauserauthtype*', autofill=False, cli_name='user_auth_type', values=[u'password', u'radius', u'otp']) +option: DateTime('krbpasswordexpiration?', autofill=False, cli_name='password_expiration') option: DateTime('krbprincipalexpiration?', autofill=False, cli_name='principal_expiration') option: Principal('krbprincipalname*', autofill=False, cli_name='principal') option: Str('l?', autofill=False, cli_name='city') @@ -5890,7 +5893,7 @@ output: Entry('result') output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>]) output: PrimaryKey('value') command: user_add/1 -args: 1,45,3 +args: 1,46,3 arg: Str('uid', cli_name='login') option: Str('addattr*', cli_name='addattr') option: Flag('all', autofill=True, cli_name='all', default=False) @@ -5910,6 +5913,7 @@ option: Str('ipasshpubkey*', cli_name='sshpubkey') option: Str('ipatokenradiusconfiglink?', cli_name='radius') option: Str('ipatokenradiususername?', cli_name='radius_username') option: StrEnum('ipauserauthtype*', cli_name='user_auth_type', values=[u'password', u'radius', u'otp']) +option: DateTime('krbpasswordexpiration?', cli_name='password_expiration') option: DateTime('krbprincipalexpiration?', cli_name='principal_expiration') option: Principal('krbprincipalname*', autofill=True, cli_name='principal') option: Str('l?', cli_name='city') @@ -6011,7 +6015,7 @@ output: Output('result', type=[<type 'bool'>]) output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>]) output: PrimaryKey('value') command: user_find/1 -args: 1,56,4 +args: 1,57,4 arg: Str('criteria?') option: Flag('all', autofill=True, cli_name='all', default=False) option: Str('carlicense*', autofill=False) @@ -6034,6 +6038,7 @@ option: Str('initials?', autofill=False) option: Str('ipatokenradiusconfiglink?', autofill=False, cli_name='radius') option: Str('ipatokenradiususername?', autofill=False, cli_name='radius_username') option: StrEnum('ipauserauthtype*', autofill=False, cli_name='user_auth_type', values=[u'password', u'radius', u'otp']) +option: DateTime('krbpasswordexpiration?', autofill=False, cli_name='password_expiration') option: DateTime('krbprincipalexpiration?', autofill=False, cli_name='principal_expiration') option: Principal('krbprincipalname*', autofill=False, cli_name='principal') option: Str('l?', autofill=False, cli_name='city') @@ -6074,7 +6079,7 @@ output: ListOfEntries('result') output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>]) output: Output('truncated', type=[<type 'bool'>]) command: user_mod/1 -args: 1,47,3 +args: 1,48,3 arg: Str('uid', cli_name='login') option: Str('addattr*', cli_name='addattr') option: Flag('all', autofill=True, cli_name='all', default=False) @@ -6095,6 +6100,7 @@ option: Str('ipasshpubkey*', autofill=False, cli_name='sshpubkey') option: Str('ipatokenradiusconfiglink?', autofill=False, cli_name='radius') option: Str('ipatokenradiususername?', autofill=False, cli_name='radius_username') option: StrEnum('ipauserauthtype*', autofill=False, cli_name='user_auth_type', values=[u'password', u'radius', u'otp']) +option: DateTime('krbpasswordexpiration?', autofill=False, cli_name='password_expiration') option: DateTime('krbprincipalexpiration?', autofill=False, cli_name='principal_expiration') option: Principal('krbprincipalname*', autofill=False, cli_name='principal') option: Str('l?', autofill=False, cli_name='city') diff --git a/VERSION.m4 b/VERSION.m4 index 4b11d48..6ec56c5 100644 --- a/VERSION.m4 +++ b/VERSION.m4 @@ -73,8 +73,8 @@ define(IPA_DATA_VERSION, 20100614120000) # # ######################################################## define(IPA_API_VERSION_MAJOR, 2) -define(IPA_API_VERSION_MINOR, 224) -# Last change: Add rename option to sudorule objects +define(IPA_API_VERSION_MINOR, 225) +# Last change: Add --password-expiration option to force password change ######################################################## diff --git a/install/updates/20-aci.update b/install/updates/20-aci.update index a15f9fe..dec2e16 100644 --- a/install/updates/20-aci.update +++ b/install/updates/20-aci.update @@ -51,10 +51,12 @@ remove:aci:(targetattr != "userPassword || krbPrincipalKey || sambaLMPassword || remove:aci:(targetattr != "userPassword || krbPrincipalKey || sambaLMPassword || sambaNTPassword || passwordHistory || krbMKey || krbPrincipalName || krbCanonicalName || krbUPEnabled || krbTicketPolicyReference || krbPrincipalExpiration || krbPasswordExpiration || krbPwdPolicyReference || krbPrincipalType || krbPwdHistory || krbLastPwdChange || krbPrincipalAliases || krbExtraData || krbLastSuccessfulAuth || krbLastFailedAuth || krbLoginFailedCount || krbTicketFlags || ipaUniqueId || memberOf || serverHostName || enrolledBy || ipaNTHash")(version 3.0; acl "Admin can manage any entry"; allow (all) groupdn = "ldap:///cn=admins,cn=groups,cn=accounts,$SUFFIX";) remove:aci:(targetattr != "userPassword || krbPrincipalKey || sambaLMPassword || sambaNTPassword || passwordHistory || krbMKey || krbPrincipalName || krbCanonicalName || krbUPEnabled || krbTicketPolicyReference || krbPrincipalExpiration || krbPasswordExpiration || krbPwdPolicyReference || krbPrincipalType || krbPwdHistory || krbLastPwdChange || krbPrincipalAliases || krbExtraData || krbLastSuccessfulAuth || krbLastFailedAuth || krbLoginFailedCount || ipaUniqueId || memberOf || serverHostName || enrolledBy || ipaNTHash")(version 3.0; acl "Admin can manage any entry"; allow (all) groupdn = "ldap:///cn=admins,cn=groups,cn=accounts,$SUFFIX";) remove:aci:(targetattr != "userPassword || krbPrincipalKey || sambaLMPassword || sambaNTPassword || passwordHistory || krbMKey || krbPrincipalName || krbCanonicalName || krbUPEnabled || krbTicketPolicyReference || krbPasswordExpiration || krbPwdPolicyReference || krbPrincipalType || krbPwdHistory || krbLastPwdChange || krbPrincipalAliases || krbExtraData || krbLastSuccessfulAuth || krbLastFailedAuth || krbLoginFailedCount || ipaUniqueId || memberOf || serverHostName || enrolledBy || ipaNTHash")(version 3.0; acl "Admin can manage any entry"; allow (all) groupdn = "ldap:///cn=admins,cn=groups,cn=accounts,$SUFFIX";) -add:aci:(targetattr != "userPassword || krbPrincipalKey || sambaLMPassword || sambaNTPassword || passwordHistory || krbMKey || krbPrincipalName || krbCanonicalName || krbPasswordExpiration || krbPwdHistory || krbLastPwdChange || krbExtraData || krbLastSuccessfulAuth || krbLastFailedAuth || ipaUniqueId || memberOf || enrolledBy || ipaNTHash || ipaProtectedOperation")(version 3.0; acl "Admin can manage any entry"; allow (all) groupdn = "ldap:///cn=admins,cn=groups,cn=accounts,$SUFFIX";) +remove:aci:(targetattr != "userPassword || krbPrincipalKey || sambaLMPassword || sambaNTPassword || passwordHistory || krbMKey || krbPrincipalName || krbCanonicalName || krbPasswordExpiration || krbPwdHistory || krbLastPwdChange || krbExtraData || krbLastSuccessfulAuth || krbLastFailedAuth || ipaUniqueId || memberOf || enrolledBy || ipaNTHash || ipaProtectedOperation")(version 3.0; acl "Admin can manage any entry"; allow (all) groupdn = "ldap:///cn=admins,cn=groups,cn=accounts,$SUFFIX";) +add:aci:(targetattr != "userPassword || krbPrincipalKey || sambaLMPassword || sambaNTPassword || passwordHistory || krbMKey || krbPrincipalName || krbCanonicalName || krbPwdHistory || krbLastPwdChange || krbExtraData || krbLastSuccessfulAuth || krbLastFailedAuth || ipaUniqueId || memberOf || enrolledBy || ipaNTHash || ipaProtectedOperation")(version 3.0; acl "Admin can manage any entry"; allow (all) groupdn = "ldap:///cn=admins,cn=groups,cn=accounts,$SUFFIX";) # Write-only remove:aci:(targetattr = "userPassword || krbPrincipalKey || sambaLMPassword || sambaNTPassword || passwordHistory")(version 3.0; acl "Admins can write passwords"; allow (add,delete,write) groupdn="ldap:///cn=admins,cn=groups,cn=accounts,$SUFFIX";) -add:aci:(targetattr = "userPassword || krbPrincipalKey || sambaLMPassword || sambaNTPassword || passwordHistory || ipaNTHash")(version 3.0; acl "Admins can write passwords"; allow (add,delete,write) groupdn="ldap:///cn=admins,cn=groups,cn=accounts,$SUFFIX";) +remove:aci:(targetattr = "userPassword || krbPrincipalKey || sambaLMPassword || sambaNTPassword || passwordHistory || ipaNTHash")(version 3.0; acl "Admins can write passwords"; allow (add,delete,write) groupdn="ldap:///cn=admins,cn=groups,cn=accounts,$SUFFIX";) +add:aci:(targetattr = "userPassword || krbPrincipalKey || sambaLMPassword || sambaNTPassword || passwordHistory || ipaNTHash || krbPasswordExpiration")(version 3.0; acl "Admins can write passwords"; allow (add,delete,write) groupdn="ldap:///cn=admins,cn=groups,cn=accounts,$SUFFIX";) add:aci:(targetfilter = "(objectClass=krbPwdPolicy)")(targetattr = "krbMaxPwdLife || krbMinPwdLife || krbPwdMinDiffChars || krbPwdMinLength || krbPwdHistoryLength")(version 3.0;acl "Admins can write password policies"; allow (read, search, compare, write) groupdn = "ldap:///cn=admins,cn=groups,cn=accounts,$SUFFIX";) # Read-only add:aci:(targetattr="ipaUniqueId || memberOf || enrolledBy || krbExtraData || krbPrincipalName || krbCanonicalName || krbPasswordExpiration || krbLastPwdChange || krbLastSuccessfulAuth || krbLastFailedAuth")(version 3.0; acl "Admin read-only attributes"; allow (read, search, compare) groupdn = "ldap:///cn=admins,cn=groups,cn=accounts,$SUFFIX";) diff --git a/ipalib/parameters.py b/ipalib/parameters.py index 7fbe63e..107cc90 100644 --- a/ipalib/parameters.py +++ b/ipalib/parameters.py @@ -1665,12 +1665,16 @@ class DateTime(Param): def _convert_scalar(self, value, index=None): if isinstance(value, six.string_types): - for date_format in self.accepted_formats: - try: - time = datetime.datetime.strptime(value, date_format) - return time - except ValueError: - pass + if value == u'now': + time = datetime.datetime.utcnow() + return time + else: + for date_format in self.accepted_formats: + try: + time = datetime.datetime.strptime(value, date_format) + return time + except ValueError: + pass # If we get here, the strptime call did not succeed for any # the accepted formats, therefore raise error diff --git a/ipaserver/plugins/baseuser.py b/ipaserver/plugins/baseuser.py index bf24dbf..8fbec73 100644 --- a/ipaserver/plugins/baseuser.py +++ b/ipaserver/plugins/baseuser.py @@ -239,6 +239,10 @@ class baseuser(LDAPObject): cli_name='principal_expiration', label=_('Kerberos principal expiration'), ), + DateTime('krbpasswordexpiration?', + cli_name='password_expiration', + label=_('User password expiration'), + ), Str('mail*', cli_name='email', label=_('Email address'), diff --git a/ipaserver/plugins/user.py b/ipaserver/plugins/user.py index 2d29dfb..9eab521 100644 --- a/ipaserver/plugins/user.py +++ b/ipaserver/plugins/user.py @@ -261,7 +261,7 @@ class user(baseuser): ], 'ipapermdefaultattr': { 'krbprincipalkey', 'passwordhistory', 'sambalmpassword', - 'sambantpassword', 'userpassword' + 'sambantpassword', 'userpassword', 'krbpasswordexpiration' }, 'replaces': [ '(target = "ldap:///uid=*,cn=users,cn=accounts,$SUFFIX")(targetattr = "userpassword || krbprincipalkey || sambalmpassword || sambantpassword || passwordhistory")(version 3.0;acl "permission:Change a user password";allow (write) groupdn = "ldap:///cn=Change a user password,cn=permissions,cn=pbac,$SUFFIX";)',
-- Manage your subscription for the Freeipa-devel mailing list: https://www.redhat.com/mailman/listinfo/freeipa-devel Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code