18.12. Checking Access Rights on Entries (Get Effective Rights)
18.12. Checking Access Rights on Entries (Get Effective Rights) Finding the access rights that a user has on attributes within a specific entry offers a convenient way for administrators to find and control the access rights. Get effective rights is a way to extend directory searches to display what access rights - such as read, search, write and self-write, add, and delete - a user has to a specified entry. In Directory Server, regular users can check their rights over entries which they can view and can check other people's access to their personal entries. The Directory Manager can check rights that one user has over another user. There are two common situations where checking the effective rights on an entry are useful: An administrator can use the get effective rights command in order to better organize access control instructions for the directory. It is frequently necessary to restrict what one group of users can view or edit versus another group. For instance, members of the QA Managers group may have the right to search and read attributes like manager and salary but only HR Group members have the rights to modify or delete them. Checking the effective rights for a user or group is one way to verify that the appropriate access controls are in place. A user can run the get effective rights command to see what attributes he can view or modify on his personal entry. For instance, a user should have access to attributes such as homePostalAddress and cn but may only have read access to manager and salary attributes. There are three entities involved in a getEffectiveRights search. The first is the requester , which is the authenticated entry when the getEffectiveRights search operation is issued. The second is the subject whose rights will be evaluated, it is defined as authorization DN in the GER control. The third is the target , which is defined by the search base, search filter, and attribute list of the request. 18.12.1. Rights Shown with a Get Effective Rights Search Any get effective rights search, when searching for it in the command line, shows the rights that the requestor has to a target entry. There are two kinds of access rights that can be allowed to any entry. The first are upper-level rights, rights on the entry itself , which means that kinds of operations that the User A can perform on User B's entry as a whole. The second level of access rights are more granular, show what rights for a given attribute User A has. In this case, User A may have different kinds of access permissions for different attributes in the same entry. Whatever access controls are allowed for a user are the effective rights over that entry. For example: Table 18.2, "Entry Rights" and Table 18.3, "Attribute Rights" show the access rights to entries and attributes, respectively, that are returned by a get effective rights search. Table 18.2. Entry Rights Permission Description a Add an entry. d Delete this entry. n Rename the DN. v View the entry. Table 18.3. Attribute Rights Permission Description r Read. s Search. w Write ( mod-add ). o Obliterate( mod-del ). Analogous to delete. c Compare. W Self-write. O Self-delete. 18.12.2. The Format of a Get Effective Rights Search Get effective rights (sometimes called GER) is an extended directory search; the GER parameters are defined with the -E option to pass an LDAP control with the ldapsearch command. (If an ldapsearch is run without the -E option, then, naturally, the entry is returned as normal, without any get effective rights information.) -b is the base DN of the subtree or entry used to search for the GER subject. If the search base is a specific entry DN or if only one entry is returned, then the results show the rights the requester has over that specific entry. If multiple entries beneath the search base match the filter, then the search returns every matching entry, with the rights for the requester over each entry. 1.3.6.1.4.1.42.2.27.9.5.2 is the OID for the get effective rights control. The exclamation point ( ! ) specifies whether the search operation should return an error if the server does not support this control ( ! ) or if it should be ignored and let the search return as normal (nothing). The GER_subject is the person whose rights are being checked. If the GER_subject is left blank ( dn: ), then the rights of an anonymous user are returned. An optional attributeList limits the get effective rights results to the specified attribute or object class. As with a regular ldapsearch , this can give specific attributes, like mail . If no attributes are listed, then every present attribute for the entry is returned. Using an asterisk ( * ) returns the rights for every possible attribute for the entry, both existing attribute and non-existent attributes. Using an plus sign ( + ) returns operational attributes for the entry. Examples for checking rights for specific attributes are given in Section 18.12.3.2, "Examples of Get Effective Rights Searches for Non-Existent Attributes" and Section 18.12.3.3, "Examples of Get Effective Rights Searches for Specific Attributes or Object Classes" . The crux of a get effective rights search is the ability to check what rights the GER subject ( -E ) has to the targets of the search ( -b ). The get effective rights search is a regular ldapsearch , in that it simply looks for entries that match the search parameters and returns their information. The get effective rights option adds extra information to those search results, showing what rights a specific user has over those results. That GER subject user can be the requester himself ( -D is the same as -E ) or someone else. If the requester is a regular user (not the Directory Manager), then the requester can only see the effective that a GER subject has on the requester's own entry. That is, if John Smith runs a request to see what effective rights Babs Jensen has, then he can only get the effective rights that Babs Jensen has on his own entry. All of the other entries return an insufficient access error for the effective rights. There are three general scenarios for a regular user when running a get effective rights search: User A checks the rights that he has over other directory entries. User A checks the rights that he has to his personal entry. User A checks the rights that User B has to User A's entry. The get effective rights search has a number of flexible different ways that it can check rights on attributes. 18.12.3. Examples of GER Searches There are a number of different ways to run GER searches, depending on the exact type of information that needs to be returned and the types of entries and attributes being searched. 18.12.3.1. General Examples on Checking Access Rights One common scenario for effective rights searches is for a regular user to determine what changes he can make to his personal entry. For example, Ted Morris wants to check the rights he has to his entry. Both the -D and -E options give his entry as the requester. Since he is checking his personal entry, the -b option also contains his DN. Example 18.36. Checking Personal Rights (User A to User A) Ted Morris may, for example, be a manager or work in a department where he has to edit other user's entries, such as IT or human resources. In this case, he may want to check what rights he has to another user's entry, as in Example 18.37, "Personally Checking the Rights of One User over Another (User A to User B)" , where Ted ( -D ) checks his rights ( -E ) to Dave Miller's entry ( -b ): Example 18.37. Personally Checking the Rights of One User over Another (User A to User B) For all attributes, Ted Morris has read, search, compare, modify, and delete permissions to Dave Miller's entry. These results are different than the ones returned in checking Ted Morris's access to his own entry, since he personally had only read, search, and compare rights to most of these attributes. The Directory Manager has the ability to check the rights that one user has over another user's entry. In Example 18.38, "The Directory Manager's Checking the Rights of One User over Another (User A to User B)" , the Directory Manager is checking the rights that a manager, Jane Smith ( -E ), has over her subordinate, Ted Morris ( -b ): Example 18.38. The Directory Manager's Checking the Rights of One User over Another (User A to User B) Only an administrator can retrieve the effective rights that a different user has on an entry. If Ted Morris tried to determine Dave Miller's rights to Dave Miller's entry, then he would receive an insufficient access error: However, a regular user can run a get effective rights search to see what rights another user has to his personal entry. In Example 18.39, "Checking the Rights Someone Else Has to a Personal Entry" , Ted Morris checks what rights Dave Miller has on Ted Morris's entry. Example 18.39. Checking the Rights Someone Else Has to a Personal Entry In this case, Dave Miller has the right to view the DN of the entry and to read, search, and compare the ou , givenName , l , and other attributes, and no rights to the userPassword attribute. 18.12.3.2. Examples of Get Effective Rights Searches for Non-Existent Attributes By default, information is not given for attributes in an entry that do not have a value; for example, if the userPassword value is removed, then a future effective rights search on the entry above would not return any effective rights for userPassword , even though self-write and self-delete rights could be allowed. Using an asterisk ( * ) with the get effective rights search returns every attribute available for the entry, including attributes not set on the entry. Example 18.40. Returning Effective Rights for Non-Existent Attributes All of the attributes available for the entry, such as secretary , are listed, even though that attribute is non-existent. 18.12.3.3. Examples of Get Effective Rights Searches for Specific Attributes or Object Classes Taking the attribute-related GER searches further, it is possible to search for the rights to a specific attribute and set of attributes and to list all of the attributes available for one of the object classes set on the entry. One of the options listed in the formatting example in Section 18.12.2, "The Format of a Get Effective Rights Search" is attributeList . To return the effective rights for only specific attributes, list the attributes, separated by spaces, at the end of the search command. Example 18.41. Get Effective Rights Results for Specific Attributes It is possible to specify a non-existent attribute in the attributeList , as with the initials attribute in Example 18.41, "Get Effective Rights Results for Specific Attributes" , to see the rights which are available, similar to using an asterisk to list all attributes. The Directory Manager can also list the rights for all of the attributes available to a specific object class. This option has the format attribute@objectClass . This returns two entries; the first for the specified GER subject and the second for a template entry for the object class. Example 18.42. Get Effective Rights Results for an Attribute within an Object Class Note Using the search format attribute@objectClass is only available if the requester ( -D ) is the Directory Manager. Using an asterisk ( * ) instead of a specific attribute returns all of the attributes (present and non-existent) for the specified GER subject and the full list of attributes for the object class template. Example 18.43. Get Effective Rights Results for All Attributes for an Object Class 18.12.3.4. Examples of Get Effective Rights Searches for Non-Existent Entries An administrator may want to check what rights a specific user ( jsmith ) would have to a non-existent user, based on the existing access control rules. For checking non-existent entries, the server generates a template entry within that subtree. For example, to check for the template entry cn=joe new user,cn=accounts,ou=people,dc=example,dc=com , the server creates cn=template,cn=accounts,ou=people,dc=example,dc=com . For checking a non-existent entry, the get effective rights search can use a specified object class to generate a template entry with all of the potential attributes of the (non-existent) entry. For cn=joe new user,cn=accounts,ou=people,dc=example,dc=com with a person object class ( @person ), the server generates cn=template_person_objectclass,cn=accounts,ou=people,dc=example,dc=com . When the server creates the template entry, it uses the first MUST attribute in the object class definition to create the RDN attribute (or it uses MAY if there is no MUST attribute). However, this may result in an erroneous RDN value which, in turn, violates or circumvents established ACIs for the given subtree. In that case, it is possible to specify the RDN value to use by passing it with the object class. This has the form @objectclass:rdn_attribute . For example, to check the rights of scarter for a non-existent Posix entry with uidNumber as its RDN: 18.12.3.5. Examples of Get Effective Rights Searches for Operational Attributes Operational attributes are not returned in regular ldapsearch es, including get effective rights searches. To return the information for the operational attributes, use the plus sign ( + ). This returns only the operational attributes that can be used in the entry. Example 18.44. Get Effective Rights Results for Operational Attributes 18.12.3.6. Examples of Get Effective Rights Results and Access Control Rules Get effective rights are returned according to whatever ACLs are in effect for the get effective rights subject entry. For example, this ACL is set and, for the purposes of this example, it is the only ACL set: Because the ACL does not include the dc=example,dc=com subtree, the get effective rights search shows that the user does not have any rights to the dc=example,dc=com entry: Example 18.45. Get Effective Rights Results with No ACL Set (Directory Manager) If a regular user, rather than Directory Manager, tried to run the same command, the result would simply be blank. Example 18.46. Get Effective Rights Results with No ACL Set (Regular User) 18.12.4. Get Effective Rights Return Codes If the criticality is not set for a get effective rights search and an error occurs, the regular entry information is returned, but, in place of rights for entryLevelRights and attributeLevelRights , an error code is returned. This code can give information on the configuration of the entry that was queried. Table 18.4, "Returned Result Codes" summarizes the error codes and the potential configuration information they can relay. Table 18.4. Returned Result Codes Code Description 0 Successfully completed. 1 Operation error. 12 The critical extension is unavailable. If the criticality expression is set to true and effective rights do not exist on the entry being queried, then this error is returned. 16 No such attribute. If an attribute is specifically queried for access rights but that attribute does not exist in the schema, this error is returned. 17 Undefined attribute type. 21 Invalid attribute syntax. 50 Insufficient rights. 52 Unavailable. 53 Unwilling to perform. 80 Other.
entryLevelRights: vadn attributeLevelRights: givenName:rscWO, sn:rscW, objectClass:rsc, uid:rsc, cn:rscW ldapsearch -x -D bind_dn -W -p server_port -h server_hostname -E [!]1.3.6.1.4.1.42.2.27.9.5.2=: GER_subject ( searchFilter ) attributeList ldapsearch -x -p 389 -h server.example.com -D "uid=tmorris,ou=people,dc=example,dc=com" -W -b "uid=tmorris,ou=people,dc=example,dc=com" -E '!1.3.6.1.4.1.42.2.27.9.5.2=:dn:uid=tmorris,ou=people,dc=example,dc=com' "(objectClass=*)" dn: uid=tmorris,ou=People,dc=example,dc=com givenName: Ted sn: Morris ou: IT ou: People l: Santa Clara manager: uid=jsmith,ou=People,dc=example,dc=com roomNumber: 4117 mail: tmorris@example.com facsimileTelephoneNumber: +1 408 555 5409 objectClass: top objectClass: person objectClass: organizationalPerson objectClass: inetOrgPerson uid: tmorris cn: Ted Morris userPassword: {SSHA}bz0uCmHZM5b357zwrCUCJs1IOHtMD6yqPyhxBA== entryLevelRights: v attributeLevelRights: givenName:rsc, sn:rsc, ou:rsc, l:rsc, manager:rsc, roomNumber:rscwo, mail:rscwo, facsimileTelephoneNumber:rscwo, objectClass:rsc, uid:rsc, cn:rsc, userPassword:wo ldapsearch -p 389 -h server.example.com -D "uid=tmorris,ou=people,dc=example,dc=com" -W -b "uid=dmiller,ou=people,dc=example,dc=com" -E '!1.3.6.1.4.1.42.2.27.9.5.2=:dn:uid=tmorris,ou=people,dc=example,dc=com' "(objectClass=*)" dn: uid=dmiller,ou=People,dc=example,dc=com entryLevelRights: vad attributeLevelRights: givenName:rscwo, sn:rscwo, ou:rscwo, l:rscwo, manager:rsc, roomNumber:rscwo, mail:rscwo, facsimileTelephoneNumber:rscwo, objectClass:rscwo, uid:rscwo, cn:rscwo, userPassword:rswo ldapsearch -p 389 -h server.example.com -D "cn=Directory Manager" -W -b "uid=tmorris,ou=people,dc=example,dc=com" -E '!1.3.6.1.4.1.42.2.27.9.5.2=:dn:uid=jsmith,ou=people,dc=example,dc=com' "(objectClass=*)" dn: uid=tmorris,ou=People,dc=example,dc=com entryLevelRights: vadn attributeLevelRights: givenName:rscwo, sn:rscwo, ou:rscwo, l:rscwo, manager:rscwo, roomNumber:rscwo, mail:rscwo, facsimileTelephoneNumber:rscwo, objectClass:rscwo, uid:rscwo, cn:rscwo, userPassword:rscwo ldapsearch -p 389 -h server.example.com -D "uid=dmiller,ou=people,dc=example,dc=com" -W -b "uid=tmorris,ou=people,dc=example,dc=com" -E '!1.3.6.1.4.1.42.2.27.9.5.2=:dn:uid=tmorris,ou=people,dc=example,dc=com' "(objectClass=*)" ldap_search: Insufficient access ldap_search: additional info: get-effective-rights: requester has no g permission on the entry ldapsearch -p 389 -h server.example.com -D "uid=tmorris,ou=people,dc=example,dc=com" -W -b "uid=tmorris,ou=people,dc=example,dc=com" -E '!1.3.6.1.4.1.42.2.27.9.5.2=:dn:uid=dmiller,ou=people,dc=example,dc=com' "(objectClass=*)" dn: uid=tmorris,ou=people,dc=example,dc=com entryLevelRights: v attributeLevelRights: givenName:rsc, sn:rsc, ou:rsc, l:rsc,manager:rsc, roomNumber:rsc, mail:rsc, facsimileTelephoneNumber:rsc, objectClass:rsc, uid:rsc, cn:rsc, userPassword:none ldapsearch -D "cn=Directory Manager" -W -b "uid=scarter,ou=people,dc=example,dc=com" -E '!1.3.6.1.4.1.42.2.27.9.5.2=:dn:uid=scarter,ou=people,dc=example,dc=com' "(objectclass=*)" "*" dn: uid=scarter,ou=People,dc=example,dc=com givenName: Sam telephoneNumber: +1 408 555 4798 sn: Carter ou: Accounting ou: People l: Sunnyvale manager: uid=dmiller,ou=People,dc=example,dc=com roomNumber: 4612 mail: scarter@example.com facsimileTelephoneNumber: +1 408 555 9700 objectClass: top objectClass: person objectClass: organizationalPerson objectClass: inetOrgPerson uid: scarter cn: Sam Carter userPassword: {SSHA}Xd9Jt8g1UsHC8enNDrEmxj3iJPKQLItlDYdD9A== entryLevelRights: vadn attributeLevelRights: objectClass:rscwo, aci:rscwo, sn:rscwo, cn:rscwo, description:rscwo, seeAlso:rscwo, telephoneNumber:rscwo, userPassword:rscwo, destinationIndicator:rscwo, facsimileTelephoneNumber:rscwo, internationaliSDNNumber:rscwo, l:rscwo, ou:rscwo, physicalDeliveryOfficeName:rscwo, postOfficeBox:rscwo, postalAddress:rscwo, postalCode:rscwo, preferredDeliveryMethod:rscwo, registeredAddress:rscwo, st:rscwo, street:rscwo, teletexTerminalIdentifier:rscwo, telexNumber:rscwo, title:rscwo, x121Address:rscwo, audio:rscwo, businessCategory:rscwo, carLicense:rscwo, departmentNumber:rscwo, displayName:rscwo, employeeType:rscwo, employeeNumber:rscwo, givenName:rscwo, homePhone:rscwo, homePostalAddress:rscwo, initials:rscwo, jpegPhoto:rscwo, labeledUri:rscwo, manager:rscwo, mobile:rscwo, pager:rscwo, photo:rscwo, preferredLanguage:rscwo, mail:rscwo, o:rscwo, roomNumber:rscwo, secretary:rscwo, uid:rscwo,x500UniqueIdentifier:rscwo, userCertificate:rscwo, userSMIMECertificate:rscwo, userPKCS12:rscwo ldapsearch -D "cn=Directory Manager" -W -b "uid=scarter,ou=people,dc=example,dc=com" -E '!1.3.6.1.4.1.42.2.27.9.5.2=:dn:uid=scarter,ou=people,dc=example,dc=com' "(objectclass=*)" cn mail initials dn: uid=scarter,ou=People,dc=example,dc=com cn: Sam Carter mail: scarter@example.com entryLevelRights: vadn attributeLevelRights: cn:rscwo, mail:rscwo, initials:rscwo ldapsearch -D "cn=Directory Manager" -W -b "uid=scarter,ou=people,dc=example,dc=com" -E '!1.3.6.1.4.1.42.2.27.9.5.2=:dn:uid=scarter,ou=people,dc=example,dc=com' "(objectclass=*)" uidNumber@posixAccount dn: cn=template_posixaccount_objectclass,uid=scarter,ou=people,dc=example,dc=com uidnumber: (template_attribute) entryLevelRights: v attributeLevelRights: uidNumber:rsc ldapsearch -D "cn=Directory Manager" -W -b "uid=scarter,ou=people,dc=example,dc=com" -E '!1.3.6.1.4.1.42.2.27.9.5.2=:dn:uid=scarter,ou=people,dc=example,dc=com' "(objectclass=*)" *@posixaccount dn: cn=template_posixaccount_objectclass,uid=scarter,ou=people,dc=example,dc=com objectClass: posixaccount objectClass: top homeDirectory: (template_attribute) gidNumber: (template_attribute) uidNumber: (template_attribute) uid: (template_attribute) cn: (template_attribute) entryLevelRights: v attributeLevelRights: cn:rsc, uid:rsc, uidNumber:rsc, gidNumber:rsc, homeDirectory:rsc, objectClass:rsc, userPassword:none, loginShell:rsc, gecos:rsc, description:rsc, aci:rsc ldapsearch -D "cn=Directory Manager" -W -b "ou=people,dc=example,dc=com" -E '!1.3.6.1.4.1.42.2.27.9.5.2=:dn:uid=scarter,ou=people,dc=example,dc=com' "(objectclass=*)" @posixaccount:uidnumber dn: uidNumber=template_posixaccount_objectclass,ou=people,dc=example,dc=com entryLevelRights: v attributeLevelRights: description:rsc, gecos:rsc, loginShell:rsc, userPassword :rsc, objectClass:rsc, homeDirectory:rsc, gidNumber:rsc, uidNumber:rsc, uid: rsc, cn:rsc ldapsearch -D "cn=Directory Manager" -W -x -b "uid=scarter,ou=people,dc=example,dc=com" -E '!1.3.6.1.4.1.42.2.27.9.5.2=:dn:uid=scarter,ou=people,dc=example,dc=com' "(objectclass=*)" "+" dn: uid=scarter,ou=People,dc=example,dc=com entryLevelRights: vadn attributeLevelRights: nsICQStatusText:rscwo, passwordGraceUserTime:rscwo, pwdGraceUserTime:rscwo, nsYIMStatusText:rscwo, modifyTimestamp:rscwo, passwordExpWarned:rscwo, pwdExpirationWarned:rscwo, entrydn:rscwo, aci:rscwo, nsSizeLimit:rscwo, nsAccountLock:rscwo, passwordExpirationTime:rscwo, entryid:rscwo, nsSchemaCSN:rscwo, nsRole:rscwo, retryCountResetTime:rscwo, ldapSchemas:rscwo, nsAIMStatusText:rscwo, copiedFrom:rscwo, nsICQStatusGraphic:rscwo, nsUniqueId:rscwo, creatorsName:rscwo, passwordRetryCount:rscwo, dncomp:rscwo, nsTimeLimit:rscwo, passwordHistory:rscwo, pwdHistory:rscwo, nscpEntryDN:rscwo, subschemaSubentry:rscwo, nsYIMStatusGraphic:rscwo, hasSubordinates:rscwo, pwdpolicysubentry:rscwo, nsAIMStatusGraphic:rscwo, nsRoleDN:rscwo, createTimestamp:rscwo, accountUnlockTime:rscwo, copyingFrom:rscwo, nsLookThroughLimit:rscwo, nsds5ReplConflict:rscwo, modifiersName:rscwo, parentid:rscwo, passwordAllowChangeTime:rscwo, nsBackendSuffix:rscwo, nsIdleTimeout:rscwo, ldapSyntaxes:rscwo, numSubordinates:rscwo dn: dc=example,dc=com objectClass: top objectClass: domain dc: example aci: (target=ldap:///ou=Accounting,dc=example,dc=com)(targetattr="*")(version 3.0; acl "test acl"; allow (read,search,compare) (userdn = "ldap:///anyone") ;) dn: ou=Accounting,dc=example,dc=com objectClass: top objectClass: organizationalUnit ou: Accounting ldapsearch -D "cn=Directory Manager" -W -b "dc=example,dc=com" -E '!1.3.6.1.4.1.42.2.27.9.5.2=:dn:uid=scarter,ou=people,dc=example,dc=com' "(objectclass=*)" "*@person" dn: cn=template_person_objectclass,uid=scarter,ou=people,dc=example,dc=com objectClass: person objectClass: top cn: (template_attribute) sn: (template_attribute) description: (template_attribute) seeAlso: (template_attribute) telephoneNumber: (template_attribute) userPassword: (template_attribute) entryLevelRights: none attributeLevelRights: sn:none, cn:none, objectClass:none, description:none, seeAlso:none, telephoneNumber:none, userPassword:none, aci:none ldapsearch -D "uid=scarter,ou=people,dc=example,dc=com" -W -b "dc=example,dc=com" -E '!1.3.6.1.4.1.42.2.27.9.5.2=:dn:uid=scarter,ou=people,dc=example,dc=com' "(objectclass=*)" "*@person"