Re-implement access control using an updated model.

The new model is based on permssions, privileges and roles.
Most importantly it corrects the reverse membership that caused problems
in the previous implementation. You add permission to privileges and
privileges to roles, not the other way around (even though it works that
way behind the scenes).

A permission object is a combination of a simple group and an aci.
The linkage between the aci and the permission is the description of
the permission. This shows as the name/description of the aci.

ldap:///self and groups granting groups (v1-style) are not supported by
this model (it will be provided separately).

This makes the aci plugin internal only.

ticket 445
This commit is contained in:
Rob Crittenden 2010-12-01 11:23:52 -05:00 committed by Simo Sorce
parent 85d5bfd1b1
commit 4ad8055341
32 changed files with 3074 additions and 2526 deletions

View File

@ -39,6 +39,7 @@ dn: cn=services,cn=accounts,$SUFFIX
changetype: modify
add: aci
aci: (targetattr="krbPrincipalName || krbCanonicalName || krbUPEnabled || krbPrincipalKey || krbTicketPolicyReference || krbPrincipalExpiration || krbPasswordExpiration || krbPwdPolicyReference || krbPrincipalType || krbPwdHistory || krbLastPwdChange || krbPrincipalAliases || krbExtraData")(version 3.0; acl "KDC System Account"; allow (read, search, compare, write) userdn="ldap:///uid=kdc,cn=sysaccounts,cn=etc,$SUFFIX";)
aci: (targetattr = "krbPrincipalKey || krbLastPwdChange")(target = "ldap:///krbprincipalname=*,cn=services,cn=accounts,$SUFFIX")(version 3.0;acl "Admins can manage service keytab";allow (write) groupdn = "ldap:///cn=admins,cn=groups,cn=accounts,$SUFFIX";)
# Define which hosts can edit services
# The managedby attribute stores the DN of hosts that are allowed to manage
@ -63,3 +64,7 @@ changetype: modify
add: aci
aci: (targetattr="userCertificate || krbPrincipalKey")(version 3.0; acl "Hosts can manage other host Certificates and kerberos keys"; allow(write) userattr = "parent[0,1].managedby#USERDN";)
dn: cn=computers,cn=accounts,$SUFFIX
changetype: modify
add: aci
aci: (targetattr = "krbPrincipalKey || krbLastPwdChange")(target = "ldap:///fqdn=*,cn=computers,cn=accounts,$SUFFIX")(version 3.0;acl "Admins can manage host keytab";allow (write) groupdn = "ldap:///cn=admins,cn=groups,cn=accounts,$SUFFIX";)

View File

@ -1,348 +1,757 @@
dn: cn=rolegroups,cn=accounts,$SUFFIX
############################################
# Configure the DIT
############################################
dn: cn=roles,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: nsContainer
cn: rolegroups
cn: roles
dn: cn=taskgroups,cn=accounts,$SUFFIX
dn: cn=privileges,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: nsContainer
cn: taskgroups
cn: privileges
dn: cn=permissions,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: nsContainer
cn: permissions
############################################
# Add the default roles
dn: cn=helpdesk,cn=rolegroups,cn=accounts,$SUFFIX
############################################
dn: cn=helpdesk,cn=roles,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
objectClass: nestedgroup
cn: helpdesk
description: Helpdesk
dn: cn=useradmin,cn=rolegroups,cn=accounts,$SUFFIX
############################################
# Add the default privileges
############################################
dn: cn=useradmin,cn=privileges,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
objectClass: nestedgroup
cn: useradmin
description: User Administrators
dn: cn=groupadmin,cn=rolegroups,cn=accounts,$SUFFIX
dn: cn=groupadmin,cn=privileges,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
objectClass: nestedgroup
cn: groupadmin
description: Group Administrators
dn: cn=hostadmin,cn=rolegroups,cn=accounts,$SUFFIX
dn: cn=hostadmin,cn=privileges,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
objectClass: nestedgroup
cn: hostadmin
description: Host Administrators
dn: cn=hostgroupadmin,cn=rolegroups,cn=accounts,$SUFFIX
dn: cn=hostgroupadmin,cn=privileges,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
objectClass: nestedgroup
cn: hostgroupadmin
description: Host Group Administrators
dn: cn=delegationadmin,cn=rolegroups,cn=accounts,$SUFFIX
dn: cn=delegationadmin,cn=privileges,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
objectClass: nestedgroup
cn: delegationadmin
description: Role administration
dn: cn=serviceadmin,cn=rolegroups,cn=accounts,$SUFFIX
dn: cn=serviceadmin,cn=privileges,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
objectClass: nestedgroup
cn: serviceadmin
description: Service Administrators
dn: cn=automountadmin,cn=rolegroups,cn=accounts,$SUFFIX
dn: cn=automountadmin,cn=privileges,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
objectClass: nestedgroup
cn: automountadmin
description: Automount Administrators
dn: cn=netgroupadmin,cn=rolegroups,cn=accounts,$SUFFIX
dn: cn=netgroupadmin,cn=privileges,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
objectClass: nestedgroup
cn: netgroupadmin
description: Netgroups Administrators
dn: cn=dnsadmin,cn=rolegroups,cn=accounts,$SUFFIX
dn: cn=certadmin,cn=privileges,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
cn: dnsadmin
description: DNS Administrators
objectClass: nestedgroup
cn: certadmin
description: Certificate Administrators
dn: cn=dnsserver,cn=rolegroups,cn=accounts,$SUFFIX
dn: cn=replicaadmin,cn=privileges,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
cn: dnsserver
description: DNS Servers
objectClass: nestedgroup
cn: replicaadmin
description: Replication Administrators
member: cn=admins,cn=groups,cn=accounts,$SUFFIX
dn: cn=addusers,cn=taskgroups,cn=accounts,$SUFFIX
dn: cn=enrollhost,cn=privileges,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
objectClass: nestedgroup
cn: enrollhost
description: Host Enrollment
dn: cn=entitlementadmin,cn=privileges,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
objectClass: nestedgroup
cn: entitlementadmin
description: Entitlement Administrators
############################################
# Default permissions.
############################################
# User administration
dn: cn=addusers,cn=permissions,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
cn: addusers
description: Add Users
member: cn=useradmin,cn=rolegroups,cn=accounts,$SUFFIX
member: cn=useradmin,cn=privileges,cn=accounts,$SUFFIX
dn: cn=change_password,cn=taskgroups,cn=accounts,$SUFFIX
dn: cn=change_password,cn=permissions,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
cn: change_password
description: Change a user password
member: cn=useradmin,cn=rolegroups,cn=accounts,$SUFFIX
member: cn=useradmin,cn=privileges,cn=accounts,$SUFFIX
dn: cn=add_user_to_default_group,cn=taskgroups,cn=accounts,$SUFFIX
dn: cn=add_user_to_default_group,cn=permissions,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
cn: add_user_to_default_group
description: Add user to default group
member: cn=useradmin,cn=rolegroups,cn=accounts,$SUFFIX
member: cn=useradmin,cn=privileges,cn=accounts,$SUFFIX
dn: cn=removeusers,cn=taskgroups,cn=accounts,$SUFFIX
dn: cn=removeusers,cn=permissions,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
cn: removeusers
description: Remove Users
member: cn=useradmin,cn=rolegroups,cn=accounts,$SUFFIX
member: cn=useradmin,cn=privileges,cn=accounts,$SUFFIX
dn: cn=modifyusers,cn=taskgroups,cn=accounts,$SUFFIX
dn: cn=modifyusers,cn=permissions,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
cn: modifyusers
description: Modify Users
member: cn=useradmin,cn=rolegroups,cn=accounts,$SUFFIX
member: cn=useradmin,cn=privileges,cn=accounts,$SUFFIX
# Add the taskgroups referenced by the ACIs for group administration
dn: cn=addgroups,cn=taskgroups,cn=accounts,$SUFFIX
# Group administration
dn: cn=addgroups,cn=permissions,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
cn: addgroups
description: Add Groups
member: cn=groupadmin,cn=rolegroups,cn=accounts,$SUFFIX
member: cn=groupadmin,cn=privileges,cn=accounts,$SUFFIX
dn: cn=removegroups,cn=taskgroups,cn=accounts,$SUFFIX
dn: cn=removegroups,cn=permissions,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
cn: removegroups
description: Remove Groups
member: cn=groupadmin,cn=rolegroups,cn=accounts,$SUFFIX
member: cn=groupadmin,cn=privileges,cn=accounts,$SUFFIX
dn: cn=modifygroups,cn=taskgroups,cn=accounts,$SUFFIX
dn: cn=modifygroups,cn=permissions,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
cn: modifygroups
description: Modify Groups
member: cn=groupadmin,cn=rolegroups,cn=accounts,$SUFFIX
member: cn=groupadmin,cn=privileges,cn=accounts,$SUFFIX
dn: cn=modifygroupmembership,cn=taskgroups,cn=accounts,$SUFFIX
dn: cn=modifygroupmembership,cn=permissions,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
cn: modifygroupmembership
description: Modify Group membership
member: cn=groupadmin,cn=rolegroups,cn=accounts,$SUFFIX
member: cn=groupadmin,cn=privileges,cn=accounts,$SUFFIX
# Add the taskgroups referenced by the ACIs for host administration
dn: cn=addhosts,cn=taskgroups,cn=accounts,$SUFFIX
# Host administration
dn: cn=addhosts,cn=permissions,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
cn: addhosts
description: Add Hosts
member: cn=hostadmin,cn=rolegroups,cn=accounts,$SUFFIX
member: cn=hostadmin,cn=privileges,cn=accounts,$SUFFIX
dn: cn=removehosts,cn=taskgroups,cn=accounts,$SUFFIX
dn: cn=removehosts,cn=permissions,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
cn: removehosts
description: Remove Hosts
member: cn=hostadmin,cn=rolegroups,cn=accounts,$SUFFIX
member: cn=hostadmin,cn=privileges,cn=accounts,$SUFFIX
dn: cn=modifyhosts,cn=taskgroups,cn=accounts,$SUFFIX
dn: cn=modifyhosts,cn=permissions,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
cn: modifyhosts
description: Modify Hosts
member: cn=hostadmin,cn=rolegroups,cn=accounts,$SUFFIX
member: cn=hostadmin,cn=privileges,cn=accounts,$SUFFIX
# Add the taskgroups referenced by the ACIs for hostgroup administration
dn: cn=addhostgroups,cn=taskgroups,cn=accounts,$SUFFIX
# Hostgroup administration
dn: cn=addhostgroups,cn=permissions,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
cn: addhostgroups
description: Add Host Groups
member: cn=hostgroupadmin,cn=rolegroups,cn=accounts,$SUFFIX
description: Add Hostgroups
member: cn=hostgroupadmin,cn=privileges,cn=accounts,$SUFFIX
dn: cn=removehostgroups,cn=taskgroups,cn=accounts,$SUFFIX
dn: cn=removehostgroups,cn=permissions,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
cn: removehostgroups
description: Remove Host Groups
member: cn=hostgroupadmin,cn=rolegroups,cn=accounts,$SUFFIX
description: Remove Hostgroups
member: cn=hostgroupadmin,cn=privileges,cn=accounts,$SUFFIX
dn: cn=modifyhostgroups,cn=taskgroups,cn=accounts,$SUFFIX
dn: cn=modifyhostgroups,cn=permissions,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
cn: modifyhostgroups
description: Modify Host Groups
member: cn=hostgroupadmin,cn=rolegroups,cn=accounts,$SUFFIX
description: Modify Hostgroups
member: cn=hostgroupadmin,cn=privileges,cn=accounts,$SUFFIX
dn: cn=modifyhostgroupmembership,cn=taskgroups,cn=accounts,$SUFFIX
dn: cn=modifyhostgroupmembership,cn=permissions,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
cn: modifyhostgroupmembership
description: Modify Host Group membership
member: cn=hostgroupadmin,cn=rolegroups,cn=accounts,$SUFFIX
description: Modify Hostgroup membership
member: cn=hostgroupadmin,cn=privileges,cn=accounts,$SUFFIX
# Add the taskgroups referenced by the ACIs for service administration
dn: cn=addservices,cn=taskgroups,cn=accounts,$SUFFIX
# Service administration
dn: cn=addservices,cn=permissions,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
cn: addservices
description: Add Services
member: cn=serviceadmin,cn=rolegroups,cn=accounts,$SUFFIX
member: cn=serviceadmin,cn=privileges,cn=accounts,$SUFFIX
dn: cn=removeservices,cn=taskgroups,cn=accounts,$SUFFIX
dn: cn=removeservices,cn=permissions,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
cn: removeservices
description: Remove Services
member: cn=serviceadmin,cn=rolegroups,cn=accounts,$SUFFIX
member: cn=serviceadmin,cn=privileges,cn=accounts,$SUFFIX
# Add the taskgroups referenced by the ACIs for delegation administration
# This just lets one manage taskgroup membership and create and delete roles
dn: cn=addroles,cn=taskgroups,cn=accounts,$SUFFIX
dn: cn=modifyservices,cn=permissions,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
cn: addhrole
description: Add Roles
member: cn=delegationadmin,cn=rolegroups,cn=accounts,$SUFFIX
cn: modifyservices
description: Modify Services
member: cn=serviceadmin,cn=privileges,cn=accounts,$SUFFIX
dn: cn=removeroles,cn=taskgroups,cn=accounts,$SUFFIX
# Delegation administration
dn: cn=addroles,cn=permissions,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
cn: addroles
description: Add Roles
member: cn=delegationadmin,cn=privileges,cn=accounts,$SUFFIX
dn: cn=removeroles,cn=permissions,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
cn: removeroles
description: Remove Roles
member: cn=delegationadmin,cn=rolegroups,cn=accounts,$SUFFIX
member: cn=delegationadmin,cn=privileges,cn=accounts,$SUFFIX
dn: cn=modifyroles,cn=taskgroups,cn=accounts,$SUFFIX
dn: cn=modifyroles,cn=permissions,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
cn: modifyroles
description: Modify Roles
member: cn=delegationadmin,cn=rolegroups,cn=accounts,$SUFFIX
member: cn=delegationadmin,cn=privileges,cn=accounts,$SUFFIX
dn: cn=modifyrolegroupmembership,cn=taskgroups,cn=accounts,$SUFFIX
dn: cn=modifyrolemembership,cn=permissions,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
cn: modifyrolegroupmembership
cn: modifyrolemembership
description: Modify Role Group membership
member: cn=delegationadmin,cn=rolegroups,cn=accounts,$SUFFIX
member: cn=delegationadmin,cn=privileges,cn=accounts,$SUFFIX
dn: cn=modifytaskgroupmembership,cn=taskgroups,cn=accounts,$SUFFIX
dn: cn=modifyprivilegemembership,cn=permissions,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: nestedgroup
cn: modifyprivilegemembership
description: Modify privilege membership
member: cn=delegationadmin,cn=privileges,cn=accounts,$SUFFIX
# Automount administration
dn: cn=addautomountmaps,cn=permissions,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
cn: modifytaskgroupmembership
description: Modify Task Group membership
member: cn=delegationadmin,cn=rolegroups,cn=accounts,$SUFFIX
cn: addautomountmaps
description: Add Automount maps
member: cn=automountadmin,cn=privileges,cn=accounts,$SUFFIX
# Add the taskgroups referenced by the ACIs for automount administration
dn: cn=addautomount,cn=taskgroups,cn=accounts,$SUFFIX
dn: cn=removeautomountmaps,cn=permissions,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
cn: addautomount
description: Add Automount maps/keys
member: cn=automountadmin,cn=rolegroups,cn=accounts,$SUFFIX
cn: removeautomountmaps
description: Remove Automount maps
member: cn=automountadmin,cn=privileges,cn=accounts,$SUFFIX
dn: cn=removeautomount,cn=taskgroups,cn=accounts,$SUFFIX
dn: cn=addautomountkeys,cn=permissions,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
cn: removeautomount
description: Remove Automount maps/keys
member: cn=automountadmin,cn=rolegroups,cn=accounts,$SUFFIX
cn: addautomountkeys
description: Add Automount keys
member: cn=automountadmin,cn=privileges,cn=accounts,$SUFFIX
# Add the taskgroups referenced by the ACIs for netgroup administration
dn: cn=addnetgroups,cn=taskgroups,cn=accounts,$SUFFIX
dn: cn=removeautomountkeys,cn=permissions,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
cn: removeautomountkeys
description: Remove Automount keys
member: cn=automountadmin,cn=privileges,cn=accounts,$SUFFIX
# Netgroup administration
dn: cn=addnetgroups,cn=permissions,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
cn: addnetgroups
description: Add netgroups
member: cn=netgroupadmin,cn=rolegroups,cn=accounts,$SUFFIX
member: cn=netgroupadmin,cn=privileges,cn=accounts,$SUFFIX
dn: cn=removenetgroups,cn=taskgroups,cn=accounts,$SUFFIX
dn: cn=removenetgroups,cn=permissions,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
cn: removenetgroups
description: Remove netgroups
member: cn=netgroupadmin,cn=rolegroups,cn=accounts,$SUFFIX
member: cn=netgroupadmin,cn=privileges,cn=accounts,$SUFFIX
dn: cn=modifynetgroups,cn=taskgroups,cn=accounts,$SUFFIX
dn: cn=modifynetgroups,cn=permissions,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
cn: modifynetgroups
description: Modify netgroups
member: cn=netgroupadmin,cn=rolegroups,cn=accounts,$SUFFIX
member: cn=netgroupadmin,cn=privileges,cn=accounts,$SUFFIX
dn: cn=modifynetgroupmembership,cn=taskgroups,cn=accounts,$SUFFIX
dn: cn=modifynetgroupmembership,cn=permissions,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
cn: modifynetgroupmembership
description: Modify netgroup membership
member: cn=netgroupadmin,cn=rolegroups,cn=accounts,$SUFFIX
member: cn=netgroupadmin,cn=privileges,cn=accounts,$SUFFIX
# Taskgroup for retrieving host keytabs
dn: cn=manage_host_keytab,cn=taskgroups,cn=accounts,$SUFFIX
# Keytab access
dn: cn=manage_host_keytab,cn=permissions,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
cn: manage_host_keytab
description: Manage host keytab
member: cn=hostadmin,cn=rolegroups,cn=accounts,$SUFFIX
member: cn=hostadmin,cn=privileges,cn=accounts,$SUFFIX
member: cn=enrollhost,cn=privileges,cn=accounts,$SUFFIX
# Taskgroup for updating the DNS entries
dn: cn=update_dns,cn=taskgroups,cn=accounts,$SUFFIX
dn: cn=manage_service_keytab,cn=permissions,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
cn: manage_host_keytab
description: Updates DNS
member: cn=dnsadmin,cn=rolegroups,cn=accounts,$SUFFIX
member: cn=dnsserver,cn=rolegroups,cn=accounts,$SUFFIX
cn: manage_service_keytab
description: Manage service keytab
member: cn=serviceadmin,cn=privileges,cn=accounts,$SUFFIX
member: cn=admins,cn=privileges,cn=accounts,$SUFFIX
# DNS administration
# The permission and aci for this is in install/updates/dns.ldif
dn: cn=enroll_host,cn=permissions,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
cn: enroll_host
description: Enroll a host
member: cn=hostadmin,cn=privileges,cn=accounts,$SUFFIX
member: cn=enrollhost,cn=privileges,cn=accounts,$SUFFIX
# Replica administration
dn: cn=managereplica,cn=permissions,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
cn: managereplica
description: Manage Replication Agreements
member: cn=replicaadmin,cn=privileges,cn=accounts,$SUFFIX
dn: cn=deletereplica,cn=permissions,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
cn: deletereplica
description: Delete Replication Agreements
member: cn=replicaadmin,cn=privileges,cn=accounts,$SUFFIX
# Entitlement management
dn: cn=addentitlements,cn=permissions,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
cn: addentitlements
description: Add Entitlements
member: cn=entitlementadmin,cn=privileges,cn=accounts,$SUFFIX
dn: cn=removeentitlements,cn=permissions,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
cn: removeentitlements
description: Remove Entitlements
member: cn=entitlementadmin,cn=privileges,cn=accounts,$SUFFIX
dn: cn=modifyentitlements,cn=permissions,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
cn: modifyentitlements
description: Modify Entitlements
member: cn=entitlementadmin,cn=privileges,cn=accounts,$SUFFIX
############################################
# Default permissions (ACIs)
############################################
# User administration
dn: $SUFFIX
changetype: modify
add: aci
aci: (target = "ldap:///uid=*,cn=users,cn=accounts,$SUFFIX")(version 3.0;acl "Add Users";allow (add) groupdn = "ldap:///cn=addusers,cn=permissions,cn=accounts,$SUFFIX";)
aci: (targetattr = "userPassword || krbPrincipalKey || sambaLMPassword || sambaNTPassword || passwordHistory")(version 3.0;acl "Change a user password";allow (write) groupdn = "ldap:///cn=change_password,cn=permissions,cn=accounts,$SUFFIX";)
aci: (targetattr = "member")(target = "ldap:///cn=ipausers,cn=groups,cn=accounts,$SUFFIX")(version 3.0;acl "Add user to default group";allow (write) groupdn = "ldap:///cn=add_user_to_default_group,cn=permissions,cn=accounts,$SUFFIX";)
aci: (target = "ldap:///uid=*,cn=users,cn=accounts,$SUFFIX")(version 3.0;acl "Remove Users";allow (delete) groupdn = "ldap:///cn=removeusers,cn=permissions,cn=accounts,$SUFFIX";)
aci: (targetattr = "givenName || sn || cn || displayName || title || initials || loginShell || gecos || homePhone || mobile || pager || facsimileTelephoneNumber || telephoneNumber || street || roomNumber || l || st || postalCode || manager || secretary || description || carLicense || labeledURI || inetUserHTTPURL || seeAlso || employeeType || businessCategory || ou || mepManagedEntry || objectclass")(target = "ldap:///uid=*,cn=users,cn=accounts,$SUFFIX")(version 3.0;acl "Modify Users";allow (write) groupdn = "ldap:///cn=modifyusers,cn=permissions,cn=accounts,$SUFFIX";)
# Group administration
dn: $SUFFIX
changetype: modify
add: aci
aci: (target = "ldap:///cn=*,cn=groups,cn=accounts,$SUFFIX")(version 3.0;acl "Add Groups";allow (add) groupdn = "ldap:///cn=addgroups,cn=permissions,cn=accounts,$SUFFIX";)
aci: (targetattr = "member")(target = "ldap:///cn=*,cn=groups,cn=accounts,$SUFFIX")(version 3.0;acl "Modify group membership";allow (write) groupdn = "ldap:///cn=modifygroupmembership,cn=permissions,cn=accounts,$SUFFIX";)
aci: (target = "ldap:///cn=*,cn=groups,cn=accounts,$SUFFIX")(version 3.0;acl "Remove Groups";allow (delete) groupdn = "ldap:///cn=removegroups,cn=permissions,cn=accounts,$SUFFIX";)
# We need objectclass and gidnumber in modify so a non-posix group can be
# promoted. We need mqpManagedBy and ipaUniqueId so a group can be detached.
aci: (targetattr = "cn || description || gidnumber || objectclass || mepManagedBy || ipaUniqueId")(target = "ldap:///cn=*,cn=groups,cn=accounts,$SUFFIX")(version 3.0;acl "Modify Groups";allow (write) groupdn = "ldap:///cn=modifygroups,cn=permissions,cn=accounts,$SUFFIX";)
# Host administration
dn: $SUFFIX
changetype: modify
add: aci
aci: (target = "ldap:///fqdn=*,cn=computers,cn=accounts,$SUFFIX")(version 3.0;acl "Add Hosts";allow (add) groupdn = "ldap:///cn=addhosts,cn=permissions,cn=accounts,$SUFFIX";)
aci: (target = "ldap:///fqdn=*,cn=computers,cn=accounts,$SUFFIX")(version 3.0;acl "Remove Hosts";allow (delete) groupdn = "ldap:///cn=removehosts,cn=permissions,cn=accounts,$SUFFIX";)
aci: (targetattr = "description || l || nshostlocation || nshardwareplatform || nsosversion")(target = "ldap:///fqdn=*,cn=computers,cn=accounts,$SUFFIX")(version 3.0;acl "Modify Hosts";allow (write) groupdn = "ldap:///cn=modifyhosts,cn=permissions,cn=accounts,$SUFFIX";)
# Hostgroup administration
dn: $SUFFIX
changetype: modify
add: aci
aci: (target = "ldap:///cn=*,cn=hostgroups,cn=accounts,$SUFFIX")(version 3.0;acl "Add Hostgroups";allow (add) groupdn = "ldap:///cn=addhostgroups,cn=permissions,cn=accounts,$SUFFIX";)
aci: (target = "ldap:///cn=*,cn=hostgroups,cn=accounts,$SUFFIX")(version 3.0;acl "Remove Hostgroups";allow (delete) groupdn = "ldap:///cn=removehostgroups,cn=permissions,cn=accounts,$SUFFIX";)
aci: (targetattr = "cn || description")(target = "ldap:///cn=*,cn=hostgroups,cn=accounts,$SUFFIX")(version 3.0; acl "Modify Hostgroups";allow (write) groupdn = "ldap:///cn=modifyhostgroups,cn=permissions,cn=accounts,$SUFFIX";)
aci: (targetattr = "member")(target = "ldap:///cn=*,cn=hostgroups,cn=accounts,$SUFFIX")(version 3.0;acl "Modify Hostgroup membership";allow (write) groupdn = "ldap:///cn=modifyhostgroupmembership,cn=permissions,cn=accounts,$SUFFIX";)
# Service administration
dn: $SUFFIX
changetype: modify
add: aci
aci: (target = "ldap:///krbprincipalname=*,cn=services,cn=accounts,$SUFFIX")(version 3.0;acl "Add Services";allow (add) groupdn = "ldap:///cn=addservices,cn=permissions,cn=accounts,$SUFFIX";)
aci: (target = "ldap:///krbprincipalname=*,cn=services,cn=accounts,$SUFFIX")(version 3.0;acl "Remove Services";allow (delete) groupdn = "ldap:///cn=removeservices,cn=permissions,cn=accounts,$SUFFIX";)
aci: (targetattr = "userCertificate")(target = "ldap:///krbprincipalname=*,cn=services,cn=accounts,$SUFFIX")(version 3.0;acl "Modify Services";allow (write) groupdn = "ldap:///cn=modifyservices,cn=permissions,cn=accounts,$SUFFIX";)
# Delegation administration
dn: $SUFFIX
changetype: modify
add: aci
aci: (target = "ldap:///cn=*,cn=roles,cn=accounts,$SUFFIX")(version 3.0;acl "Add Roles";allow (add) groupdn = "ldap:///cn=addroles,cn=permissions,cn=accounts,$SUFFIX";)
aci: (target = "ldap:///cn=*,cn=roles,cn=accounts,$SUFFIX")(version 3.0;acl "Remove Roles";allow (delete) groupdn = "ldap:///cn=removeroles,cn=permissions,cn=accounts,$SUFFIX";)
aci: (targetattr = "cn || description")(target = "ldap:///cn=*,cn=roles,cn=accounts,$SUFFIX")(version 3.0; acl "Modify Roles";allow (write) groupdn = "ldap:///cn=modifyroles,cn=permissions,cn=accounts,$SUFFIX";)
aci: (targetattr = "member")(target = "ldap:///cn=*,cn=roles,cn=accounts,$SUFFIX")(version 3.0;acl "Modify role group membership";allow (write) groupdn = "ldap:///cn=modifyrolemembership,cn=permissions,cn=accounts,$SUFFIX";)
aci: (targetattr = "member")(target = "ldap:///cn=*,cn=permissions,cn=accounts,$SUFFIX")(version 3.0;acl "Modify privilege membership";allow (write) groupdn = "ldap:///cn=modifyprivilegemembership,cn=permissions,cn=accounts,$SUFFIX";)
# Automount administration
dn: $SUFFIX
changetype: modify
add: aci
aci: (target = "ldap:///automountmapname=*,cn=automount,$SUFFIX")(version 3.0;acl "Add Automount maps";allow (add) groupdn = "ldap:///cn=addautomountmaps,cn=permissions,cn=accounts,$SUFFIX";)
aci: (target = "ldap:///automountmapname=*,cn=automount,$SUFFIX")(version 3.0;acl "Remove automount maps";allow (delete) groupdn = "ldap:///cn=removeautomountmaps,cn=permissions,cn=accounts,$SUFFIX";)
aci: (target = "ldap:///automountkey=*,automountmapname=*,cn=automount,$SUFFIX")(version 3.0;acl "Add automount keys";allow (add) groupdn = "ldap:///cn=addautomountkeys,cn=permissions,cn=accounts,$SUFFIX";)
aci: (target = "ldap:///automountkey=*,automountmapname=*,cn=automount,$SUFFIX")(version 3.0;acl "Remove automount keys";allow (delete) groupdn = "ldap:///cn=removeautomountkeys,cn=permissions,cn=accounts,$SUFFIX";)
# Netgroup administration
dn: $SUFFIX
changetype: modify
add: aci
aci: (target = "ldap:///ipauniqueid=*,cn=ng,cn=alt,$SUFFIX")(version 3.0;acl "Add netgroups";allow (add) groupdn = "ldap:///cn=addnetgroups,cn=permissions,cn=accounts,$SUFFIX";)
aci: (target = "ldap:///ipauniqueid=*,cn=ng,cn=alt,$SUFFIX")(version 3.0;acl "Remove netgroups";allow (delete) groupdn = "ldap:///cn=removenetgroups,cn=permissions,cn=accounts,$SUFFIX";)
aci: (targetattr = "description")(target = "ldap:///ipauniqueid=*,cn=ng,cn=alt,$SUFFIX")(version 3.0; acl "Modify netgroups";allow (write) groupdn = "ldap:///cn=modifynetgroups,cn=permissions,cn=accounts,$SUFFIX";)
aci: (targetattr = "memberhost || externalhost || memberuser || member")(target = "ldap:///ipauniqueid=*,cn=ng,cn=alt,$SUFFIX")(version 3.0;acl "Modify netgroup membership";allow (write) groupdn = "ldap:///cn=modifynetgroupmembership,cn=permissions,cn=accounts,$SUFFIX";)
# Host keytab admin
dn: $SUFFIX
changetype: modify
add: aci
aci: (targetattr = "krbPrincipalKey || krbLastPwdChange")(target = "ldap:///fqdn=*,cn=computers,cn=accounts,$SUFFIX")(version 3.0;acl "Manage host keytab";allow (write) groupdn = "ldap:///cn=manage_host_keytab,cn=permissions,cn=accounts,$SUFFIX";)
# Service keytab admin
dn: $SUFFIX
changetype: modify
add: aci
aci: (targetattr = "krbPrincipalKey || krbLastPwdChange")(target = "ldap:///krbprincipalname=*,cn=services,cn=accounts,$SUFFIX")(version 3.0;acl "Manage service keytab";allow (write) groupdn = "ldap:///cn=manage_service_keytab,cn=permissions,cn=accounts,$SUFFIX";)
# Allow enrolledBy to be removed when a host is not enrolled
dn: $SUFFIX
changetype: modify
add: aci
aci: (target = "ldap:///fqdn=*,cn=computers,cn=accounts,$SUFFIX")(targetattr = "enrolledBy")(targetfilter="(!(krblastpwdchange=*))")(targattrfilters="del=enrolledby:(enrolledBy=*)")(version 3.0;acl "Allow enrolledBy to be removed when a host is not enrolled"; allow (write) groupdn = "ldap:///cn=manage_host_keytab,cn=permissions,cn=accounts,$SUFFIX";)
# Add the ACI needed to do host enrollment. When this occurs we
# set the krbPrincipalName, add krbPrincipalAux to objectClass and
# set enrolledBy to whoever ran join.
dn: $SUFFIX
changetype: modify
add: aci
aci: (targetattr = "enrolledBy || objectClass")(target = "ldap:///fqdn=*,cn=computers,cn=accounts,$SUFFIX")(version 3.0;acl "Enroll a host";allow (write) groupdn = "ldap:///cn=enroll_host,cn=permissions,cn=accounts,$SUFFIX";)
# Replica administration
dn: cn="$SUFFIX",cn=mapping tree,cn=config
changetype: modify
add: aci
aci: (targetattr=*)(targetfilter="(|(objectclass=nsds5Replica)(objectclass=nsds5replicationagreement)(objectclass=nsDSWindowsReplicationAgreement))")(version 3.0; acl "Manage Replication Agreements"; allow (read, write, search) groupdn = "ldap:///cn=managereplica,cn=permissions,cn=accounts,$SUFFIX";)
dn: cn="$SUFFIX",cn=mapping tree,cn=config
changetype: modify
add: aci
aci: (targetattr=*)(targetfilter="(|(objectclass=nsds5replicationagreement)(objectclass=nsDSWindowsReplicationAgreement))")(version 3.0;acl "Delete Replication Agreements";allow (delete) groupdn = "ldap:///cn=deletereplica,cn=permissions,cn=accounts,$SUFFIX";)
# Entitlement administration
dn: $SUFFIX
changetype: modify
add: aci
aci: (target = "ldap:///ipauniqueid=*,cn=entitlements,cn=etc,$SUFFIX")(version 3.0;acl "Add Entitlements";allow (add) groupdn = "ldap:///cn=addentitlements,cn=permissions,cn=accounts,$SUFFIX";)
dn: $SUFFIX
changetype: modify
add: aci
aci: (targetattr = "userCertificate")(target = "ldap:///ipauniqueid=*,cn=entitlements,cn=etc,$SUFFIX")(version 3.0;acl "Modify Entitlements";allow (write) groupdn = "ldap:///cn=modifyentitlements,cn=permissions,cn=accounts,$SUFFIX";)
dn: $SUFFIX
changetype: modify
add: aci
aci: (target = "ldap:///ipauniqueid=*,cn=entitlements,cn=etc,$SUFFIX")(version 3.0;acl "Remove Entitlements";allow (delete) groupdn = "ldap:///cn=removeentitlements,cn=permissions,cn=accounts,$SUFFIX";)
# Create virtual operations entry. This is used to control access to
# operations that don't rely on LDAP directly.
dn: cn=virtual operations,$SUFFIX
changetype: add
objectClass: top
objectClass: nsContainer
cn: virtual operations
# Retrieve Certificate virtual op
dn: cn=retrieve certificate,cn=virtual operations,$SUFFIX
changetype: add
objectClass: top
objectClass: nsContainer
cn: retrieve certificate
dn: cn=retrieve_certs,cn=permissions,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
cn: retrieve_certs
description: Retrieve Certificates from the CA
member: cn=certadmin,cn=privileges,cn=accounts,$SUFFIX
dn: $SUFFIX
changetype: modify
add: aci
aci: (targetattr = "objectClass")(target = "ldap:///cn=retrieve certificate,cn=virtual operations,$SUFFIX" )(version 3.0 ; acl "Retrieve Certificates from the CA" ; allow (write) groupdn = "ldap:///cn=retrieve_certs,cn=permissions,cn=accounts,$SUFFIX";)
# Request Certificate virtual op
dn: cn=request certificate,cn=virtual operations,$SUFFIX
changetype: add
objectClass: top
objectClass: nsContainer
cn: request certificate
dn: cn=request_certs,cn=permissions,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
cn: request_certs
description: Request Certificates from the CA
member: cn=certadmin,cn=privileges,cn=accounts,$SUFFIX
dn: $SUFFIX
changetype: modify
add: aci
aci: (targetattr = "objectClass")(target = "ldap:///cn=request certificate,cn=virtual operations,$SUFFIX" )(version 3.0 ; acl "Request Certificates from the CA" ; allow (write) groupdn = "ldap:///cn=request_certs,cn=permissions,cn=accounts,$SUFFIX";)
# Request Certificate from different host virtual op
dn: cn=request certificate different host,cn=virtual operations,$SUFFIX
changetype: add
objectClass: top
objectClass: nsContainer
cn: request certificate different host
dn: cn=request_cert_different_host,cn=permissions,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
cn: request_cert_different_host
description: Request Certificates from a different host
member: cn=certadmin,cn=privileges,cn=accounts,$SUFFIX
dn: $SUFFIX
changetype: modify
add: aci
aci: (targetattr = "objectClass")(target = "ldap:///cn=request certificate different host,cn=virtual operations,$SUFFIX" )(version 3.0 ; acl "Request Certificates from a different host" ; allow (write) groupdn = "ldap:///cn=request_cert_different_host,cn=permissions,cn=accounts,$SUFFIX";)
# Certificate Status virtual op
dn: cn=certificate status,cn=virtual operations,$SUFFIX
changetype: add
objectClass: top
objectClass: nsContainer
cn: certificate status
dn: cn=certificate_status,cn=permissions,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
cn: certificate_status
description: Get Certificates status from the CA
member: cn=certadmin,cn=privileges,cn=accounts,$SUFFIX
dn: $SUFFIX
changetype: modify
add: aci
aci: (targetattr = "objectClass")(target = "ldap:///cn=certificate status,cn=virtual operations,$SUFFIX" )(version 3.0 ; acl "Get Certificates status from the CA" ; allow (write) groupdn = "ldap:///cn=certificate_status,cn=permissions,cn=accounts,$SUFFIX";)
# Revoke Certificate virtual op
dn: cn=revoke certificate,cn=virtual operations,$SUFFIX
changetype: add
objectClass: top
objectClass: nsContainer
cn: revoke certificate
dn: cn=revoke_certificate,cn=permissions,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
cn: revoke_certificate
description: Revoke Certificate
member: cn=certadmin,cn=privileges,cn=accounts,$SUFFIX
dn: $SUFFIX
changetype: modify
add: aci
aci: (targetattr = "objectClass")(target = "ldap:///cn=revoke certificate,cn=virtual operations,$SUFFIX" )(version 3.0 ; acl "Revoke Certificate"; allow (write) groupdn = "ldap:///cn=revoke_certificate,cn=permissions,cn=accounts,$SUFFIX";)
# Certificate Remove Hold virtual op
dn: cn=certificate remove hold,cn=virtual operations,$SUFFIX
changetype: add
objectClass: top
objectClass: nsContainer
cn: certificate remove hold
dn: cn=certificate_remove_hold,cn=permissions,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
cn: certificate_remove_hold
description: Certificate Remove Hold
member: cn=certadmin,cn=privileges,cn=accounts,$SUFFIX
dn: $SUFFIX
changetype: modify
add: aci
aci: (targetattr = "objectClass")(target = "ldap:///cn=certificate remove hold,cn=virtual operations,$SUFFIX" )(version 3.0 ; acl "Certificate Remove Hold"; allow (write) groupdn = "ldap:///cn=certificate_remove_hold,cn=permissions,cn=accounts,$SUFFIX";)

View File

@ -3,4 +3,29 @@ changetype: add
objectClass: nsContainer
objectClass: top
cn: dns
aci: (targetfilter = "(objectClass=idnsRecord)")(targetattr != "aci")(version 3.0; acl "DNS Servers Updates"; allow (add,write,delete) groupdn = "ldap:///cn=update_dns,cn=taskgroups,cn=accounts,$SUFFIX";)
aci: (targetfilter = "(objectClass=idnsRecord)")(targetattr != "aci")(version 3.0; acl "DNS Servers Updates"; allow (add,write,delete) groupdn = "ldap:///cn=update_dns,cn=permissions,cn=accounts,$SUFFIX";)
dn: cn=update_dns,cn=permissions,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
cn: update_dns
description: DNS Servers Updates
member: cn=dnsadmin,cn=privileges,cn=accounts,$SUFFIX
member: cn=dnsserver,cn=privileges,cn=accounts,$SUFFIX
dn: cn=dnsadmin,cn=privileges,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
objectClass: nestedgroup
cn: dnsadmin
description: DNS Administrators
dn: cn=dnsserver,cn=privileges,cn=accounts,$SUFFIX
changetype: add
objectClass: top
objectClass: groupofnames
objectClass: nestedgroup
cn: dnsserver
description: DNS Servers

View File

@ -1,6 +0,0 @@
# Add the rolegroup container
dn: cn=rolegroups,cn=accounts,$SUFFIX
add:objectClass: nsContainer
add:cn: rolegroups

View File

@ -1,5 +0,0 @@
# Add the taskgroup container
dn: cn=taskgroups,cn=accounts,$SUFFIX
add:objectClass: nsContainer
add:cn: taskgroups

View File

