From 51937cc571ec8ea5e782b8dcd45f0ec5fe0f310b Mon Sep 17 00:00:00 2001 From: Thierry Bordaz Date: Fri, 8 May 2015 10:41:44 +0200 Subject: User life cycle: Stage user Administrators permission/priviledge Creation of stage user administrator https://fedorahosted.org/freeipa/ticket/3813 Reviewed-By: David Kupka --- ACI.txt | 18 +++ API.txt | 12 +- install/share/60basev3.ldif | 4 +- install/share/delegation.ldif | 8 ++ install/updates/30-provisioning.update | 1 + install/updates/45-roles.update | 3 + ipalib/plugins/permission.py | 28 +++++ ipalib/plugins/stageuser.py | 123 ++++++++++++++++++++- .../install/plugins/update_managed_permissions.py | 12 +- ipatests/test_xmlrpc/test_old_permission_plugin.py | 2 + ipatests/test_xmlrpc/test_permission_plugin.py | 2 + 11 files changed, 206 insertions(+), 7 deletions(-) diff --git a/ACI.txt b/ACI.txt index 933b57cb9..534689c4b 100644 --- a/ACI.txt +++ b/ACI.txt @@ -212,6 +212,24 @@ dn: cn=services,cn=accounts,dc=ipa,dc=example aci: (targetattr = "createtimestamp || entryusn || ipakrbauthzdata || ipakrbprincipalalias || ipauniqueid || krbcanonicalname || krblastpwdchange || krbobjectreferences || krbpasswordexpiration || krbprincipalaliases || krbprincipalexpiration || krbprincipalname || managedby || memberof || modifytimestamp || objectclass || usercertificate")(targetfilter = "(objectclass=ipaservice)")(version 3.0;acl "permission:System: Read Services";allow (compare,read,search) userdn = "ldap:///all";) dn: cn=services,cn=accounts,dc=ipa,dc=example aci: (targetfilter = "(objectclass=ipaservice)")(version 3.0;acl "permission:System: Remove Services";allow (delete) groupdn = "ldap:///cn=System: Remove Services,cn=permissions,cn=pbac,dc=ipa,dc=example";) +dn: cn=staged users,cn=accounts,cn=provisioning,dc=ipa,dc=example +aci: (targetattr = "*")(target = "ldap:///uid=*,cn=staged users,cn=accounts,cn=provisioning,dc=ipa,dc=example")(targetfilter = "(objectclass=*)")(version 3.0;acl "permission:System: Add delete modify Stage Users by administrators";allow (add,delete,write) groupdn = "ldap:///cn=System: Add delete modify Stage Users by administrators,cn=permissions,cn=pbac,dc=ipa,dc=example";) +dn: dc=ipa,dc=example +aci: (target_to = "ldap:///cn=deleted users,cn=accounts,cn=provisioning,dc=ipa,dc=example")(target_from = "ldap:///cn=users,cn=accounts,dc=ipa,dc=example")(targetfilter = "(objectclass=nsContainer)")(version 3.0;acl "permission:System: Preserve an active user to a delete Users";allow (moddn) groupdn = "ldap:///cn=System: Preserve an active user to a delete Users,cn=permissions,cn=pbac,dc=ipa,dc=example";) +dn: dc=ipa,dc=example +aci: (target_to = "ldap:///cn=users,cn=accounts,dc=ipa,dc=example")(target_from = "ldap:///cn=deleted users,cn=accounts,cn=provisioning,dc=ipa,dc=example")(targetfilter = "(objectclass=nsContainer)")(version 3.0;acl "permission:System: Reactive delete users";allow (moddn) groupdn = "ldap:///cn=System: Reactive delete users,cn=permissions,cn=pbac,dc=ipa,dc=example";) +dn: cn=staged users,cn=accounts,cn=provisioning,dc=ipa,dc=example +aci: (targetattr = "krbprincipalkey || userpassword")(target = "ldap:///uid=*,cn=staged users,cn=accounts,cn=provisioning,dc=ipa,dc=example")(targetfilter = "(objectclass=*)")(version 3.0;acl "permission:System: Read Stage User kerberos principal key and password";allow (compare,read,search) groupdn = "ldap:///cn=System: Read Stage User kerberos principal key and password,cn=permissions,cn=pbac,dc=ipa,dc=example";) +dn: cn=staged users,cn=accounts,cn=provisioning,dc=ipa,dc=example +aci: (targetattr = "*")(target = "ldap:///uid=*,cn=staged users,cn=accounts,cn=provisioning,dc=ipa,dc=example")(targetfilter = "(objectclass=*)")(version 3.0;acl "permission:System: Read Stage Users by administrators";allow (compare,read,search) groupdn = "ldap:///cn=System: Read Stage Users by administrators,cn=permissions,cn=pbac,dc=ipa,dc=example";) +dn: cn=deleted users,cn=accounts,cn=provisioning,dc=ipa,dc=example +aci: (targetattr = "*")(target = "ldap:///uid=*,cn=deleted users,cn=accounts,cn=provisioning,dc=ipa,dc=example")(targetfilter = "(objectclass=posixaccount)")(version 3.0;acl "permission:System: Read/Write delete Users by administrators";allow (compare,read,search,write) groupdn = "ldap:///cn=System: Read/Write delete Users by administrators,cn=permissions,cn=pbac,dc=ipa,dc=example";) +dn: cn=deleted users,cn=accounts,cn=provisioning,dc=ipa,dc=example +aci: (targetattr = "krblastpwdchange || krbpasswordexpiration || krbprincipalkey || userpassword")(target = "ldap:///uid=*,cn=deleted users,cn=accounts,cn=provisioning,dc=ipa,dc=example")(targetfilter = "(objectclass=posixaccount)")(version 3.0;acl "permission:System: Reset userPassord and kerberos keys of delete users by administrator";allow (read,search,write) groupdn = "ldap:///cn=System: Reset userPassord and kerberos keys of delete users by administrator,cn=permissions,cn=pbac,dc=ipa,dc=example";) +dn: cn=users,cn=accounts,dc=ipa,dc=example +aci: (targetattr = "uid")(target = "ldap:///uid=*,cn=users,cn=accounts,dc=ipa,dc=example")(targetfilter = "(objectclass=posixaccount)")(version 3.0;acl "permission:System: Write Active Users RDN by administrators";allow (write) groupdn = "ldap:///cn=System: Write Active Users RDN by administrators,cn=permissions,cn=pbac,dc=ipa,dc=example";) +dn: cn=deleted users,cn=accounts,cn=provisioning,dc=ipa,dc=example +aci: (targetattr = "uid")(target = "ldap:///uid=*,cn=deleted users,cn=accounts,cn=provisioning,dc=ipa,dc=example")(targetfilter = "(objectclass=posixaccount)")(version 3.0;acl "permission:System: Write Delete Users RDN by administrators";allow (write) groupdn = "ldap:///cn=System: Write Delete Users RDN by administrators,cn=permissions,cn=pbac,dc=ipa,dc=example";) dn: cn=sudocmds,cn=sudo,dc=ipa,dc=example aci: (targetfilter = "(objectclass=ipasudocmd)")(version 3.0;acl "permission:System: Add Sudo Command";allow (add) groupdn = "ldap:///cn=System: Add Sudo Command,cn=permissions,cn=pbac,dc=ipa,dc=example";) dn: cn=sudocmds,cn=sudo,dc=ipa,dc=example diff --git a/API.txt b/API.txt index e6b63428a..0808f3c64 100644 --- a/API.txt +++ b/API.txt @@ -2775,7 +2775,7 @@ output: Output('result', , None) output: Output('summary', (, ), None) output: PrimaryKey('value', None, None) command: permission_add -args: 1,19,3 +args: 1,21,3 arg: Str('cn', attribute=True, cli_name='name', multivalue=False, pattern='^[-_ a-zA-Z0-9.]+$', primary_key=True, required=True) option: Str('addattr*', cli_name='addattr', exclude='webui') option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui') @@ -2787,6 +2787,8 @@ option: DNOrURL('ipapermlocation', alwaysask=True, attribute=True, autofill=Fals option: StrEnum('ipapermright', alwaysask=True, attribute=True, autofill=False, cli_name='right', deprecated_cli_aliases=set(['permissions']), multivalue=True, query=False, required=False, values=(u'read', u'search', u'compare', u'write', u'add', u'delete', u'all')) option: DNParam('ipapermtarget', attribute=True, cli_name='target', multivalue=False, required=False) option: Str('ipapermtargetfilter', attribute=True, cli_name='rawfilter', multivalue=True, required=False) +option: DNParam('ipapermtargetfrom', attribute=True, cli_name='targetfrom', multivalue=False, required=False) +option: DNParam('ipapermtargetto', attribute=True, cli_name='targetto', multivalue=False, required=False) option: Str('memberof', alwaysask=True, attribute=False, autofill=False, cli_name='memberof', multivalue=True, query=False, required=False) option: Flag('no_members', autofill=True, default=False, exclude='webui') option: Str('permissions', attribute=False, cli_name='permissions', multivalue=True, required=False) @@ -2831,7 +2833,7 @@ output: Output('result', , None) output: Output('summary', (, ), None) output: ListOfPrimaryKeys('value', None, None) command: permission_find -args: 1,24,4 +args: 1,26,4 arg: Str('criteria?', noextrawhitespace=False) option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui') option: Str('attrs', attribute=False, autofill=False, cli_name='attrs', multivalue=True, query=True, required=False) @@ -2846,6 +2848,8 @@ option: DNOrURL('ipapermlocation', attribute=True, autofill=False, cli_name='sub option: StrEnum('ipapermright', attribute=True, autofill=False, cli_name='right', deprecated_cli_aliases=set(['permissions']), multivalue=True, query=True, required=False, values=(u'read', u'search', u'compare', u'write', u'add', u'delete', u'all')) option: DNParam('ipapermtarget', attribute=True, autofill=False, cli_name='target', multivalue=False, query=True, required=False) option: Str('ipapermtargetfilter', attribute=True, autofill=False, cli_name='rawfilter', multivalue=True, query=True, required=False) +option: DNParam('ipapermtargetfrom', attribute=True, autofill=False, cli_name='targetfrom', multivalue=False, query=True, required=False) +option: DNParam('ipapermtargetto', attribute=True, autofill=False, cli_name='targetto', multivalue=False, query=True, required=False) option: Str('memberof', attribute=False, autofill=False, cli_name='memberof', multivalue=True, query=True, required=False) option: Flag('no_members', autofill=True, default=False, exclude='webui') option: Str('permissions', attribute=False, autofill=False, cli_name='permissions', multivalue=True, query=True, required=False) @@ -2862,7 +2866,7 @@ output: ListOfEntries('result', (, ), Gettext('A list output: Output('summary', (, ), None) output: Output('truncated', , None) command: permission_mod -args: 1,24,3 +args: 1,26,3 arg: Str('cn', attribute=True, cli_name='name', multivalue=False, pattern='^[-_ a-zA-Z0-9.:/]+$', primary_key=True, query=True, required=True) option: Str('addattr*', cli_name='addattr', exclude='webui') option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui') @@ -2877,6 +2881,8 @@ option: DNOrURL('ipapermlocation', attribute=True, autofill=False, cli_name='sub option: StrEnum('ipapermright', attribute=True, autofill=False, cli_name='right', deprecated_cli_aliases=set(['permissions']), multivalue=True, required=False, values=(u'read', u'search', u'compare', u'write', u'add', u'delete', u'all')) option: DNParam('ipapermtarget', attribute=True, autofill=False, cli_name='target', multivalue=False, required=False) option: Str('ipapermtargetfilter', attribute=True, autofill=False, cli_name='rawfilter', multivalue=True, required=False) +option: DNParam('ipapermtargetfrom', attribute=True, autofill=False, cli_name='targetfrom', multivalue=False, required=False) +option: DNParam('ipapermtargetto', attribute=True, autofill=False, cli_name='targetto', multivalue=False, required=False) option: Str('memberof', attribute=False, autofill=False, cli_name='memberof', multivalue=True, required=False) option: Flag('no_members', autofill=True, default=False, exclude='webui') option: Str('permissions', attribute=False, autofill=False, cli_name='permissions', multivalue=True, required=False) diff --git a/install/share/60basev3.ldif b/install/share/60basev3.ldif index 4efb1fe8b..eb1c1298b 100644 --- a/install/share/60basev3.ldif +++ b/install/share/60basev3.ldif @@ -54,6 +54,8 @@ attributeTypes: (2.16.840.1.113730.3.8.11.55 NAME 'ipaSecretKey' DESC 'Encrypted attributeTypes: (2.16.840.1.113730.3.8.11.61 NAME 'ipaWrappingKey' DESC 'PKCS#11 URI of the wrapping key' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'IPA v4.1' ) attributeTypes: (2.16.840.1.113730.3.8.11.64 NAME 'ipaSecretKeyRef' DESC 'DN of the ipa key object' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'IPA v4.1' ) attributeTypes: (2.16.840.1.113730.3.8.11.65 NAME 'ipaWrappingMech' DESC 'PKCS#11 wrapping mechanism equivalent to CK_MECHANISM_TYPE' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'IPA v4.1') +attributeTypes: (2.16.840.1.113730.3.8.11.70 NAME 'ipaPermTargetTo' DESC 'Destination location to move an entry IPA permission ACI' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-ORIGIN 'IPA v4.0' ) +attributeTypes: (2.16.840.1.113730.3.8.11.71 NAME 'ipaPermTargetFrom' DESC 'Source location from where moving an entry IPA permission ACI' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-ORIGIN 'IPA v4.0' ) objectClasses: (2.16.840.1.113730.3.8.12.1 NAME 'ipaExternalGroup' SUP top STRUCTURAL MUST ( cn ) MAY ( ipaExternalMember $ memberOf $ description $ owner) X-ORIGIN 'IPA v3' ) objectClasses: (2.16.840.1.113730.3.8.12.2 NAME 'ipaNTUserAttrs' SUP top AUXILIARY MUST ( ipaNTSecurityIdentifier ) MAY ( ipaNTHash $ ipaNTLogonScript $ ipaNTProfilePath $ ipaNTHomeDirectory $ ipaNTHomeDirectoryDrive ) X-ORIGIN 'IPA v3' ) objectClasses: (2.16.840.1.113730.3.8.12.3 NAME 'ipaNTGroupAttrs' SUP top AUXILIARY MUST ( ipaNTSecurityIdentifier ) X-ORIGIN 'IPA v3' ) @@ -71,7 +73,7 @@ objectClasses: (2.16.840.1.113730.3.8.12.16 NAME 'ipaDomainIDRange' SUP ipaIDran objectClasses: (2.16.840.1.113730.3.8.12.17 NAME 'ipaTrustedADDomainRange' SUP ipaIDrange STRUCTURAL MUST ( ipaBaseRID $ ipaNTTrustedDomainSID ) X-ORIGIN 'IPA v3' ) objectClasses: (2.16.840.1.113730.3.8.12.19 NAME 'ipaUserAuthTypeClass' SUP top AUXILIARY DESC 'Class for authentication methods definition' MAY ipaUserAuthType X-ORIGIN 'IPA v3') objectClasses: (2.16.840.1.113730.3.8.12.20 NAME 'ipaUser' AUXILIARY MUST ( uid ) MAY ( userClass ) X-ORIGIN 'IPA v3' ) -objectClasses: (2.16.840.1.113730.3.8.12.21 NAME 'ipaPermissionV2' DESC 'IPA Permission objectclass, version 2' SUP ipaPermission AUXILIARY MUST ( ipaPermBindRuleType $ ipaPermLocation ) MAY ( ipaPermDefaultAttr $ ipaPermIncludedAttr $ ipaPermExcludedAttr $ ipaPermRight $ ipaPermTargetFilter $ ipaPermTarget ) X-ORIGIN 'IPA v4.0' ) +objectClasses: (2.16.840.1.113730.3.8.12.21 NAME 'ipaPermissionV2' DESC 'IPA Permission objectclass, version 2' SUP ipaPermission AUXILIARY MUST ( ipaPermBindRuleType $ ipaPermLocation ) MAY ( ipaPermDefaultAttr $ ipaPermIncludedAttr $ ipaPermExcludedAttr $ ipaPermRight $ ipaPermTargetFilter $ ipaPermTarget $ ipaPermTargetTo $ ipaPermTargetFrom ) X-ORIGIN 'IPA v4.0' ) objectClasses: (2.16.840.1.113730.3.8.12.22 NAME 'ipaAllowedOperations' SUP top AUXILIARY DESC 'Class to apply access controls to arbitrary operations' MAY ( ipaAllowedToPerform $ ipaProtectedOperation ) X-ORIGIN 'IPA v4.0') objectClasses: (2.16.840.1.113730.3.8.12.24 NAME 'ipaPublicKeyObject' DESC 'Wrapped public keys' SUP top AUXILIARY MUST ( ipaPublicKey ) X-ORIGIN 'IPA v4.1' ) objectClasses: (2.16.840.1.113730.3.8.12.25 NAME 'ipaPrivateKeyObject' DESC 'Wrapped private keys' SUP top AUXILIARY MUST ( ipaPrivateKey $ ipaWrappingKey $ ipaWrappingMech ) X-ORIGIN 'IPA v4.1' ) diff --git a/install/share/delegation.ldif b/install/share/delegation.ldif index 66a9f1b07..76e726fb9 100644 --- a/install/share/delegation.ldif +++ b/install/share/delegation.ldif @@ -129,6 +129,14 @@ objectClass: nestedgroup cn: Host Enrollment description: Host Enrollment +dn: cn=Stage User Administrators,cn=privileges,cn=pbac,$SUFFIX +changetype: add +objectClass: top +objectClass: groupofnames +objectClass: nestedgroup +cn: Stage User Administrators +description: Stage User Administrators + ############################################ # Default permissions. ############################################ diff --git a/install/updates/30-provisioning.update b/install/updates/30-provisioning.update index f1666ff3a..b8ec80e00 100644 --- a/install/updates/30-provisioning.update +++ b/install/updates/30-provisioning.update @@ -26,6 +26,7 @@ dn: cn=staged users,cn=accounts,cn=provisioning,$SUFFIX add:aci: (targetattr="userPassword || krbPrincipalKey")(version 3.0; acl "Search existence of password and kerberos keys"; allow(read, search) userdn = "ldap:///uid=admin,cn=users,cn=accounts,$SUFFIX";) # This is used for the admin to reset the delete users credential +# No one is allowed to add entry in Delete container dn: cn=deleted users,cn=accounts,cn=provisioning,$SUFFIX add:aci: (targetattr="userPassword || krbPrincipalKey || krbPasswordExpiration || krbLastPwdChange")(version 3.0; acl "Admins allowed to reset password and kerberos keys"; allow(read, search, write) userdn = "ldap:///uid=admin,cn=users,cn=accounts,$SUFFIX";) add:aci: (targetattr = "*")(version 3.0; acl "No one can add entry in Delete container"; deny (add) userdn = "ldap:///all";) diff --git a/install/updates/45-roles.update b/install/updates/45-roles.update index 3442c7bf8..eb50e2b9c 100644 --- a/install/updates/45-roles.update +++ b/install/updates/45-roles.update @@ -28,6 +28,9 @@ add: member: cn=User Administrator,cn=roles,cn=accounts,$SUFFIX dn: cn=Group Administrators,cn=privileges,cn=pbac,$SUFFIX add: member: cn=User Administrator,cn=roles,cn=accounts,$SUFFIX +dn: cn=Stage User Administrators,cn=privileges,cn=pbac,$SUFFIX +add: member: cn=User Administrator,cn=roles,cn=accounts,$SUFFIX + dn: cn=IT Specialist,cn=roles,cn=accounts,$SUFFIX default:objectClass: groupofnames default:objectClass: nestedgroup diff --git a/ipalib/plugins/permission.py b/ipalib/plugins/permission.py index 3895d8eae..f46affc34 100644 --- a/ipalib/plugins/permission.py +++ b/ipalib/plugins/permission.py @@ -302,6 +302,22 @@ class permission(baseldap.LDAPObject): '(must be in the subtree, but may not yet exist)'), ), + DNParam( + 'ipapermtargetto?', + cli_name='targetto', + label=_('Target DN subtree'), + doc=_('Optional DN subtree where an entry can be moved to ' + '(must be in the subtree, but may not yet exist)'), + ), + + DNParam( + 'ipapermtargetfrom?', + cli_name='targetfrom', + label=_('Origin DN subtree'), + doc=_('Optional DN subtree from where an entry can be moved ' + '(must be in the subtree, but may not yet exist)'), + ), + Str('memberof*', label=_('Member of group'), # FIXME: Does this label make sense? doc=_('Target members of a group (sets memberOf targetfilter)'), @@ -532,6 +548,18 @@ class permission(baseldap.LDAPObject): aci_parts.append("(target = \"%s\")" % 'ldap:///%s' % ipapermtarget) + # target_to + ipapermtargetto = entry.single_value.get('ipapermtargetto') + if ipapermtargetto: + aci_parts.append("(target_to = \"%s\")" % + 'ldap:///%s' % ipapermtargetto) + + # target_from + ipapermtargetfrom = entry.single_value.get('ipapermtargetfrom') + if ipapermtargetfrom: + aci_parts.append("(target_from = \"%s\")" % + 'ldap:///%s' % ipapermtargetfrom) + # targetfilter ipapermtargetfilter = entry.get('ipapermtargetfilter') if ipapermtargetfilter: diff --git a/ipalib/plugins/stageuser.py b/ipalib/plugins/stageuser.py index 01166af30..c4d9bb687 100644 --- a/ipalib/plugins/stageuser.py +++ b/ipalib/plugins/stageuser.py @@ -111,7 +111,128 @@ class stageuser(baseuser): label_singular = _('Stage User') object_name = _('stage user') object_name_plural = _('stage users') - managed_permissions = {} + managed_permissions = { + # + # Stage container + # + # Stage user administrators allowed to read kerberos/password + # when the user is activated (to copy them in the active entry) + 'System: Read Stage User kerberos principal key and password': { + 'ipapermlocation': DN(baseuser.stage_container_dn, api.env.basedn), + 'ipapermbindruletype': 'permission', + 'ipapermtarget': DN('uid=*', baseuser.stage_container_dn, api.env.basedn), + 'ipapermtargetfilter': {'(objectclass=*)'}, + 'ipapermright': {'read', 'search', 'compare'}, + 'ipapermdefaultattr': { + 'userPassword', 'krbPrincipalKey', + }, + 'default_privileges': {'Stage User Administrators'}, + }, + # Stage user administrator allowed to create/delete stage users and + # to update them + 'System: Add delete modify Stage Users by administrators': { + 'ipapermlocation': DN(baseuser.stage_container_dn, api.env.basedn), + 'ipapermbindruletype': 'permission', + 'ipapermtarget': DN('uid=*', baseuser.stage_container_dn, api.env.basedn), + 'ipapermtargetfilter': {'(objectclass=*)'}, + 'ipapermright': {'add','delete','write'}, + 'ipapermdefaultattr': {'*'}, + 'default_privileges': {'Stage User Administrators'}, + }, + # Stage user administrator allowed to read any attributes + # of stage users + 'System: Read Stage Users by administrators': { + 'ipapermlocation': DN(baseuser.stage_container_dn, api.env.basedn), + 'ipapermbindruletype': 'permission', + 'ipapermtarget': DN('uid=*', baseuser.stage_container_dn, api.env.basedn), + 'ipapermtargetfilter': {'(objectclass=*)'}, + 'ipapermright': {'read', 'search', 'compare'}, + 'ipapermdefaultattr': {'*'}, + 'default_privileges': {'Stage User Administrators'}, + }, + # + # Delete container + # + # Stage user administrator allow to read all attributes (when delete + # an active user with preserve flag) + # We also need to reset some of the attributes syntax DN/credential + # so allowed write on all the attributes + 'System: Read/Write delete Users by administrators': { + 'ipapermlocation': DN(baseuser.delete_container_dn, api.env.basedn), + 'ipapermbindruletype': 'permission', + 'ipapermtarget': DN('uid=*', baseuser.delete_container_dn, api.env.basedn), + 'ipapermtargetfilter': {'(objectclass=posixaccount)'}, + 'ipapermright': {'read', 'search', 'compare', 'write'}, + 'ipapermdefaultattr': {'*'}, + 'default_privileges': {'Stage User Administrators'}, + }, + # + # Stage user administrator allows to write the RDN + # when the delete user is undeleted + 'System: Write Delete Users RDN by administrators': { + 'ipapermlocation': DN(baseuser.delete_container_dn, api.env.basedn), + 'ipapermbindruletype': 'permission', + 'ipapermtarget': DN('uid=*', baseuser.delete_container_dn, api.env.basedn), + 'ipapermtargetfilter': {'(objectclass=posixaccount)'}, + 'ipapermright': {'write'}, + 'ipapermdefaultattr': {'uid'}, + 'default_privileges': {'Stage User Administrators'}, + }, + # Stage user administrator allows to reset kerberos/password + # when a deleted user is preserved + 'System: Reset userPassord and kerberos keys of delete users by administrator': { + 'ipapermlocation': DN(baseuser.delete_container_dn, api.env.basedn), + 'ipapermbindruletype': 'permission', + 'ipapermtarget': DN('uid=*', baseuser.delete_container_dn, api.env.basedn), + 'ipapermtargetfilter': {'(objectclass=posixaccount)'}, + 'ipapermright': {'read', 'search', 'write'}, + 'ipapermdefaultattr': { + 'userPassword', 'krbPrincipalKey','krbPasswordExpiration','krbLastPwdChange' + }, + 'default_privileges': {'Stage User Administrators'}, + }, + # + # Active container + # + # Stage user administrators need write right on RDN when + # the active user is deleted (preserved) + 'System: Write Active Users RDN by administrators': { + 'ipapermlocation': DN(baseuser.active_container_dn, api.env.basedn), + 'ipapermbindruletype': 'permission', + 'ipapermtarget': DN('uid=*', baseuser.active_container_dn, api.env.basedn), + 'ipapermtargetfilter': {'(objectclass=posixaccount)'}, + 'ipapermright': {'write'}, + 'ipapermdefaultattr': {'uid'}, + 'default_privileges': {'Stage User Administrators'}, + }, + # + # Cross containers autorization + # + # Stage user administrators need a moddn right when preserving + # a delete user. + # Note: targetfilter is the target parent container + 'System: Preserve an active user to a delete Users': { + 'ipapermlocation': DN(api.env.basedn), + 'ipapermbindruletype': 'permission', + 'ipapermtargetfrom': DN(baseuser.active_container_dn, api.env.basedn), + 'ipapermtargetto': DN(baseuser.delete_container_dn, api.env.basedn), + 'ipapermtargetfilter': {'(objectclass=nsContainer)'}, + 'ipapermright': {'moddn'}, + 'default_privileges': {'Stage User Administrators'}, + }, + # Stage user administrators need a moddn right when undelete + # a delete user. + # Note: targetfilter is the target parent container + 'System: Reactive delete users': { + 'ipapermlocation': DN(api.env.basedn), + 'ipapermbindruletype': 'permission', + 'ipapermtargetfrom': DN(baseuser.delete_container_dn, api.env.basedn), + 'ipapermtargetto': DN(baseuser.active_container_dn, api.env.basedn), + 'ipapermtargetfilter': {'(objectclass=nsContainer)'}, + 'ipapermright': {'moddn'}, + 'default_privileges': {'Stage User Administrators'}, + }, + } @register() class stageuser_add(baseuser_add): diff --git a/ipaserver/install/plugins/update_managed_permissions.py b/ipaserver/install/plugins/update_managed_permissions.py index 9ca3eac6c..1fbfd9993 100644 --- a/ipaserver/install/plugins/update_managed_permissions.py +++ b/ipaserver/install/plugins/update_managed_permissions.py @@ -40,13 +40,13 @@ dict of the same format is defined in this module. The permission name must start with the "System:" prefix. The template dictionary can have the following keys: -* ipapermtarget, ipapermtargetfilter, ipapermlocation, ipapermright, objectclass +* ipapermtarget, ipapermtargetfilter, ipapermlocation, ipapermright, ,ipapermtargetto, ipapermtargetfrom, objectclass - Directly used as attributes on the permission. - Replaced when upgrading an existing permission - If not specified, these default to the defaults of a permission of the corresponding --type, or, if non_object is specified, or if not on an object, to general permission defaults . - - ipapermlocation and ipapermtarget must be DNs + - ipapermlocation, ipatargetto, ipapermtargetfrom, ipapermtarget must be DNs - ipapermtargetfilter and objectclass must be iterables of strings * ipapermbindruletype - Directly used as attribute on the permission. @@ -670,6 +670,14 @@ class update_managed_permissions(Updater): if ipapermtarget is not None: entry['ipapermtarget'] = ipapermtarget + ipapermtargetto = template.pop('ipapermtargetto', None) + if ipapermtargetto is not None: + entry['ipapermtargetto'] = ipapermtargetto + + ipapermtargetfrom = template.pop('ipapermtargetfrom', None) + if ipapermtargetfrom is not None: + entry['ipapermtargetfrom'] = ipapermtargetfrom + # Attributes from template bindruletype = template.pop('ipapermbindruletype', 'permission') if is_new: diff --git a/ipatests/test_xmlrpc/test_old_permission_plugin.py b/ipatests/test_xmlrpc/test_old_permission_plugin.py index e69c4f824..b8f06e28c 100644 --- a/ipatests/test_xmlrpc/test_old_permission_plugin.py +++ b/ipatests/test_xmlrpc/test_old_permission_plugin.py @@ -76,6 +76,8 @@ permission3_attributelevelrights = { 'ipapermright': u'rscwo', 'ipapermtarget': u'rscwo', 'ipapermtargetfilter': u'rscwo', + 'ipapermtargetto': u'rscwo', + 'ipapermtargetfrom': u'rscwo', } privilege1 = u'testpriv1' diff --git a/ipatests/test_xmlrpc/test_permission_plugin.py b/ipatests/test_xmlrpc/test_permission_plugin.py index 9946378fb..4503b0d5a 100644 --- a/ipatests/test_xmlrpc/test_permission_plugin.py +++ b/ipatests/test_xmlrpc/test_permission_plugin.py @@ -81,6 +81,8 @@ permission3_attributelevelrights = { 'nsaccountlock': u'rscwo', 'description': u'rscwo', 'ipapermtargetfilter': u'rscwo', + 'ipapermtargetto': u'rscwo', + 'ipapermtargetfrom': u'rscwo', 'ipapermbindruletype': u'rscwo', 'ipapermlocation': u'rscwo', 'ipapermtarget': u'rscwo', -- cgit