[ Team LiB ] Previous Section Next Section

3.6 Access Control Lists (ACLs)

The Directory ACLs provided by OpenLDAP are simple in their syntax, yet very flexible and powerful in their implementation. The basic idea is to define Who has Access to What? The most frequent forms of "Who" include:

*

Matches any connected user, including anonymous connection

self

The DN of the currently connected user, assuming he has been successfully authenticated by a previous bind request

anonymous

Nonauthenticated user connections

users

Authenticated user connections

Regular expression

Matches a DN or an SASL identity

Remember that the login name used to specify a user for authentication takes the form of a DN (e.g., dn="cn=gerald carter,ou=people,dc=plainjoe,dc=org") or an SASL identify (e.g., dn="uid=jerry,cn=gssapi,cn=auth"). The self value is used as a shortcut for the DN of the authenticated user of the current session. The examples later in this section will help clarify this concept.

The notion of an access level is a new concept. Table 3-7 summarizes the various access privileges. Higher levels possess all of the capabilities of the lower levels. For example, compare access implies auth access, and write access implies read, search, compare, and auth.

Table 3-7. Summary of access levels from most (top) to least (bottom)

Access level

Permission granted

write

Access to update attribute values (e.g., Change this telephoneNumber to 555-2345).

read

Access to read search results (e.g., Show me all the entries with a telephoneNumber of 555*).

search

Access to apply search filters (e.g., Are there any entries with a telephoneNumber of 555*).

compare

Access to compare attributes (e.g., Is your telephoneNumber 555-1234?).

auth

Access to bind (authenticate). This requires that the client send a username in the form of a DN and some type of credentials to prove his or her identity.

none

No access.

The simplest way to control access is to define a default level of authorization. A global slapd.conf parameter defines the default access given to a user in the absence of a more explicit rule. For example, adding the following lines to the global section of slapd.conf gives all users search access unless an explicit ACL says otherwise:

## Give users search access when no other ACL applies.
defaultaccess     search

Finally, the "What" defines the entry and attributes to which the ACL should apply. It is composed of three basic parts, all of which are optional.

  • A regular expression defining the DN of the proposed target of the ACL. The actual syntax is dn.targetstyle=regex, in which targetstyle is one of base, subtree, one, or children, and regex is a regular expression representing a DN. The targetstyle, which defaults to subtree, is used to broaden or narrow the scope of the ACL. If, for example, the targetstyle is set to one, the ACL applies only to children immediately below the defined DN. Very rarely does this setting need be changed from its default. The regex follows normal regular expression rules, with the addition that the DN must be in normalized form. The most common error is to add extra whitespace between components of the DN—for example, you can't add a space after the comma in dc=plainjoe,dc=org.

  • An LDAP search filter that conforms to RFC 2254. (More on LDAP searches will be covered in the next chapter.) The syntax for specifying a filter is filter=ldapFilter.

  • A comma-separated list of attribute names taking the form attrs=attributeList. If this item is not present, the ACL applies to all attributes held by the entry that matches the DN regular expression pattern.

If none of these components are present, a single asterisk (*) is used as a placeholder (for "What") to include everything.

Now that we've looked at the parts of an ACL, let's see how to put an ACL together. It is easiest to understand the syntax of an ACL by examining some practical uses. The following ACL grants read access to everyone:

# Simple ACL granting read access to the world
access to * 
     by * read

The space at the beginning of the second line indicates that this is a continuation of the previous line. This control list could have been written on a single line, but the multiline style is more readable for complex ACLs.

This next example restricts access to the userPassword attribute; any user can access the attribute, but can access it only for authentication purposes. Users can't read or write this attribute.

# Restrict userPassword to be used for authentication only.
access to attrs=userPassword
     by * auth

If a user should be allowed to modify her own password in the directory, the ACL would need to be rewritten as follows:

# Restrict userPassword to be used for authentication only, but allow users to modify
# their own passwords.
access to attrs=userPassword
     by self write
     by * auth

Once authenticated, a user can write her own password. Anyone is allowed to use passwords for authentication purposes.

ACLs are evaluated on a "first match wins" basis. An ACL listed first takes precedence over ACLs mentioned later. This means that more restrictive ACLs should be listed prior to more general ones. Consider what behavior would result from the following two ACLs. What sort of access would be granted to the userPassword attribute?

# Simple ACL granting read access to the world
access to * 
     by * read
      
# Restrict userPassword to be used for authentication only, but allow users to modify
# their own passwords.
access to attrs=userPassword
     by self write
     by * auth

The previous ACLs grant all users (anonymous and authenticated) read access to userPassword. This clearly isn't a policy you would want. To achieve the desired effect of restricting read privileges to this attribute, the ACLs should be ordered as follows:

# Restrict userPassword to be used for authentication only, but allow users to modify
# their own passwords.
access to attrs=userPassword
     by self write
     by * auth
      
# Simple ACL granting read access to the world
access to * 
     by * read

For the next example, assume that the following conditions are met:

  • Administrative user accounts are located beneath the DN ou=admins,ou=eng, dc=plainjoe,dc=org.

  • Normal user accounts are located beneath ou=users,ou=eng,dc=plainjoe,dc=org.

  • Normal users should not be able to view passwords of other users.

  • A user should be able to modify his password.

  • Administrative users should be able to modify any user's password.

We can model these rules with the following ACL:

# Set control on the userPassword attribute.
access to dn=".*,ou=eng,dc=plainjoe,dc=org"
  attrs=userPassword
  by self write
  by * auth
  by dn=".*,ou=admins,ou=eng,dc=plainjoe,dc=org" write

ACLs can very often be written in more than one equivalent form. The following access rule is functionally identical to the one just presented:

# Set control on the userPassword attribute.
access to dn.chilren="ou=eng,dc=plainjoe,dc=org"
  attrs=userPassword
  by self write
  by * auth
  by dn.children="ou=admins,ou=eng,dc=plainjoe,dc=org" write

These examples are only a few possibilities of what can be done. We will continue to explore ACLs as a means of securing our server as we add more information into the directory in later chapters.

    [ Team LiB ] Previous Section Next Section