@ -1,732 +0,0 @@
# Add the default roles
dn: cn=helpdesk,cn=rolegroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: helpdesk
add:description: Helpdesk
dn: cn=useradmin,cn=rolegroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: useradmin
add:description: User Administrators
dn: cn=groupadmin,cn=rolegroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: groupadmin
add:description: Group Administrators
dn: cn=hostadmin,cn=rolegroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: hostadmin
add:description: Host Administrators
dn: cn=hostgroupadmin,cn=rolegroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: hostgroupadmin
add:description: Host Group Administrators
dn: cn=delegationadmin,cn=rolegroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: delegationadmin
add:description: Role administration
dn: cn=serviceadmin,cn=rolegroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: serviceadmin
add:description: Service Administrators
dn: cn=automountadmin,cn=rolegroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: automountadmin
add:description: Automount Administrators
dn: cn=netgroupadmin,cn=rolegroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: netgroupadmin
add:description: Netgroups Administrators
dn: cn=dnsadmin,cn=rolegroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: dnsadmin
add:description: DNS Administrators
dn: cn=dnsserver,cn=rolegroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: dnsserver
add:description: DNS Servers
dn: cn=certadmin,cn=rolegroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: certadmin
add:description: Certificate Administrators
dn: cn=replicaadmin,cn=rolegroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: replicaadmin
add:description: Replication Administrators
add:member:'cn=admins,cn=groups,cn=accounts,$SUFFIX'
dn: cn=enrollhost,cn=rolegroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: enrollhost
add:description: Host Enrollment
dn: cn=entitlementadmin,cn=rolegroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: entitlementadmin
add:description: Entitlement Administrators
# Add the taskgroups referenced by the ACIs for user administration
dn: cn=taskgroups,cn=accounts,$SUFFIX
add:objectClass: nsContainer
add:objectClass: top
add:cn: taskgroups
dn: cn=addusers,cn=taskgroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: addusers
add:description: Add Users
add:member:'cn=useradmin,cn=rolegroups,cn=accounts,$SUFFIX'
dn: cn=change_password,cn=taskgroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: change_password
add:description: Change a user password
add:member:'cn=useradmin,cn=rolegroups,cn=accounts,$SUFFIX'
dn: cn=add_user_to_default_group,cn=taskgroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: add_user_to_default_group
add:description: Add user to default group
add:member:'cn=useradmin,cn=rolegroups,cn=accounts,$SUFFIX'
dn: cn=removeusers,cn=taskgroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: removeusers
add:description: Remove Users
add:member:'cn=useradmin,cn=rolegroups,cn=accounts,$SUFFIX'
dn: cn=modifyusers,cn=taskgroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: modifyusers
add:description: Modify Users
add:member:'cn=useradmin,cn=rolegroups,cn=accounts,$SUFFIX'
# Add the ACIs that grant these permissions for user administration
dn: $SUFFIX
add:aci: '(target = "ldap:///uid=*,cn=users,cn=accounts,$SUFFIX")(version
3.0;acl "Add Users";allow (add) groupdn = "ldap:///cn=addusers,cn=taskgroups
,cn=accounts,$SUFFIX";)'
add:aci: '(targetattr = "userPassword || krbPrincipalKey || sambaLMPassword || samb
aNTPassword || passwordHistory")(version 3.0;acl "change_password";allow (wri
te) groupdn = "ldap:///cn=change_password,cn=taskgroups,cn=accounts,$SUFFIX
";)'
add:aci: '(targetattr = "member")(target = "ldap:///cn=ipausers,cn=groups,cn=accoun
ts,$SUFFIX")(version 3.0;acl "Add user to default group";allow (wri
te) groupdn = "ldap:///cn=add_user_to_default_group,cn=taskgroups,cn=accounts
,$SUFFIX";)'
add:aci: '(target = "ldap:///uid=*,cn=users,cn=accounts,$SUFFIX")(version
3.0;acl "Remove Users";allow (delete) groupdn = "ldap:///cn=removeusers,cn=t
askgroups,cn=accounts,$SUFFIX";)'
add:aci: '(targetattr = "givenName || sn || cn || displayName || title || initials
|| loginShell || gecos || homePhone || mobile || pager || facsimileTelephoneN
umber || telephoneNumber || street || roomNumber || l || st || postalCode ||
manager || secretary || description || carLicense || labeledURI || inetUserHT
TPURL || seeAlso || employeeType || businessCategory || ou || mepManagedEntry
|| objectclass")(target = "ldap:///uid=*,cn=users,cn=accounts,$SUFFIX")
(version 3.0;acl "Modify Users";allow (write) groupdn =
"ldap:///cn=modifyusers,cn=taskgroups,cn=accounts,$SUFFIX";)'
# Add the taskgroups referenced by the ACIs for group administration
dn: cn=addgroups,cn=taskgroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: addgroups
add:description: Add Groups
add:member:'cn=groupadmin,cn=rolegroups,cn=accounts,$SUFFIX'
dn: cn=removegroups,cn=taskgroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: removegroups
add:description: Remove Groups
add:member:'cn=groupadmin,cn=rolegroups,cn=accounts,$SUFFIX'
dn: cn=modifygroups,cn=taskgroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: modifygroups
add:description: Modify Groups
add:member:'cn=groupadmin,cn=rolegroups,cn=accounts,$SUFFIX'
dn: cn=modifygroupmembership,cn=taskgroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: modifygroupmembership
add:description: Modify Group membership
add:member:'cn=groupadmin,cn=rolegroups,cn=accounts,$SUFFIX'
# Add the ACIs that grant these permissions for group administration
dn: $SUFFIX
add:aci: '(target = "ldap:///cn=*,cn=groups,cn=accounts,$SUFFIX")(version
3.0;acl "Add Groups";allow (add) groupdn = "ldap:///cn=addgroups,cn=taskgroups
,cn=accounts,$SUFFIX";)'
add:aci: '(targetattr = "member")(target = "ldap:///cn=*,cn=groups,cn=accoun
ts,$SUFFIX")(version 3.0;acl "Modify group membership";allow (wri
te) groupdn = "ldap:///cn=modifygroupmembership,cn=taskgroups,cn=accounts
,$SUFFIX";)'
add:aci: '(target = "ldap:///cn=*,cn=groups,cn=accounts,$SUFFIX")(version
3.0;acl "Remove Groups";allow (delete) groupdn = "ldap:///cn=removegroups,cn=t
askgroups,cn=accounts,$SUFFIX";)'
# we need objectclass and gidnumber in modify so a non-posix group can be
# promoted
add:aci: '(targetattr = "cn || description || gidnumber || objectclass ||
mepManagedBy")(target = "ldap:///cn=*,cn=groups,cn=accounts,$SUFFIX")
(version 3.0;acl "Modify Groups";allow (write) groupdn =
"ldap:///cn=modifygroups,cn=taskgroups,cn=accounts,$SUFFIX";)'
# Add the taskgroups referenced by the ACIs for host administration
dn: cn=addhosts,cn=taskgroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: addhosts
add:description: Add Hosts
add:member:'cn=hostadmin,cn=rolegroups,cn=accounts,$SUFFIX'
dn: cn=removehosts,cn=taskgroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: removehosts
add:description: Remove Hosts
add:member:'cn=hostadmin,cn=rolegroups,cn=accounts,$SUFFIX'
dn: cn=modifyhosts,cn=taskgroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: modifyhosts
add:description: Modify Hosts
add:member:'cn=hostadmin,cn=rolegroups,cn=accounts,$SUFFIX'
# Add the ACIs that grant these permissions for host administration
dn: $SUFFIX
add:aci: '(target = "ldap:///fqdn=*,cn=computers,cn=accounts,$SUFFIX")(version
3.0;acl "Add Hosts";allow (add) groupdn = "ldap:///cn=addhosts,cn=taskgroups
,cn=accounts,$SUFFIX";)'
add:aci: '(target = "ldap:///fqdn=*,cn=computers,cn=accounts,$SUFFIX")(version
3.0;acl "Remove Hosts";allow (delete) groupdn = "ldap:///cn=removehosts,cn=
taskgroups,cn=accounts,$SUFFIX";)'
add:aci: '(targetattr = "description || l || nshostlocation ||
nshardwareplatform || nsosversion")
(target = "ldap:///fqdn=*,cn=computers,cn=accounts,$SUFFIX")(version 3.0;
acl "Modify Hosts";allow (write) groupdn = "ldap:///cn=modifyhosts,
cn=taskgroups,cn=accounts,$SUFFIX";)'
# Add the taskgroups referenced by the ACIs for hostgroup administration
dn: cn=addhostgroups,cn=taskgroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: addhostgroups
add:description: Add Host Groups
add:member:'cn=hostgroupadmin,cn=rolegroups,cn=accounts,$SUFFIX'
dn: cn=removehostgroups,cn=taskgroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: removehostgroups
add:description: Remove Host Groups
add:member:'cn=hostgroupadmin,cn=rolegroups,cn=accounts,$SUFFIX'
dn: cn=modifyhostgroups,cn=taskgroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: modifyhostgroups
add:description: Modify Host Groups
add:member:'cn=hostgroupadmin,cn=rolegroups,cn=accounts,$SUFFIX'
dn: cn=modifyhostgroupmembership,cn=taskgroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: modifyhostgroupmembership
add:description: Modify Host Group membership
add:member:'cn=hostgroupadmin,cn=rolegroups,cn=accounts,$SUFFIX'
# Add the ACIs that grant these permissions for hostgroup administration
dn: $SUFFIX
add:aci: '(target = "ldap:///cn=*,cn=hostgroups,cn=accounts,$SUFFIX")(version
3.0;acl "Add Hostgroups";allow (add) groupdn = "ldap:///cn=addhostgroups,cn=
taskgroups,cn=accounts,$SUFFIX";)'
add:aci: '(target = "ldap:///cn=*,cn=hostgroups,cn=accounts,$SUFFIX")(version
3.0;acl "Remove Hostgroups";allow (delete) groupdn = "ldap:///cn=
removehostgroups,cn=taskgroups,cn=accounts,$SUFFIX";)'
add:aci: '(targetattr = "cn || description")(target = "ldap:///cn=*,cn=
hostgroups,cn=accounts,$SUFFIX")(version 3.0; acl "Modify Hostgroups";allow
(write) groupdn = "ldap:///cn=modifyhostgroups,cn=taskgroups,
cn=accounts,$SUFFIX";)'
add:aci: '(targetattr = "member")(target = "ldap:///cn=*,cn=hostgroups,cn=accoun
ts,$SUFFIX")(version 3.0;acl "Modify host group membership";allow (wri
te) groupdn = "ldap:///cn=modifyhostgroupmembership,cn=taskgroups,cn=accounts
,$SUFFIX";)'
# Add the taskgroups referenced by the ACIs for service administration
dn: cn=addservices,cn=taskgroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: addservices
add:description: Add Services
add:member:'cn=serviceadmin,cn=rolegroups,cn=accounts,$SUFFIX'
dn: cn=removeservices,cn=taskgroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: removeservices
add:description: Remove Services
add:member:'cn=serviceadmin,cn=rolegroups,cn=accounts,$SUFFIX'
dn: cn=modifyservices,cn=taskgroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: modifyservices
add:description: Modify Services
add:member:'cn=serviceadmin,cn=rolegroups,cn=accounts,$SUFFIX'
# Add the ACIs that grant these permissions for service administration
dn: $SUFFIX
add:aci: '(target = "ldap:///krbprincipalname=*,cn=services,cn=accounts,
$SUFFIX")(version 3.0;acl "Add Services";allow (add) groupdn = "ldap:///cn
=addservices,cn=taskgroups,cn=accounts,$SUFFIX";)'
add:aci: '(target = "ldap:///krbprincipalname=*,cn=services,cn=accounts,
$SUFFIX")(version 3.0;acl "Remove Services";allow (delete) groupdn = "ldap
:///cn=removeservices,cn=taskgroups,cn=accounts,$SUFFIX";)'
add:aci: '(targetattr = "userCertificate")(target = "ldap:///krbprincipal
name=*,cn=services,cn=accounts,$SUFFIX")(version 3.0;acl "Modify Services"
;allow (write) groupdn = "ldap:///cn=modifyservices,cn=taskgroups,cn=acco
unts,$SUFFIX";)'
# Add the taskgroups referenced by the ACIs for delegation administration
# This just lets one manage taskgroup membership and create and delete roles
dn: cn=addroles,cn=taskgroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: addhrole
add:description: Add Roles
add:member:'cn=delegationadmin,cn=rolegroups,cn=accounts,$SUFFIX'
dn: cn=removeroles,cn=taskgroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: removeroles
add:description: Remove Roles
add:member:'cn=delegationadmin,cn=rolegroups,cn=accounts,$SUFFIX'
dn: cn=modifyroles,cn=taskgroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: modifyroles
add:description: Modify Roles
add:member:'cn=delegationadmin,cn=rolegroups,cn=accounts,$SUFFIX'
dn: cn=modifyrolegroupmembership,cn=taskgroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: modifyrolegroupmembership
add:description: Modify Role Group membership
add:member:'cn=delegationadmin,cn=rolegroups,cn=accounts,$SUFFIX'
dn: cn=modifytaskgroupmembership,cn=taskgroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: modifytaskgroupmembership
add:description: Modify Task Group membership
add:member:'cn=delegationadmin,cn=rolegroups,cn=accounts,$SUFFIX'
# Add the ACIs that grant these permissions for delegation administration
dn: $SUFFIX
add:aci: '(target = "ldap:///cn=*,cn=rolegroups,cn=accounts,$SUFFIX")(version
3.0;acl "Add Roles";allow (add) groupdn = "ldap:///cn=addroles,cn=taskgroups
,cn=accounts,$SUFFIX";)'
add:aci: '(target = "ldap:///cn=*,cn=rolegroups,cn=accounts,$SUFFIX")(version
3.0;acl "Remove Roles";allow (delete) groupdn = "ldap:///cn=removeroles,cn=
taskgroups,cn=accounts,$SUFFIX";)'
add:aci: '(targetattr = "cn || description")(target = "ldap:///cn=*,cn=rolegro
ups,cn=accounts,$SUFFIX")(version 3.0; acl "Modify Roles";allow (write) grou
pdn = "ldap:///cn=modifyroles,cn=taskgroups,cn=accounts,$SUFFIX";)'
add:aci: '(targetattr = "member")(target = "ldap:///cn=*,cn=rolegroups,cn=accoun
ts,$SUFFIX")(version 3.0;acl "Modify role group membership";allow (wri
te) groupdn = "ldap:///cn=modifyrolegroupmembership,cn=taskgroups,cn=accounts
,$SUFFIX";)'
add:aci: '(targetattr = "member")(target = "ldap:///cn=*,cn=taskgroups,cn=accoun
ts,$SUFFIX")(version 3.0;acl "Modify task group membership";allow (wri
te) groupdn = "ldap:///cn=modifytaskgroupmembership,cn=taskgroups,cn=accounts
,$SUFFIX";)'
# Add the taskgroups referenced by the ACIs for automount administration
dn: cn=addautomount,cn=taskgroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: addautomount
add:description: Add Automount maps/keys
add:member:'cn=automountadmin,cn=rolegroups,cn=accounts,$SUFFIX'
dn: cn=removeautomount,cn=taskgroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: removeautomount
add:description: Remove Automount maps/keys
add:member:'cn=automountadmin,cn=rolegroups,cn=accounts,$SUFFIX'
# Add the ACIs that grant these permissions for service administration
dn: $SUFFIX
add:aci: '(target = "ldap:///automountmapname=*,cn=automount,
$SUFFIX")(version 3.0;acl "Add automount maps";allow (add) groupdn = "ldap
:///cn=addautomount,cn=taskgroups,cn=accounts,$SUFFIX";)'
add:aci: '(target = "ldap:///automountmapname=*,cn=automount,
$SUFFIX")(version 3.0;acl "Remove automount maps";allow (delete) groupdn =
"ldap:///cn=removeautomount,cn=taskgroups,cn=accounts,$SUFFIX";)'
add:aci: '(target = "ldap:///automountkey=*,automountmapname=*,cn=automount,
$SUFFIX")(version 3.0;acl "Add automount keys";allow (add) groupdn = "ldap
:///cn=addautomount,cn=taskgroups,cn=accounts,$SUFFIX";)'
add:aci: '(target = "ldap:///automountkey=*,automountmapname=*,cn=automount,
$SUFFIX")(version 3.0;acl "Remove automount keys";allow (delete) groupdn =
"ldap:///cn=removeautomount,cn=taskgroups,cn=accounts,$SUFFIX";)'
# Add the taskgroups referenced by the ACIs for netgroup administration
dn: cn=addnetgroups,cn=taskgroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: addnetgroups
add:description: Add netgroups
add:member:'cn=netgroupadmin,cn=rolegroups,cn=accounts,$SUFFIX'
dn: cn=removenetgroups,cn=taskgroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: removenetgroups
add:description: Remove netgroups
add:member:'cn=netgroupadmin,cn=rolegroups,cn=accounts,$SUFFIX'
dn: cn=modifynetgroups,cn=taskgroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: modifynetgroups
add:description: Modify netgroups
add:member:'cn=netgroupadmin,cn=rolegroups,cn=accounts,$SUFFIX'
dn: cn=modifynetgroupmembership,cn=taskgroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: modifynetgroupmembership
add:description: Modify netgroup membership
add:member:'cn=netgroupadmin,cn=rolegroups,cn=accounts,$SUFFIX'
# Add the ACIs that grant these permissions for netgroup administration
dn: $SUFFIX
add:aci: '(target = "ldap:///ipauniqueid=*,cn=ng,cn=alt,$SUFFIX")(version
3.0;acl "Add netgroups";allow (add) groupdn = "ldap:///cn=addnetgroups,cn=
taskgroups,cn=accounts,$SUFFIX";)'
add:aci: '(target = "ldap:///ipauniqueid=*,cn=ng,cn=alt,$SUFFIX")(version
3.0;acl "Remove netgroups";allow (delete) groupdn = "ldap:///cn=
removenetgroups,cn=taskgroups,cn=accounts,$SUFFIX";)'
add:aci: '(targetattr = "description")(target = "ldap:///ipauniqueid=*,cn=ng,
cn=alt,$SUFFIX")(version 3.0; acl "Modify netgroups";allow (write) groupdn
= "ldap:///cn=modifynetgroups,cn=taskgroups,cn=accounts,$SUFFIX";)'
add:aci: '(targetattr = "memberhost || externalhost || memberuser || member")
(target = "ldap:///ipauniqueid=*,cn=ng,cn=alt,$SUFFIX")(version 3.0;acl "Mo
dify netgroup membership";allow (write) groupdn = "ldap:///cn=modifynetgrou
pmembership,cn=taskgroups,cn=accounts,$SUFFIX";)'
# Taskgroup for retrieving host keytabs
dn: cn=manage_host_keytab,cn=taskgroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: manage_host_keytab
add:description: Manage host keytab
add:member:'cn=hostadmin,cn=rolegroups,cn=accounts,$SUFFIX'
add:member:'cn=enrollhost,cn=rolegroups,cn=accounts,$SUFFIX'
# Add the ACI needed to do host keytab admin
dn: $SUFFIX
add:aci: '(targetattr = "krbPrincipalKey || krbLastPwdChange")
(target = "ldap:///fqdn=*,cn=computers,cn=accounts,$SUFFIX")
(version 3.0;acl "Manage host keytab";
allow (write) groupdn = "ldap:///cn=manage_host_keytab,cn=taskgroups,
cn=accounts,$SUFFIX";)'
# Taskgroup for enrolling hosts. Note that this also requires
# manage_host_keytab access
dn: cn=enroll_host,cn=taskgroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: enroll_host
add:description: Enroll a host
add:member:'cn=hostadmin,cn=rolegroups,cn=accounts,$SUFFIX'
add:member:'cn=enrollhost,cn=rolegroups,cn=accounts,$SUFFIX'
# Add the ACI needed to do host enrollment. When this occurs we
# set the krbPrincipalName, add krbPrincipalAux to objectClass and
# set enrolledBy to whoever ran join.
dn: $SUFFIX
add:aci: '(targetattr = "enrolledBy || objectClass")
(target = "ldap:///fqdn=*,cn=computers,cn=accounts,$SUFFIX")
(version 3.0;acl "Enroll a host";
allow (write) groupdn = "ldap:///cn=enroll_host,cn=taskgroups,
cn=accounts,$SUFFIX";)'
# Taskgroup for updating the DNS entries
dn: cn=update_dns,cn=taskgroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: update_sn
add:description: Updates DNS
add:member:'cn=dnsadmin,cn=rolegroups,cn=accounts,$SUFFIX'
add:member:'cn=dnsserver,cn=rolegroups,cn=accounts,$SUFFIX'
# Create virtual operations entry. This is used to control access to
# operations that don't rely on LDAP directly.
dn: cn=virtual operations,$SUFFIX
add:objectClass: top
add:objectClass: nsContainer
add:cn: virtual operations
# Retrieve Certificate virtual op
dn: cn=retrieve certificate,cn=virtual operations,$SUFFIX
add:objectClass: top
add:objectClass: nsContainer
add:cn: retrieve certificate
# Taskgroup for retrieving certs
dn: cn=retrieve_certs,cn=taskgroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: retrieve_certs
add:description: Retrieve SSL Certificates
add:member:'cn=certadmin,cn=rolegroups,cn=accounts,$SUFFIX'
dn: $SUFFIX
add: aci: '(targetattr = "objectClass")(target =
"ldap:///cn=retrieve certificate,cn=virtual operations,
$SUFFIX" )(version 3.0 ; acl "Retrieve Certificates from the
CA" ; allow (write) groupdn = "ldap:///cn=retrieve_certs,cn=taskgroups,
cn=accounts,$SUFFIX";)'
# Request Certificate virtual op
dn: cn=request certificate,cn=virtual operations,$SUFFIX
add:objectClass: top
add:objectClass: nsContainer
add:cn: request certificate
# Taskgroup for requesting certs
dn: cn=request_certs,cn=taskgroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: request_certs
add:description: Request a SSL Certificate
add:member:'cn=certadmin,cn=rolegroups,cn=accounts,$SUFFIX'
dn: $SUFFIX
add: aci: '(targetattr = "objectClass")(target =
"ldap:///cn=request certificate,cn=virtual operations,
$SUFFIX" )(version 3.0 ; acl "Request Certificates from the
CA" ; allow (write) groupdn = "ldap:///cn=request_certs,cn=taskgroups,
cn=accounts,$SUFFIX";)'
# Request Certificate from different host virtual op
dn: cn=request certificate different host,cn=virtual operations,$SUFFIX
add:objectClass: top
add:objectClass: nsContainer
add:cn: request certificate different host
# Taskgroup for requesting certs from a different host
dn: cn=request_cert_different_host,cn=taskgroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: request_cert_different_host
add:description: Request a SSL Certificate from a different host
add:member:'cn=certadmin,cn=rolegroups,cn=accounts,$SUFFIX'
dn: $SUFFIX
add: aci: '(targetattr = "objectClass")(target =
"ldap:///cn=request certificate different host,cn=virtual operations,
$SUFFIX" )(version 3.0 ; acl "Request Certificates from a
different host" ; allow (write) groupdn = "ldap:///cn=request_cert
_different_host,cn=taskgroups,cn=accounts,$SUFFIX";)'
# Certificate Status virtual op
dn: cn=certificate status,cn=virtual operations,$SUFFIX
add:objectClass: top
add:objectClass: nsContainer
add:cn: certificate status
# Taskgroup for requesting certs
dn: cn=certificate_status,cn=taskgroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: certificate_status
add:description: Status of cert request
add:member:'cn=certadmin,cn=rolegroups,cn=accounts,$SUFFIX'
dn: $SUFFIX
add: aci: '(targetattr = "objectClass")(target =
"ldap:///cn=certificate status,cn=virtual operations,
$SUFFIX" )(version 3.0 ; acl "Get Certificates status from the
CA" ; allow (write) groupdn = "ldap:///cn=certificate_status,
cn=taskgroups,cn=accounts,$SUFFIX";)'
# Revoke Certificate virtual op
dn: cn=revoke certificate,cn=virtual operations,$SUFFIX
add:objectClass: top
add:objectClass: nsContainer
add:cn: revoke certificate
# Taskgroup for requesting certs
dn: cn=revoke_certificate,cn=taskgroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: revoke_certificate
add:description: Revoke Certificate
add:member:'cn=certadmin,cn=rolegroups,cn=accounts,$SUFFIX'
dn: $SUFFIX
add: aci: '(targetattr = "objectClass")(target =
"ldap:///cn=revoke certificate,cn=virtual operations,
$SUFFIX" )(version 3.0 ; acl "Revoke Certificate"
; allow (write) groupdn = "ldap:///cn=revoke_certificate,
cn=taskgroups,cn=accounts,$SUFFIX";)'
# Revoke Certificate virtual op
dn: cn=revoke certificate,cn=virtual operations,$SUFFIX
add:objectClass: top
add:objectClass: nsContainer
add:cn: revoke certificate
# Taskgroup for requesting certs
dn: cn=revoke_certificate,cn=taskgroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: revoke_certificate
add:description: Revoke Certificate
add:member:'cn=certadmin,cn=rolegroups,cn=accounts,$SUFFIX'
dn: $SUFFIX
add: aci: '(targetattr = "objectClass")(target =
"ldap:///cn=revoke certificate,cn=virtual operations,
$SUFFIX" )(version 3.0 ; acl "Revoke Certificate"
; allow (write) groupdn = "ldap:///cn=revoke_certificate,
cn=taskgroups,cn=accounts,$SUFFIX";)'
# Certificate Remove Hold virtual op
dn: cn=certificate remove hold,cn=virtual operations,$SUFFIX
add:objectClass: top
add:objectClass: nsContainer
add:cn: certificate remove hold
# Taskgroup for requesting certs
dn: cn=certificate_remove_hold,cn=taskgroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: certificate_remove_hold
add:description: Certificate Remove Hold
add:member:'cn=certadmin,cn=rolegroups,cn=accounts,$SUFFIX'
dn: $SUFFIX
add: aci: '(targetattr = "objectClass")(target =
"ldap:///cn=certificate remove hold,cn=virtual operations,
$SUFFIX" )(version 3.0 ; acl "Certificate Remove Hold"
; allow (write) groupdn = "ldap:///cn=certificate_remove_hold,
cn=taskgroups,cn=accounts,$SUFFIX";)'
# Taskgroup for managing replicas
dn: cn=managereplica,cn=taskgroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: managereplica
add:description: Manage Replication Agreements
add:member:'cn=replicaadmin,cn=rolegroups,cn=accounts,$SUFFIX'
# Taskgroup for deleting replicas
dn: cn=deletereplica,cn=taskgroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: deletereplica
add:description: Delete Replication Agreements
add:member:'cn=replicaadmin,cn=rolegroups,cn=accounts,$SUFFIX'
# Add acis allowing admins to read/write/delete replicas
dn: cn="$SUFFIX",cn=mapping tree,cn=config
add: aci: '(targetattr=*)(targetfilter="(|(objectclass=nsds5Replica)
(objectclass=nsds5replicationagreement)(objectclass=
nsDSWindowsReplicationAgreement))")(version 3.0; acl "Manage
replication agreements"; allow (read, write, search) groupdn =
"ldap:///cn=managereplica,cn=taskgroups,cn=accounts,$SUFFIX";)'
dn: cn="$SUFFIX",cn=mapping tree,cn=config
add: aci: '(targetattr=*)(targetfilter="(|(objectclass=
nsds5replicationagreement)(objectclass=nsDSWindowsReplicationAgreement
))")(version 3.0;acl "Delete replication agreements";allow (delete)
groupdn = "ldap:///cn=deletereplica,cn=taskgroups,cn=accounts,$SUFFIX";)'
# Entitlement management
dn: cn=addentitlements,cn=taskgroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: addentitlements
add:description: Add Entitlements
add:member:'cn=entitlementadmin,cn=rolegroups,cn=accounts,$SUFFIX'
dn: cn=removeentitlements,cn=taskgroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: removeentitlements
add:description: Remove Entitlements
add:member:'cn=entitlementadmin,cn=rolegroups,cn=accounts,$SUFFIX'
dn: cn=modifyentitlements,cn=taskgroups,cn=accounts,$SUFFIX
add:objectClass: top
add:objectClass: nestedgroup
add:cn: modifyentitlements
add:description: Modify Entitlements
add:member:'cn=entitlementadmin,cn=rolegroups,cn=accounts,$SUFFIX'
dn: $SUFFIX
add: aci: '(target = "ldap:///ipauniqueid=*,cn=entitlements,cn=etc,$SUFFIX")(version 3.0;acl "Add entitlements";allow (add) groupdn = "ldap:///cn=addentitlements,cn=taskgroups,cn=accounts,$SUFFIX";)'
dn: $SUFFIX
add: aci: '(targetattr = "userCertificate")(target = "ldap:///ipauniqueid=*,cn=entitlements,cn=etc,$SUFFIX")(version 3.0;acl "Modify entitlements";allow (write) groupdn = "ldap:///cn=modifyentitlements,cn=taskgroups,cn=accounts,$SUFFIX";)'
dn: $SUFFIX
add: aci: '(target = "ldap:///ipauniqueid=*,cn=entitlements,cn=etc,$SUFFIX")(version 3.0;acl "Remove entitlement entries";allow (delete) groupdn = "ldap:///cn=removeentitlements,cn=taskgroups,cn=accounts,$SUFFIX";)'

