MODDN operation specifies a target entry and an optional ‘’ ‘new superior dn’ ‘’. If the ‘’ ‘new superior dn’ ‘’ is different than the parent of the targeted entry, that means the operation tries to move the targeted entry from one part of the DIT (aka ‘source tree’) to an other (aka ‘target tree’).
Currently, access control requires that the bind user is granted the permission to ‘ ADD ‘ an entry in the ‘ target tree ‘. That means 389-DS makes no difference between a user doing a ‘ ADD’ and a ‘MODDN’. In addition 389-DS does no access control on the ‘source tree’, although it could be valuable to control that a given user is allowed to move an entry from one part of the DIT but not from an other part.
This document describes how to enhance the ‘MODDN’ operation and ‘ACI to support access control during a MODDN on:
This changes is handled with ticket https://fedorahosted.org/389/ticket/47553
Being bound as user ‘‘uid=admin_accounts, dc=example,dc=com” (for example), we want to control that this user can:
but can not:
Access control is implemented in ACI code. There is no ACI permission specific to the MODDN operation, so we need a new permission keyword moddn. In MODDN there is a source entry and a destination entry. We want to restrict the MODDN permission to an entry/subtree that is a specified source entry/subtree and a specified destination entry/subtree. To do this we will introduce new target keyword target_from and target_to.
For example, the following ACI will allow ‘uid=admin_accounts,dc=example,dc=com’ to move an entry from staging to production:
aci: (target_from="ldap:///cn=staging,dc=example,dc=com")(target_to="ldap:///cn=production,dc=example,dc=com)") (version 3.0; acl "MODDN from"; allow (moddn)) userdn="ldap:///uid=admin_accounts,dc=example,dc=com";)
The values of those target will be filters. So the following aci is legal:
dn: dc=example,dc=com aci: (target_from="ldap:///uid=*,cn=staging,dc=example,dc=com")(target_to="ldap:///cn=production,dc=example,dc=com") (version 3.0; acl "MODDN from"; allow (moddn)) userdn="ldap:///uid=admin_accounts,dc=example,dc=com";)
It will grant the moddn right to entries that are moved from any of the subtrees “uid=*,cn=staging,dc=example,dc=com” to cn=production,dc=example,dc=com
As usual the ACI only applies in the subtree where it is defined. So in the previous example it applies under “dc=example,dc=com” but not under “dc=tests,dc=com”.
If target_to is missing, the ACI can match any destination resource under where it is defined (“dc=example,dc=com”).
If target_from is missing, the ACI can match any source resource under where it is defined (“dc=example,dc=com”).
The following example shows how to grant a user (bind_entry) to move an entry from staging to accounts with a restriction that deny to move an entry under cn=except,cn=accounts,dc=example,dc=com
Currently MODRDN/MODDN is authorized if the bound user is allowed to ‘ADD’ and ‘WRITE’ under the target entry.
This ticket introduces a new ACI permission moddn to better control MODRDN/MODDN.
If ‘ADD’ and ‘WRITE’ permissions were granted, the customer use to be able to process successfully MODRDN/MODDN. If the customer wants to keep this ability without adding the moddn aci there is three alternatives:
The second alternative is possible but will have a performance impact as ACIs will be scanned/evaluated first on ADD then on MODDN. The last alternative triggers large changes as acl_access_allow only supports a single access value (although access is a bit mask).
To address this compatibility issue, we will introduce a new config parameter (under cn=config): nsslapd-moddn-aci: on/off. By default (value on), during a MODDN operation (move) we will check for moddn permission and during a MODRDN operation (rename RDN) we will check for moddn and write permissions. If the value is off, during a MODDN operation (move) we will check for ADD permission and during a MODRDN operation (rename RDN) we will check for ADD and write permission.
To be selected, the MODDN ACIs should be added in an ancestor of the destination entry. It is not required that the ACI is at a common ancestor of both source/destination entries (TBC). Others targets keywords (‘‘target, targetfilter, targetattr ?, targattrfilter ?) are allowed with target_to and target_from.
If the operation applies on a readonly backend, the moddn permission is not granted
Get Effective Rights is a search control (184.108.40.206.220.127.116.11.18.104.22.168), that returns the rights granted (for a given bound user) on each returned entry and attributes. When this control is present, for each returned entry it calls acl_get_effective_rights that adds the operational attributes: entryLevelRights and attributesLevelRights. Each granted rights is coded in those attributes as described in https://access.redhat.com/site/documentation/en-US/Red_Hat_Directory_Server/9.0/html/Administration_Guide/Viewing_the_ACIs_for_an_Entry-Get_Effective_Rights_Control.html.
MODDN right is an entry level right and is returned with entryLevelRights. If MODDN (aka rename) right is granted it returns the character n.
The main drawback of this alternative is source and destination rights are not evaluated in a single aci. The problem is that if we have
Then although we do not want to allow the move C->B, aci #1 will allow the move to B and aci #4 will allow the move from C.
Access control is implemented in ACI code. There is no ACI permission specific to the MODDN operation, so we need a new permission keyword. For this new permission we need to specify if the target entries of an ACI are either the source tree or the target tree. In addition of the permission keyword for MODDN, the permission keyword must also specify if the target entries are the source tree of the target tree of the MODDN. The new permission keywords are:
For example, the following ACI will allow ‘uid=admin_accounts,dc=example,dc=com’ to move an entry from staging:
aci: (target="ldap:///cn=staging,dc=example,dc=com")(version 3.0; acl "MODDN from"; allow (moddn_from)) userdn="ldap:///uid=admin_accounts,dc=example,dc=com";)
The following ACI will allow ‘uid=admin_accounts,dc=example,dc=com’ to move an entry to accounts:
aci: (target="ldap:///cn=accounts,dc=example,dc=com")(version 3.0; acl "MODDN to"; allow (moddn_to)) userdn="ldap:///uid=admin_accounts,dc=example,dc=com" ;)
Currently MODRDN is granted if the bound user is allowed to ‘ADD and ‘WRITE under the target entries. If such permissions are granted, MODRDN will not be impacted by the changes. The behavior of 389-DS processing MODRDN will be identical whether it exists or not moddn_to and/or moddn_from ACIs.
Currently MODDN is granted if the bound user is allowed to ‘ADD’ an entry under the new superior. With this changes MODDN will FAIL, if there is no ACI granting moddn_from. In fact, superior changing from one DIT to an other, having the ADD permission to the target DIT does not give the right to move the entry from the source DIT.
One can imagine a config compatibility flag, to allow the move.
The ACI scope is the set of entries where the aci is defined and its subtree. We may specify aci targets (target, targetfilter, targetscope, targetattr, targattrfilter) to limit entries where the ACI applies.
For example, we may add the ACI attribute directly at the entry (cn=accounts) where it should apply or set it at an upper level and use the aci targets to select the subtree/entries where it will apply (cn=staging).
The granted rights can be ALLOW or DENY as usual ACI mechanism. It can be useful to put a subtree as a DENY exception to upper level being ALLOWED. In that case the ‘bind_entry’ user can move entries from staging to accounts subtree except under cn=except,cn=accounts,dc=example,dc=com.
Support of new ‘targets’ target_to and target_from
Support of new ‘permission’ moddn
When calling access control (plugin_call_acl_plugin), it checks if given ‘rights’ are allowed on a given entry.
Before evaluating the rights, ACI code selects a set of ACIs. It goes through the list of the ACIs checking for each ACI if it deals with the expected rights and if its targets match the given entry. Once the list of interesting ACIs is built, it then checks the binding rule to see if the ACI applies or not.
The difficulty here is that plugin_call_acl_plugin deals with the rights on one entry, but in case of this new ACI (target_to, target_from) we have to check that target_to matches the destination entry and target_from matches the source entry. To do this checking on two entries, a new field is required in aclpb, to store the source entry SDN.
The changes are:
Update print_access_control_summary/aclanom_match_profile so that if the moddn permission is granted, to display the source/destinations entry DN in case of MODRDN/MODDN.
If the ADD permission is not granted (this is for compatibility), then it checks if MODDN is granted.
If the RDN is not changed (move an entry), do not check if WRITE permission is granted.
This is done by adding in _ger_get_entry_rights a call to acl_access_allowed with SLAPI_ACL_MODDN access
In the ACI code, new permissions “moddn_to” and “moddn_from” should be added (at least get_acl_rights_as_int and acl_access2str).
In slapi_plugin.h, new aclpb_access code to support SLAPI_ACL_MODDN_TO and SLAPI_ACL_MODDN_FROM
In ldbm_back_modrdn, if the ADD permission is not granted check that we have the MODDN_TO permission. If we change to a new superior, check that we have the MODDN_FROM permission on the old superior.
A new on/off configuration parameter is created under ‘cn=config’: nsslapd-moddn-aci. Its default value is on.
By default (value ‘on’), during a MODDN operation (move) we will check for moddn permission and during a MODRDN operation (rename RDN) we will check for moddn and write permissions.
If the value is ‘off’, during a MODDN operation (move) we will check for ADD permission and during a MODRDN operation (rename RDN) we will check for ADD and write permission.
When the new ACIs are replicated to an older version of 389-DS. The new permission moddn and targets target_to and target_from are not recognized. The consequence on replica that do not support this enhancement, is that ACI parser fails to parse the ACIs and they are ignored. A consequence would be that a MODDN user operation can be authorized on a server implementing this ticket and rejected on older version.
ACIs are not checked on replicated operation, so a legacy version of 389-DS will successfully process a replicated MODDN. This even if the original MODDN was authorized by a ADD and WRITE or by a MODDN permission.