2 # Copyright 1999-2009 The OpenLDAP Foundation, All Rights Reserved.
3 # COPYING RESTRICTIONS APPLY, see COPYRIGHT.
9 As the directory gets populated with more and more data of varying sensitivity,
10 controlling the kinds of access granted to the directory becomes more and more
11 critical. For instance, the directory may contain data of a confidential nature
12 that you may need to protect by contract or by law. Or, if using the directory
13 to control access to other services, inappropriate access to the directory may
14 create avenues of attack to your sites security that result in devastating
15 damage to your assets.
17 Access to your directory can be configured via two methods, the first using
18 {{SECT:The slapd Configuration File}} and the second using the {{slapd-config}}(5)
19 format ({{SECT:Configuring slapd}}).
21 The default access control policy is allow read by all clients. Regardless of
22 what access control policy is defined, the {{rootdn}} is always allowed full
23 rights (i.e. auth, search, compare, read and write) on everything and anything.
25 As a consequence, it's useless (and results in a performance penalty) to explicitly
26 list the {{rootdn}} among the {{<by>}} clauses.
28 The following sections will describe Access Control Lists in more details and
29 follow with some examples and recommendations.
31 H2: Access Control via Static Configuration
33 Access to entries and attributes is controlled by the
34 access configuration file directive. The general form of an
37 > <access directive> ::= access to <what>
38 > [by <who> [<access>] [<control>] ]+
40 > [dn[.<basic-style>]=<regex> | dn.<scope-style>=<DN>]
41 > [filter=<ldapfilter>] [attrs=<attrlist>]
42 > <basic-style> ::= regex | exact
43 > <scope-style> ::= base | one | subtree | children
44 > <attrlist> ::= <attr> [val[.<basic-style>]=<regex>] | <attr> , <attrlist>
45 > <attr> ::= <attrname> | entry | children
46 > <who> ::= * | [anonymous | users | self
47 > | dn[.<basic-style>]=<regex> | dn.<scope-style>=<DN>]
49 > [group[/<objectclass>[/<attrname>][.<basic-style>]]=<regex>]
50 > [peername[.<basic-style>]=<regex>]
51 > [sockname[.<basic-style>]=<regex>]
52 > [domain[.<basic-style>]=<regex>]
53 > [sockurl[.<basic-style>]=<regex>]
56 > <access> ::= [self]{<level>|<priv>}
57 > <level> ::= none | disclose | auth | compare | search | read | write | manage
58 > <priv> ::= {=|+|-}{m|w|r|s|c|x|d|0}+
59 > <control> ::= [stop | continue | break]
61 where the <what> part selects the entries and/or attributes to which
62 the access applies, the {{EX:<who>}} part specifies which entities
63 are granted access, and the {{EX:<access>}} part specifies the
64 access granted. Multiple {{EX:<who> <access> <control>}} triplets
65 are supported, allowing many entities to be granted different access
66 to the same set of entries and attributes. Not all of these access
67 control options are described here; for more details see the
68 {{slapd.access}}(5) man page.
71 H3: What to control access to
73 The <what> part of an access specification determines the entries
74 and attributes to which the access control applies. Entries are
75 commonly selected in two ways: by DN and by filter. The following
76 qualifiers select entries by DN:
79 > to dn[.<basic-style>]=<regex>
80 > to dn.<scope-style>=<DN>
82 The first form is used to select all entries. The second form may
83 be used to select entries by matching a regular expression against
84 the target entry's {{normalized DN}}. (The second form is not
85 discussed further in this document.) The third form is used to
86 select entries which are within the requested scope of DN. The
87 <DN> is a string representation of the Distinguished Name, as
88 described in {{REF:RFC4514}}.
90 The scope can be either {{EX:base}}, {{EX:one}}, {{EX:subtree}},
91 or {{EX:children}}. Where {{EX:base}} matches only the entry with
92 provided DN, {{EX:one}} matches the entries whose parent is the
93 provided DN, {{EX:subtree}} matches all entries in the subtree whose
94 root is the provided DN, and {{EX:children}} matches all entries
95 under the DN (but not the entry named by the DN).
97 For example, if the directory contained entries named:
100 > 1: cn=Manager,o=suffix
101 > 2: ou=people,o=suffix
102 > 3: uid=kdz,ou=people,o=suffix
103 > 4: cn=addresses,uid=kdz,ou=people,o=suffix
104 > 5: uid=hyc,ou=people,o=suffix
107 . {{EX:dn.base="ou=people,o=suffix"}} match 2;
108 . {{EX:dn.one="ou=people,o=suffix"}} match 3, and 5;
109 . {{EX:dn.subtree="ou=people,o=suffix"}} match 2, 3, 4, and 5; and
110 . {{EX:dn.children="ou=people,o=suffix"}} match 3, 4, and 5.
113 Entries may also be selected using a filter:
115 > to filter=<ldap filter>
117 where <ldap filter> is a string representation of an LDAP
118 search filter, as described in {{REF:RFC4515}}. For example:
120 > to filter=(objectClass=person)
122 Note that entries may be selected by both DN and filter by
123 including both qualifiers in the <what> clause.
125 > to dn.one="ou=people,o=suffix" filter=(objectClass=person)
127 Attributes within an entry are selected by including a comma-separated
128 list of attribute names in the <what> selector:
130 > attrs=<attribute list>
132 A specific value of an attribute is selected by using a single
133 attribute name and also using a value selector:
135 > attrs=<attribute> val[.<style>]=<regex>
137 There are two special {{pseudo}} attributes {{EX:entry}} and
138 {{EX:children}}. To read (and hence return) a target entry, the
139 subject must have {{EX:read}} access to the target's {{entry}}
140 attribute. To perform a search, the subject must have
141 {{EX:search}} access to the search base's {{entry}} attribute.
142 To add or delete an entry, the subject must have
143 {{EX:write}} access to the entry's {{EX:entry}} attribute AND must
144 have {{EX:write}} access to the entry's parent's {{EX:children}}
145 attribute. To rename an entry, the subject must have {{EX:write}}
146 access to entry's {{EX:entry}} attribute AND have {{EX:write}}
147 access to both the old parent's and new parent's {{EX:children}}
148 attributes. The complete examples at the end of this section should
149 help clear things up.
151 Lastly, there is a special entry selector {{EX:"*"}} that is used to
152 select any entry. It is used when no other {{EX:<what>}}
153 selector has been provided. It's equivalent to "{{EX:dn=.*}}"
156 H3: Who to grant access to
158 The <who> part identifies the entity or entities being granted
159 access. Note that access is granted to "entities" not "entries."
160 The following table summarizes entity specifiers:
162 !block table; align=Center; coltags="EX,N"; \
163 title="Table 6.3: Access Entity Specifiers"
165 *|All, including anonymous and authenticated users
166 anonymous|Anonymous (non-authenticated) users
167 users|Authenticated users
168 self|User associated with target entry
169 dn[.<basic-style>]=<regex>|Users matching a regular expression
170 dn.<scope-style>=<DN>|Users within scope of a DN
173 The DN specifier behaves much like <what> clause DN specifiers.
175 Other control factors are also supported. For example, a {{EX:<who>}}
176 can be restricted by an entry listed in a DN-valued attribute in
177 the entry to which the access applies:
179 > dnattr=<dn-valued attribute name>
181 The dnattr specification is used to give access to an entry
182 whose DN is listed in an attribute of the entry (e.g., give
183 access to a group entry to whoever is listed as the owner of
186 Some factors may not be appropriate in all environments (or any).
187 For example, the domain factor relies on IP to domain name lookups.
188 As these can easily be spoofed, the domain factor should be avoided.
191 H3: The access to grant
193 The kind of <access> granted can be one of the following:
195 !block table; colaligns="LRL"; coltags="EX,EX,N"; align=Center; \
196 title="Table 6.4: Access Levels"
197 Level Privileges Description
199 disclose =d needed for information disclosure on error
200 auth =dx needed to authenticate (bind)
201 compare =cdx needed to compare
202 search =scdx needed to apply search filters
203 read =rscdx needed to read search results
204 write =wrscdx needed to modify/rename
205 manage =mwrscdx needed to manage
208 Each level implies all lower levels of access. So, for example,
209 granting someone {{EX:write}} access to an entry also grants them
210 {{EX:read}}, {{EX:search}}, {{EX:compare}}, {{EX:auth}} and
211 {{EX:disclose}} access. However, one may use the privileges specifier
212 to grant specific permissions.
215 H3: Access Control Evaluation
217 When evaluating whether some requester should be given access to
218 an entry and/or attribute, slapd compares the entry and/or attribute
219 to the {{EX:<what>}} selectors given in the configuration file.
220 For each entry, access controls provided in the database which holds
221 the entry (or the global access directives if not held in any database) apply
222 first, followed by the global access directives. However, when dealing with
223 an access list, because the global access list is effectively appended
224 to each per-database list, if the resulting list is non-empty then the
225 access list will end with an implicit {{EX:access to * by * none}} directive.
226 If there are no access directives applicable to a backend, then a default
230 priority, access directives are examined in the order in which they
231 appear in the config file. Slapd stops with the first {{EX:<what>}}
232 selector that matches the entry and/or attribute. The corresponding
233 access directive is the one slapd will use to evaluate access.
235 Next, slapd compares the entity requesting access to the {{EX:<who>}}
236 selectors within the access directive selected above in the order
237 in which they appear. It stops with the first {{EX:<who>}} selector
238 that matches the requester. This determines the access the entity
239 requesting access has to the entry and/or attribute.
241 Finally, slapd compares the access granted in the selected
242 {{EX:<access>}} clause to the access requested by the client. If
243 it allows greater or equal access, access is granted. Otherwise,
246 The order of evaluation of access directives makes their placement
247 in the configuration file important. If one access directive is
248 more specific than another in terms of the entries it selects, it
249 should appear first in the config file. Similarly, if one {{EX:<who>}}
250 selector is more specific than another it should come first in the
251 access directive. The access control examples given below should
252 help make this clear.
256 H3: Access Control Examples
258 The access control facility described above is quite powerful. This
259 section shows some examples of its use for descriptive purposes.
263 > access to * by * read
265 This access directive grants read access to everyone.
272 This directive allows the user to modify their entry, allows anonymous
273 to authentication against these entries, and allows all others to
274 read these entries. Note that only the first {{EX:by <who>}} clause
275 which matches applies. Hence, the anonymous users are granted
276 {{EX:auth}}, not {{EX:read}}. The last clause could just as well
277 have been "{{EX:by users read}}".
279 It is often desirable to restrict operations based upon the level
280 of protection in place. The following shows how security strength
281 factors (SSF) can be used.
284 > by ssf=128 self write
285 > by ssf=64 anonymous auth
286 > by ssf=64 users read
288 This directive allows users to modify their own entries if security
289 protections have of strength 128 or better have been established,
290 allows authentication access to anonymous users, and read access
291 when 64 or better security protections have been established. If
292 client has not establish sufficient security protections, the
293 implicit {{EX:by * none}} clause would be applied.
295 The following example shows the use of a style specifiers to select
296 the entries by DN in two access directives where ordering is
299 > access to dn.children="dc=example,dc=com"
301 > access to dn.children="dc=com"
304 Read access is granted to entries under the {{EX:dc=com}} subtree,
305 except for those entries under the {{EX:dc=example,dc=com}} subtree,
306 to which search access is granted. No access is granted to
307 {{EX:dc=com}} as neither access directive matches this DN. If the
308 order of these access directives was reversed, the trailing directive
309 would never be reached, since all entries under {{EX:dc=example,dc=com}}
310 are also under {{EX:dc=com}} entries.
312 Also note that if no {{EX:access to}} directive matches or no {{EX:by
313 <who>}} clause, {{B:access is denied}}. That is, every {{EX:access
314 to}} directive ends with an implicit {{EX:by * none}} clause. When dealing
315 with an access list, because the global access list is effectively appended
316 to each per-database list, if the resulting list is non-empty then the access
317 list will end with an implicit {{EX:access to * by * none}} directive. If
318 there are no access directives applicable to a backend, then a default read is
321 The next example again shows the importance of ordering, both of
322 the access directives and the {{EX:by <who>}} clauses. It also
323 shows the use of an attribute selector to grant access to a specific
324 attribute and various {{EX:<who>}} selectors.
326 > access to dn.subtree="dc=example,dc=com" attrs=homePhone
328 > by dn.children="dc=example,dc=com" search
329 > by peername.regex=IP:10\..+ read
330 > access to dn.subtree="dc=example,dc=com"
332 > by dn.children="dc=example,dc=com" search
335 This example applies to entries in the "{{EX:dc=example,dc=com}}"
336 subtree. To all attributes except {{EX:homePhone}}, an entry can
337 write to itself, entries under {{EX:example.com}} entries can search
338 by them, anybody else has no access (implicit {{EX:by * none}})
339 excepting for authentication/authorization (which is always done
340 anonymously). The {{EX:homePhone}} attribute is writable by the
341 entry, searchable by entries under {{EX:example.com}}, readable by
342 clients connecting from network 10, and otherwise not readable
343 (implicit {{EX:by * none}}). All other access is denied by the
344 implicit {{EX:access to * by * none}}.
346 Sometimes it is useful to permit a particular DN to add or
347 remove itself from an attribute. For example, if you would like to
348 create a group and allow people to add and remove only
349 their own DN from the member attribute, you could accomplish
350 it with an access directive like this:
352 > access to attrs=member,entry
353 > by dnattr=member selfwrite
355 The dnattr {{EX:<who>}} selector says that the access applies to
356 entries listed in the {{EX:member}} attribute. The {{EX:selfwrite}} access
357 selector says that such members can only add or delete their
358 own DN from the attribute, not other values. The addition of
359 the entry attribute is required because access to the entry is
360 required to access any of the entry's attributes.
363 For more details on how to use the {{EX:access}} directive,
364 consult the {{Advanced Access Control}} chapter.
368 H3: Configuration File Example
370 The following is an example configuration file, interspersed
371 with explanatory text. It defines two databases to handle
372 different parts of the {{TERM:X.500}} tree; both are {{TERM:BDB}}
373 database instances. The line numbers shown are provided for
374 reference only and are not included in the actual file. First, the
375 global configuration section:
377 E: 1. # example config file - global configuration section
378 E: 2. include /usr/local/etc/schema/core.schema
379 E: 3. referral ldap://root.openldap.org
380 E: 4. access to * by * read
382 Line 1 is a comment. Line 2 includes another config file
383 which contains {{core}} schema definitions.
384 The {{EX:referral}} directive on line 3
385 means that queries not local to one of the databases defined
386 below will be referred to the LDAP server running on the
387 standard port (389) at the host {{EX:root.openldap.org}}.
389 Line 4 is a global access control. It applies to all
390 entries (after any applicable database-specific access
393 The next section of the configuration file defines a BDB
394 backend that will handle queries for things in the
395 "dc=example,dc=com" portion of the tree. The
396 database is to be replicated to two slave slapds, one on
397 truelies, the other on judgmentday. Indices are to be
398 maintained for several attributes, and the {{EX:userPassword}}
399 attribute is to be protected from unauthorized access.
401 E: 5. # BDB definition for the example.com
403 E: 7. suffix "dc=example,dc=com"
404 E: 8. directory /usr/local/var/openldap-data
405 E: 9. rootdn "cn=Manager,dc=example,dc=com"
407 E: 11. # indexed attribute definitions
408 E: 12. index uid pres,eq
409 E: 13. index cn,sn,uid pres,eq,approx,sub
410 E: 14. index objectClass eq
411 E: 15. # database access control definitions
412 E: 16. access to attrs=userPassword
414 E: 18. by anonymous auth
415 E: 19. by dn.base="cn=Admin,dc=example,dc=com" write
419 E: 23. by dn.base="cn=Admin,dc=example,dc=com" write
422 Line 5 is a comment. The start of the database definition is marked
423 by the database keyword on line 6. Line 7 specifies the DN suffix
424 for queries to pass to this database. Line 8 specifies the directory
425 in which the database files will live.
427 Lines 9 and 10 identify the database {{super-user}} entry and associated
428 password. This entry is not subject to access control or size or
429 time limit restrictions.
431 Lines 12 through 14 indicate the indices to maintain for various
434 Lines 16 through 24 specify access control for entries in this
435 database. For all applicable entries, the {{EX:userPassword}} attribute is writable
436 by the entry itself and by the "admin" entry. It may be used for
437 authentication/authorization purposes, but is otherwise not readable.
438 All other attributes are writable by the entry and the "admin"
439 entry, but may be read by all users (authenticated or not).
441 The next section of the example configuration file defines another
442 BDB database. This one handles queries involving the
443 {{EX:dc=example,dc=net}} subtree but is managed by the same entity
444 as the first database. Note that without line 39, the read access
445 would be allowed due to the global access rule at line 4.
447 E: 33. # BDB definition for example.net
449 E: 35. suffix "dc=example,dc=net"
450 E: 36. directory /usr/local/var/openldap-data-net
451 E: 37. rootdn "cn=Manager,dc=example,dc=com"
452 E: 38. index objectClass eq
453 E: 39. access to * by users read
455 H2: Access Control via Dynamic Configuration
457 Access to slapd entries and attributes is controlled by the
458 olcAccess attribute, whose values are a sequence of access directives.
459 The general form of the olcAccess configuration is:
461 > olcAccess: <access directive>
462 > <access directive> ::= to <what>
463 > [by <who> [<access>] [<control>] ]+
465 > [dn[.<basic-style>]=<regex> | dn.<scope-style>=<DN>]
466 > [filter=<ldapfilter>] [attrs=<attrlist>]
467 > <basic-style> ::= regex | exact
468 > <scope-style> ::= base | one | subtree | children
469 > <attrlist> ::= <attr> [val[.<basic-style>]=<regex>] | <attr> , <attrlist>
470 > <attr> ::= <attrname> | entry | children
471 > <who> ::= * | [anonymous | users | self
472 > | dn[.<basic-style>]=<regex> | dn.<scope-style>=<DN>]
473 > [dnattr=<attrname>]
474 > [group[/<objectclass>[/<attrname>][.<basic-style>]]=<regex>]
475 > [peername[.<basic-style>]=<regex>]
476 > [sockname[.<basic-style>]=<regex>]
477 > [domain[.<basic-style>]=<regex>]
478 > [sockurl[.<basic-style>]=<regex>]
481 > <access> ::= [self]{<level>|<priv>}
482 > <level> ::= none | disclose | auth | compare | search | read | write | manage
483 > <priv> ::= {=|+|-}{m|w|r|s|c|x|d|0}+
484 > <control> ::= [stop | continue | break]
486 where the <what> part selects the entries and/or attributes to which
487 the access applies, the {{EX:<who>}} part specifies which entities
488 are granted access, and the {{EX:<access>}} part specifies the
489 access granted. Multiple {{EX:<who> <access> <control>}} triplets
490 are supported, allowing many entities to be granted different access
491 to the same set of entries and attributes. Not all of these access
492 control options are described here; for more details see the
493 {{slapd.access}}(5) man page.
496 H3: What to control access to
498 The <what> part of an access specification determines the entries
499 and attributes to which the access control applies. Entries are
500 commonly selected in two ways: by DN and by filter. The following
501 qualifiers select entries by DN:
504 > to dn[.<basic-style>]=<regex>
505 > to dn.<scope-style>=<DN>
507 The first form is used to select all entries. The second form may
508 be used to select entries by matching a regular expression against
509 the target entry's {{normalized DN}}. (The second form is not
510 discussed further in this document.) The third form is used to
511 select entries which are within the requested scope of DN. The
512 <DN> is a string representation of the Distinguished Name, as
513 described in {{REF:RFC4514}}.
515 The scope can be either {{EX:base}}, {{EX:one}}, {{EX:subtree}},
516 or {{EX:children}}. Where {{EX:base}} matches only the entry with
517 provided DN, {{EX:one}} matches the entries whose parent is the
518 provided DN, {{EX:subtree}} matches all entries in the subtree whose
519 root is the provided DN, and {{EX:children}} matches all entries
520 under the DN (but not the entry named by the DN).
522 For example, if the directory contained entries named:
525 > 1: cn=Manager,o=suffix
526 > 2: ou=people,o=suffix
527 > 3: uid=kdz,ou=people,o=suffix
528 > 4: cn=addresses,uid=kdz,ou=people,o=suffix
529 > 5: uid=hyc,ou=people,o=suffix
532 . {{EX:dn.base="ou=people,o=suffix"}} match 2;
533 . {{EX:dn.one="ou=people,o=suffix"}} match 3, and 5;
534 . {{EX:dn.subtree="ou=people,o=suffix"}} match 2, 3, 4, and 5; and
535 . {{EX:dn.children="ou=people,o=suffix"}} match 3, 4, and 5.
538 Entries may also be selected using a filter:
540 > to filter=<ldap filter>
542 where <ldap filter> is a string representation of an LDAP
543 search filter, as described in {{REF:RFC4515}}. For example:
545 > to filter=(objectClass=person)
547 Note that entries may be selected by both DN and filter by
548 including both qualifiers in the <what> clause.
550 > to dn.one="ou=people,o=suffix" filter=(objectClass=person)
552 Attributes within an entry are selected by including a comma-separated
553 list of attribute names in the <what> selector:
555 > attrs=<attribute list>
557 A specific value of an attribute is selected by using a single
558 attribute name and also using a value selector:
560 > attrs=<attribute> val[.<style>]=<regex>
562 There are two special {{pseudo}} attributes {{EX:entry}} and
563 {{EX:children}}. To read (and hence return) a target entry, the
564 subject must have {{EX:read}} access to the target's {{entry}}
565 attribute. To perform a search, the subject must have
566 {{EX:search}} access to the search base's {{entry}} attribute.
567 To add or delete an entry, the subject must have
568 {{EX:write}} access to the entry's {{EX:entry}} attribute AND must
569 have {{EX:write}} access to the entry's parent's {{EX:children}}
570 attribute. To rename an entry, the subject must have {{EX:write}}
571 access to entry's {{EX:entry}} attribute AND have {{EX:write}}
572 access to both the old parent's and new parent's {{EX:children}}
573 attributes. The complete examples at the end of this section should
574 help clear things up.
576 Lastly, there is a special entry selector {{EX:"*"}} that is used to
577 select any entry. It is used when no other {{EX:<what>}}
578 selector has been provided. It's equivalent to "{{EX:dn=.*}}"
581 H3: Who to grant access to
583 The <who> part identifies the entity or entities being granted
584 access. Note that access is granted to "entities" not "entries."
585 The following table summarizes entity specifiers:
587 !block table; align=Center; coltags="EX,N"; \
588 title="Table 5.3: Access Entity Specifiers"
590 *|All, including anonymous and authenticated users
591 anonymous|Anonymous (non-authenticated) users
592 users|Authenticated users
593 self|User associated with target entry
594 dn[.<basic-style>]=<regex>|Users matching a regular expression
595 dn.<scope-style>=<DN>|Users within scope of a DN
598 The DN specifier behaves much like <what> clause DN specifiers.
600 Other control factors are also supported. For example, a {{EX:<who>}}
601 can be restricted by an entry listed in a DN-valued attribute in
602 the entry to which the access applies:
604 > dnattr=<dn-valued attribute name>
606 The dnattr specification is used to give access to an entry
607 whose DN is listed in an attribute of the entry (e.g., give
608 access to a group entry to whoever is listed as the owner of
611 Some factors may not be appropriate in all environments (or any).
612 For example, the domain factor relies on IP to domain name lookups.
613 As these can easily be spoofed, the domain factor should be avoided.
616 H3: The access to grant
618 The kind of <access> granted can be one of the following:
620 !block table; colaligns="LRL"; coltags="EX,EX,N"; align=Center; \
621 title="Table 5.4: Access Levels"
622 Level Privileges Description
624 disclose =d needed for information disclosure on error
625 auth =dx needed to authenticate (bind)
626 compare =cdx needed to compare
627 search =scdx needed to apply search filters
628 read =rscdx needed to read search results
629 write =wrscdx needed to modify/rename
630 manage =mwrscdx needed to manage
633 Each level implies all lower levels of access. So, for example,
634 granting someone {{EX:write}} access to an entry also grants them
635 {{EX:read}}, {{EX:search}}, {{EX:compare}}, {{EX:auth}} and
636 {{EX:disclose}} access. However, one may use the privileges specifier
637 to grant specific permissions.
640 H3: Access Control Evaluation
642 When evaluating whether some requester should be given access to
643 an entry and/or attribute, slapd compares the entry and/or attribute
644 to the {{EX:<what>}} selectors given in the configuration. For
645 each entry, access controls provided in the database which holds
646 the entry (or the global access directives if not held in any database) apply
647 first, followed by the global access directives (which are held in
648 the {{EX:frontend}} database definition). However, when dealing with
649 an access list, because the global access list is effectively appended
650 to each per-database list, if the resulting list is non-empty then the
651 access list will end with an implicit {{EX:access to * by * none}} directive.
652 If there are no access directives applicable to a backend, then a default
655 Within this priority,
656 access directives are examined in the order in which they appear
657 in the configuration attribute. Slapd stops with the first
658 {{EX:<what>}} selector that matches the entry and/or attribute. The
659 corresponding access directive is the one slapd will use to evaluate
662 Next, slapd compares the entity requesting access to the {{EX:<who>}}
663 selectors within the access directive selected above in the order
664 in which they appear. It stops with the first {{EX:<who>}} selector
665 that matches the requester. This determines the access the entity
666 requesting access has to the entry and/or attribute.
668 Finally, slapd compares the access granted in the selected
669 {{EX:<access>}} clause to the access requested by the client. If
670 it allows greater or equal access, access is granted. Otherwise,
673 The order of evaluation of access directives makes their placement
674 in the configuration file important. If one access directive is
675 more specific than another in terms of the entries it selects, it
676 should appear first in the configuration. Similarly, if one {{EX:<who>}}
677 selector is more specific than another it should come first in the
678 access directive. The access control examples given below should
679 help make this clear.
683 H3: Access Control Examples
685 The access control facility described above is quite powerful. This
686 section shows some examples of its use for descriptive purposes.
690 > olcAccess: to * by * read
692 This access directive grants read access to everyone.
699 This directive allows the user to modify their entry, allows anonymous
700 to authenticate against these entries, and allows all others to
701 read these entries. Note that only the first {{EX:by <who>}} clause
702 which matches applies. Hence, the anonymous users are granted
703 {{EX:auth}}, not {{EX:read}}. The last clause could just as well
704 have been "{{EX:by users read}}".
706 It is often desirable to restrict operations based upon the level
707 of protection in place. The following shows how security strength
708 factors (SSF) can be used.
711 > by ssf=128 self write
712 > by ssf=64 anonymous auth
713 > by ssf=64 users read
715 This directive allows users to modify their own entries if security
716 protections of strength 128 or better have been established,
717 allows authentication access to anonymous users, and read access
718 when strength 64 or better security protections have been established. If
719 the client has not establish sufficient security protections, the
720 implicit {{EX:by * none}} clause would be applied.
722 The following example shows the use of style specifiers to select
723 the entries by DN in two access directives where ordering is
726 > olcAccess: to dn.children="dc=example,dc=com"
728 > olcAccess: to dn.children="dc=com"
731 Read access is granted to entries under the {{EX:dc=com}} subtree,
732 except for those entries under the {{EX:dc=example,dc=com}} subtree,
733 to which search access is granted. No access is granted to
734 {{EX:dc=com}} as neither access directive matches this DN. If the
735 order of these access directives was reversed, the trailing directive
736 would never be reached, since all entries under {{EX:dc=example,dc=com}}
737 are also under {{EX:dc=com}} entries.
739 Also note that if no {{EX:olcAccess: to}} directive matches or no {{EX:by
740 <who>}} clause, {{B:access is denied}}. When dealing with an access list,
741 because the global access list is effectively appended to each per-database
742 list, if the resulting list is non-empty then the access list will end with
743 an implicit {{EX:access to * by * none}} directive. If there are no access
744 directives applicable to a backend, then a default read is used.
746 The next example again shows the importance of ordering, both of
747 the access directives and the {{EX:by <who>}} clauses. It also
748 shows the use of an attribute selector to grant access to a specific
749 attribute and various {{EX:<who>}} selectors.
751 > olcAccess: to dn.subtree="dc=example,dc=com" attrs=homePhone
753 > by dn.children=dc=example,dc=com" search
754 > by peername.regex=IP:10\..+ read
755 > olcAccess: to dn.subtree="dc=example,dc=com"
757 > by dn.children="dc=example,dc=com" search
760 This example applies to entries in the "{{EX:dc=example,dc=com}}"
761 subtree. To all attributes except {{EX:homePhone}}, an entry can
762 write to itself, entries under {{EX:example.com}} entries can search
763 by them, anybody else has no access (implicit {{EX:by * none}})
764 excepting for authentication/authorization (which is always done
765 anonymously). The {{EX:homePhone}} attribute is writable by the
766 entry, searchable by entries under {{EX:example.com}}, readable by
767 clients connecting from network 10, and otherwise not readable
768 (implicit {{EX:by * none}}). All other access is denied by the
769 implicit {{EX:access to * by * none}}.
771 Sometimes it is useful to permit a particular DN to add or
772 remove itself from an attribute. For example, if you would like to
773 create a group and allow people to add and remove only
774 their own DN from the member attribute, you could accomplish
775 it with an access directive like this:
777 > olcAccess: to attrs=member,entry
778 > by dnattr=member selfwrite
780 The dnattr {{EX:<who>}} selector says that the access applies to
781 entries listed in the {{EX:member}} attribute. The {{EX:selfwrite}} access
782 selector says that such members can only add or delete their
783 own DN from the attribute, not other values. The addition of
784 the entry attribute is required because access to the entry is
785 required to access any of the entry's attributes.
789 H3: Access Control Ordering
791 Since the ordering of {{EX:olcAccess}} directives is essential to their
792 proper evaluation, but LDAP attributes normally do not preserve the
793 ordering of their values, OpenLDAP uses a custom schema extension to
794 maintain a fixed ordering of these values. This ordering is maintained
795 by prepending a {{EX:"{X}"}} numeric index to each value, similarly to
796 the approach used for ordering the configuration entries. These index
797 tags are maintained automatically by slapd and do not need to be specified
798 when originally defining the values. For example, when you create the
801 > olcAccess: to attrs=member,entry
802 > by dnattr=member selfwrite
803 > olcAccess: to dn.children="dc=example,dc=com"
805 > olcAccess: to dn.children="dc=com"
808 when you read them back using slapcat or ldapsearch they will contain
810 > olcAccess: {0}to attrs=member,entry
811 > by dnattr=member selfwrite
812 > olcAccess: {1}to dn.children="dc=example,dc=com"
814 > olcAccess: {2}to dn.children="dc=com"
817 The numeric index may be used to specify a particular value to change
818 when using ldapmodify to edit the access rules. This index can be used
819 instead of (or in addition to) the actual access value. Using this
820 numeric index is very helpful when multiple access rules are being managed.
822 For example, if we needed to change the second rule above to grant
823 write access instead of search, we could try this LDIF:
827 > olcAccess: to dn.children="dc=example,dc=com" by * search
830 > olcAccess: to dn.children="dc=example,dc=com" by * write
833 But this example {{B:will not}} guarantee that the existing values remain in
834 their original order, so it will most likely yield a broken security
835 configuration. Instead, the numeric index should be used:
842 > olcAccess: {1}to dn.children="dc=example,dc=com" by * write
845 This example deletes whatever rule is in value #1 of the {{EX:olcAccess}}
846 attribute (regardless of its value) and adds a new value that is
847 explicitly inserted as value #1. The result will be
849 > olcAccess: {0}to attrs=member,entry
850 > by dnattr=member selfwrite
851 > olcAccess: {1}to dn.children="dc=example,dc=com"
853 > olcAccess: {2}to dn.children="dc=com"
856 which is exactly what was intended.
859 For more details on how to use the {{EX:access}} directive,
860 consult the {{Advanced Access Control}} chapter.
864 H3: Configuration Example
866 The following is an example configuration, interspersed
867 with explanatory text. It defines two databases to handle
868 different parts of the {{TERM:X.500}} tree; both are {{TERM:BDB}}
869 database instances. The line numbers shown are provided for
870 reference only and are not included in the actual file. First, the
871 global configuration section:
873 E: 1. # example config file - global configuration entry
875 E: 3. objectClass: olcGlobal
877 E: 5. olcReferral: ldap://root.openldap.org
880 Line 1 is a comment. Lines 2-4 identify this as the global
882 The {{EX:olcReferral:}} directive on line 5
883 means that queries not local to one of the databases defined
884 below will be referred to the LDAP server running on the
885 standard port (389) at the host {{EX:root.openldap.org}}.
886 Line 6 is a blank line, indicating the end of this entry.
888 E: 7. # internal schema
889 E: 8. dn: cn=schema,cn=config
890 E: 9. objectClass: olcSchemaConfig
894 Line 7 is a comment. Lines 8-10 identify this as the root of
895 the schema subtree. The actual schema definitions in this entry
896 are hardcoded into slapd so no additional attributes are specified here.
897 Line 11 is a blank line, indicating the end of this entry.
899 E: 12. # include the core schema
900 E: 13. include: file:///usr/local/etc/openldap/schema/core.ldif
903 Line 12 is a comment. Line 13 is an LDIF include directive which
904 accesses the {{core}} schema definitions in LDIF format. Line 14
907 Next comes the database definitions. The first database is the
908 special {{EX:frontend}} database whose settings are applied globally
909 to all the other databases.
911 E: 15. # global database parameters
912 E: 16. dn: olcDatabase=frontend,cn=config
913 E: 17. objectClass: olcDatabaseConfig
914 E: 18. olcDatabase: frontend
915 E: 19. olcAccess: to * by * read
918 Line 15 is a comment. Lines 16-18 identify this entry as the global
919 database entry. Line 19 is a global access control. It applies to all
920 entries (after any applicable database-specific access controls).
922 The next entry defines a BDB backend that will handle queries for things
923 in the "dc=example,dc=com" portion of the tree. Indices are to be maintained
924 for several attributes, and the {{EX:userPassword}} attribute is to be
925 protected from unauthorized access.
927 E: 21. # BDB definition for example.com
928 E: 22. dn: olcDatabase=bdb,cn=config
929 E: 23. objectClass: olcDatabaseConfig
930 E: 24. objectClass: olcBdbConfig
931 E: 25. olcDatabase: bdb
932 E: 26. olcSuffix: "dc=example,dc=com"
933 E: 27. olcDbDirectory: /usr/local/var/openldap-data
934 E: 28. olcRootDN: "cn=Manager,dc=example,dc=com"
935 E: 29. olcRootPW: secret
936 E: 30. olcDbIndex: uid pres,eq
937 E: 31. olcDbIndex: cn,sn,uid pres,eq,approx,sub
938 E: 32. olcDbIndex: objectClass eq
939 E: 33. olcAccess: to attrs=userPassword
941 E: 35. by anonymous auth
942 E: 36. by dn.base="cn=Admin,dc=example,dc=com" write
944 E: 38. olcAccess: to *
946 E: 40. by dn.base="cn=Admin,dc=example,dc=com" write
950 Line 21 is a comment. Lines 22-25 identify this entry as a BDB database
951 configuration entry. Line 26 specifies the DN suffix
952 for queries to pass to this database. Line 27 specifies the directory
953 in which the database files will live.
955 Lines 28 and 29 identify the database {{super-user}} entry and associated
956 password. This entry is not subject to access control or size or
957 time limit restrictions.
959 Lines 30 through 32 indicate the indices to maintain for various
962 Lines 33 through 41 specify access control for entries in this
963 database. For all applicable entries, the {{EX:userPassword}} attribute is writable
964 by the entry itself and by the "admin" entry. It may be used for
965 authentication/authorization purposes, but is otherwise not readable.
966 All other attributes are writable by the entry and the "admin"
967 entry, but may be read by all users (authenticated or not).
969 Line 42 is a blank line, indicating the end of this entry.
971 The next section of the example configuration file defines another
972 BDB database. This one handles queries involving the
973 {{EX:dc=example,dc=net}} subtree but is managed by the same entity
974 as the first database. Note that without line 52, the read access
975 would be allowed due to the global access rule at line 19.
977 E: 43. # BDB definition for example.net
978 E: 44. dn: olcDatabase=bdb,cn=config
979 E: 45. objectClass: olcDatabaseConfig
980 E: 46. objectClass: olcBdbConfig
981 E: 47. olcDatabase: bdb
982 E: 48. olcSuffix: "dc=example,dc=net"
983 E: 49. olcDbDirectory: /usr/local/var/openldap-data-net
984 E: 50. olcRootDN: "cn=Manager,dc=example,dc=com"
985 E: 51. olcDbIndex: objectClass eq
986 E: 52. olcAccess: to * by users read
989 H3: Converting from {{slapd.conf}}(5) to a {{B:cn=config}} directory format
991 Discuss slap* -f slapd.conf -F slapd.d/ (man slapd-config)
994 H2: Access Control Common Examples
998 Generally one should start with some basic ACLs such as:
1000 > access to attr=userPassword
1011 The first ACL allows users to update (but not read) their passwords, anonymous
1012 users to authenticate against this attribute, and (implicitly) denying all
1015 The second ACL allows users full access to their entry, authenticated users read
1016 access to anything, and (implicitly) denying all access to others (in this case,
1020 H3: Matching Anonymous and Authenticated users
1022 An anonymous user has a empty DN. While the {{dn.exact=""}} or {{dn.regex="^$"}}
1023 could be used, {{slapd}}(8)) offers an anonymous shorthand which should be
1030 denies all access to anonymous users while granting others read.
1032 Authenticated users have a subject DN. While {{dn.regex=".+"}} will match any
1033 authenticated user, OpenLDAP provides the users short hand which should be used
1040 This ACL grants read permissions to authenticated users while denying others
1041 (i.e.: anonymous users).
1044 H3: Controlling rootdn access
1046 You could specify the {{rootdn}} in {{slapd.conf}}(5) or {[slapd.d}} without
1047 specifying a {{rootpw}}. Then you have to add an actual directory entry with
1050 > dn: cn=Manager,o=MyOrganization
1053 > objectClass: person
1055 > userPassword: {SSHA}someSSHAdata
1057 Then binding as the {{rootdn}} will require a regular bind to that DN, which
1058 in turn requires auth access to that entry's DN and {{userPassword}}, and this
1059 can be restricted via ACLs. E.g.:
1061 > access to dn.base="cn=Manager,o=MyOrganization"
1062 > by peername.regex=127\.0\.0\.1 auth
1063 > by peername.regex=192\.168\.0\..* auth
1067 The ACLs above will only allow binding using rootdn from localhost and
1071 H3: Managing access with Groups
1073 There are a few ways to do this. One approach is illustrated here. Consider the
1074 following DIT layout:
1076 > +-dc=example,dc=com
1077 > +---cn=administrators,dc=example,dc=com
1078 > +---cn=fred blogs,dc=example,dc=com
1080 and the following group object (in LDIF format):
1082 > dn: cn=administrators,dc=example,dc=com
1083 > cn: administrators of this region
1084 > objectclass: groupOfNames (important for the group acl feature)
1085 > member: cn=fred blogs,dc=example,dc=com
1086 > member: cn=somebody else,dc=example,dc=com
1088 One can then grant access to the members of this this group by adding appropriate
1089 {{by group}} clause to an access directive in {{slapd.conf}}(5). For instance,
1091 > access to dn.children="dc=example,dc=com"
1093 > by group.exact="cn=Administrators,dc=example,dc=com" write
1096 Like by {[dn}} clauses, one can also use {{expand}} to expand the group name
1097 based upon the regular expression matching of the target, that is, the to {{dn.regex}}).
1100 > access to dn.regex="(.+,)?ou=People,(dc=[^,]+,dc=[^,]+)$"
1101 > attrs=children,entry,uid
1102 > by group.expand="cn=Managers,$2" write
1107 The above illustration assumed that the group members are to be found in the
1108 {{member}} attribute type of the {{groupOfNames}} object class. If you need to
1109 use a different group object and/or a different attribute type then use the
1110 following {{slapd.conf}}(5) (abbreviated) syntax:
1113 > by group/<objectclass>/<attributename>=<DN> <access>
1118 > by group/organizationalRole/roleOccupant="cn=Administrator,dc=example,dc=com" write
1120 In this case, we have an ObjectClass {{organizationalRole}} which contains the
1121 administrator DN's in the {{roleOccupant}} attribute. For instance:
1123 > dn: cn=Administrator,dc=example,dc=com
1125 > objectclass: organizationalRole
1126 > roleOccupant: cn=Jane Doe,dc=example,dc=com
1128 Note: the specified member attribute type MUST be of DN or {{NameAndOptionalUID}} syntax,
1129 and the specified object class SHOULD allow the attribute type.
1131 Dynamic Groups are also supported in Access Control. Please see {{slapo-dynlist}}(5)
1132 and the {{SECT:Dynamic Lists}} overlay section.
1135 H3: Granting access to a subset of attributes
1137 You can grant access to a set of attributes by specifying a list of attribute names
1138 in the ACL {{to}} clause. To be useful, you also need to grant access to the
1139 {{entry}} itself. Also note how {{children}} controls the ability to add, delete,
1142 > # mail: self may write, authenticated users may read
1143 > access to attrs=mail
1148 > # cn, sn: self my write, all may read
1149 > access to attrs=cn,sn
1153 > # immediate children: only self can add/delete entries under this entry
1154 > access to attrs=children
1157 > # entry itself: self may write, all may read
1158 > access to attrs=entry
1162 > # other attributes: self may write, others have no access
1167 ObjectClass names may also be specified in this list, which will affect
1168 all the attributes that are required and/or allowed by that {{objectClass}}.
1169 Actually, names in {{attrlist}} that are prefixed by {{@}} are directly treated
1170 as objectClass names. A name prefixed by {{!}} is also treated as an objectClass,
1171 but in this case the access rule affects the attributes that are not required
1172 nor allowed by that {{objectClass}}.
1175 H3: Allowing a user write to all entries below theirs
1177 For a setup where a user can write to its own record and to all of its children:
1179 > access to dn.regex="(.+,)?(uid=[^,]+,o=Company)$"
1180 > by dn.exact,expand="$2" write
1183 (Add more examples for above)
1186 H3: Allowing entry creation
1188 Let's say, you have it like this:
1192 > associatedDomain=<somedomain>
1195 > uid=<someotheruserid>
1201 and, for another domain <someotherdomain>:
1205 > associatedDomain=<someotherdomain>
1208 > uid=<someotheruserid>
1210 > uid=<someotheruserid>
1214 then, if you wanted user {{uid=<someuserid>}} to {{B:ONLY}} create an entry
1215 for its own thing, you could write an ACL like this:
1217 > # this rule lets users of "associatedDomain=<matcheddomain>"
1218 > # write under "ou=addressbook,associatedDomain=<matcheddomain>,ou=domains,o=<basedn>",
1219 > # i.e. a user can write ANY entry below its domain's address book;
1220 > # this permission is necessary, but not sufficient, the next
1221 > # will restrict this permission further
1224 > access to dn.regex="^ou=addressbook,associatedDomain=([^,]+),ou=domains,o=<basedn>$" attrs=children
1225 > by dn.regex="^uid=([^,]+),ou=users,associatedDomain=$1,ou=domains,o=<basedn>$$" write
1229 > # Note that above the "by" clause needs a "regex" style to make sure
1230 > # it expands to a DN that starts with a "uid=<someuserid>" pattern
1231 > # while substituting the associatedDomain submatch from the "what" clause.
1234 > # This rule lets a user with "uid=<matcheduid>" of "<associatedDomain=matcheddomain>"
1235 > # write (i.e. add, modify, delete) the entry whose DN is exactly
1236 > # "uid=<matcheduid>,ou=addressbook,associatedDomain=<matcheddomain>,ou=domains,o=<basedn>"
1237 > # and ANY entry as subtree of it
1240 > access to dn.regex="^(.+,)?uid=([^,]+),ou=addressbook,associatedDomain=([^,]+),ou=domains,o=<basedn>$"
1241 > by dn.exact,expand="uid=$2,ou=users,associatedDomain=$3,ou=domains,o=<basedn>" write
1245 > # Note that above the "by" clause uses the "exact" style with the "expand"
1246 > # modifier because now the whole pattern can be rebuilt by means of the
1247 > # submatches from the "what" clause, so a "regex" compilation and evaluation
1248 > # is no longer required.
1251 H3: Tips for using regular expressions in Access Control
1253 Always use {{dn.regex=<pattern>}} when you intend to use regular expression
1254 matching. {{dn=<pattern>}} alone defaults to {{dn.exact<pattern>}}.
1256 Use {{(.+)}} instead of {{(.*)}} when you want at least one char to be matched.
1257 {{(.*)}} matches the empty string as well.
1259 Don't use regular expressions for matches that can be done otherwise in a safer
1260 and cheaper manner. Examples:
1262 > dn.regex=".*dc=example,dc=com"
1264 is unsafe and expensive:
1266 * unsafe because any string containing {{dc=example,dc=com }}will match,
1267 not only those that end with the desired pattern; use {{.*dc=example,dc=com$}} instead.
1268 * unsafe also because it would allow any {{attributeType}} ending with {{dc}}
1269 as naming attribute for the first RDN in the string, e.g. a custom attributeType
1270 {{mydc}} would match as well. If you really need a regular expression that allows
1271 just {{dc=example,dc=com}} or any of its subtrees, use {{^(.+,)?dc=example,dc=com$}},
1272 which means: anything to the left of dc=..., if any (the question mark after the
1273 pattern within brackets), must end with a comma;
1274 * expensive because if you don't need submatches, you could use scoping styles, e.g.
1276 > dn.subtree="dc=example,dc=com"
1278 to include {{dc=example,dc=com}} in the matching patterns,
1280 > dn.children="dc=example,dc=com"
1282 to exclude {{dc=example,dc=com}} from the matching patterns, or
1284 > dn.onelevel="dc=example,dc=com"
1286 to allow exactly one sublevel matches only.
1288 Always use {{^}} and {{$}} in regexes, whenever appropriate, because
1289 {{ou=(.+),ou=(.+),ou=addressbooks,o=basedn}} will match
1290 {{something=bla,ou=xxx,ou=yyy,ou=addressbooks,o=basedn,ou=addressbooks,o=basedn,dc=some,dc=org}}
1292 Always use {{([^,]+)}} to indicate exactly one RDN, because {{(.+)}} can
1293 include any number of RDNs; e.g. {{ou=(.+),dc=example,dc=com}} will match
1294 {{ou=My,o=Org,dc=example,dc=com}}, which might not be what you want.
1296 Never add the rootdn to the by clauses. ACLs are not even processed for operations
1297 performed with rootdn identity (otherwise there would be no reason to define a
1300 Use shorthands. The user directive matches authenticated users and the anonymous
1301 directive matches anonymous users.
1303 Don't use the {{dn.regex}} form for <by> clauses if all you need is scoping
1304 and/or substring replacement; use scoping styles (e.g. {{exact}}, {{onelevel}},
1305 {{children}} or {{subtree}}) and the style modifier expand to cause substring expansion.
1309 > access to dn.regex=".+,dc=([^,]+),dc=([^,]+)$"
1310 > by dn.regex="^[^,],ou=Admin,dc=$1,dc=$2$$" write
1312 although correct, can be safely and efficiently replaced by
1314 > access to dn.regex=".+,(dc=[^,]+,dc=[^,]+)$"
1315 > by dn.onelevel,expand="ou=Admin,$1" write
1317 where the regex in the {{<what>}} clause is more compact, and the one in the {{<by>}}
1318 clause is replaced by a much more efficient scoping style of onelevel with substring expansion.
1321 H3: Granting and Denying access based on security strength factors (ssf)
1323 You can restrict access based on the security strength factor (SSF)
1325 > access to dn="cn=example,cn=edu"
1328 0 (zero) implies no protection,
1329 1 implies integrity protection only,
1330 56 DES or other weak ciphers,
1331 112 triple DES and other strong ciphers,
1332 128 RC4, Blowfish and other modern strong ciphers.
1334 Other possibilities:
1342 See {{slapd.conf}}(5) for information on {{ssf}}.
1345 H3: When things aren't working as expected
1347 Consider this example:
1358 You may think this will allow any user to login, to read everything and change
1359 his own data if he is logged in. But in this example only the login works and
1360 an ldapsearch returns no data. The Problem is that SLAPD goes through its access
1361 config line by line and stops as soon as it finds a match in the part of the
1362 access rule.(here: {{to *}})
1364 To get what we wanted the file has to read:
1371 The general rule is: "special access rules first, generic access rules last"
1373 See also {{slapd.access}}(8), loglevel 128 and {{slapacl}}(8) for debugging
1377 H2: Sets - Granting rights based on relationships
1379 Sets are best illustrated via examples. The following sections will present
1380 a few set ACL examples in order to facilitate their understanding.
1382 (Sets in Access Controls FAQ Entry: {{URL:http://www.openldap.org/faq/data/cache/1133.html}})
1384 Note: Sets are considered experimental.
1387 H3: Groups of Groups
1389 The OpenLDAP ACL for groups doesn't expand groups within groups, which are
1390 groups that have another group as a member. For example:
1392 > dn: cn=sudoadm,ou=group,dc=example,dc=com
1394 > objectClass: groupOfNames
1395 > member: uid=john,ou=people,dc=example,dc=com
1396 > member: cn=accountadm,ou=group,dc=example,dc=com
1398 > dn: cn=accountadm,ou=group,dc=example,dc=com
1400 > objectClass: groupOfNames
1401 > member: uid=mary,ou=people,dc=example,dc=com
1403 If we use standard group ACLs with the above entries and allow members of the
1404 {{F:sudoadm}} group to write somewhere, {{F:mary}} won't be included:
1406 > access to dn.subtree="ou=sudoers,dc=example,dc=com"
1407 > by group.exact="cn=sudoadm,ou=group,dc=example,dc=com" write
1410 With sets we can make the ACL be recursive and consider group within groups. So
1411 for each member that is a group, it is further expanded:
1413 > access to dn.subtree="ou=sudoers,dc=example,dc=com"
1414 > by set="[cn=sudoadm,ou=group,dc=example,dc=com]/member* & user" write
1417 This set ACL means: take the {{F:cn=sudoadm}} DN, check its {{F:member}}
1418 attribute(s) (where the "{{F:*}}" means recursively) and intersect the result
1419 with the authenticated user's DN. If the result is non-empty, the ACL is
1420 considered a match and write access is granted.
1422 The following drawing explains how this set is built:
1423 !import "set-recursivegroup.png"; align="center"; title="Building a recursive group"
1424 FT[align="Center"] Figure X.Y: Populating a recursive group set
1426 First we get the {{F:uid=john}} DN. This entry doesn't have a {{F:member}}
1427 attribute, so the expansion stops here. Now we get to {{F:cn=accountadm}}.
1428 This one does have a {{F:member}} attribute, which is {{F:uid=mary}}. The
1429 {{F:uid=mary}} entry, however, doesn't have member, so we stop here again. The
1432 > {"uid=john,ou=people,dc=example,dc=com","uid=mary,ou=people,dc=example,dc=com"} & user
1434 If the authenticated user's DN is any one of those two, write access is
1435 granted. So this set will include {{F:mary}} in the {{F:sudoadm}} group and she
1436 will be allowed the write access.
1438 H3: Group ACLs without DN syntax
1440 The traditional group ACLs, and even the previous example about recursive groups, require
1441 that the members are specified as DNs instead of just usernames.
1443 With sets, however, it's also possible to use simple names in group ACLs, as this example will
1446 Let's say we want to allow members of the {{F:sudoadm}} group to write to the
1447 {{F:ou=suders}} branch of our tree. But our group definition now is using {{F:memberUid}} for
1450 > dn: cn=sudoadm,ou=group,dc=example,dc=com
1452 > objectClass: posixGroup
1456 With this type of group, we can't use group ACLs. But with a set ACL we can
1457 grant the desired access:
1459 > access to dn.subtree="ou=sudoers,dc=example,dc=com"
1460 > by set="[cn=sudoadm,ou=group,dc=example,dc=com]/memberUid & user/uid" write
1463 We use a simple intersection where we compare the {{F:uid}} attribute
1464 of the connecting (and authenticated) user with the {{F:memberUid}} attributes
1465 of the group. If they match, the intersection is non-empty and the ACL will
1468 This drawing illustrates this set when the connecting user is authenticated as
1469 {{F:uid=john,ou=people,dc=example,dc=com}}:
1470 !import "set-memberUid.png"; align="center"; title="Sets with memberUid"
1471 FT[align="Center"] Figure X.Y: Sets with {{F:memberUid}}
1473 In this case, it's a match. If it were {{F:mary}} authenticating, however, she
1474 would be denied write access to {{F:ou=sudoers}} because her {{F:uid}}
1475 attribute is not listed in the group's {{F:memberUid}}.
1477 H3: Following references
1479 We will now show a quite powerful example of what can be done with sets. This
1480 example tends to make OpenLDAP administrators smile after they have understood
1481 it and its implications.
1483 Let's start with an user entry:
1485 > dn: uid=john,ou=people,dc=example,dc=com
1487 > objectClass: inetOrgPerson
1491 > manager: uid=mary,ou=people,dc=example,dc=com
1493 Writing an ACL to allow the manager to update some attributes is quite simple
1496 > access to dn.exact="uid=john,ou=people,dc=example,dc=com"
1497 > attrs=carLicense,homePhone,mobile,pager,telephoneNumber
1499 > by set="this/manager & user" write
1502 In that set, {{F:this}} expands to the entry being accessed, so that
1503 {{F:this/manager}} expands to {{F:uid=mary,ou=people,dc=example,dc=com}} when
1504 john's entry is accessed. If the manager herself is accessing John's entry,
1505 the ACL will match and write access to those attributes will be granted.
1507 So far, this same behavior can be obtained with the {{F:dnattr}} keyword. With
1508 sets, however, we can further enhance this ACL. Let's say we want to allow the
1509 secretary of the manager to also update these attributes. This is how we do it:
1511 > access to dn.exact="uid=john,ou=people,dc=example,dc=com"
1512 > attrs=carLicense,homePhone,mobile,pager,telephoneNumber
1514 > by set="this/manager & user" write
1515 > by set="this/manager/secretary & user" write
1518 Now we need a picture to help explain what is happening here (entries shortened
1521 !import "set-following-references.png"; align="center"; title="Sets jumping through entries"
1522 FT[align="Center"] Figure X.Y: Sets jumping through entries
1524 In this example, Jane is the secretary of Mary, which is the manager of John.
1525 This whole relationship is defined with the {{F:manager}} and {{F:secretary}}
1526 attributes, which are both of the distinguishedName syntax (i.e., full DNs).
1527 So, when the {{F:uid=john}} entry is being accessed, the
1528 {{F:this/manager/secretary}} set becomes
1529 {{F:{"uid=jane,ou=people,dc=example,dc=com"}}} (follow the references in the
1532 > this = [uid=john,ou=people,dc=example,dc=com]
1534 > [uid=john,ou=people,dc=example,dc=com]/manager = uid=mary,ou=people,dc=example,dc=com
1535 > this/manager/secretary = \
1536 > [uid=mary,ou=people,dc=example,dc=com]/secretary = uid=jane,ou=people,dc=example,dc=com
1538 The end result is that when Jane accesses John's entry, she will be granted
1539 write access to the specified attributes. Better yet, this will happen to any
1540 entry she accesses which has Mary as the manager.
1542 This is all cool and nice, but perhaps gives to much power to secretaries. Maybe we need to further
1543 restrict it. For example, let's only allow executive secretaries to have this power:
1545 > access to dn.exact="uid=john,ou=people,dc=example,dc=com"
1546 > attrs=carLicense,homePhone,mobile,pager,telephoneNumber
1548 > by set="this/manager & user" write
1549 > by set="this/manager/secretary &
1550 > [cn=executive,ou=group,dc=example,dc=com]/member* &
1554 It's almost the same ACL as before, but we now also require that the connecting user be a member
1555 of the (possibly nested) {{F:cn=executive}} group.