]> git.sur5r.net Git - openldap/blob - doc/guide/admin/access-control.sdf
Happy New Year!
[openldap] / doc / guide / admin / access-control.sdf
1 # $OpenLDAP$
2 # Copyright 1999-2011 The OpenLDAP Foundation, All Rights Reserved.
3 # COPYING RESTRICTIONS APPLY, see COPYRIGHT.
4
5 H1: Access Control
6
7 H2: Introduction
8
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.
16
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}}).
20
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.
24
25 As a consequence, it's useless (and results in a performance penalty) to explicitly 
26 list the {{rootdn}} among the {{<by>}} clauses.
27
28 The following sections will describe Access Control Lists in more details and 
29 follow with some examples and recommendations. 
30
31 H2: Access Control via Static Configuration
32
33 Access to entries and attributes is controlled by the
34 access configuration file directive. The general form of an
35 access line is:
36
37 >    <access directive> ::= access to <what>
38 >        [by <who> [<access>] [<control>] ]+
39 >    <what> ::= * |
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>] 
48 >        [dnattr=<attrname>]
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>]
54 >        [set=<setspec>]
55 >        [aci=<attrname>]
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]
60
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.
69
70
71 H3: What to control access to
72
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:
77
78 >    to *
79 >    to dn[.<basic-style>]=<regex>
80 >    to dn.<scope-style>=<DN>
81
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}}.
89
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).
96
97 For example, if the directory contained entries named:
98
99 >    0: o=suffix
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
105
106 \Then:
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.
111
112
113 Entries may also be selected using a filter:
114
115 >    to filter=<ldap filter>
116
117 where <ldap filter> is a string representation of an LDAP
118 search filter, as described in {{REF:RFC4515}}.  For example:
119
120 >    to filter=(objectClass=person)
121
122 Note that entries may be selected by both DN and filter by
123 including both qualifiers in the <what> clause.
124
125 >    to dn.one="ou=people,o=suffix" filter=(objectClass=person)
126
127 Attributes within an entry are selected by including a comma-separated
128 list of attribute names in the <what> selector:
129
130 >    attrs=<attribute list>
131
132 A specific value of an attribute is selected by using a single
133 attribute name and also using a value selector:
134
135 >    attrs=<attribute> val[.<style>]=<regex>
136
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.
150
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=.*}}"
154
155
156 H3: Who to grant access to
157
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:
161
162 !block table; align=Center; coltags="EX,N"; \
163     title="Table 6.3: Access Entity Specifiers"
164 Specifier|Entities
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
171 !endblock
172
173 The DN specifier behaves much like <what> clause DN specifiers.
174
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:
178
179 >    dnattr=<dn-valued attribute name>
180
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
184 the group entry).
185
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.
189
190
191 H3: The access to grant
192
193 The kind of <access> granted can be one of the following:
194
195 !block table; colaligns="LRL"; coltags="EX,EX,N"; align=Center; \
196     title="Table 6.4: Access Levels"
197 Level        Privileges    Description
198 none        =0             no access
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
206 !endblock
207
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.
213
214
215 H3: Access Control Evaluation
216
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 
227 read is used.
228
229 Within this
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.
234
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.
240
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,
244 access is denied.
245
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.
253
254
255
256 H3: Access Control Examples
257
258 The access control facility described above is quite powerful.  This
259 section shows some examples of its use for descriptive purposes.
260
261 A simple example:
262
263 >    access to * by * read
264
265 This access directive grants read access to everyone.
266
267 >    access to *
268 >        by self write
269 >        by anonymous auth
270 >        by * read
271
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}}".
278
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.
282
283 >    access to *
284 >        by ssf=128 self write
285 >        by ssf=64 anonymous auth
286 >        by ssf=64 users read
287
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.
294
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
297 significant.
298
299 >    access to dn.children="dc=example,dc=com"
300 >         by * search
301 >    access to dn.children="dc=com"
302 >         by * read
303
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.
311
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
319 used.
320
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.
325
326 >    access to dn.subtree="dc=example,dc=com" attrs=homePhone
327 >        by self write
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"
331 >        by self write
332 >        by dn.children="dc=example,dc=com" search
333 >        by anonymous auth
334
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}}.
345
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:
351
352 >    access to attrs=member,entry
353 >         by dnattr=member selfwrite
354
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.
361
362 !if 0
363 For more details on how to use the {{EX:access}} directive,
364 consult the {{Advanced Access Control}} chapter.
365 !endif
366
367
368 H2: Access Control via Dynamic Configuration
369
370 Access to slapd entries and attributes is controlled by the
371 olcAccess attribute, whose values are a sequence of access directives.
372 The general form of the olcAccess configuration is:
373
374 >    olcAccess: <access directive>
375 >    <access directive> ::= to <what>
376 >        [by <who> [<access>] [<control>] ]+
377 >    <what> ::= * |
378 >        [dn[.<basic-style>]=<regex> | dn.<scope-style>=<DN>]
379 >        [filter=<ldapfilter>] [attrs=<attrlist>]
380 >    <basic-style> ::= regex | exact
381 >    <scope-style> ::= base | one | subtree | children
382 >    <attrlist> ::= <attr> [val[.<basic-style>]=<regex>] | <attr> , <attrlist>
383 >    <attr> ::= <attrname> | entry | children
384 >    <who> ::= * | [anonymous | users | self
385 >            | dn[.<basic-style>]=<regex> | dn.<scope-style>=<DN>] 
386 >        [dnattr=<attrname>]
387 >        [group[/<objectclass>[/<attrname>][.<basic-style>]]=<regex>]
388 >        [peername[.<basic-style>]=<regex>]
389 >        [sockname[.<basic-style>]=<regex>]
390 >        [domain[.<basic-style>]=<regex>]
391 >        [sockurl[.<basic-style>]=<regex>]
392 >        [set=<setspec>]
393 >        [aci=<attrname>]
394 >    <access> ::= [self]{<level>|<priv>}
395 >    <level> ::= none | disclose | auth | compare | search | read | write | manage
396 >    <priv> ::= {=|+|-}{m|w|r|s|c|x|d|0}+
397 >    <control> ::= [stop | continue | break]
398
399 where the <what> part selects the entries and/or attributes to which
400 the access applies, the {{EX:<who>}} part specifies which entities
401 are granted access, and the {{EX:<access>}} part specifies the
402 access granted. Multiple {{EX:<who> <access> <control>}} triplets
403 are supported, allowing many entities to be granted different access
404 to the same set of entries and attributes. Not all of these access
405 control options are described here; for more details see the
406 {{slapd.access}}(5) man page.
407
408
409 H3: What to control access to
410
411 The <what> part of an access specification determines the entries
412 and attributes to which the access control applies.  Entries are
413 commonly selected in two ways: by DN and by filter.  The following
414 qualifiers select entries by DN:
415
416 >    to *
417 >    to dn[.<basic-style>]=<regex>
418 >    to dn.<scope-style>=<DN>
419
420 The first form is used to select all entries.  The second form may
421 be used to select entries by matching a regular expression against
422 the target entry's {{normalized DN}}.   (The second form is not
423 discussed further in this document.)  The third form is used to
424 select entries which are within the requested scope of DN.  The
425 <DN> is a string representation of the Distinguished Name, as
426 described in {{REF:RFC4514}}.
427
428 The scope can be either {{EX:base}}, {{EX:one}}, {{EX:subtree}},
429 or {{EX:children}}.  Where {{EX:base}} matches only the entry with
430 provided DN, {{EX:one}} matches the entries whose parent is the
431 provided DN, {{EX:subtree}} matches all entries in the subtree whose
432 root is the provided DN, and {{EX:children}} matches all entries
433 under the DN (but not the entry named by the DN).
434
435 For example, if the directory contained entries named:
436
437 >    0: o=suffix
438 >    1: cn=Manager,o=suffix
439 >    2: ou=people,o=suffix
440 >    3: uid=kdz,ou=people,o=suffix
441 >    4: cn=addresses,uid=kdz,ou=people,o=suffix
442 >    5: uid=hyc,ou=people,o=suffix
443
444 \Then:
445 . {{EX:dn.base="ou=people,o=suffix"}} match 2;
446 . {{EX:dn.one="ou=people,o=suffix"}} match 3, and 5;
447 . {{EX:dn.subtree="ou=people,o=suffix"}} match 2, 3, 4, and 5; and
448 . {{EX:dn.children="ou=people,o=suffix"}} match 3, 4, and 5.
449
450
451 Entries may also be selected using a filter:
452
453 >    to filter=<ldap filter>
454
455 where <ldap filter> is a string representation of an LDAP
456 search filter, as described in {{REF:RFC4515}}.  For example:
457
458 >    to filter=(objectClass=person)
459
460 Note that entries may be selected by both DN and filter by
461 including both qualifiers in the <what> clause.
462
463 >    to dn.one="ou=people,o=suffix" filter=(objectClass=person)
464
465 Attributes within an entry are selected by including a comma-separated
466 list of attribute names in the <what> selector:
467
468 >    attrs=<attribute list>
469
470 A specific value of an attribute is selected by using a single
471 attribute name and also using a value selector:
472
473 >    attrs=<attribute> val[.<style>]=<regex>
474
475 There are two special {{pseudo}} attributes {{EX:entry}} and
476 {{EX:children}}.  To read (and hence return) a target entry, the
477 subject must have {{EX:read}} access to the target's {{entry}}
478 attribute.  To perform a search, the subject must have
479 {{EX:search}} access to the search base's {{entry}} attribute.
480 To add or delete an entry, the subject must have
481 {{EX:write}} access to the entry's {{EX:entry}} attribute AND must
482 have {{EX:write}} access to the entry's parent's {{EX:children}}
483 attribute.  To rename an entry, the subject must have {{EX:write}}
484 access to entry's {{EX:entry}} attribute AND have {{EX:write}}
485 access to both the old parent's and new parent's {{EX:children}}
486 attributes.  The complete examples at the end of this section should
487 help clear things up.
488
489 Lastly, there is a special entry selector {{EX:"*"}} that is used to
490 select any entry.  It is used when no other {{EX:<what>}}
491 selector has been provided.  It's equivalent to "{{EX:dn=.*}}"
492
493
494 H3: Who to grant access to
495
496 The <who> part identifies the entity or entities being granted
497 access. Note that access is granted to "entities" not "entries."
498 The following table summarizes entity specifiers:
499
500 !block table; align=Center; coltags="EX,N"; \
501     title="Table 5.3: Access Entity Specifiers"
502 Specifier|Entities
503 *|All, including anonymous and authenticated users
504 anonymous|Anonymous (non-authenticated) users
505 users|Authenticated users
506 self|User associated with target entry
507 dn[.<basic-style>]=<regex>|Users matching a regular expression
508 dn.<scope-style>=<DN>|Users within scope of a DN
509 !endblock
510
511 The DN specifier behaves much like <what> clause DN specifiers.
512
513 Other control factors are also supported.  For example, a {{EX:<who>}}
514 can be restricted by an entry listed in a DN-valued attribute in
515 the entry to which the access applies:
516
517 >    dnattr=<dn-valued attribute name>
518
519 The dnattr specification is used to give access to an entry
520 whose DN is listed in an attribute of the entry (e.g., give
521 access to a group entry to whoever is listed as the owner of
522 the group entry).
523
524 Some factors may not be appropriate in all environments (or any).
525 For example, the domain factor relies on IP to domain name lookups.
526 As these can easily be spoofed, the domain factor should be avoided.
527
528
529 H3: The access to grant
530
531 The kind of <access> granted can be one of the following:
532
533 !block table; colaligns="LRL"; coltags="EX,EX,N"; align=Center; \
534     title="Table 5.4: Access Levels"
535 Level        Privileges    Description
536 none         =0            no access
537 disclose     =d            needed for information disclosure on error
538 auth         =dx           needed to authenticate (bind)
539 compare      =cdx          needed to compare
540 search       =scdx         needed to apply search filters
541 read         =rscdx        needed to read search results
542 write        =wrscdx       needed to modify/rename
543 manage       =mwrscdx      needed to manage
544 !endblock
545
546 Each level implies all lower levels of access. So, for example,
547 granting someone {{EX:write}} access to an entry also grants them
548 {{EX:read}}, {{EX:search}}, {{EX:compare}}, {{EX:auth}} and
549 {{EX:disclose}} access.  However, one may use the privileges specifier
550 to grant specific permissions.
551
552
553 H3: Access Control Evaluation
554
555 When evaluating whether some requester should be given access to
556 an entry and/or attribute, slapd compares the entry and/or attribute
557 to the {{EX:<what>}} selectors given in the configuration.  For
558 each entry, access controls provided in the database which holds
559 the entry (or the global access directives if not held in any database) apply
560 first, followed by the global access directives (which are held in
561 the {{EX:frontend}} database definition). However, when dealing with 
562 an access list, because the global access list is effectively appended 
563 to each per-database list, if the resulting list is non-empty then the 
564 access list will end with an implicit {{EX:access to * by * none}} directive. 
565 If there are no access directives applicable to a backend, then a default 
566 read is used.
567
568 Within this priority,
569 access directives are examined in the order in which they appear
570 in the configuration attribute.  Slapd stops with the first
571 {{EX:<what>}} selector that matches the entry and/or attribute. The
572 corresponding access directive is the one slapd will use to evaluate
573 access.
574
575 Next, slapd compares the entity requesting access to the {{EX:<who>}}
576 selectors within the access directive selected above in the order
577 in which they appear. It stops with the first {{EX:<who>}} selector
578 that matches the requester. This determines the access the entity
579 requesting access has to the entry and/or attribute.
580
581 Finally, slapd compares the access granted in the selected
582 {{EX:<access>}} clause to the access requested by the client. If
583 it allows greater or equal access, access is granted. Otherwise,
584 access is denied.
585
586 The order of evaluation of access directives makes their placement
587 in the configuration file important. If one access directive is
588 more specific than another in terms of the entries it selects, it
589 should appear first in the configuration. Similarly, if one {{EX:<who>}}
590 selector is more specific than another it should come first in the
591 access directive. The access control examples given below should
592 help make this clear.
593
594
595
596 H3: Access Control Examples
597
598 The access control facility described above is quite powerful.  This
599 section shows some examples of its use for descriptive purposes.
600
601 A simple example:
602
603 >    olcAccess: to * by * read
604
605 This access directive grants read access to everyone.
606
607 >    olcAccess: to *
608 >        by self write
609 >        by anonymous auth
610 >        by * read
611
612 This directive allows the user to modify their entry, allows anonymous
613 to authenticate against these entries, and allows all others to
614 read these entries.  Note that only the first {{EX:by <who>}} clause
615 which matches applies.  Hence, the anonymous users are granted
616 {{EX:auth}}, not {{EX:read}}.  The last clause could just as well
617 have been "{{EX:by users read}}".
618
619 It is often desirable to restrict operations based upon the level
620 of protection in place.  The following shows how security strength
621 factors (SSF) can be used.
622
623 >    olcAccess: to *
624 >        by ssf=128 self write
625 >        by ssf=64 anonymous auth
626 >        by ssf=64 users read
627
628 This directive allows users to modify their own entries if security
629 protections of strength 128 or better have been established,
630 allows authentication access to anonymous users, and read access
631 when strength 64 or better security protections have been established.  If
632 the client has not establish sufficient security protections, the
633 implicit {{EX:by * none}} clause would be applied.
634
635 The following example shows the use of style specifiers to select
636 the entries by DN in two access directives where ordering is
637 significant.
638
639 >    olcAccess: to dn.children="dc=example,dc=com"
640 >         by * search
641 >    olcAccess: to dn.children="dc=com"
642 >         by * read
643
644 Read access is granted to entries under the {{EX:dc=com}} subtree,
645 except for those entries under the {{EX:dc=example,dc=com}} subtree,
646 to which search access is granted.  No access is granted to
647 {{EX:dc=com}} as neither access directive matches this DN.  If the
648 order of these access directives was reversed, the trailing directive
649 would never be reached, since all entries under {{EX:dc=example,dc=com}}
650 are also under {{EX:dc=com}} entries.
651
652 Also note that if no {{EX:olcAccess: to}} directive matches or no {{EX:by
653 <who>}} clause, {{B:access is denied}}.  When dealing with an access list, 
654 because the global access list is effectively appended to each per-database 
655 list, if the resulting list is non-empty then the access list will end with 
656 an implicit {{EX:access to * by * none}} directive. If there are no access 
657 directives applicable to a backend, then a default read is used.
658
659 The next example again shows the importance of ordering, both of
660 the access directives and the {{EX:by <who>}} clauses.  It also
661 shows the use of an attribute selector to grant access to a specific
662 attribute and various {{EX:<who>}} selectors.
663
664 >    olcAccess: to dn.subtree="dc=example,dc=com" attrs=homePhone
665 >        by self write
666 >        by dn.children=dc=example,dc=com" search
667 >        by peername.regex=IP:10\..+ read
668 >    olcAccess: to dn.subtree="dc=example,dc=com"
669 >        by self write
670 >        by dn.children="dc=example,dc=com" search
671 >        by anonymous auth
672
673 This example applies to entries in the "{{EX:dc=example,dc=com}}"
674 subtree. To all attributes except {{EX:homePhone}}, an entry can
675 write to itself, entries under {{EX:example.com}} entries can search
676 by them, anybody else has no access (implicit {{EX:by * none}})
677 excepting for authentication/authorization (which is always done
678 anonymously).  The {{EX:homePhone}} attribute is writable by the
679 entry, searchable by entries under {{EX:example.com}}, readable by
680 clients connecting from network 10, and otherwise not readable
681 (implicit {{EX:by * none}}).  All other access is denied by the
682 implicit {{EX:access to * by * none}}.
683
684 Sometimes it is useful to permit a particular DN to add or
685 remove itself from an attribute. For example, if you would like to
686 create a group and allow people to add and remove only
687 their own DN from the member attribute, you could accomplish
688 it with an access directive like this:
689
690 >    olcAccess: to attrs=member,entry
691 >         by dnattr=member selfwrite
692
693 The dnattr {{EX:<who>}} selector says that the access applies to
694 entries listed in the {{EX:member}} attribute. The {{EX:selfwrite}} access
695 selector says that such members can only add or delete their
696 own DN from the attribute, not other values. The addition of
697 the entry attribute is required because access to the entry is
698 required to access any of the entry's attributes.
699
700
701
702 H3: Access Control Ordering
703
704 Since the ordering of {{EX:olcAccess}} directives is essential to their
705 proper evaluation, but LDAP attributes normally do not preserve the
706 ordering of their values, OpenLDAP uses a custom schema extension to
707 maintain a fixed ordering of these values. This ordering is maintained
708 by prepending a {{EX:"{X}"}} numeric index to each value, similarly to
709 the approach used for ordering the configuration entries. These index
710 tags are maintained automatically by slapd and do not need to be specified
711 when originally defining the values. For example, when you create the
712 settings
713
714 >    olcAccess: to attrs=member,entry
715 >         by dnattr=member selfwrite
716 >    olcAccess: to dn.children="dc=example,dc=com"
717 >         by * search
718 >    olcAccess: to dn.children="dc=com"
719 >         by * read
720
721 when you read them back using slapcat or ldapsearch they will contain
722
723 >    olcAccess: {0}to attrs=member,entry
724 >         by dnattr=member selfwrite
725 >    olcAccess: {1}to dn.children="dc=example,dc=com"
726 >         by * search
727 >    olcAccess: {2}to dn.children="dc=com"
728 >         by * read
729
730 The numeric index may be used to specify a particular value to change
731 when using ldapmodify to edit the access rules. This index can be used
732 instead of (or in addition to) the actual access value. Using this 
733 numeric index is very helpful when multiple access rules are being managed.
734
735 For example, if we needed to change the second rule above to grant
736 write access instead of search, we could try this LDIF:
737
738 >    changetype: modify
739 >    delete: olcAccess
740 >    olcAccess: to dn.children="dc=example,dc=com" by * search
741 >    -
742 >    add: olcAccess
743 >    olcAccess: to dn.children="dc=example,dc=com" by * write
744 >    -
745
746 But this example {{B:will not}} guarantee that the existing values remain in
747 their original order, so it will most likely yield a broken security
748 configuration. Instead, the numeric index should be used:
749
750 >    changetype: modify
751 >    delete: olcAccess
752 >    olcAccess: {1}
753 >    -
754 >    add: olcAccess
755 >    olcAccess: {1}to dn.children="dc=example,dc=com" by * write
756 >    -
757
758 This example deletes whatever rule is in value #1 of the {{EX:olcAccess}}
759 attribute (regardless of its value) and adds a new value that is
760 explicitly inserted as value #1. The result will be
761
762 >    olcAccess: {0}to attrs=member,entry
763 >         by dnattr=member selfwrite
764 >    olcAccess: {1}to dn.children="dc=example,dc=com"
765 >         by * write
766 >    olcAccess: {2}to dn.children="dc=com"
767 >         by * read
768
769 which is exactly what was intended.
770
771 !if 0
772 For more details on how to use the {{EX:access}} directive,
773 consult the {{Advanced Access Control}} chapter.
774 !endif
775
776
777 H2: Access Control Common Examples
778
779 H3: Basic ACLs
780
781 Generally one should start with some basic ACLs such as:
782
783 >    access to attr=userPassword
784 >        by self =xw
785 >        by anonymous auth
786 >        by * none
787 >
788 >
789 >      access to *
790 >        by self write
791 >        by users read
792 >        by * none
793
794 The first ACL allows users to update (but not read) their passwords, anonymous 
795 users to authenticate against this attribute, and (implicitly) denying all 
796 access to others.
797
798 The second ACL allows users full access to their entry, authenticated users read 
799 access to anything, and (implicitly) denying all access to others (in this case, 
800 anonymous users). 
801
802
803 H3: Matching Anonymous and Authenticated users
804
805 An anonymous user has a empty DN. While the {{dn.exact=""}} or {{dn.regex="^$"}}
806  could be used, {{slapd}}(8)) offers an anonymous shorthand which should be 
807 used instead.
808
809 >    access to *
810 >      by anonymous none
811 >      by * read
812
813 denies all access to anonymous users while granting others read. 
814
815 Authenticated users have a subject DN. While {{dn.regex=".+"}} will match any 
816 authenticated user, OpenLDAP provides the users short hand which should be used 
817 instead.
818
819 >    access to *
820 >      by users read
821 >      by * none
822
823 This ACL grants read permissions to authenticated users while denying others 
824 (i.e.: anonymous users).
825
826
827 H3: Controlling rootdn access
828
829 You could specify the {{rootdn}} in {{slapd.conf}}(5) or {{slapd.d}} without 
830 specifying a {{rootpw}}. Then you have to add an actual directory entry with 
831 the same dn, e.g.:
832
833 >    dn: cn=Manager,o=MyOrganization
834 >    cn: Manager
835 >    sn: Manager
836 >    objectClass: person
837 >    objectClass: top
838 >    userPassword: {SSHA}someSSHAdata
839
840 Then binding as the {{rootdn}} will require a regular bind to that DN, which 
841 in turn requires auth access to that entry's DN and {{userPassword}}, and this 
842 can be restricted via ACLs. E.g.:
843
844 >    access to dn.base="cn=Manager,o=MyOrganization"
845 >      by peername.regex=127\.0\.0\.1 auth
846 >      by peername.regex=192\.168\.0\..* auth
847 >      by users none
848 >      by * none
849
850 The ACLs above will only allow binding using rootdn from localhost and 
851 192.168.0.0/24.
852
853
854 H3: Managing access with Groups
855
856 There are a few ways to do this. One approach is illustrated here. Consider the 
857 following DIT layout:
858
859 >    +-dc=example,dc=com
860 >    +---cn=administrators,dc=example,dc=com
861 >    +---cn=fred blogs,dc=example,dc=com 
862
863 and the following group object (in LDIF format):
864
865 >    dn: cn=administrators,dc=example,dc=com
866 >    cn: administrators of this region
867 >    objectclass: groupOfNames  (important for the group acl feature)
868 >    member: cn=fred blogs,dc=example,dc=com 
869 >    member: cn=somebody else,dc=example,dc=com
870
871 One can then grant access to the members of this this group by adding appropriate 
872 {{by group}} clause to an access directive in {{slapd.conf}}(5). For instance,
873
874 >    access to dn.children="dc=example,dc=com" 
875 >        by self write 
876 >        by group.exact="cn=Administrators,dc=example,dc=com" write  
877 >        by * auth
878
879 Like by {{dn}} clauses, one can also use {{expand}} to expand the group name 
880 based upon the regular expression matching of the target, that is, the to {{dn.regex}}). 
881 For instance,
882
883 >    access to dn.regex="(.+,)?ou=People,(dc=[^,]+,dc=[^,]+)$"
884 >             attrs=children,entry,uid
885 >        by group.expand="cn=Managers,$2" write
886 >        by users read
887 >        by * auth
888
889
890 The above illustration assumed that the group members are to be found in the 
891 {{member}} attribute type of the {{groupOfNames}} object class. If you need to 
892 use a different group object and/or a different attribute type then use the 
893 following {{slapd.conf}}(5) (abbreviated) syntax:
894
895 >    access to <what>
896 >            by group/<objectclass>/<attributename>=<DN> <access>
897
898 For example:
899
900 >    access to *
901 >      by group/organizationalRole/roleOccupant="cn=Administrator,dc=example,dc=com" write
902
903 In this case, we have an ObjectClass {{organizationalRole}} which contains the 
904 administrator DN's in the {{roleOccupant}} attribute. For instance:
905
906 >    dn: cn=Administrator,dc=example,dc=com
907 >    cn: Administrator
908 >    objectclass: organizationalRole
909 >    roleOccupant: cn=Jane Doe,dc=example,dc=com 
910
911 Note: the specified member attribute type MUST be of DN or {{NameAndOptionalUID}} syntax, 
912 and the specified object class SHOULD allow the attribute type.
913
914 Dynamic Groups are also supported in Access Control. Please see {{slapo-dynlist}}(5)
915 and the {{SECT:Dynamic Lists}} overlay section.
916
917
918 H3:  Granting access to a subset of attributes
919
920 You can grant access to a set of attributes by specifying a list of attribute names 
921 in the ACL {{to}} clause. To be useful, you also need to grant access to the 
922 {{entry}} itself. Also note how {{children}} controls the ability to add, delete, 
923 and rename entries.
924
925 >    # mail: self may write, authenticated users may read
926 >    access to attrs=mail
927 >      by self write
928 >      by users read
929 >      by * none
930 >    
931 >    # cn, sn: self my write, all may read
932 >    access to attrs=cn,sn
933 >      by self write
934 >      by * read
935 >    
936 >    # immediate children: only self can add/delete entries under this entry
937 >    access to attrs=children
938 >      by self write
939 >    
940 >    # entry itself: self may write, all may read
941 >    access to attrs=entry
942 >      by self write
943 >      by * read
944 >    
945 >    # other attributes: self may write, others have no access
946 >    access to *
947 >      by self write
948 >      by * none
949
950 ObjectClass names may also be specified in this list, which will affect 
951 all the attributes that are required and/or allowed by that {{objectClass}}. 
952 Actually, names in {{attrlist}} that are prefixed by {{@}} are directly treated 
953 as objectClass names. A name prefixed by {{!}} is also treated as an objectClass, 
954 but in this case the access rule affects the attributes that are not required 
955 nor allowed by that {{objectClass}}. 
956
957
958 H3: Allowing a user write to all entries below theirs
959
960 For a setup where a user can write to its own record and to all of its children:
961
962 >    access to dn.regex="(.+,)?(uid=[^,]+,o=Company)$"
963 >       by dn.exact,expand="$2" write
964 >       by anonymous auth
965
966 (Add more examples for above)
967
968
969 H3: Allowing entry creation
970
971 Let's say, you have it like this:
972
973 >        o=<basedn>
974 >            ou=domains
975 >                associatedDomain=<somedomain>
976 >                    ou=users
977 >                        uid=<someuserid>            
978 >                        uid=<someotheruserid>
979 >                    ou=addressbooks
980 >                        uid=<someuserid>
981 >                            cn=<someone>
982 >                            cn=<someoneelse>
983
984 and, for another domain <someotherdomain>:
985
986 >        o=<basedn>
987 >            ou=domains
988 >                associatedDomain=<someotherdomain>
989 >                    ou=users
990 >                        uid=<someuserid>            
991 >                        uid=<someotheruserid>
992 >                    ou=addressbooks
993 >                        uid=<someotheruserid>
994 >                            cn=<someone>
995 >                            cn=<someoneelse>
996
997 then, if you wanted user {{uid=<someuserid>}} to {{B:ONLY}} create an entry 
998 for its own thing, you could write an ACL like this:
999
1000 >    # this rule lets users of "associatedDomain=<matcheddomain>"
1001 >    # write under "ou=addressbook,associatedDomain=<matcheddomain>,ou=domains,o=<basedn>",
1002 >    # i.e. a user can write ANY entry below its domain's address book;
1003 >    # this permission is necessary, but not sufficient, the next 
1004 >    # will restrict this permission further
1005 >    
1006 >    
1007 >    access to dn.regex="^ou=addressbook,associatedDomain=([^,]+),ou=domains,o=<basedn>$" attrs=children
1008 >            by dn.regex="^uid=([^,]+),ou=users,associatedDomain=$1,ou=domains,o=<basedn>$$" write
1009 >            by * none
1010 >    
1011 >    
1012 >    # Note that above the "by" clause needs a "regex" style to make sure
1013 >    # it expands to a DN that starts with a "uid=<someuserid>" pattern
1014 >    # while substituting the associatedDomain submatch from the "what" clause.
1015 >    
1016 >    
1017 >    # This rule lets a user with "uid=<matcheduid>" of "<associatedDomain=matcheddomain>"
1018 >    # write (i.e. add, modify, delete) the entry whose DN is exactly
1019 >    # "uid=<matcheduid>,ou=addressbook,associatedDomain=<matcheddomain>,ou=domains,o=<basedn>"
1020 >    # and ANY entry as subtree of it
1021 >    
1022 >    
1023 >    access to dn.regex="^(.+,)?uid=([^,]+),ou=addressbook,associatedDomain=([^,]+),ou=domains,o=<basedn>$"
1024 >            by dn.exact,expand="uid=$2,ou=users,associatedDomain=$3,ou=domains,o=<basedn>" write
1025 >            by * none 
1026 >    
1027 >    
1028 >    # Note that above the "by" clause uses the "exact" style with the "expand"
1029 >    # modifier because now the whole pattern can be rebuilt by means of the
1030 >    # submatches from the "what" clause, so a "regex" compilation and evaluation
1031 >    # is no longer required.
1032
1033
1034 H3: Tips for using regular expressions in Access Control 
1035
1036 Always use {{dn.regex=<pattern>}} when you intend to use regular expression 
1037 matching. {{dn=<pattern>}} alone defaults to {{dn.exact<pattern>}}.
1038
1039 Use {{(.+)}} instead of {{(.*)}} when you want at least one char to be matched. 
1040 {{(.*)}} matches the empty string as well.
1041
1042 Don't use regular expressions for matches that can be done otherwise in a safer 
1043 and cheaper manner. Examples:
1044
1045 >    dn.regex=".*dc=example,dc=com"
1046
1047 is unsafe and expensive:
1048
1049     * unsafe because any string containing {{dc=example,dc=com }}will match, 
1050 not only those that end with the desired pattern; use {{.*dc=example,dc=com$}} instead.
1051     * unsafe also because it would allow any {{attributeType}} ending with {{dc}}
1052  as naming attribute for the first RDN in the string, e.g. a custom attributeType 
1053 {{mydc}} would match as well. If you really need a regular expression that allows 
1054 just {{dc=example,dc=com}} or any of its subtrees, use {{^(.+,)?dc=example,dc=com$}}, 
1055 which means: anything to the left of dc=..., if any (the question mark after the 
1056 pattern within brackets), must end with a comma;
1057     * expensive because if you don't need submatches, you could use scoping styles, e.g.
1058
1059 >    dn.subtree="dc=example,dc=com"
1060
1061 to include {{dc=example,dc=com}} in the matching patterns,
1062
1063 >    dn.children="dc=example,dc=com"
1064
1065 to exclude {{dc=example,dc=com}} from the matching patterns, or
1066
1067 >    dn.onelevel="dc=example,dc=com"
1068
1069 to allow exactly one sublevel matches only. 
1070
1071 Always use {{^}} and {{$}} in regexes, whenever appropriate, because 
1072 {{ou=(.+),ou=(.+),ou=addressbooks,o=basedn}} will match 
1073 {{something=bla,ou=xxx,ou=yyy,ou=addressbooks,o=basedn,ou=addressbooks,o=basedn,dc=some,dc=org}}
1074
1075 Always use {{([^,]+)}} to indicate exactly one RDN, because {{(.+)}} can 
1076 include any number of RDNs; e.g. {{ou=(.+),dc=example,dc=com}} will match 
1077 {{ou=My,o=Org,dc=example,dc=com}}, which might not be what you want.
1078
1079 Never add the rootdn to the by clauses. ACLs are not even processed for operations 
1080 performed with rootdn identity (otherwise there would be no reason to define a 
1081 rootdn at all).
1082
1083 Use shorthands. The user directive matches authenticated users and the anonymous
1084 directive matches anonymous users.
1085
1086 Don't use the {{dn.regex}} form for <by> clauses if all you need is scoping 
1087 and/or substring replacement; use scoping styles (e.g. {{exact}}, {{onelevel}}, 
1088 {{children}} or {{subtree}}) and the style modifier expand to cause substring expansion.
1089
1090 For instance,
1091
1092 >    access to dn.regex=".+,dc=([^,]+),dc=([^,]+)$"
1093 >      by dn.regex="^[^,],ou=Admin,dc=$1,dc=$2$$" write
1094
1095 although correct, can be safely and efficiently replaced by
1096
1097 >    access to dn.regex=".+,(dc=[^,]+,dc=[^,]+)$"
1098 >      by dn.onelevel,expand="ou=Admin,$1" write
1099
1100 where the regex in the {{<what>}} clause is more compact, and the one in the {{<by>}} 
1101 clause is replaced by a much more efficient scoping style of onelevel with substring expansion. 
1102
1103
1104 H3: Granting and Denying access based on security strength factors (ssf)
1105
1106 You can restrict access based on the security strength factor (SSF)
1107
1108 >    access to dn="cn=example,cn=edu"
1109 >          by * ssf=256 read
1110
1111 0 (zero) implies no protection,
1112 1 implies integrity protection only,
1113 56 DES or other weak ciphers,
1114 112 triple DES and other strong ciphers,
1115 128 RC4, Blowfish and other modern strong ciphers.
1116
1117 Other possibilities:
1118
1119 >    transport_ssf=<n>
1120 >    tls_ssf=<n>
1121 >    sasl_ssf=<n>
1122
1123 256 is recommended.
1124
1125 See {{slapd.conf}}(5) for information on {{ssf}}.
1126
1127
1128 H3: When things aren't working as expected
1129
1130 Consider this example:
1131
1132 >    access to *
1133 >      by anonymous auth
1134 >    
1135 >    access to *
1136 >      by self write
1137 >    
1138 >    access to *
1139 >      by users read 
1140
1141 You may think this will allow any user to login, to read everything and change 
1142 his own data if he is logged in. But in this example only the login works and 
1143 an ldapsearch returns no data. The Problem is that SLAPD goes through its access 
1144 config line by line and stops as soon as it finds a match in the part of the 
1145 access rule.(here: {{to *}})
1146
1147 To get what we wanted the file has to read:
1148
1149 >    access to *
1150 >      by anonymous auth
1151 >      by self write
1152 >      by users read 
1153
1154 The general rule is: "special access rules first, generic access rules last"
1155
1156 See also {{slapd.access}}(8), loglevel 128 and {{slapacl}}(8) for debugging
1157 information.
1158
1159
1160 H2: Sets - Granting rights based on relationships
1161
1162 Sets are best illustrated via examples. The following sections will present 
1163 a few set ACL examples in order to facilitate their understanding.
1164
1165 (Sets in Access Controls FAQ Entry: {{URL:http://www.openldap.org/faq/data/cache/1133.html}})
1166
1167 Note: Sets are considered experimental. 
1168
1169
1170 H3: Groups of Groups
1171
1172 The OpenLDAP ACL for groups doesn't expand groups within groups, which are
1173 groups that have another group as a member. For example:
1174
1175 > dn: cn=sudoadm,ou=group,dc=example,dc=com
1176 > cn: sudoadm
1177 > objectClass: groupOfNames
1178 > member: uid=john,ou=people,dc=example,dc=com
1179 > member: cn=accountadm,ou=group,dc=example,dc=com
1180 >
1181 > dn: cn=accountadm,ou=group,dc=example,dc=com
1182 > cn: accountadm
1183 > objectClass: groupOfNames
1184 > member: uid=mary,ou=people,dc=example,dc=com
1185
1186 If we use standard group ACLs with the above entries and allow members of the
1187 {{F:sudoadm}} group to write somewhere, {{F:mary}} won't be included:
1188
1189 > access to dn.subtree="ou=sudoers,dc=example,dc=com"
1190 >         by group.exact="cn=sudoadm,ou=group,dc=example,dc=com" write
1191 >         by * read
1192
1193 With sets we can make the ACL be recursive and consider group within groups. So
1194 for each member that is a group, it is further expanded:
1195
1196 > access to dn.subtree="ou=sudoers,dc=example,dc=com"
1197 >       by set="[cn=sudoadm,ou=group,dc=example,dc=com]/member* & user" write
1198 >       by * read
1199
1200 This set ACL means: take the {{F:cn=sudoadm}} DN, check its {{F:member}}
1201 attribute(s) (where the "{{F:*}}" means recursively) and intersect the result
1202 with the authenticated user's DN. If the result is non-empty, the ACL is
1203 considered a match and write access is granted.
1204
1205 The following drawing explains how this set is built:
1206 !import "set-recursivegroup.png"; align="center"; title="Building a recursive group"
1207 FT[align="Center"] Figure X.Y: Populating a recursive group set
1208
1209 First we get the {{F:uid=john}} DN. This entry doesn't have a {{F:member}}
1210 attribute, so the expansion stops here.  Now we get to {{F:cn=accountadm}}.
1211 This one does have a {{F:member}} attribute, which is {{F:uid=mary}}. The
1212 {{F:uid=mary}} entry, however, doesn't have member, so we stop here again. The
1213 end comparison is:
1214
1215 > {"uid=john,ou=people,dc=example,dc=com","uid=mary,ou=people,dc=example,dc=com"} & user
1216
1217 If the authenticated user's DN is any one of those two, write access is
1218 granted. So this set will include {{F:mary}} in the {{F:sudoadm}} group and she
1219 will be allowed the write access.
1220
1221 H3: Group ACLs without DN syntax
1222
1223 The traditional group ACLs, and even the previous example about recursive groups, require
1224 that the members are specified as DNs instead of just usernames.
1225
1226 With sets, however, it's also possible to use simple names in group ACLs, as this example will
1227 show.
1228
1229 Let's say we want to allow members of the {{F:sudoadm}} group to write to the
1230 {{F:ou=suders}} branch of our tree. But our group definition now is using {{F:memberUid}} for
1231 the group members:
1232
1233 > dn: cn=sudoadm,ou=group,dc=example,dc=com
1234 > cn: sudoadm
1235 > objectClass: posixGroup
1236 > gidNumber: 1000
1237 > memberUid: john
1238
1239 With this type of group, we can't use group ACLs. But with a set ACL we can
1240 grant the desired access:
1241
1242 > access to dn.subtree="ou=sudoers,dc=example,dc=com"
1243 >       by set="[cn=sudoadm,ou=group,dc=example,dc=com]/memberUid & user/uid" write
1244 >       by * read
1245
1246 We use a simple intersection where we compare the {{F:uid}} attribute
1247 of the connecting (and authenticated) user with the {{F:memberUid}} attributes
1248 of the group. If they match, the intersection is non-empty and the ACL will
1249 grant write access.
1250
1251 This drawing illustrates this set when the connecting user is authenticated as
1252 {{F:uid=john,ou=people,dc=example,dc=com}}:
1253 !import "set-memberUid.png"; align="center"; title="Sets with memberUid"
1254 FT[align="Center"] Figure X.Y: Sets with {{F:memberUid}}
1255
1256 In this case, it's a match. If it were {{F:mary}} authenticating, however, she
1257 would be denied write access to {{F:ou=sudoers}} because her {{F:uid}}
1258 attribute is not listed in the group's {{F:memberUid}}.
1259
1260 H3: Following references
1261
1262 We will now show a quite powerful example of what can be done with sets. This
1263 example tends to make OpenLDAP administrators smile after they have understood
1264 it and its implications.
1265
1266 Let's start with an user entry:
1267
1268 > dn: uid=john,ou=people,dc=example,dc=com
1269 > uid: john
1270 > objectClass: inetOrgPerson
1271 > givenName: John
1272 > sn: Smith
1273 > cn: john
1274 > manager: uid=mary,ou=people,dc=example,dc=com
1275
1276 Writing an ACL to allow the manager to update some attributes is quite simple
1277 using sets:
1278
1279 > access to dn.exact="uid=john,ou=people,dc=example,dc=com"
1280 >    attrs=carLicense,homePhone,mobile,pager,telephoneNumber
1281 >    by self write
1282 >    by set="this/manager & user" write
1283 >    by * read
1284
1285 In that set, {{F:this}} expands to the entry being accessed, so that
1286 {{F:this/manager}} expands to {{F:uid=mary,ou=people,dc=example,dc=com}} when
1287 john's entry is accessed.  If the manager herself is accessing John's entry,
1288 the ACL will match and write access to those attributes will be granted.
1289
1290 So far, this same behavior can be obtained with the {{F:dnattr}} keyword. With
1291 sets, however, we can further enhance this ACL. Let's say we want to allow the
1292 secretary of the manager to also update these attributes. This is how we do it:
1293
1294 > access to dn.exact="uid=john,ou=people,dc=example,dc=com"
1295 >    attrs=carLicense,homePhone,mobile,pager,telephoneNumber
1296 >    by self write
1297 >    by set="this/manager & user" write
1298 >    by set="this/manager/secretary & user" write
1299 >    by * read
1300
1301 Now we need a picture to help explain what is happening here (entries shortened
1302 for clarity):
1303
1304 !import "set-following-references.png"; align="center"; title="Sets jumping through entries"
1305 FT[align="Center"] Figure X.Y: Sets jumping through entries
1306
1307 In this example, Jane is the secretary of Mary, which is the manager of John.
1308 This whole relationship is defined with the {{F:manager}} and {{F:secretary}}
1309 attributes, which are both of the distinguishedName syntax (i.e., full DNs).
1310 So, when the {{F:uid=john}} entry is being accessed, the
1311 {{F:this/manager/secretary}} set becomes
1312 {{F:{"uid=jane,ou=people,dc=example,dc=com"}}} (follow the references in the
1313 picture):
1314
1315 > this = [uid=john,ou=people,dc=example,dc=com]
1316 > this/manager = \
1317 >   [uid=john,ou=people,dc=example,dc=com]/manager = uid=mary,ou=people,dc=example,dc=com
1318 > this/manager/secretary = \
1319 >   [uid=mary,ou=people,dc=example,dc=com]/secretary = uid=jane,ou=people,dc=example,dc=com
1320
1321 The end result is that when Jane accesses John's entry, she will be granted
1322 write access to the specified attributes. Better yet, this will happen to any
1323 entry she accesses which has Mary as the manager.
1324
1325 This is all cool and nice, but perhaps gives to much power to secretaries. Maybe we need to further
1326 restrict it. For example, let's only allow executive secretaries to have this power:
1327
1328 > access to dn.exact="uid=john,ou=people,dc=example,dc=com"
1329 >   attrs=carLicense,homePhone,mobile,pager,telephoneNumber
1330 >   by self write
1331 >   by set="this/manager & user" write
1332 >   by set="this/manager/secretary & 
1333 >           [cn=executive,ou=group,dc=example,dc=com]/member* & 
1334 >           user" write
1335 >   by * read
1336
1337 It's almost the same ACL as before, but we now also require that the connecting user be a member
1338 of the (possibly nested) {{F:cn=executive}} group.
1339
1340