View File

@ -13,9 +13,6 @@ app_DATA = \
30-hbacsvc.update \
30-groupofhosts.update \
30-netgroups.update \
30-rolegroup.update \
30-taskgroup.update \
40-delegation.update \
$(NULL)
EXTRA_DIST = \

View File

@ -84,8 +84,9 @@ DEFAULT_CONFIG = (
('container_service', 'cn=services,cn=accounts'),
('container_host', 'cn=computers,cn=accounts'),
('container_hostgroup', 'cn=hostgroups,cn=accounts'),
('container_rolegroup', 'cn=rolegroups,cn=accounts'),
('container_taskgroup', 'cn=taskgroups,cn=accounts'),
('container_rolegroup', 'cn=roles,cn=accounts'),
('container_permission', 'cn=permissions,cn=accounts'),
('container_privilege', 'cn=privileges,cn=accounts'),
('container_automount', 'cn=automount'),
('container_policies', 'cn=policies'),
('container_configs', 'cn=configs,cn=policies'),

View File

@ -961,12 +961,12 @@ class NotGroupMember(ExecutionError):
>>> raise NotGroupMember()
Traceback (most recent call last):
...
NotGroupMember: This entry is not a member of the group
NotGroupMember: This entry is not a member
"""
errno = 4012
format = _('This entry is not a member of the group')
format = _('This entry is not a member')
class RecursiveGroup(ExecutionError):
"""
@ -993,12 +993,12 @@ class AlreadyGroupMember(ExecutionError):
>>> raise AlreadyGroupMember()
Traceback (most recent call last):
...
AlreadyGroupMember: This entry is already a member of the group
AlreadyGroupMember: This entry is already a member
"""
errno = 4014
format = _('This entry is already a member of the group')
format = _('This entry is already a member')
class Base64DecodeError(ExecutionError):
"""

View File

@ -28,11 +28,11 @@ existing entries or adding or deleting new ones. The goal of the ACIs
that ship with IPA is to provide a set of low-level permissions that
grant access to special groups called taskgroups. These low-level
permissions can be combined into roles that grant broader access. These
roles are another type of group, rolegroups.
roles are another type of group, roles.
For example, if you have taskgroups that allow adding and modifying users you
could create a rolegroup, useradmin. You would assign users to the useradmin
rolegroup to allow them to do the operations defined by the taskgroups.
could create a role, useradmin. You would assign users to the useradmin
role to allow them to do the operations defined by the taskgroups.
You can create ACIs that delegate permission so users in group A can write
attributes on group B.
@ -64,7 +64,7 @@ be editabe.
The bind rule defines who this ACI grants permissions to. The LDAP server
allows this to be any valid LDAP entry but we encourage the use of
taskgroups so that the rights can be easily shared through rolegroups.
taskgroups so that the rights can be easily shared through roles.
For a more thorough description of access controls see
http://www.redhat.com/docs/manuals/dir-server/ag/8.0/Managing_Access_Control.html
@ -80,6 +80,9 @@ EXAMPLES:
Add an ACI that allows members of the "addusers" taskgroup to add new users:
ipa aci-add --type=user --taskgroup=addusers --permissions=add "Add new users"
Add an ACI that lets members of the edotors manage members of the admins group:
ipa aci-add --permissions=write --attrs=member --targetgroup=admins --group=editors "Editors manage admins"
The show command shows the raw 389-ds ACI.
IMPORTANT: When modifying the target attributes of an existing ACI you
@ -148,25 +151,25 @@ def _make_aci(current, aciname, kw):
raise errors.ValidationError(name='target', error=_('at least one of: type, filter, subtree, targetgroup, attrs or memberof are required'))
group = 'group' in kw
taskgroup = 'taskgroup' in kw
permission = 'permission' in kw
selfaci = 'selfaci' in kw and kw['selfaci'] == True
if group + taskgroup + selfaci > 1:
raise errors.ValidationError(name='target', error=_('group, taskgroup and self are mutually exclusive'))
elif group + taskgroup + selfaci == 0:
raise errors.ValidationError(name='target', error=_('One of group, taskgroup or self is required'))
if group + permission + selfaci > 1:
raise errors.ValidationError(name='target', error=_('group, permission and self are mutually exclusive'))
elif group + permission + selfaci == 0:
raise errors.ValidationError(name='target', error=_('One of group, permission or self is required'))
# Grab the dn of the group we're granting access to. This group may be a
# taskgroup or a user group.
# permission or a user group.
entry_attrs = []
if taskgroup:
if permission:
# This will raise NotFound if the permission doesn't exist
try:
entry_attrs = api.Command['taskgroup_show'](kw['taskgroup'])['result']
except errors.NotFound:
# The task group doesn't exist, let's be helpful and add it
tgkw = {'description': aciname}
entry_attrs = api.Command['taskgroup_add'](
kw['taskgroup'], **tgkw
)['result']
entry_attrs = api.Command['permission_show'](kw['permission'])['result']
except errors.NotFound, e:
if 'test' in kw and not kw.get('test'):
raise e
else:
entry_attrs = {'dn': 'cn=%s,%s' % (kw['permission'], api.env.container_permission)}
elif group:
# Not so friendly with groups. This will raise
try:
@ -186,7 +189,7 @@ def _make_aci(current, aciname, kw):
a.set_target_attr(kw['attrs'])
if 'memberof' in kw:
entry_attrs = api.Command['group_show'](kw['memberof'])['result']
a.set_target_filter('memberOf=%s' % dn)
a.set_target_filter('memberOf=%s' % entry_attrs['dn'])
if 'filter' in kw:
a.set_target_filter(kw['filter'])
if 'type' in kw:
@ -195,7 +198,7 @@ def _make_aci(current, aciname, kw):
if 'targetgroup' in kw:
# Purposely no try here so we'll raise a NotFound
entry_attrs = api.Command['group_show'](kw['targetgroup'])['result']
target = 'ldap:///%s' % dn
target = 'ldap:///%s' % entry_attrs['dn']
a.set_target(target)
if 'subtree' in kw:
# See if the subtree is a full URI
@ -206,7 +209,7 @@ def _make_aci(current, aciname, kw):
return a
def _aci_to_kw(ldap, a):
def _aci_to_kw(ldap, a, test=False):
"""Convert an ACI into its equivalent keywords.
This is used for the modify operation so we can merge the
@ -254,11 +257,20 @@ def _aci_to_kw(ldap, a):
pass
else:
if groupdn.startswith('cn='):
(dn, entry_attrs) = ldap.get_entry(groupdn, ['cn'])
if api.env.container_taskgroup in dn:
kw['taskgroup'] = entry_attrs['cn'][0]
dn = ''
entry_attrs = {}
try:
(dn, entry_attrs) = ldap.get_entry(groupdn, ['cn'])
except errors.NotFound, e:
# FIXME, use real name here
if test:
dn = 'cn=%s,%s' % ('test', api.env.container_permission)
entry_attrs = {'cn': [u'test']}
if api.env.container_permission in dn:
kw['permission'] = entry_attrs['cn'][0]
else:
kw['group'] = entry_attrs['cn'][0]
if 'cn' in entry_attrs:
kw['group'] = entry_attrs['cn'][0]
return kw
@ -299,6 +311,7 @@ class aci(Object):
"""
ACI object.
"""
INTERNAL = True
label = _('ACIs')
@ -308,10 +321,10 @@ class aci(Object):
label=_('ACI name'),
primary_key=True,
),
Str('taskgroup?',
cli_name='taskgroup',
label=_('Taskgroup'),
doc=_('Taskgroup ACI grants access to'),
Str('permission?',
cli_name='permission',
label=_('Permission'),
doc=_('Permission ACI grants access to'),
),
Str('group?',
cli_name='group',
@ -370,8 +383,16 @@ class aci_add(crud.Create):
"""
Create new ACI.
"""
INTERNAL = True
msg_summary = _('Created ACI "%(value)s"')
takes_options = (
Flag('test?',
doc=_('Test the ACI syntax but don\'t write anything'),
default=False,
),
)
def execute(self, aciname, **kw):
"""
Execute the aci-create operation.
@ -390,18 +411,20 @@ class aci_add(crud.Create):
acis = _convert_strings_to_acis(entry_attrs.get('aci', []))
for a in acis:
if a.isequal(newaci):
# FIXME: add check for permission_group = permission_group
if a.isequal(newaci) or newaci.name == a.name:
raise errors.DuplicateEntry()
newaci_str = unicode(newaci)
entry_attrs['aci'].append(newaci_str)
ldap.update_entry(dn, entry_attrs)
if not kw.get('test', False):
ldap.update_entry(dn, entry_attrs)
if kw.get('raw', False):
result = dict(aci=unicode(newaci_str))
else:
result = _aci_to_kw(ldap, newaci)
result = _aci_to_kw(ldap, newaci, kw.get('test', False))
return dict(
result=result,
value=aciname,
@ -414,6 +437,7 @@ class aci_del(crud.Delete):
"""
Delete ACI.
"""
INTERNAL = True
has_output = output.standard_delete
msg_summary = _('Deleted ACI "%(value)s"')
@ -454,6 +478,7 @@ class aci_mod(crud.Update):
"""
Modify ACI.
"""
INTERNAL = True
has_output_params = (
Str('aci',
label=_('ACI'),
@ -485,6 +510,8 @@ class aci_mod(crud.Update):
# _make_aci is what is run in aci_add and validates the input.
# Do this before we delete the existing ACI.
newaci = _make_aci(None, aciname, newkw)
if aci.isequal(newaci):
raise errors.EmptyModlist()
self.api.Command['aci_del'](aciname)
@ -522,6 +549,7 @@ class aci_find(crud.Search):
have ipausers as a memberof. There may be other ACIs that apply to
members of that group indirectly.
"""
INTERNAL = True
msg_summary = ngettext('%(count)d ACI matched', '%(count)d ACIs matched', 0)
def execute(self, term, **kw):
@ -560,10 +588,10 @@ class aci_find(crud.Search):
results.remove(a)
acis = list(results)
if 'taskgroup' in kw:
if 'permission' in kw:
try:
self.api.Command['taskgroup_show'](
kw['taskgroup']
self.api.Command['permission_show'](
kw['permission']
)
except errors.NotFound:
pass
@ -600,7 +628,24 @@ class aci_find(crud.Search):
# uncomment next line if you add more search criteria
# acis = list(results)
# TODO: searching by: type, filter, subtree
for a in acis:
if 'target' in a.target:
target = a.target['target']['expression']
else:
results.remove(a)
continue
found = False
for k in _type_map.keys():
if _type_map[k] == target and 'type' in kw and kw['type'] == k:
found = True
break;
if not found:
try:
results.remove(a)
except ValueError:
pass
# TODO: searching by: filter, subtree
acis = []
for result in results:
@ -623,6 +668,7 @@ class aci_show(crud.Retrieve):
"""
Display a single ACI given an ACI name.
"""
INTERNAL = True
has_output_params = (
Str('aci',
@ -656,3 +702,64 @@ class aci_show(crud.Retrieve):
)
api.register(aci_show)
class aci_rename(crud.Update):
"""
Rename an ACI.
"""
INTERNAL = True
has_output_params = (
Str('aci',
label=_('ACI'),
),
)
takes_options = (
Str('newname',
doc=_('New ACI name'),
),
)
msg_summary = _('Renameed ACI to "%(value)s"')
def execute(self, aciname, **kw):
ldap = self.api.Backend.ldap2
(dn, entry_attrs) = ldap.get_entry(self.api.env.basedn, ['aci'])
acis = _convert_strings_to_acis(entry_attrs.get('aci', []))
aci = _find_aci_by_name(acis, aciname)
for a in acis:
if kw['newname'] == a.name:
raise errors.DuplicateEntry()
# The strategy here is to convert the ACI we're updating back into
# a series of keywords. Then we replace any keywords that have been
# updated and convert that back into an ACI and write it out.
newkw = _aci_to_kw(ldap, aci)
if 'selfaci' in newkw and newkw['selfaci'] == True:
# selfaci is set in aci_to_kw to True only if the target is self
kw['selfaci'] = True
if 'aciname' in newkw:
del newkw['aciname']
# _make_aci is what is run in aci_add and validates the input.
# Do this before we delete the existing ACI.
newaci = _make_aci(None, kw['newname'], newkw)
self.api.Command['aci_del'](aciname)
result = self.api.Command['aci_add'](kw['newname'], **newkw)['result']
if kw.get('raw', False):
result = dict(aci=unicode(newaci))
else:
result = _aci_to_kw(ldap, newaci)
return dict(
result=result,
value=kw['newname'],
)
api.register(aci_rename)

View File

@ -42,17 +42,29 @@ global_output_params = (
Str('member_group?',
label=_('Member groups'),
),
Str('memberof_group?',
label=_('Member of groups'),
),
Str('member_host?',
label=_('Member hosts'),
),
Str('memberof_hostgroup?',
label=_('Member of host-groups'),
),
Str('memberof_taskgroup?',
label=_('Member of task-groups'),
Str('memberof_permission?',
label=_('Permissions'),
),
Str('member_rolegroup?',
label=_('Member role-groups'),
Str('memberof_privilege?',
label='Privileges',
),
Str('memberof_role?',
label=_('Roles'),
),
Str('member_privilege?',
label='Granted to Privilege',
),
Str('member_role?',
label=_('Granting privilege to roles'),
),
Str('member_netgroup?',
label=_('Member netgroups'),
@ -93,11 +105,11 @@ global_output_params = (
Str('memberindirect_hostgroup?',
label=_('Indirect Member host-groups'),
),
Str('memberindirect_rolegroup?',
label=_('Indirect Member role-groups'),
Str('memberindirect_role?',
label=_('Indirect Member of roles'),
),
Str('memberindirect_taskgroup?',
label=_('Indirect Member role-groups'),
Str('memberindirect_permission?',
label=_('Indirect Member permissions'),
),
Str('memberindirect_hbacsvc?',
label=_('Indirect Member HBAC service'),
@ -1192,9 +1204,11 @@ class LDAPSearch(CallbackInterface, crud.Search):
for callback in self.POST_CALLBACKS:
if hasattr(callback, 'im_self'):
callback(ldap, entries, truncated, *args, **options)
more = callback(ldap, entries, truncated, *args, **options)
else:
callback(self, ldap, entries, truncated, *args, **options)
more = callback(self, ldap, entries, truncated, *args, **options)
if more:
entries = entries + more
if not options.get('raw', False):
for e in entries:
@ -1214,8 +1228,236 @@ class LDAPSearch(CallbackInterface, crud.Search):
return (filter, base_dn, scope)
def post_callback(self, ldap, entries, truncated, *args, **options):
pass
return []
def exc_callback(self, args, options, exc, call_func, *call_args, **call_kwargs):
raise exc
class LDAPModReverseMember(LDAPQuery):
"""
Base class for reverse member manipulation.
"""
reverse_attributes = ['member']
reverse_param_doc = 'comma-separated list of %s'
reverse_count_out = ('%i member processed.', '%i members processed.')
has_output_params = global_output_params
def get_options(self):
for option in super(LDAPModReverseMember, self).get_options():
yield option
for attr in self.reverse_attributes:
for ldap_obj_name in self.obj.reverse_members[attr]:
ldap_obj = self.api.Object[ldap_obj_name]
name = to_cli(ldap_obj_name)
doc = self.reverse_param_doc % ldap_obj.object_name_plural
yield List('%s?' % name, cli_name='%ss' % name, doc=doc,
label=ldap_obj.object_name)
class LDAPAddReverseMember(LDAPModReverseMember):
"""
Add other LDAP entries to members in reverse.
The call looks like "add A to B" but in fact executes
add B to A to handle reverse membership.
"""
member_param_doc = 'comma-separated list of %s to add'
member_count_out = ('%i member added.', '%i members added.')
show_command = None
member_command = None
reverse_attr = None
member_attr = None
has_output = (
output.Entry('result'),
output.Output('failed',
type=dict,
doc=_('Members that could not be added'),
),
output.Output('completed',
type=int,
doc=_('Number of members added'),
),
)
has_output_params = global_output_params
def execute(self, *keys, **options):
ldap = self.obj.backend
# Ensure our target exists
result = self.api.Command[self.show_command](keys[-1])['result']
dn = result['dn']
for callback in self.PRE_CALLBACKS:
if hasattr(callback, 'im_self'):
dn = callback(ldap, dn, *keys, **options)
else:
dn = callback(
self, ldap, dn, *keys, **options
)
if options.get('all', False):
attrs_list = ['*'] + self.obj.default_attributes
else:
attrs_list = self.obj.default_attributes
completed = 0
failed = {'member': {self.reverse_attr: []}}
for attr in options.get(self.reverse_attr, []):
try:
options = {'%s' % self.member_attr: keys[-1]}
try:
result = self.api.Command[self.member_command](attr, **options)
if result['completed'] == 1:
completed = completed + 1
else:
failed['member'][self.reverse_attr].append((attr, result['failed']['member'][self.member_attr][0][1]))
except errors.ExecutionError, e:
try:
(dn, entry_attrs) = self._call_exc_callbacks(
keys, options, e, self.member_command, dn, attrs_list,
normalize=self.obj.normalize_dn
)
except errors.NotFound, e:
msg = str(e)
(attr, msg) = msg.split(':', 1)
failed['member'][self.reverse_attr].append((attr, unicode(msg.strip())))
except errors.PublicError, e:
failed['member'][self.reverse_attr].append((attr, unicode(msg)))
entry_attrs = self.api.Command[self.show_command](keys[-1])['result']
for callback in self.POST_CALLBACKS:
if hasattr(callback, 'im_self'):
(completed, dn) = callback(
ldap, completed, failed, dn, entry_attrs, *keys, **options
)
else:
(completed, dn) = callback(
self, ldap, completed, failed, dn, entry_attrs, *keys,
**options
)
entry_attrs['dn'] = dn
return dict(
completed=completed,
failed=failed,
result=entry_attrs,
)
def pre_callback(self, ldap, dn, *keys, **options):
return dn
def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
return (completed, dn)
def exc_callback(self, keys, options, exc, call_func, *call_args, **call_kwargs):
raise exc
class LDAPRemoveReverseMember(LDAPModReverseMember):
"""
Remove other LDAP entries from members in reverse.
The call looks like "remove A from B" but in fact executes
remove B from A to handle reverse membership.
"""
member_param_doc = 'comma-separated list of %s to remove'
member_count_out = ('%i member removed.', '%i members removed.')
show_command = None
member_command = None
reverse_attr = None
member_attr = None
has_output = (
output.Entry('result'),
output.Output('failed',
type=dict,
doc=_('Members that could not be removed'),
),
output.Output('completed',
type=int,
doc=_('Number of members removed'),
),
)
has_output_params = global_output_params
def execute(self, *keys, **options):
ldap = self.obj.backend
# Ensure our target exists
result = self.api.Command[self.show_command](keys[-1])['result']
dn = result['dn']
for callback in self.PRE_CALLBACKS:
if hasattr(callback, 'im_self'):
dn = callback(ldap, dn, *keys, **options)
else:
dn = callback(
self, ldap, dn, *keys, **options
)
if options.get('all', False):
attrs_list = ['*'] + self.obj.default_attributes
else:
attrs_list = self.obj.default_attributes
completed = 0
failed = {'member': {self.reverse_attr: []}}
for attr in options.get(self.reverse_attr, []):
try:
options = {'%s' % self.member_attr: keys[-1]}
try:
result = self.api.Command[self.member_command](attr, **options)
if result['completed'] == 1:
completed = completed + 1
else:
failed['member'][self.reverse_attr].append((attr, result['failed']['member'][self.member_attr][0][1]))
except errors.ExecutionError, e:
try:
(dn, entry_attrs) = self._call_exc_callbacks(
keys, options, e, self.member_command, dn, attrs_list,
normalize=self.obj.normalize_dn
)
except errors.NotFound, e:
msg = str(e)
(attr, msg) = msg.split(':', 1)
failed['member'][self.reverse_attr].append((attr, unicode(msg.strip())))
except errors.PublicError, e:
failed['member'][self.reverse_attr].append((attr, unicode(msg)))
entry_attrs = self.api.Command[self.show_command](keys[-1])['result']
for callback in self.POST_CALLBACKS:
if hasattr(callback, 'im_self'):
(completed, dn) = callback(
ldap, completed, failed, dn, entry_attrs, *keys, **options
)
else:
(completed, dn) = callback(
self, ldap, completed, failed, dn, entry_attrs, *keys,
**options
)
entry_attrs['dn'] = dn
return dict(
completed=completed,
failed=failed,
result=entry_attrs,
)
def pre_callback(self, ldap, dn, *keys, **options):
return dn
def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
return (completed, dn)
def exc_callback(self, keys, options, exc, call_func, *call_args, **call_kwargs):
raise exc

View File

@ -89,8 +89,8 @@ class group(LDAPObject):
uuid_attribute = 'ipauniqueid'
attribute_members = {
'member': ['user', 'group'],
'memberof': ['group', 'netgroup', 'rolegroup', 'taskgroup'],
'memberindirect': ['user', 'group', 'netgroup', 'rolegroup', 'taskgroup'],
'memberof': ['group', 'netgroup', 'role',],
'memberindirect': ['user', 'group', 'netgroup', 'role'],
}
rdnattr = 'cn'

View File

@ -31,10 +31,10 @@ ENROLLMENT:
There are three enrollment scenarios when enrolling a new client:
1. You are enrolling as a full administrator. The host entry may exist
or not. A full administrator is a member of the hostadmin rolegroup
or not. A full administrator is a member of the hostadmin role
or the admins group.
2. You are enrolling as a limited administrator. The host must already
exist. A limited administrator is a member of the enrollhost rolegroup.
exist. A limited administrator is a member of the enrollhost role.
3. The host has been created with a one-time password.
A host can only be enrolled once. If a client has enrolled and needs to
@ -162,7 +162,7 @@ class host(LDAPObject):
uuid_attribute = 'ipauniqueid'
attribute_members = {
'enrolledby': ['user'],
'memberof': ['hostgroup', 'netgroup', 'rolegroup'],
'memberof': ['hostgroup', 'netgroup', 'role'],
'managedby': ['host'],
}

View File

@ -0,0 +1,363 @@
# Authors:
# Rob Crittenden <rcritten@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; version 2 only
#
# 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, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
"""
Permissions
A permission enables fine-grained delegation of permissions. Access Control
Rules, or instructions (ACIs), grant permission to permissions to perform
given tasks such as adding a user, modifying a group, etc.
A permission may not be members of other permissions.
* A permissions grants access to read, write, add or delete.
* A privilege combines similar permissions (for example all the permissions
needed to add a user).
* A role grants a set of privileges to users, groups, hosts or hostgroups.
A permission is made up of a number of different parts:
1. The name of the permission.
2. The description of the permission.
3. The target of the permission.
4. The permissions granted by the permission.
The permissions define what operations are allowed and are one or more of:
1. write - write one or more attributes
2. read - read one or more attributes
3. add - add a new entry to the tree
4. delete - delete an existing entry
5. all - all permissions are granted
Note the distinction between attributes and entries. The permissions are
independent, so being able to add a user does not mean that the user will
be editabe.
There are a number of allowed targets:
1. type: a type of object (user, group, etc).
2. memberof: a memberof a group or hostgroup
3. filter: an LDAP filter
4. subtree: an LDAP filter specifying part of the LDAP DIT
5. targetgroup
EXAMPLES:
Add a permission that grants the creation of users:
ipa permission-add --desc="Add a User" --type=user --permissions=add adduser
Add a permission that grants the ability to manage group membership:
ipa permission-add --desc='Manage group members' --attrs=member --permissions=-write --type=group manage_group_members
"""
import copy
from ipalib.plugins.baseldap import *
from ipalib import api, _, ngettext
from ipalib import Flag, Str, StrEnum
from ipalib.request import context
class permission(LDAPObject):
"""
Permission object.
"""
container_dn = api.env.container_permission
object_name = 'permission'
object_name_plural = 'permissions'
object_class = ['groupofnames']
default_attributes = ['cn', 'description', 'member', 'memberof',
'memberindirect',
]
aci_attributes = ['group', 'permissions', 'attrs', 'type',
'filter', 'subtree', 'targetgroup',
]
attribute_members = {
'member': ['privilege'],
# 'memberindirect': ['user', 'group', 'role'],
}
rdnattr='cn'
label = _('Permissions')
takes_params = (
Str('cn',
cli_name='name',
label=_('Permission name'),
primary_key=True,
normalizer=lambda value: value.lower(),
),
Str('description',
cli_name='desc',
label=_('Description'),
doc=_('Permission description'),
),
List('permissions',
cli_name='permissions',
label=_('Permissions'),
doc=_('Comma-separated list of permissions to grant ' \
'(read, write, add, delete, all)'),
),
List('attrs?',
cli_name='attrs',
label=_('Attributes'),
doc=_('Comma-separated list of attributes'),
),
StrEnum('type?',
cli_name='type',
label=_('Type'),
doc=_('Type of IPA object (user, group, host, hostgroup, service, netgroup)'),
values=(u'user', u'group', u'host', u'service', u'hostgroup', u'netgroup'),
),
Str('memberof?',
cli_name='memberof',
label=_('Member of group'), # FIXME: Does this label make sense?
doc=_('Target members of a group'),
),
Str('filter?',
cli_name='filter',
label=_('Filter'),
doc=_('Legal LDAP filter (e.g. ou=Engineering)'),
),
Str('subtree?',
cli_name='subtree',
label=_('Subtree'),
doc=_('Subtree to apply permissions to'),
),
Str('targetgroup?',
cli_name='targetgroup',
label=_('Target group'),
doc=_('User group to apply permissions to'),
),
)
api.register(permission)
class permission_add(LDAPCreate):
"""
Add a new permission.
"""
msg_summary = _('Added permission "%(value)s"')
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
# Test the ACI before going any further
opts = copy.copy(options)
del opts['description']
opts['test'] = True
opts['permission'] = keys[-1]
try:
self.api.Command.aci_add(options['description'], **opts)
except Exception, e:
raise e
# Clear the aci attributes out of the permission entry
for o in options:
try:
if o not in ['description', 'objectclass']:
del entry_attrs[o]
except:
pass
return dn
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
# Now actually add the aci.
opts = copy.copy(options)
del opts['description']
opts['test'] = False
opts['permission'] = keys[-1]
try:
result = self.api.Command.aci_add(options['description'], **opts)['result']
for attr in self.obj.aci_attributes:
if attr in result:
entry_attrs[attr] = result[attr]
except Exception, e:
self.api.Command.aci_del(keys[-1])
raise e
return dn
api.register(permission_add)
class permission_del(LDAPDelete):
"""
Delete a permission.
"""
msg_summary = _('Deleted permission "%(value)s"')
def pre_callback(self, ldap, dn, *keys, **options):
(dn, entry_attrs) = ldap.get_entry(dn, ['*'])
if 'description' in entry_attrs:
try:
self.api.Command.aci_del(entry_attrs['description'][0])
except errors.NotFound:
pass
return dn
api.register(permission_del)
class permission_mod(LDAPUpdate):
"""
Modify a permission.
"""
msg_summary = _('Modified permission "%(value)s"')
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
(dn, attrs) = ldap.get_entry(
dn, attrs_list, normalize=self.obj.normalize_dn
)
opts = copy.copy(options)
if 'description' in opts:
del opts['description']
for o in self.obj.aci_attributes + ['all', 'raw', 'rights']:
if o in opts:
del opts[o]
setattr(context, 'aciupdate', False)
# If there are no options left we don't need to do anything to the
# underlying ACI.
if len(opts) > 0:
opts['test'] = False
opts['permission'] = keys[-1]
try:
self.api.Command.aci_mod(attrs['description'][0], **opts)
setattr(context, 'aciupdate', True)
except Exception, e:
raise e
# Clear the aci attributes out of the permission entry
for o in self.obj.aci_attributes:
try:
del entry_attrs[o]
except:
pass
if 'description' in options:
(dn, attrs) = ldap.get_entry(dn, ['description'])
self.api.Command.aci_rename(attrs['description'][0], newname=options['description'])
return dn
def exc_callback(self, keys, options, exc, call_func, *call_args, **call_kwargs):
if isinstance(exc, errors.EmptyModlist):
aciupdate = getattr(context, 'aciupdate')
opts = copy.copy(options)
# Clear the aci attributes out of the permission entry
for o in self.obj.aci_attributes + ['all', 'raw', 'rights']:
try:
del opts[o]
except:
pass
if len(opts) > 0:
raise exc
else:
raise exc
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
result = self.api.Command.permission_show(keys[-1])['result']
for r in result:
if not r.startswith('member'):
entry_attrs[r] = result[r]
return dn
api.register(permission_mod)
class permission_find(LDAPSearch):
"""
Search for permissions.
"""
msg_summary = ngettext(
'%(count)d permission matched', '%(count)d permissions matched'
)
def post_callback(self, ldap, entries, truncated, *args, **options):
newentries = []
for entry in entries:
(dn, attrs) = entry
try:
aci = self.api.Command.aci_show(attrs['description'][0])['result']
for attr in self.obj.aci_attributes:
if attr in aci:
attrs[attr] = aci[attr]
except errors.NotFound:
self.debug('ACI not found for %s' % attrs['description'][0])
# Now find all the ACIs that match. Once we find them, add any that
# aren't already in the list along with their permission info.
aciresults = self.api.Command.aci_find(*args, **options)
truncated = truncated or aciresults['truncated']
results = aciresults['result']
for aci in results:
found = False
if 'permission' in aci:
for entry in entries:
if aci['permission'] == entry['cn']:
found = True
break
if not found in aci:
permission = self.api.Command.permission_show(aci['permission'])
attrs = permission['result']
for attr in self.obj.aci_attributes:
if attr in aci:
attrs[attr] = aci[attr]
dn = attrs['dn']
del attrs['dn']
newentries.append((dn, attrs))
return newentries
api.register(permission_find)
class permission_show(LDAPRetrieve):
"""
Display information about a permission.
"""
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
try:
aci = self.api.Command.aci_show(entry_attrs['description'][0])['result']
for attr in self.obj.aci_attributes:
if attr in aci:
entry_attrs[attr] = aci[attr]
except errors.NotFound:
self.debug('ACI not found for %s' % entry_attrs['description'][0])
return dn
api.register(permission_show)
class permission_add_member(LDAPAddMember):
"""
Add members to a permission.
"""
INTERNAL = True
api.register(permission_add_member)
class permission_remove_member(LDAPRemoveMember):
"""
Remove members from a permission.
"""
INTERNAL = True
api.register(permission_remove_member)

191
ipalib/plugins/privilege.py Normal file
View File

@ -0,0 +1,191 @@
# Authors:
# Rob Crittenden <rcritten@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; version 2 only
#
# 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, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
"""
Privileges
A privilege enables fine-grained delegation of permissions. Access Control
Rules, or instructions (ACIs), grant permission to privileges to perform
given tasks such as adding a user, modifying a group, etc.
A privilege may not be members of other privileges.
See role and permission for additional information.
"""
from ipalib.plugins.baseldap import *
from ipalib import api, _, ngettext
class privilege(LDAPObject):
"""
Privilege object.
"""
container_dn = api.env.container_privilege
object_name = 'privilege'
object_name_plural = 'privileges'
object_class = ['nestedgroup', 'groupofnames']
default_attributes = ['cn', 'description', 'member', 'memberof',
'memberindirect'
]
attribute_members = {
'member': ['permission', 'role'],
'memberof': ['permission'],
# 'memberindirect': ['permission'],
# FIXME: privilege can be member of ???
}
reverse_members = {
'member': ['permission'],
}
rdnattr='cn'
label = _('Privileges')
takes_params = (
Str('cn',
cli_name='name',
label=_('Privilege name'),
primary_key=True,
normalizer=lambda value: value.lower(),
),
Str('description',
cli_name='desc',
label=_('Description'),
doc=_('Privilege description'),
),
)
api.register(privilege)
class privilege_add(LDAPCreate):
"""
Add a new privilege.
"""
msg_summary = _('Added privilege "%(value)s"')
api.register(privilege_add)
class privilege_del(LDAPDelete):
"""
Delete a privilege.
"""
msg_summary = _('Deleted privilege "%(value)s"')
api.register(privilege_del)
class privilege_mod(LDAPUpdate):
"""
Modify a privilege.
"""
msg_summary = _('Modified privilege "%(value)s"')
api.register(privilege_mod)
class privilege_find(LDAPSearch):
"""
Search for privileges.
"""
msg_summary = ngettext(
'%(count)d privilege matched', '%(count)d privileges matched'
)
api.register(privilege_find)
class privilege_show(LDAPRetrieve):
"""
Display information about a privilege.
"""
api.register(privilege_show)
class privilege_add_member(LDAPAddMember):
"""
Add members to a privilege
"""
INTERNAL=True
api.register(privilege_add_member)
class privilege_remove_member(LDAPRemoveMember):
"""
Remove members from a privilege
"""
INTERNAL=True
api.register(privilege_remove_member)
class privilege_add_permission(LDAPAddReverseMember):
"""
Add permissions to a privilege.
"""
show_command = 'privilege_show'
member_command = 'permission_add_member'
reverse_attr = 'permission'
member_attr = 'privilege'
has_output = (
output.Entry('result'),
output.Output('failed',
type=dict,
doc=_('Members that could not be added'),
),
output.Output('completed',
type=int,
doc=_('Number of permissions added'),
),
)
api.register(privilege_add_permission)
class privilege_remove_permission(LDAPRemoveReverseMember):
"""
Remove permissions from a privilege.
"""
show_command = 'privilege_show'
member_command = 'permission_remove_member'
reverse_attr = 'permission'
member_attr = 'privilege'
permission_count_out = ('%i permission removed.', '%i permissions removed.')
has_output = (
output.Entry('result'),
output.Output('failed',
type=dict,
doc=_('Members that could not be added'),
),
output.Output('completed',
type=int,
doc=_('Number of permissions removed'),
),
)
api.register(privilege_remove_permission)

212
ipalib/plugins/role.py Normal file
View File

@ -0,0 +1,212 @@
# Authors:
# Rob Crittenden <rcritten@redhat.com>
# Pavel Zuna <pzuna@redhat.com>
#
# Copyright (C) 2009 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; version 2 only
#
# 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, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
"""
Roles
A role is used for fine-grained delegation. A permission grants the ability
to perform given low-level tasks (add a user, modify a group, etc.). A
privilege combines one or more permissions into a higher-level abstraction
such as useradmin. A useradmin would be able to add, delete and modify users.
Privileges are assigned to Roles.
Users, groups, hosts and hostgroups may be members of a Role.
Roles can not contain other roles.
EXAMPLES:
Add a new role:
ipa role-add --desc="Junior-level admin" junioradmin
Add some privileges to this role:
ipa role-add-privilege --privileges=addusers junioradmin
ipa role-add-privilege --privileges=change_password junioradmin
ipa role-add-privilege --privileges=add_user_to_default_group juioradmin
Add a group of users to this role:
ipa group-add --desc="User admins" useradmins
ipa role-add-member --groups=useradmins junioradmin
Display information about a role:
ipa role-show junioradmin
The result of this is that any users in the group 'useradmins' can
add users, reset passwords or add a user to the default IPA user group.
"""
from ipalib.plugins.baseldap import *
from ipalib import api, Str, _, ngettext
from ipalib import Command
from ipalib.plugins import privilege
class role(LDAPObject):
"""
Role object.
"""
container_dn = api.env.container_rolegroup
object_name = 'role'
object_name_plural = 'roles'
object_class = ['groupofnames', 'nestedgroup']
default_attributes = ['cn', 'description', 'member', 'memberof',
'memberindirect'
]
attribute_members = {
'member': ['user', 'group', 'host', 'hostgroup'],
'memberof': ['privilege'],
# 'memberindirect': ['user', 'group', 'host', 'hostgroup'],
}
reverse_members = {
'member': ['privilege'],
}
rdnattr='cn'
label = _('Role Groups')
takes_params = (
Str('cn',
cli_name='name',
label=_('Role name'),
primary_key=True,
normalizer=lambda value: value.lower(),
),
Str('description',
cli_name='desc',
label=_('Description'),
doc=_('A description of this role-group'),
),
)
api.register(role)
class role_add(LDAPCreate):
"""
Add a new role.
"""
msg_summary = _('Added role "%(value)s"')
api.register(role_add)
class role_del(LDAPDelete):
"""
Delete a role.
"""
msg_summary = _('Deleted role "%(value)s"')
api.register(role_del)
class role_mod(LDAPUpdate):
"""
Modify a role.
"""
msg_summary = _('Modified role "%(value)s"')
api.register(role_mod)
class role_find(LDAPSearch):
"""
Search for roles.
"""
msg_summary = ngettext(
'%(count)d role matched', '%(count)d roles matched'
)
api.register(role_find)
class role_show(LDAPRetrieve):
"""
Display information about a role.
"""
api.register(role_show)
class role_add_member(LDAPAddMember):
"""
Add members to a role.
"""
api.register(role_add_member)
class role_remove_member(LDAPRemoveMember):
"""
Remove members from a role.
"""
api.register(role_remove_member)
class role_add_privilege(LDAPAddReverseMember):
"""
Add privileges to a role.
"""
show_command = 'role_show'
member_command = 'privilege_add_member'
reverse_attr = 'privilege'
member_attr = 'role'
has_output = (
output.Entry('result'),
output.Output('failed',
type=dict,
doc=_('Members that could not be added'),
),
output.Output('completed',
type=int,
doc=_('Number of privileges added'),
),
)
api.register(role_add_privilege)
class role_remove_privilege(LDAPRemoveReverseMember):
"""
Remove privileges from a role.
"""
show_command = 'role_show'
member_command = 'privilege_remove_member'
reverse_attr = 'privilege'
member_attr = 'role'
has_output = (
output.Entry('result'),
output.Output('failed',
type=dict,
doc=_('Members that could not be added'),
),
output.Output('completed',
type=int,
doc=_('Number of privileges removed'),
),
)
api.register(role_remove_privilege)

View File

@ -1,165 +0,0 @@
# Authors:
# Rob Crittenden <rcritten@redhat.com>
# Pavel Zuna <pzuna@redhat.com>
#
# Copyright (C) 2009 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; version 2 only
#
# 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, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
"""
Rolegroups
A rolegroup is used for fine-grained delegation. Access control rules
(ACIs) grant permission to perform given tasks (add a user, modify a group,
etc.), to task groups. Rolegroups are members of taskgroups, giving them
permission to perform the task.
The logic behind ACIs and rolegroups proceeds as follows:
ACIs grants permission to taskgroup
rolegroups are members of taskgroups
users, groups, hosts and hostgroups are members of rolegroups
Rolegroups can contain both hosts and hostgroups, enabling
operations using the host service principal associated with a machine.
Rolegroups can not contain other rolegroups.
EXAMPLES:
Add a new rolegroup:
ipa rolegroup-add --desc="Junior-level admin" junioradmin
Add this role to some tasks:
ipa taskgroup-add-member --rolegroups=junioradmin addusers
ipa taskgroup-add-member --rolegroups=junioradmin change_password
ipa taskgroup-add-member --rolegroups=junioradmin add_user_to_default_group
Yes, this can seem backwards. The taskgroup is the entry that is granted
permissions by the ACIs. By adding a rolegroup as a member of a taskgroup
it inherits those permissions.
Add a group of users to this role:
ipa group-add --desc="User admins" useradmins
ipa rolegroup-add-member --groups=useradmins junioradmin
Display information about a rolegroup:
ipa rolegroup-show junioradmin
"""
from ipalib.plugins.baseldap import *
from ipalib import api, Str, _, ngettext
class rolegroup(LDAPObject):
"""
Rolegroup object.
"""
container_dn = api.env.container_rolegroup
object_name = 'rolegroup'
object_name_plural = 'rolegroups'
object_class = ['groupofnames', 'nestedgroup']
default_attributes = ['cn', 'description', 'member', 'memberof',
'memberindirect'
]
attribute_members = {
'member': ['user', 'group', 'host', 'hostgroup'],
'memberof': ['taskgroup'],
'memberindirect': ['user', 'group', 'host', 'hostgroup'],
}
rdnattr='cn'
label = _('Role Groups')
takes_params = (
Str('cn',
cli_name='name',
label=_('Role-group name'),
primary_key=True,
normalizer=lambda value: value.lower(),
),
Str('description',
cli_name='desc',
label=_('Description'),
doc=_('A description of this role-group'),
),
)
api.register(rolegroup)
class rolegroup_add(LDAPCreate):
"""
Add a new rolegroup.
"""
msg_summary = _('Added rolegroup "%(value)s"')
api.register(rolegroup_add)
class rolegroup_del(LDAPDelete):
"""
Delete a rolegroup.
"""
msg_summary = _('Deleted rolegroup "%(value)s"')
api.register(rolegroup_del)
class rolegroup_mod(LDAPUpdate):
"""
Modify a rolegroup.
"""
msg_summary = _('Modified rolegroup "%(value)s"')
api.register(rolegroup_mod)
class rolegroup_find(LDAPSearch):
"""
Search for rolegroups.
"""
msg_summary = ngettext(
'%(count)d rolegroup matched', '%(count)d rolegroups matched'
)
api.register(rolegroup_find)
class rolegroup_show(LDAPRetrieve):
"""
Display information about a rolegroup.
"""
api.register(rolegroup_show)
class rolegroup_add_member(LDAPAddMember):
"""
Add members to a rolegroup.
"""
api.register(rolegroup_add_member)
class rolegroup_remove_member(LDAPRemoveMember):
"""
Remove members from a rolegroup.
"""
api.register(rolegroup_remove_member)

View File

@ -47,7 +47,7 @@ EXAMPLES:
Allow a host to manage an IPA service certificate:
ipa service-add-host --hosts=web.example.com HTTP/web.example.com
ipa rolegroup-add-member --hosts=web.example.com certadmin
ipa role-add-member --hosts=web.example.com certadmin
Delete an IPA service:
ipa service-del HTTP/web.example.com

View File

@ -1,136 +0,0 @@
# Authors:
# Rob Crittenden <rcritten@redhat.com>
# Pavel Zuna <pzuna@redhat.com>
#
# Copyright (C) 2009 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; version 2 only
#
# 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, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
"""
Taskgroups
A taskgroup enables fine-grained delegation of permissions. Access Control
Rules, or instructions (ACIs), grant permission to taskgroups to perform
given tasks such as adding a user, modifying a group, etc.
A taskgroup may not be members of other taskgroups.
See rolegroup and aci for additional information.
"""
from ipalib.plugins.baseldap import *
from ipalib import api, _, ngettext
class taskgroup(LDAPObject):
"""
Taskgroup object.
"""
container_dn = api.env.container_taskgroup
object_name = 'taskgroup'
object_name_plural = 'taskgroups'
object_class = ['groupofnames']
default_attributes = ['cn', 'description', 'member', 'memberof',
'memberindirect'
]
attribute_members = {
'member': ['user', 'group', 'rolegroup'],
'memberindirect': ['user', 'group', 'rolegroup'],
# FIXME: taskgroup can be member of ???
}
rdnattr='cn'
label = _('Task Groups')
takes_params = (
Str('cn',
cli_name='name',
label=_('Task-group name'),
primary_key=True,
normalizer=lambda value: value.lower(),
),
Str('description',
cli_name='desc',
label=_('Description'),
doc=_('Task-group description'),
),
)
api.register(taskgroup)
class taskgroup_add(LDAPCreate):
"""
Add a new taskgroup.
"""
msg_summary = _('Added taskgroup "%(value)s"')
api.register(taskgroup_add)
class taskgroup_del(LDAPDelete):
"""
Delete a taskgroup.
"""
msg_summary = _('Deleted taskgroup "%(value)s"')
api.register(taskgroup_del)
class taskgroup_mod(LDAPUpdate):
"""
Modify a taskgroup.
"""
msg_summary = _('Modified taskgroup "%(value)s"')
api.register(taskgroup_mod)
class taskgroup_find(LDAPSearch):
"""
Search for taskgroups.
"""
msg_summary = ngettext(
'%(count)d taskgroup matched', '%(count)d taskgroups matched'
)
api.register(taskgroup_find)
class taskgroup_show(LDAPRetrieve):
"""
Display information about a taskgroup.
"""
api.register(taskgroup_show)
class taskgroup_add_member(LDAPAddMember):
"""
Add members to a taskgroup.
"""
api.register(taskgroup_add_member)
class taskgroup_remove_member(LDAPRemoveMember):
"""
Remove members from a taskgroup.
"""
api.register(taskgroup_remove_member)

View File

@ -70,7 +70,7 @@ class user(LDAPObject):
]
uuid_attribute = 'ipauniqueid'
attribute_members = {
'memberof': ['group', 'netgroup', 'rolegroup', 'taskgroup'],
'memberof': ['group', 'netgroup', 'role'],
}
rdnattr = 'uid'

View File

@ -357,7 +357,7 @@ class BindInstance(service.Service):
logging.critical("Could not connect to the Directory Server on %s" % self.fqdn)
raise e
dns_group = "cn=dnsserver,cn=rolegroups,cn=accounts,%s" % self.suffix
dns_group = "cn=dnsserver,cn=privileges,cn=accounts,%s" % self.suffix
if isinstance(dns_principal, unicode):
dns_principal = dns_principal.encode('utf-8')
mod = [(ldap.MOD_ADD, 'member', dns_principal)]

View File

@ -61,13 +61,19 @@ hostgroup = [
u'top',
]
rolegroup = [
role = [
u'groupofnames',
u'nestedgroup',
u'top',
]
taskgroup = [
permission = [
u'groupofnames',
u'top'
]
privilege = [
u'nestedgroup',
u'groupofnames',
u'top'
]

View File

@ -1,321 +0,0 @@
# Authors:
# Rob Crittenden <rcritten@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; version 2 only
#
# 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, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
"""
Test the `ipalib/plugins/aci.py` module.
"""
from ipalib import api, errors
from tests.test_xmlrpc import objectclasses
from xmlrpc_test import Declarative, fuzzy_digits, fuzzy_uuid
aci1=u'test1'
taskgroup = u'testtaskgroup'
aci2=u'selftest1'
class test_aci(Declarative):
cleanup_commands = [
('aci_del', [aci1], {}),
('aci_del', [aci2], {}),
]
tests = [
dict(
desc='Try to retrieve non-existent %r' % aci1,
command=('aci_show', [aci1], {}),
expected=errors.NotFound(reason='no such entry'),
),
dict(
desc='Try to update non-existent %r' % aci1,
command=('aci_mod', [aci1], dict(permissions=u'write')),
expected=errors.NotFound(reason='no such entry'),
),
dict(
desc='Try to delete non-existent %r' % aci1,
command=('aci_del', [aci1], {}),
expected=errors.NotFound(reason='no such entry'),
),
dict(
desc='Create %r' % aci1,
command=(
'aci_add', [aci1], dict(permissions=u'add', type=u'user', taskgroup=taskgroup)
),
expected=dict(
value=aci1,
summary=u'Created ACI "%s"' % aci1,
result=dict(
aciname=u'%s' % aci1,
type=u'user',
taskgroup=u'%s' % taskgroup,
permissions=[u'add'],
),
),
),
dict(
desc='Try to create duplicate %r' % aci1,
command=(
'aci_add', [aci1], dict(permissions=u'add', type=u'user', taskgroup=taskgroup)
),
expected=errors.DuplicateEntry(),
),
dict(
desc='Retrieve %r' % aci1,
command=(
'aci_show', [aci1], {}
),
expected=dict(
value=aci1,
summary=None,
result=dict(
aciname=u'%s' % aci1,
type=u'user',
taskgroup=u'%s' % taskgroup,
permissions=[u'add'],
),
),
),
dict(
desc='Search for %r with all=True' % aci1,
command=(
'aci_find', [aci1], {'all': True}
),
expected=dict(
result=[
dict(
aciname=u'%s' % aci1,
type=u'user',
taskgroup=u'%s' % taskgroup,
permissions=[u'add'],
),
],
summary=u'1 ACI matched',
count=1,
truncated=False,
),
),
dict(
desc='Search for %r with minimal attributes' % aci1,
command=(
'aci_find', [aci1], {}
),
expected=dict(
result=[
dict(
aciname=u'%s' % aci1,
type=u'user',
taskgroup=u'%s' % taskgroup,
permissions=[u'add'],
),
],
summary=u'1 ACI matched',
count=1,
truncated=False,
),
),
dict(
desc='Update permissions in %r' % aci1,
command=(
'aci_mod', [aci1], dict(permissions=u'add,write')
),
expected=dict(
value=aci1,
summary=u'Modified ACI "%s"' % aci1,
result=dict(
aciname=u'%s' % aci1,
type=u'user',
taskgroup=u'%s' % taskgroup,
permissions=[u'add', u'write'],
),
),
),
dict(
desc='Retrieve %r to verify update' % aci1,
command=('aci_show', [aci1], {}),
expected=dict(
value=aci1,
summary=None,
result=dict(
aciname=u'%s' % aci1,
type=u'user',
taskgroup=u'%s' % taskgroup,
permissions=[u'add', u'write'],
),
),
),
dict(
desc='Update attributes in %r' % aci1,
command=(
'aci_mod', [aci1], dict(attrs=u'cn, sn,givenName')
),
expected=dict(
value=aci1,
summary=u'Modified ACI "%s"' % aci1,
result=dict(
aciname=u'%s' % aci1,
attrs=[u'cn', u'sn', u'givenName'],
type=u'user',
taskgroup=u'%s' % taskgroup,
permissions=[u'add', u'write'],
),
),
),
dict(
desc='Update type in %r' % aci1,
command=(
'aci_mod', [aci1], dict(type=u'group')
),
expected=dict(
value=aci1,
summary=u'Modified ACI "%s"' % aci1,
result=dict(
aciname=u'%s' % aci1,
attrs=[u'cn', u'sn', u'givenName'],
type=u'group',
taskgroup=u'%s' % taskgroup,
permissions=[u'add', u'write'],
),
),
),
dict(
desc='Update memberOf in %r' % aci1,
command=(
'aci_mod', [aci1], dict(memberof=u'ipausers')
),
expected=dict(
value=aci1,
summary=u'Modified ACI "%s"' % aci1,
result=dict(
aciname=u'%s' % aci1,
taskgroup=u'%s' % taskgroup,
filter=u'(memberOf=cn=%s,cn=taskgroups,cn=accounts,%s)' % (taskgroup, api.env.basedn),
attrs=[u'cn', u'sn', u'givenName'],
type=u'group',
permissions=[u'add', u'write'],
),
),
),
dict(
desc='Delete %r' % aci1,
command=('aci_del', [aci1], {}),
expected=dict(
result=True,
summary=u'Deleted ACI "%s"' % aci1,
value=aci1,
),
),
dict(
desc='Try to delete non-existent %r' % aci1,
command=('aci_del', [aci1], {}),
expected=errors.NotFound(reason='no such entry'),
),
dict(
desc='Try to retrieve non-existent %r' % aci1,
command=('aci_show', [aci1], {}),
expected=errors.NotFound(reason='no such entry'),
),
dict(
desc='Try to update non-existent %r' % aci1,
command=('aci_mod', [aci1], dict(givenname=u'Foo')),
expected=errors.NotFound(reason='no such entry'),
),
dict(
desc='Create %r' % aci2,
command=(
'aci_add', [aci2], dict(permissions=u'write', attrs=(u'givenName',u'sn',u'cn'), selfaci=True)
),
expected=dict(
value=aci2,
summary=u'Created ACI "%s"' % aci2,
result=dict(
selfaci=True,
aciname=u'%s' % aci2,
attrs=[u'givenName', u'sn', u'cn'],
permissions=[u'write'],
),
),
),
dict(
desc='Update attributes in %r' % aci2,
command=(
'aci_mod', [aci2], dict(attrs=(u'givenName',u'sn',u'cn',u'uidNumber'))
),
expected=dict(
value=aci2,
summary=u'Modified ACI "%s"' % aci2,
result=dict(
selfaci=True,
aciname=u'%s' % aci2,
attrs=[u'givenName', u'sn', u'cn', u'uidNumber'],
permissions=[u'write'],
),
),
),
dict(
desc='Update self ACI with a taskgroup %r' % aci2,
command=(
'aci_mod', [aci2], dict(attrs=(u'givenName',u'sn',u'cn',u'uidNumber'), taskgroup=taskgroup)
),
expected=errors.ValidationError(name='target', error='group, taskgroup and self are mutually exclusive'),
),
]

View File

@ -31,7 +31,6 @@ renamedgroup1 = u'testgroup'
user1 = u'tuser1'
invalidgroup1=u'+tgroup1'
invalidgroup2=u'tgroup1234567890123456789012345678901234567890'
class test_group(Declarative):
@ -335,8 +334,6 @@ class test_group(Declarative):
'gidnumber': [fuzzy_digits],
'cn': [u'admins'],
'description': [u'Account administrators group'],
'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,
@ -449,7 +446,7 @@ class test_group(Declarative):
completed=0,
failed=dict(
member=dict(
group=[(u'notfound', u'This entry is not a member of the group')],
group=[(u'notfound', u'This entry is not a member')],
user=tuple(),
),
),
@ -569,12 +566,6 @@ class test_group(Declarative):
),
dict(
desc='Test a group name that is too long %r' % invalidgroup2,
command=('group_add', [invalidgroup2], dict(description=u'Test')),
expected=errors.ValidationError(name='cn', error='can be at most 33 characters'),
),
##### managed entry tests
dict(
desc='Create %r' % user1,

View File

@ -495,7 +495,7 @@ class test_netgroup(Declarative):
),
memberuser=dict(
group=tuple(),
user=[('%s' % user1, u'This entry is already a member of the group')],
user=[('%s' % user1, u'This entry is already a member')],
),
memberhost=dict(
hostgroup=tuple(),
@ -528,7 +528,7 @@ class test_netgroup(Declarative):
netgroup=tuple(),
),
memberuser=dict(
group=[('%s' % group1, u'This entry is already a member of the group')],
group=[('%s' % group1, u'This entry is already a member')],
user=tuple(),
),
memberhost=dict(
@ -568,7 +568,7 @@ class test_netgroup(Declarative):
),
memberhost=dict(
hostgroup=tuple(),
host=[('%s' % host1, u'This entry is already a member of the group')],
host=[('%s' % host1, u'This entry is already a member')],
),
),
result={
@ -602,7 +602,7 @@ class test_netgroup(Declarative):
user=tuple(),
),
memberhost=dict(
hostgroup=[('%s' % hostgroup1, u'This entry is already a member of the group')],
hostgroup=[('%s' % hostgroup1, u'This entry is already a member')],
host=tuple(),
),
),
@ -907,7 +907,7 @@ class test_netgroup(Declarative):
),
memberhost=dict(
hostgroup=tuple(),
host=[('%s' % host1, u'This entry is not a member of the group')]
host=[('%s' % host1, u'This entry is not a member')]
),
),
result={
@ -937,7 +937,7 @@ class test_netgroup(Declarative):
user=tuple(),
),
memberhost=dict(
hostgroup=[('%s' % hostgroup1, u'This entry is not a member of the group')],
hostgroup=[('%s' % hostgroup1, u'This entry is not a member')],
host=tuple(),
),
),
@ -965,7 +965,7 @@ class test_netgroup(Declarative):
),
memberuser=dict(
group=tuple(),
user=[('%s' % user1, u'This entry is not a member of the group')],
user=[('%s' % user1, u'This entry is not a member')],
),
memberhost=dict(
hostgroup=tuple(),
@ -995,7 +995,7 @@ class test_netgroup(Declarative):
netgroup=tuple(),
),
memberuser=dict(
group= [('%s' % group1, u'This entry is not a member of the group')],
group= [('%s' % group1, u'This entry is not a member')],
user=tuple(),
),
memberhost=dict(
@ -1023,7 +1023,7 @@ class test_netgroup(Declarative):
completed=0,
failed=dict(
member=dict(
netgroup=[('%s' % netgroup2, u'This entry is not a member of the group')],
netgroup=[('%s' % netgroup2, u'This entry is not a member')],
),
memberuser=dict(
group=tuple(),

View File

@ -0,0 +1,400 @@
# Authors:
# Rob Crittenden <rcritten@redhat.com>
# Pavel Zuna <pzuna@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; version 2 only
#
# 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, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
"""
Test the `ipalib/plugins/permission.py` module.
"""
from ipalib import api, errors
from tests.test_xmlrpc import objectclasses
from xmlrpc_test import Declarative, fuzzy_digits, fuzzy_uuid
permission1 = u'testperm'
permission1_dn = u'cn=%s,%s,%s' % (permission1,
api.env.container_permission,api.env.basedn,
)
permission2 = u'testperm2'
permission2_dn = u'cn=%s,%s,%s' % (permission2,
api.env.container_permission,api.env.basedn,
)
privilege1 = u'testpriv1'
privilege1_dn = u'cn=%s,%s,%s' % (
privilege1, api.env.container_privilege, api.env.basedn
)
class test_permission(Declarative):
cleanup_commands = [
('permission_del', [permission1], {}),
('permission_del', [permission2], {}),
('privilege_del', [privilege1], {}),
]
tests = [
dict(
desc='Try to retrieve non-existent %r' % permission1,
command=('permission_show', [permission1], {}),
expected=errors.NotFound(reason='no such entry'),
),
dict(
desc='Try to update non-existent %r' % permission1,
command=('permission_mod', [permission1], dict(description=u'Foo')),
expected=errors.NotFound(reason='no such entry'),
),
dict(
desc='Try to delete non-existent %r' % permission1,
command=('permission_del', [permission1], {}),
expected=errors.NotFound(reason='no such entry'),
),
dict(
desc='Search for non-existent %r' % permission1,
command=('permission_find', [permission1], {}),
expected=dict(
count=0,
truncated=False,
summary=u'0 permissions matched',
result=[],
),
),
dict(
desc='Create %r' % permission1,
command=(
'permission_add', [permission1], dict(
description=u'Test desc 1',
type=u'user',
permissions=u'write',
)
),
expected=dict(
value=permission1,
summary=u'Added permission "%s"' % permission1,
result=dict(
dn=permission1_dn,
cn=[permission1],
description=[u'Test desc 1'],
objectclass=objectclasses.permission,
type=u'user',
permissions=[u'write'],
),
),
),
dict(
desc='Try to create duplicate %r' % permission1,
command=(
'permission_add', [permission1], dict(
description=u'Test desc 1',
type=u'user',
permissions=u'write',
),
),
expected=errors.DuplicateEntry(),
),
dict(
desc='Create %r' % privilege1,
command=('privilege_add', [privilege1],
dict(description=u'privilege desc. 1')
),
expected=dict(
value=privilege1,
summary=u'Added privilege "%s"' % privilege1,
result=dict(
dn=privilege1_dn,
cn=[privilege1],
description=[u'privilege desc. 1'],
objectclass=objectclasses.privilege,
),
),
),
dict(
desc='Add permission %r to privilege %r' % (permission1, privilege1),
command=('privilege_add_permission', [privilege1],
dict(permission=permission1)
),
expected=dict(
completed=1,
failed=dict(
member=dict(
permission=[],
),
),
result={
'dn': privilege1_dn,
'cn': [privilege1],
'description': [u'privilege desc. 1'],
'memberof_permission': [permission1],
}
),
),
dict(
desc='Retrieve %r' % permission1,
command=('permission_show', [permission1], {}),
expected=dict(
value=permission1,
summary=None,
result={
'dn': permission1_dn,
'cn': [permission1],
'description': [u'Test desc 1'],
'member_privilege': [privilege1],
'type': u'user',
'permissions': [u'write'],
},
),
),
dict(
desc='Search for %r' % permission1,
command=('permission_find', [permission1], {}),
expected=dict(
count=1,
truncated=False,
summary=u'1 permission matched',
result=[
{
'dn': permission1_dn,
'cn': [permission1],
'description': [u'Test desc 1'],
'member_privilege': [privilege1],
'type': u'user',
'permissions': [u'write'],
},
],
),
),
dict(
desc='Search for %r' % privilege1,
command=('permission_find', [privilege1], {}),
expected=dict(
count=1,
truncated=False,
summary=u'1 permission matched',
result=[
{
'dn': permission1_dn,
'cn': [permission1],
'description': [u'Test desc 1'],
'member_privilege': [privilege1],
'type': u'user',
'permissions': [u'write'],
},
],
),
),
dict(
desc='Create %r' % permission2,
command=(
'permission_add', [permission2], dict(
description=u'Test desc 2',
type=u'user',
permissions=u'write',
)
),
expected=dict(
value=permission2,
summary=u'Added permission "%s"' % permission2,
result=dict(
dn=permission2_dn,
cn=[permission2],
description=[u'Test desc 2'],
objectclass=objectclasses.permission,
type=u'user',
permissions=[u'write'],
),
),
),
dict(
desc='Search for %r' % permission1,
command=('permission_find', [permission1], {}),
expected=dict(
count=2,
truncated=False,
summary=u'2 permissions matched',
result=[
{
'dn': permission1_dn,
'cn': [permission1],
'description': [u'Test desc 1'],
'member_privilege': [privilege1],
'type': u'user',
'permissions': [u'write'],
},
{
'dn': permission2_dn,
'cn': [permission2],
'description': [u'Test desc 2'],
'type': u'user',
'permissions': [u'write'],
},
],
),
),
dict(
desc='Search for %r' % privilege1,
command=('privilege_find', [privilege1], {}),
expected=dict(
count=1,
truncated=False,
summary=u'1 privilege matched',
result=[
{
'dn': privilege1_dn,
'cn': [privilege1],
'description': [u'privilege desc. 1'],
'memberof_permission': [permission1],
},
],
),
),
dict(
desc='Update %r' % permission1,
command=(
'permission_mod', [permission1], dict(description=u'New desc 1')
),
expected=dict(
value=permission1,
summary=u'Modified permission "%s"' % permission1,
result=dict(
dn=permission1_dn,
cn=[permission1],
description=[u'New desc 1'],
member_privilege=[privilege1],
type=u'user',
permissions=[u'write'],
),
),
),
dict(
desc='Retrieve %r to verify update' % permission1,
command=('permission_show', [permission1], {}),
expected=dict(
value=permission1,
summary=None,
result={
'dn': permission1_dn,
'cn': [permission1],
'description': [u'New desc 1'],
'member_privilege': [privilege1],
'type': u'user',
'permissions': [u'write'],
},
),
),
dict(
desc='Delete %r' % permission1,
command=('permission_del', [permission1], {}),
expected=dict(
result=True,
value=permission1,
summary=u'Deleted permission "%s"' % permission1,
)
),
dict(
desc='Try to delete non-existent %r' % permission1,
command=('permission_del', [permission1], {}),
expected=errors.NotFound(reason='no such entry'),
),
dict(
desc='Try to retrieve non-existent %r' % permission1,
command=('permission_show', [permission1], {}),
expected=errors.NotFound(reason='no such entry'),
),
dict(
desc='Try to update non-existent %r' % permission1,
command=('permission_mod', [permission1], dict(description=u'Foo')),
expected=errors.NotFound(reason='no such entry'),
),
dict(
desc='Delete %r' % permission2,
command=('permission_del', [permission2], {}),
expected=dict(
result=True,
value=permission2,
summary=u'Deleted permission "%s"' % permission2,
)
),
dict(
desc='Search for %r' % permission1,
command=('permission_find', [permission1], {}),
expected=dict(
count=0,
truncated=False,
summary=u'0 permissions matched',
result=[],
),
),
dict(
desc='Delete %r' % privilege1,
command=('privilege_del', [privilege1], {}),
expected=dict(
result=True,
value=privilege1,
summary=u'Deleted privilege "%s"' % privilege1,
)
),
]

View File

@ -0,0 +1,365 @@
# Authors:
# Rob Crittenden <rcritten@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; version 2 only
#
# 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, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
"""
Test the `ipalib/plugins/privilege.py` module.
"""
from ipalib import api, errors
from tests.test_xmlrpc import objectclasses
from xmlrpc_test import Declarative, fuzzy_digits, fuzzy_uuid
permission1 = u'testperm'
permission1_dn = u'cn=%s,%s,%s' % (permission1,
api.env.container_permission,api.env.basedn,
)
permission2 = u'testperm2'
permission2_dn = u'cn=%s,%s,%s' % (permission2,
api.env.container_permission,api.env.basedn,
)
privilege1 = u'testpriv1'
privilege1_dn = u'cn=%s,%s,%s' % (
privilege1, api.env.container_privilege, api.env.basedn
)
class test_privilege(Declarative):
cleanup_commands = [
('permission_del', [permission1], {}),
('permission_del', [permission2], {}),
('privilege_del', [privilege1], {}),
]
tests = [
dict(
desc='Try to retrieve non-existent %r' % privilege1,
command=('privilege_show', [privilege1], {}),
expected=errors.NotFound(reason='no such entry'),
),
dict(
desc='Try to update non-existent %r' % privilege1,
command=('privilege_mod', [privilege1], dict(description=u'Foo')),
expected=errors.NotFound(reason='no such entry'),
),
dict(
desc='Try to delete non-existent %r' % privilege1,
command=('privilege_del', [privilege1], {}),
expected=errors.NotFound(reason='no such entry'),
),
dict(
desc='Search for non-existent %r' % privilege1,
command=('privilege_find', [privilege1], {}),
expected=dict(
count=0,
truncated=False,
summary=u'0 privileges matched',
result=[],
),
),
dict(
desc='Create %r' % permission1,
command=(
'permission_add', [permission1], dict(
description=u'Test desc 1',
type=u'user',
permissions=u'add, delete',
)
),
expected=dict(
value=permission1,
summary=u'Added permission "%s"' % permission1,
result=dict(
dn=permission1_dn,
cn=[permission1],
description=[u'Test desc 1'],
objectclass=objectclasses.permission,
type=u'user',
permissions=[u'add', u'delete'],
),
),
),
dict(
desc='Create %r' % privilege1,
command=('privilege_add', [privilege1],
dict(description=u'privilege desc. 1')
),
expected=dict(
value=privilege1,
summary=u'Added privilege "%s"' % privilege1,
result=dict(
dn=privilege1_dn,
cn=[privilege1],
description=[u'privilege desc. 1'],
objectclass=objectclasses.privilege,
),
),
),
dict(
desc='Add permission %r to privilege %r' % (permission1, privilege1),
command=('privilege_add_permission', [privilege1],
dict(permission=permission1)
),
expected=dict(
completed=1,
failed=dict(
member=dict(
permission=[],
),
),
result={
'dn': privilege1_dn,
'cn': [privilege1],
'description': [u'privilege desc. 1'],
'memberof_permission': [permission1],
}
),
),
dict(
desc='Retrieve %r' % privilege1,
command=('privilege_show', [privilege1], {}),
expected=dict(
value=privilege1,
summary=None,
result={
'dn': privilege1_dn,
'cn': [privilege1],
'description': [u'privilege desc. 1'],
'memberof_permission': [permission1],
},
),
),
dict(
desc='Search for %r' % privilege1,
command=('privilege_find', [privilege1], {}),
expected=dict(
count=1,
truncated=False,
summary=u'1 privilege matched',
result=[
{
'dn': privilege1_dn,
'cn': [privilege1],
'description': [u'privilege desc. 1'],
'memberof_permission': [permission1],
},
],
),
),
dict(
desc='Search for %r' % privilege1,
command=('privilege_find', [privilege1], {}),
expected=dict(
count=1,
truncated=False,
summary=u'1 privilege matched',
result=[
{
'dn': privilege1_dn,
'cn': [privilege1],
'description': [u'privilege desc. 1'],
'memberof_permission': [permission1],
},
],
),
),
dict(
desc='Create %r' % permission2,
command=(
'permission_add', [permission2], dict(
description=u'Test desc 2',
type=u'user',
permissions=u'write',
)
),
expected=dict(
value=permission2,
summary=u'Added permission "%s"' % permission2,
result=dict(
dn=permission2_dn,
cn=[permission2],
description=[u'Test desc 2'],
objectclass=objectclasses.permission,
type=u'user',
permissions=[u'write'],
),
),
),
dict(
desc='Add permission %r to privilege %r' % (permission2, privilege1),
command=('privilege_add_permission', [privilege1],
dict(permission=permission2)
),
expected=dict(
completed=1,
failed=dict(
member=dict(
permission=[],
),
),
result={
'dn': privilege1_dn,
'cn': [privilege1],
'description': [u'privilege desc. 1'],
'memberof_permission': [permission1, permission2],
}
),
),
dict(
desc='Add permission %r to privilege %r again' % (permission2, privilege1),
command=('privilege_add_permission', [privilege1],
dict(permission=permission2)
),
expected=dict(
completed=0,
failed=dict(
member=dict(
permission=[(u'testperm2', u'This entry is already a member'),],
),
),
result={
'dn': privilege1_dn,
'cn': [privilege1],
'description': [u'privilege desc. 1'],
'memberof_permission': [permission1, permission2],
}
),
),
dict(
desc='Search for %r' % privilege1,
command=('privilege_find', [privilege1], {}),
expected=dict(
count=1,
truncated=False,
summary=u'1 privilege matched',
result=[
{
'dn': privilege1_dn,
'cn': [privilege1],
'description': [u'privilege desc. 1'],
'memberof_permission': [permission1, permission2],
},
],
),
),
dict(
desc='Update %r' % privilege1,
command=(
'privilege_mod', [privilege1], dict(description=u'New desc 1')
),
expected=dict(
value=privilege1,
summary=u'Modified privilege "%s"' % privilege1,
result=dict(
cn=[privilege1],
description=[u'New desc 1'],
memberof_permission=[permission1, permission2],
),
),
),
dict(
desc='Remove permission from %r' % privilege1,
command=('privilege_remove_permission', [privilege1],
dict(permission=permission1),
),
expected=dict(
completed=1,
failed=dict(
member=dict(
permission=[],
),
),
result={
'dn': privilege1_dn,
'cn': [privilege1],
'description': [u'New desc 1'],
'memberof_permission': [permission2],
}
),
),
dict(
desc='Remove permission from %r again' % privilege1,
command=('privilege_remove_permission', [privilege1],
dict(permission=permission1),
),
expected=dict(
completed=0,
failed=dict(
member=dict(
permission=[(u'testperm', u'This entry is not a member'),],
),
),
result={
'dn': privilege1_dn,
'cn': [privilege1],
'description': [u'New desc 1'],
'memberof_permission': [permission2],
}
),
),
dict(
desc='Delete %r' % privilege1,
command=('privilege_del', [privilege1], {}),
expected=dict(
result=True,
value=privilege1,
summary=u'Deleted privilege "%s"' % privilege1,
)
),
]

View File

@ -0,0 +1,566 @@
# Authors:
# Rob Crittenden <rcritten@redhat.com>
# Pavel Zuna <pzuna@redhat.com>
#
# Copyright (C) 2009 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; version 2 only
#
# 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, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
"""
Test the `ipalib/plugins/role.py` module.
"""
from ipalib import api, errors
from tests.test_xmlrpc import objectclasses
from xmlrpc_test import Declarative, fuzzy_digits, fuzzy_uuid
search = u'test-role'
role1 = u'test-role-1'
role1_dn = u'cn=%s,%s,%s' % (
role1, api.env.container_rolegroup, api.env.basedn
)
renamedrole1 = u'test-role'
role2 = u'test-role-2'
role2_dn = u'cn=%s,%s,%s' % (
role2, api.env.container_rolegroup, api.env.basedn
)
group1 = u'testgroup1'
group1_dn = u'cn=%s,%s,%s' % (group1, api.env.container_group, api.env.basedn)
privilege1 = u'testpriv1'
privilege1_dn = u'cn=%s,%s,%s' % (privilege1, api.env.container_privilege, api.env.basedn)
class test_role(Declarative):
cleanup_commands = [
('role_del', [role1], {}),
('role_del', [role2], {}),
('group_del', [group1], {}),
('privilege_del', [privilege1], {}),
]
tests = [
dict(
desc='Try to retrieve non-existent %r' % role1,
command=('role_show', [role1], {}),
expected=errors.NotFound(reason='no such entry'),
),
dict(
desc='Try to update non-existent %r' % role1,
command=('role_mod', [role1], dict(description=u'Foo')),
expected=errors.NotFound(reason='no such entry'),
),
dict(
desc='Try to delete non-existent %r' % role1,
command=('role_del', [role1], {}),
expected=errors.NotFound(reason='no such entry'),
),
dict(
desc='Try to rename non-existent %r' % role1,
command=('role_del', [role1], dict(setattr=u'cn=%s' % renamedrole1)),
expected=errors.NotFound(reason='no such entry'),
),
dict(
desc='Search for non-existent %r' % role1,
command=('role_find', [role1], {}),
expected=dict(
count=0,
truncated=False,
summary=u'0 roles matched',
result=[],
),
),
dict(
desc='Create %r' % role1,
command=('role_add', [role1],
dict(description=u'role desc 1')
),
expected=dict(
value=role1,
summary=u'Added role "%s"' % role1,
result=dict(
dn=role1_dn,
cn=[role1],
description=[u'role desc 1'],
objectclass=objectclasses.role,
),
),
),
dict(
desc='Retrieve %r' % role1,
command=('role_show', [role1], {}),
expected=dict(
value=role1,
summary=None,
result=dict(
dn=role1_dn,
cn=[role1],
description=[u'role desc 1'],
),
),
),
dict(
desc='Create %r' % group1,
command=(
'group_add', [group1], dict(description=u'group desc 1',
nonposix=True,)
),
expected=dict(
value=group1,
summary=u'Added group "testgroup1"',
result=dict(
dn=group1_dn,
cn=[group1],
description=[u'group desc 1'],
objectclass=objectclasses.group,
ipauniqueid=[fuzzy_uuid],
),
),
),
dict(
desc='Create %r' % privilege1,
command=('privilege_add', [privilege1],
dict(description=u'privilege desc. 1')
),
expected=dict(
value=privilege1,
summary=u'Added privilege "%s"' % privilege1,
result=dict(
dn=privilege1_dn,
cn=[privilege1],
description=[u'privilege desc. 1'],
objectclass=objectclasses.privilege,
),
),
),
dict(
desc='Add privilege %r to role %r' % (privilege1, role1),
command=('role_add_privilege', [role1],
dict(privilege=privilege1)
),
expected=dict(
completed=1,
failed=dict(
member=dict(
privilege=[],
),
),
result={
'dn': role1_dn,
'cn': [role1],
'description': [u'role desc 1'],
'memberof_privilege': [privilege1],
}
),
),
dict(
desc='Add member %r to %r' % (group1, role1),
command=('role_add_member', [role1], dict(group=group1)),
expected=dict(
completed=1,
failed=dict(
member=dict(
user=[],
group=[],
host=[],
hostgroup=[],
),
),
result={
'dn': role1_dn,
'cn': [role1],
'description': [u'role desc 1'],
'member_group': [group1],
'memberof_privilege': [privilege1],
}
),
),
dict(
desc='Retrieve %r to verify member-add' % role1,
command=('role_show', [role1], {}),
expected=dict(
value=role1,
summary=None,
result={
'dn': role1_dn,
'cn': [role1],
'description': [u'role desc 1'],
'member_group': [group1],
'memberof_privilege': [privilege1],
},
),
),
dict(
desc='Search for %r' % role1,
command=('role_find', [role1], {}),
expected=dict(
count=1,
truncated=False,
summary=u'1 role matched',
result=[
{
'dn': role1_dn,
'cn': [role1],
'description': [u'role desc 1'],
'member_group': [group1],
'memberof_privilege': [privilege1],
},
],
),
),
dict(
desc='Search for %r' % search,
command=('role_find', [search], {}),
expected=dict(
count=1,
truncated=False,
summary=u'1 role matched',
result=[
{
'dn': role1_dn,
'cn': [role1],
'description': [u'role desc 1'],
'member_group': [group1],
'memberof_privilege': [privilege1],
},
],
),
),
dict(
desc='Create %r' % role2,
command=('role_add', [role2],
dict(description=u'role desc 2')
),
expected=dict(
value=role2,
summary=u'Added role "%s"' % role2,
result=dict(
dn=role2_dn,
cn=[role2],
description=[u'role desc 2'],
objectclass=objectclasses.role,
),
),
),
dict(
desc='Search for %r' % role1,
command=('role_find', [role1], {}),
expected=dict(
count=1,
truncated=False,
summary=u'1 role matched',
result=[
{
'dn': role1_dn,
'cn': [role1],
'description': [u'role desc 1'],
'member_group': [group1],
'memberof_privilege': [privilege1],
},
],
),
),
dict(
desc='Search for %r' % search,
command=('role_find', [search], {}),
expected=dict(
count=2,
truncated=False,
summary=u'2 roles matched',
result=[
{
'dn': role1_dn,
'cn': [role1],
'description': [u'role desc 1'],
'member_group': [group1],
'memberof_privilege': [privilege1],
},
{
'dn': role2_dn,
'cn': [role2],
'description': [u'role desc 2'],
},
],
),
),
dict(
desc='Update %r' % role1,
command=(
'role_mod', [role1], dict(description=u'New desc 1')
),
expected=dict(
value=role1,
summary=u'Modified role "%s"' % role1,
result=dict(
cn=[role1],
description=[u'New desc 1'],
member_group=[group1],
memberof_privilege=[privilege1],
),
),
),
dict(
desc='Retrieve %r to verify update' % role1,
command=('role_show', [role1], {}),
expected=dict(
value=role1,
summary=None,
result={
'dn': role1_dn,
'cn': [role1],
'description': [u'New desc 1'],
'member_group': [group1],
'memberof_privilege': [privilege1],
},
),
),
dict(
desc='Remove member %r from %r' % (group1, role1),
command=('role_remove_member', [role1], dict(group=group1)),
expected=dict(
completed=1,
failed=dict(
member=dict(
user=[],
group=[],
host=[],
hostgroup=[],
),
),
result={
'dn': role1_dn,
'cn': [role1],
'description': [u'New desc 1'],
'memberof_privilege': [privilege1],
},
),
),
dict(
desc='Retrieve %r to verify member-del' % role1,
command=('role_show', [role1], {}),
expected=dict(
value=role1,
summary=None,
result={
'dn': role1_dn,
'cn': [role1],
'description': [u'New desc 1'],
'memberof_privilege': [privilege1],
},
),
),
dict(
desc='Delete %r' % group1,
command=('group_del', [group1], {}),
expected=dict(
result=True,
value=group1,
summary=u'Deleted group "testgroup1"',
)
),
dict(
desc='Rename %r' % role1,
command=('role_mod', [role1], dict(setattr=u'cn=%s' % renamedrole1)),
expected=dict(
value=role1,
result=dict(
cn=[renamedrole1],
description=[u'New desc 1'],
memberof_privilege=[privilege1],
),
summary=u'Modified role "%s"' % role1
)
),
dict(
desc='Rename %r back' % renamedrole1,
command=('role_mod', [renamedrole1], dict(setattr=u'cn=%s' % role1)),
expected=dict(
value=renamedrole1,
result=dict(
cn=[role1],
description=[u'New desc 1'],
memberof_privilege=[privilege1],
),
summary=u'Modified role "%s"' % renamedrole1
)
),
dict(
desc='Remove privilege %r from role %r' % (privilege1, role1),
command=('role_remove_privilege', [role1],
dict(privilege=privilege1)
),
expected=dict(
completed=1,
failed=dict(
member=dict(
privilege=[],
),
),
result={
'dn': role1_dn,
'cn': [role1],
'description': [u'New desc 1'],
}
),
),
dict(
desc='Remove privilege %r from role %r again' % (privilege1, role1),
command=('role_remove_privilege', [role1],
dict(privilege=privilege1)
),
expected=dict(
completed=0,
failed=dict(
member=dict(
privilege=[(u'%s' % privilege1, u'This entry is not a member'),],
),
),
result={
'dn': role1_dn,
'cn': [role1],
'description': [u'New desc 1'],
}
),
),
dict(
desc='Delete %r' % role1,
command=('role_del', [role1], {}),
expected=dict(
result=True,
value=role1,
summary=u'Deleted role "%s"' % role1,
)
),
dict(
desc='Try to delete non-existent %r' % role1,
command=('role_del', [role1], {}),
expected=errors.NotFound(reason='no such entry'),
),
dict(
desc='Try to retrieve non-existent %r' % role1,
command=('role_show', [group1], {}),
expected=errors.NotFound(reason='no such entry'),
),
dict(
desc='Try to update non-existent %r' % role1,
command=('role_mod', [role1], dict(description=u'Foo')),
expected=errors.NotFound(reason='no such entry'),
),
dict(
desc='Search for %r' % search,
command=('role_find', [search], {}),
expected=dict(
count=1,
truncated=False,
summary=u'1 role matched',
result=[
{
'dn': role2_dn,
'cn': [role2],
'description': [u'role desc 2'],
},
],
),
),
dict(
desc='Delete %r' % role2,
command=('role_del', [role2], {}),
expected=dict(
result=True,
value=role2,
summary=u'Deleted role "%s"' % role2,
)
),
dict(
desc='Search for %r' % search,
command=('role_find', [search], {}),
expected=dict(
count=0,
truncated=False,
summary=u'0 roles matched',
result=[],
),
),
]

View File

@ -1,467 +0,0 @@
# Authors:
# Rob Crittenden <rcritten@redhat.com>
# Pavel Zuna <pzuna@redhat.com>
#
# Copyright (C) 2009 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; version 2 only
#
# 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, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
"""
Test the `ipalib/plugins/rolegroup.py` module.
"""
from ipalib import api, errors
from tests.test_xmlrpc import objectclasses
from xmlrpc_test import Declarative, fuzzy_digits, fuzzy_uuid
search = u'test-rolegroup'
rolegroup1 = u'test-rolegroup-1'
rolegroup1_dn = u'cn=%s,cn=rolegroups,cn=accounts,%s' % (
rolegroup1, api.env.basedn
)
renamedrolegroup1 = u'test-rolegroup'
rolegroup2 = u'test-rolegroup-2'
rolegroup2_dn = u'cn=%s,cn=rolegroups,cn=accounts,%s' % (
rolegroup2, api.env.basedn
)
group1 = u'testgroup1'
group1_dn = u'cn=%s,cn=groups,cn=accounts,%s' % (group1, api.env.basedn)
class test_rolegroup(Declarative):
cleanup_commands = [
('rolegroup_del', [rolegroup1], {}),
('rolegroup_del', [rolegroup2], {}),
('group_del', [group1], {}),
]
tests = [
dict(
desc='Try to retrieve non-existent %r' % rolegroup1,
command=('rolegroup_show', [rolegroup1], {}),
expected=errors.NotFound(reason='no such entry'),
),
dict(
desc='Try to update non-existent %r' % rolegroup1,
command=('rolegroup_mod', [rolegroup1], dict(description=u'Foo')),
expected=errors.NotFound(reason='no such entry'),
),
dict(
desc='Try to delete non-existent %r' % rolegroup1,
command=('rolegroup_del', [rolegroup1], {}),
expected=errors.NotFound(reason='no such entry'),
),
dict(
desc='Try to rename non-existent %r' % rolegroup1,
command=('rolegroup_del', [rolegroup1], dict(setattr=u'cn=%s' % renamedrolegroup1)),
expected=errors.NotFound(reason='no such entry'),
),
dict(
desc='Search for non-existent %r' % rolegroup1,
command=('rolegroup_find', [rolegroup1], {}),
expected=dict(
count=0,
truncated=False,
summary=u'0 rolegroups matched',
result=[],
),
),
dict(
desc='Create %r' % rolegroup1,
command=('rolegroup_add', [rolegroup1],
dict(description=u'rolegroup desc 1')
),
expected=dict(
value=rolegroup1,
summary=u'Added rolegroup "test-rolegroup-1"',
result=dict(
dn=rolegroup1_dn,
cn=[rolegroup1],
description=[u'rolegroup desc 1'],
objectclass=objectclasses.rolegroup,
),
),
),
dict(
desc='Retrieve %r' % rolegroup1,
command=('rolegroup_show', [rolegroup1], {}),
expected=dict(
value=rolegroup1,
summary=None,
result=dict(
dn=rolegroup1_dn,
cn=[rolegroup1],
description=[u'rolegroup desc 1'],
),
),
),
dict(
desc='Create %r' % group1,
command=(
'group_add', [group1], dict(description=u'group desc 1',
nonposix=True,)
),
expected=dict(
value=group1,
summary=u'Added group "testgroup1"',
result=dict(
dn=group1_dn,
cn=[group1],
description=[u'group desc 1'],
objectclass=objectclasses.group,
ipauniqueid=[fuzzy_uuid],
),
),
),
dict(
desc='Add member %r to %r' % (group1, rolegroup1),
command=('rolegroup_add_member', [rolegroup1], dict(group=group1)),
expected=dict(
completed=1,
failed=dict(
member=dict(
user=[],
group=[],
host=[],
hostgroup=[],
),
),
result={
'dn': rolegroup1_dn,
'cn': [rolegroup1],
'description': [u'rolegroup desc 1'],
'member_group': [group1],
}
),
),
dict(
desc='Retrieve %r to verify member-add' % rolegroup1,
command=('rolegroup_show', [rolegroup1], {}),
expected=dict(
value=rolegroup1,
summary=None,
result={
'dn': rolegroup1_dn,
'cn': [rolegroup1],
'description': [u'rolegroup desc 1'],
'member_group': [group1],
},
),
),
dict(
desc='Search for %r' % rolegroup1,
command=('rolegroup_find', [rolegroup1], {}),
expected=dict(
count=1,
truncated=False,
summary=u'1 rolegroup matched',
result=[
{
'dn': rolegroup1_dn,
'cn': [rolegroup1],
'description': [u'rolegroup desc 1'],
'member_group': [group1],
},
],
),
),
dict(
desc='Search for %r' % search,
command=('rolegroup_find', [search], {}),
expected=dict(
count=1,
truncated=False,
summary=u'1 rolegroup matched',
result=[
{
'dn': rolegroup1_dn,
'cn': [rolegroup1],
'description': [u'rolegroup desc 1'],
'member_group': [group1],
},
],
),
),
dict(
desc='Create %r' % rolegroup2,
command=('rolegroup_add', [rolegroup2],
dict(description=u'rolegroup desc 2')
),
expected=dict(
value=rolegroup2,
summary=u'Added rolegroup "test-rolegroup-2"',
result=dict(
dn=rolegroup2_dn,
cn=[rolegroup2],
description=[u'rolegroup desc 2'],
objectclass=objectclasses.rolegroup,
),
),
),
dict(
desc='Search for %r' % rolegroup1,
command=('rolegroup_find', [rolegroup1], {}),
expected=dict(
count=1,
truncated=False,
summary=u'1 rolegroup matched',
result=[
{
'dn': rolegroup1_dn,
'cn': [rolegroup1],
'description': [u'rolegroup desc 1'],
'member_group': [group1],
},
],
),
),
dict(
desc='Search for %r' % search,
command=('rolegroup_find', [search], {}),
expected=dict(
count=2,
truncated=False,
summary=u'2 rolegroups matched',
result=[
{
'dn': rolegroup1_dn,
'cn': [rolegroup1],
'description': [u'rolegroup desc 1'],
'member_group': [group1],
},
{
'dn': rolegroup2_dn,
'cn': [rolegroup2],
'description': [u'rolegroup desc 2'],
},
],
),
),
dict(
desc='Updated %r' % rolegroup1,
command=(
'rolegroup_mod', [rolegroup1], dict(description=u'New desc 1')
),
expected=dict(
value=rolegroup1,
summary=u'Modified rolegroup "test-rolegroup-1"',
result=dict(
cn=[rolegroup1],
description=[u'New desc 1'],
member_group=[group1],
),
),
),
dict(
desc='Retrieve %r to verify update' % rolegroup1,
command=('rolegroup_show', [rolegroup1], {}),
expected=dict(
value=rolegroup1,
summary=None,
result={
'dn': rolegroup1_dn,
'cn': [rolegroup1],
'description': [u'New desc 1'],
'member_group': [group1],
},
),
),
dict(
desc='Remove member %r from %r' % (group1, rolegroup1),
command=('rolegroup_remove_member', [rolegroup1], dict(group=group1)),
expected=dict(
completed=1,
failed=dict(
member=dict(
user=[],
group=[],
host=[],
hostgroup=[],
),
),
result={
'dn': rolegroup1_dn,
'cn': [rolegroup1],
'description': [u'New desc 1'],
},
),
),
dict(
desc='Retrieve %r to verify member-del' % rolegroup1,
command=('rolegroup_show', [rolegroup1], {}),
expected=dict(
value=rolegroup1,
summary=None,
result={
'dn': rolegroup1_dn,
'cn': [rolegroup1],
'description': [u'New desc 1'],
},
),
),
dict(
desc='Delete %r' % group1,
command=('group_del', [group1], {}),
expected=dict(
result=True,
value=group1,
summary=u'Deleted group "testgroup1"',
)
),
dict(
desc='Rename %r' % rolegroup1,
command=('rolegroup_mod', [rolegroup1], dict(setattr=u'cn=%s' % renamedrolegroup1)),
expected=dict(
value=rolegroup1,
result=dict(
cn=[renamedrolegroup1],
description=[u'New desc 1'],
),
summary=u'Modified rolegroup "%s"' % rolegroup1
)
),
dict(
desc='Rename %r back' % renamedrolegroup1,
command=('rolegroup_mod', [renamedrolegroup1], dict(setattr=u'cn=%s' % rolegroup1)),
expected=dict(
value=renamedrolegroup1,
result=dict(
cn=[rolegroup1],
description=[u'New desc 1'],
),
summary=u'Modified rolegroup "%s"' % renamedrolegroup1
)
),
dict(
desc='Delete %r' % rolegroup1,
command=('rolegroup_del', [rolegroup1], {}),
expected=dict(
result=True,
value=rolegroup1,
summary=u'Deleted rolegroup "test-rolegroup-1"',
)
),
dict(
desc='Try to delete non-existent %r' % rolegroup1,
command=('rolegroup_del', [rolegroup1], {}),
expected=errors.NotFound(reason='no such entry'),
),
dict(
desc='Try to retrieve non-existent %r' % rolegroup1,
command=('rolegroup_show', [group1], {}),
expected=errors.NotFound(reason='no such entry'),
),
dict(
desc='Try to update non-existent %r' % rolegroup1,
command=('rolegroup_mod', [rolegroup1], dict(description=u'Foo')),
expected=errors.NotFound(reason='no such entry'),
),
dict(
desc='Search for %r' % search,
command=('rolegroup_find', [search], {}),
expected=dict(
count=1,
truncated=False,
summary=u'1 rolegroup matched',
result=[
{
'dn': rolegroup2_dn,
'cn': [rolegroup2],
'description': [u'rolegroup desc 2'],
},
],
),
),
dict(
desc='Delete %r' % rolegroup2,
command=('rolegroup_del', [rolegroup2], {}),
expected=dict(
result=True,
value=rolegroup2,
summary=u'Deleted rolegroup "test-rolegroup-2"',
)
),
dict(
desc='Search for %r' % search,
command=('rolegroup_find', [search], {}),
expected=dict(
count=0,
truncated=False,
summary=u'0 rolegroups matched',
result=[],
),
),
]

View File

@ -430,7 +430,7 @@ class test_sudocmdgroup(Declarative):
failed=dict(
member=dict(
sudocmdgroup=tuple(),
sudocmd=[(u'notfound', u'This entry is not a member of the group')],
sudocmd=[(u'notfound', u'This entry is not a member')],
),
),
result={

View File

@ -1,496 +0,0 @@
# Authors:
# Rob Crittenden <rcritten@redhat.com>
# Pavel Zuna <pzuna@redhat.com>
#
# Copyright (C) 2009 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; version 2 only
#
# 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, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
"""
Test the `ipalib/plugins/taskgroup.py` module.
"""
from ipalib import api, errors
from tests.test_xmlrpc import objectclasses
from xmlrpc_test import Declarative, fuzzy_digits, fuzzy_uuid
search = u'test-taskgroup'
taskgroup1 = u'test-taskgroup-1'
taskgroup1_dn = u'cn=%s,cn=taskgroups,cn=accounts,%s' % (
taskgroup1, api.env.basedn
)
renamedtaskgroup1 = u'test-taskgroup1'
taskgroup2 = u'test-taskgroup-2'
taskgroup2_dn = u'cn=%s,cn=taskgroups,cn=accounts,%s' % (
taskgroup2, api.env.basedn
)
group1 = u'testgroup1'
group1_dn = u'cn=%s,cn=groups,cn=accounts,%s' % (group1, api.env.basedn)
rolegroup1 = u'test-rolegroup-1'
rolegroup1_dn = u'cn=%s,cn=rolegroups,cn=accounts,%s' % (
rolegroup1, api.env.basedn
)
class test_taskgroup(Declarative):
cleanup_commands = [
('taskgroup_del', [taskgroup1], {}),
('taskgroup_del', [taskgroup2], {}),
('group_del', [group1], {}),
('rolegroup_del', [rolegroup1], {}),
]
tests = [
dict(
desc='Try to retrieve non-existent %r' % taskgroup1,
command=('taskgroup_show', [taskgroup1], {}),
expected=errors.NotFound(reason='no such entry'),
),
dict(
desc='Try to update non-existent %r' % taskgroup1,
command=('taskgroup_mod', [taskgroup1], dict(description=u'Foo')),
expected=errors.NotFound(reason='no such entry'),
),
dict(
desc='Try to delete non-existent %r' % taskgroup1,
command=('taskgroup_del', [taskgroup1], {}),
expected=errors.NotFound(reason='no such entry'),
),
dict(
desc='Try to rename non-existent %r' % taskgroup1,
command=('taskgroup_del', [taskgroup1], dict(setattr=u'cn=%s' % renamedtaskgroup1)),
expected=errors.NotFound(reason='no such entry'),
),
dict(
desc='Search for non-existent %r' % taskgroup1,
command=('taskgroup_find', [taskgroup1], {}),
expected=dict(
count=0,
truncated=False,
summary=u'0 taskgroups matched',
result=[],
),
),
dict(
desc='Create %r' % taskgroup1,
command=(
'taskgroup_add', [taskgroup1], dict(description=u'Test desc 1')
),
expected=dict(
value=taskgroup1,
summary=u'Added taskgroup "test-taskgroup-1"',
result=dict(
dn=taskgroup1_dn,
cn=[taskgroup1],
description=[u'Test desc 1'],
objectclass=objectclasses.taskgroup,
),
),
),
dict(
desc='Try to create duplicate %r' % taskgroup1,
command=(
'taskgroup_add', [taskgroup1], dict(description=u'Test desc 1')
),
expected=errors.DuplicateEntry(),
),
dict(
desc='Create %r' % rolegroup1,
command=('rolegroup_add', [rolegroup1],
dict(description=u'rolegroup desc. 1')
),
expected=dict(
value=rolegroup1,
summary=u'Added rolegroup "test-rolegroup-1"',
result=dict(
dn=rolegroup1_dn,
cn=[rolegroup1],
description=[u'rolegroup desc. 1'],
objectclass=objectclasses.rolegroup,
),
),
),
dict(
desc='Create %r' % group1,
command=(
'group_add', [group1], dict(description=u'Test group desc 1',
nonposix=True,)
),
expected=dict(
value=group1,
summary=u'Added group "testgroup1"',
result=dict(
dn=group1_dn,
cn=[group1],
description=[u'Test group desc 1'],
objectclass=objectclasses.group,
ipauniqueid=[fuzzy_uuid],
),
),
),
dict(
desc='Add member to %r' % taskgroup1,
command=('taskgroup_add_member', [taskgroup1],
dict(rolegroup=rolegroup1, group=group1)
),
expected=dict(
completed=2,
failed=dict(
member=dict(
rolegroup=[],
group=[],
user=[],
),
),
result={
'dn': taskgroup1_dn,
'cn': [taskgroup1],
'description': [u'Test desc 1'],
'member_rolegroup': [rolegroup1],
'member_group': [group1],
}
),
),
dict(
desc='Retrieve %r' % taskgroup1,
command=('taskgroup_show', [taskgroup1], {}),
expected=dict(
value=taskgroup1,
summary=None,
result={
'dn': taskgroup1_dn,
'cn': [taskgroup1],
'description': [u'Test desc 1'],
'member_rolegroup': [rolegroup1],
'member_group': [group1],
},
),
),
dict(
desc='Search for %r' % taskgroup1,
command=('taskgroup_find', [taskgroup1], {}),
expected=dict(
count=1,
truncated=False,
summary=u'1 taskgroup matched',
result=[
{
'dn': taskgroup1_dn,
'cn': [taskgroup1],
'description': [u'Test desc 1'],
'member_rolegroup': [rolegroup1],
'member_group': [group1],
},
],
),
),
dict(
desc='Search for %r' % search,
command=('taskgroup_find', [search], {}),
expected=dict(
count=1,
truncated=False,
summary=u'1 taskgroup matched',
result=[
{
'dn': taskgroup1_dn,
'cn': [taskgroup1],
'description': [u'Test desc 1'],
'member_rolegroup': [rolegroup1],
'member_group': [group1],
},
],
),
),
dict(
desc='Create %r' % taskgroup2,
command=(
'taskgroup_add', [taskgroup2], dict(description=u'Test desc 2')
),
expected=dict(
value=taskgroup2,
summary=u'Added taskgroup "test-taskgroup-2"',
result=dict(
dn=taskgroup2_dn,
cn=[taskgroup2],
description=[u'Test desc 2'],
objectclass=objectclasses.taskgroup,
),
),
),
dict(
desc='Search for %r' % taskgroup1,
command=('taskgroup_find', [taskgroup1], {}),
expected=dict(
count=1,
truncated=False,
summary=u'1 taskgroup matched',
result=[
{
'dn': taskgroup1_dn,
'cn': [taskgroup1],
'description': [u'Test desc 1'],
'member_rolegroup': [rolegroup1],
'member_group': [group1],
},
],
),
),
dict(
desc='Search for %r' % search,
command=('taskgroup_find', [search], {}),
expected=dict(
count=2,
truncated=False,
summary=u'2 taskgroups matched',
result=[
{
'dn': taskgroup1_dn,
'cn': [taskgroup1],
'description': [u'Test desc 1'],
'member_rolegroup': [rolegroup1],
'member_group': [group1],
},
{
'dn': taskgroup2_dn,
'cn': [taskgroup2],
'description': [u'Test desc 2'],
},
],
),
),
dict(
desc='Updated %r' % taskgroup1,
command=(
'taskgroup_mod', [taskgroup1], dict(description=u'New desc 1')
),
expected=dict(
value=taskgroup1,
summary=u'Modified taskgroup "test-taskgroup-1"',
result=dict(
cn=[taskgroup1],
description=[u'New desc 1'],
member_rolegroup=[rolegroup1],
member_group=[group1],
),
),
),
dict(
desc='Retrieve %r to verify update' % taskgroup1,
command=('taskgroup_show', [taskgroup1], {}),
expected=dict(
value=taskgroup1,
summary=None,
result={
'dn': taskgroup1_dn,
'cn': [taskgroup1],
'description': [u'New desc 1'],
'member_rolegroup': [rolegroup1],
'member_group': [group1],
},
),
),
dict(
desc='Remove member from %r' % taskgroup1,
command=('taskgroup_remove_member', [taskgroup1],
dict(group=group1),
),
expected=dict(
completed=1,
failed=dict(
member=dict(
rolegroup=[],
group=[],
user=[],
),
),
result={
'dn': taskgroup1_dn,
'cn': [taskgroup1],
'description': [u'New desc 1'],
'member_rolegroup': [rolegroup1],
}
),
),
dict(
desc='Rename %r' % taskgroup1,
command=('taskgroup_mod', [taskgroup1], dict(setattr=u'cn=%s' % renamedtaskgroup1)),
expected=dict(
value=taskgroup1,
result=dict(
cn=[renamedtaskgroup1],
description=[u'New desc 1'],
member_rolegroup=[u'test-rolegroup-1'],
),
summary=u'Modified taskgroup "%s"' % taskgroup1
)
),
dict(
desc='Rename %r back' % renamedtaskgroup1,
command=('taskgroup_mod', [renamedtaskgroup1], dict(setattr=u'cn=%s' % taskgroup1)),
expected=dict(
value=renamedtaskgroup1,
result=dict(
cn=[taskgroup1],
description=[u'New desc 1'],
member_rolegroup=[u'test-rolegroup-1'],
),
summary=u'Modified taskgroup "%s"' % renamedtaskgroup1
)
),
dict(
desc='Delete %r' % taskgroup1,
command=('taskgroup_del', [taskgroup1], {}),
expected=dict(
result=True,
value=taskgroup1,
summary=u'Deleted taskgroup "test-taskgroup-1"',
)
),
dict(
desc='Try to delete non-existent %r' % taskgroup1,
command=('taskgroup_del', [taskgroup1], {}),
expected=errors.NotFound(reason='no such entry'),
),
dict(
desc='Try to retrieve non-existent %r' % taskgroup1,
command=('taskgroup_show', [group1], {}),
expected=errors.NotFound(reason='no such entry'),
),
dict(
desc='Try to update non-existent %r' % taskgroup1,
command=('taskgroup_mod', [taskgroup1], dict(description=u'Foo')),
expected=errors.NotFound(reason='no such entry'),
),
dict(
desc='Search for %r' % search,
command=('taskgroup_find', [search], {}),
expected=dict(
count=1,
truncated=False,
summary=u'1 taskgroup matched',
result=[
{
'dn': taskgroup2_dn,
'cn': [taskgroup2],
'description': [u'Test desc 2'],
},
],
),
),
dict(
desc='Delete %r' % taskgroup2,
command=('taskgroup_del', [taskgroup2], {}),
expected=dict(
result=True,
value=taskgroup2,
summary=u'Deleted taskgroup "test-taskgroup-2"',
)
),
dict(
desc='Search for %r' % search,
command=('taskgroup_find', [search], {}),
expected=dict(
count=0,
truncated=False,
summary=u'0 taskgroups matched',
result=[],
),
),
dict(
desc='Delete %r' % group1,
command=('group_del', [group1], {}),
expected=dict(
result=True,
value=group1,
summary=u'Deleted group "testgroup1"',
)
),
dict(
desc='Delete %r' % rolegroup1,
command=('rolegroup_del', [rolegroup1], {}),
expected=dict(
result=True,
value=rolegroup1,
summary=u'Deleted rolegroup "test-rolegroup-1"',
)
),
]

View File

@ -201,8 +201,6 @@ class test_user(Declarative):
sn=[u'Administrator'],
uid=[u'admin'],
memberof_group=[u'admins'],
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'],
nsaccountlock=[u'False'],
),
dict(
@ -237,8 +235,6 @@ class test_user(Declarative):
sn=[u'Administrator'],
uid=[u'admin'],
memberof_group=[u'admins'],
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'],
nsaccountlock=[u'False'],
),
],