12.14. Refining Access Controls

Right now, your directory is read-only for everyone, and read/write for the admin user. Is there a way to allocate access controls more finely?

Of course there is. Let's start with our simple example DIT, the one with the suffix of dc=alrac, dc=net, and its single second-level ou=people:

	dc=alrac, dc=net

	ou=people

Let's say we have a number of users in people with the following attributes:

	objectClass:
	cn:
	sn:
	uid:
	title:
	jpegPhoto:
	telephoneNumber:
	homePhone:
	homePostalAddress:
	mail:
	description:

It would be nice to let users control some of their own data, such as passwords, email addresses, and telephone numbers. But, not everything: UIDs, titles, CNs, and such should be protected from mischievous users. So, let's take our access controls from Recipe 12.4 and add to them. The new entries are in bold, and our ACLs are now numbered so we can keep track more easily:

	#ACL 1
	access to attrs=userPassword,shadowLastChange
	    by dn="cn=admin,dc=alrac,dc=net" write
	    by anonymous auth
	    by self write
	    by * none

	#ACL 2
	access to attrs=homePostalAddress,homePhone,telephoneNumber,mail
	    by dn="cn=admin,dc=alrac,dc=net" write
	    by self write
	    by * none

	#ACL 3
	access to dn.base="" by * read

	#ACL 3
	access to *
	        by dn="cn=admin,dc=alrac,dc=net" write
	        by * read

Save your changes, run slaptest, and restart slapd; then fire up an LDAP client, and verify that users can make their own changes:

	$ ldapmodify -xD "uid=cschroder,ou=people,dc=alrac,dc=net" -W
	Enter LDAP Password:
	dn: uid=cschroder,ou=people,dc=alrac,dc=net
	changetype: modify
	replace:mail
	mail: newmail@newmail.com

	modifying entry "uid=cschroder,ou=people,dc=alrac,dc=net"

Hit the return key twice to write your changes, and Ctrl-D to exit.

Now for some trickier stuff. Maybe you want select other persons to have write access to user's entries, such as human resources. We can do this with groups. Create a new OU just for them, like Figure 12-8 shows.

Create a new LDIF file to add these to your directory:

	##groups.ldif
	dn: ou=groups,dc=alrac,dc=net
	objectclass:organizationalUnit
	ou: groups
	description: special administrative groups

	dn: ou=hr,ou=groups,dc=alrac,dc=net
	objectclass: groupOfNames
	ou: hr
	cn: Human Resources
	description: Human Resources staff
	member: uid=thanson,ou=people,dc=alrac,dc=net
	member: uid=ajones,ou=people,dc=alrac,dc=net

Add these new entries to the directory:

	# ldapadd -xD "cn=admin,dc=alrac,dc=net" -W -f groups.ldif

Now, add this as ACL #3 to slapd.conf:

	# ACL 3
	access to dn.one="ou=people,dc=alrac,dc=net"
	    by dn="cn=admin,dc=alrac,dc=net" write
	    by group.exact="ou=hr,ou=groups,dc=example,dc=com" write
	    by users read
	    by * none

Let's do one more. This lets human resources people edit all of their own data:

	# ACL 4
	access to *
	    by dn="cn=admin,dc=alrac,dc=net" write
     	by self write
	    by group.exact="ou=hr,ou=groups,dc=alrac,dc=net" write
	    by users read
	    by * none

Order is important. As soon as a match is found, it is executed. As a rule of thumb, the most specific rules come first, and more general rules later.

ACLs are real power tools, and they can drive you nuts. Please study man 5 slapd.access; it's not the most riveting reading, but it is the most accurate and detailed.

These are the most common user matches:

These are the access levels: