1# $OpenLDAP: pkg/openldap-guide/admin/access-control.sdf,v 1.3.2.2 2008/05/20 00:17:58 quanah Exp $ 2# Copyright 1999-2008 The OpenLDAP Foundation, All Rights Reserved. 3# COPYING RESTRICTIONS APPLY, see COPYRIGHT. 4 5H1: Access Control 6 7H2: Introduction 8 9As the directory gets populated with more and more data of varying sensitivity, 10controlling the kinds of access granted to the directory becomes more and more 11critical. For instance, the directory may contain data of a confidential nature 12that you may need to protect by contract or by law. Or, if using the directory 13to control access to other services, inappropriate access to the directory may 14create avenues of attack to your sites security that result in devastating 15damage to your assets. 16 17Access 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) 19format ({{SECT:Configuring slapd}}). 20 21The default access control policy is allow read by all clients. Regardless of 22what access control policy is defined, the {{rootdn}} is always allowed full 23rights (i.e. auth, search, compare, read and write) on everything and anything. 24 25As a consequence, it's useless (and results in a performance penalty) to explicitly 26list the {{rootdn}} among the {{<by>}} clauses. 27 28The following sections will describe Access Control Lists in more details and 29follow with some examples and recommendations. 30 31H2: Access Control via Static Configuration 32 33Access to entries and attributes is controlled by the 34access configuration file directive. The general form of an 35access 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 61where the <what> part selects the entries and/or attributes to which 62the access applies, the {{EX:<who>}} part specifies which entities 63are granted access, and the {{EX:<access>}} part specifies the 64access granted. Multiple {{EX:<who> <access> <control>}} triplets 65are supported, allowing many entities to be granted different access 66to the same set of entries and attributes. Not all of these access 67control options are described here; for more details see the 68{{slapd.access}}(5) man page. 69 70 71H3: What to control access to 72 73The <what> part of an access specification determines the entries 74and attributes to which the access control applies. Entries are 75commonly selected in two ways: by DN and by filter. The following 76qualifiers select entries by DN: 77 78> to * 79> to dn[.<basic-style>]=<regex> 80> to dn.<scope-style>=<DN> 81 82The first form is used to select all entries. The second form may 83be used to select entries by matching a regular expression against 84the target entry's {{normalized DN}}. (The second form is not 85discussed further in this document.) The third form is used to 86select entries which are within the requested scope of DN. The 87<DN> is a string representation of the Distinguished Name, as 88described in {{REF:RFC4514}}. 89 90The scope can be either {{EX:base}}, {{EX:one}}, {{EX:subtree}}, 91or {{EX:children}}. Where {{EX:base}} matches only the entry with 92provided DN, {{EX:one}} matches the entries whose parent is the 93provided DN, {{EX:subtree}} matches all entries in the subtree whose 94root is the provided DN, and {{EX:children}} matches all entries 95under the DN (but not the entry named by the DN). 96 97For 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 113Entries may also be selected using a filter: 114 115> to filter=<ldap filter> 116 117where <ldap filter> is a string representation of an LDAP 118search filter, as described in {{REF:RFC4515}}. For example: 119 120> to filter=(objectClass=person) 121 122Note that entries may be selected by both DN and filter by 123including both qualifiers in the <what> clause. 124 125> to dn.one="ou=people,o=suffix" filter=(objectClass=person) 126 127Attributes within an entry are selected by including a comma-separated 128list of attribute names in the <what> selector: 129 130> attrs=<attribute list> 131 132A specific value of an attribute is selected by using a single 133attribute name and also using a value selector: 134 135> attrs=<attribute> val[.<style>]=<regex> 136 137There are two special {{pseudo}} attributes {{EX:entry}} and 138{{EX:children}}. To read (and hence return) a target entry, the 139subject must have {{EX:read}} access to the target's {{entry}} 140attribute. To perform a search, the subject must have 141{{EX:search}} access to the search base's {{entry}} attribute. 142To add or delete an entry, the subject must have 143{{EX:write}} access to the entry's {{EX:entry}} attribute AND must 144have {{EX:write}} access to the entry's parent's {{EX:children}} 145attribute. To rename an entry, the subject must have {{EX:write}} 146access to entry's {{EX:entry}} attribute AND have {{EX:write}} 147access to both the old parent's and new parent's {{EX:children}} 148attributes. The complete examples at the end of this section should 149help clear things up. 150 151Lastly, there is a special entry selector {{EX:"*"}} that is used to 152select any entry. It is used when no other {{EX:<what>}} 153selector has been provided. It's equivalent to "{{EX:dn=.*}}" 154 155 156H3: Who to grant access to 157 158The <who> part identifies the entity or entities being granted 159access. Note that access is granted to "entities" not "entries." 160The following table summarizes entity specifiers: 161 162!block table; align=Center; coltags="EX,N"; \ 163 title="Table 6.3: Access Entity Specifiers" 164Specifier|Entities 165*|All, including anonymous and authenticated users 166anonymous|Anonymous (non-authenticated) users 167users|Authenticated users 168self|User associated with target entry 169dn[.<basic-style>]=<regex>|Users matching a regular expression 170dn.<scope-style>=<DN>|Users within scope of a DN 171!endblock 172 173The DN specifier behaves much like <what> clause DN specifiers. 174 175Other control factors are also supported. For example, a {{EX:<who>}} 176can be restricted by an entry listed in a DN-valued attribute in 177the entry to which the access applies: 178 179> dnattr=<dn-valued attribute name> 180 181The dnattr specification is used to give access to an entry 182whose DN is listed in an attribute of the entry (e.g., give 183access to a group entry to whoever is listed as the owner of 184the group entry). 185 186Some factors may not be appropriate in all environments (or any). 187For example, the domain factor relies on IP to domain name lookups. 188As these can easily be spoofed, the domain factor should be avoided. 189 190 191H3: The access to grant 192 193The 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" 197Level Privileges Description 198none =0 no access 199disclose =d needed for information disclosure on error 200auth =dx needed to authenticate (bind) 201compare =cdx needed to compare 202search =scdx needed to apply search filters 203read =rscdx needed to read search results 204write =wrscdx needed to modify/rename 205manage =mwrscdx needed to manage 206!endblock 207 208Each level implies all lower levels of access. So, for example, 209granting 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 212to grant specific permissions. 213 214 215H3: Access Control Evaluation 216 217When evaluating whether some requester should be given access to 218an entry and/or attribute, slapd compares the entry and/or attribute 219to the {{EX:<what>}} selectors given in the configuration file. 220For each entry, access controls provided in the database which holds 221the entry (or the first database if not held in any database) apply 222first, followed by the global access directives. Within this 223priority, access directives are examined in the order in which they 224appear in the config file. Slapd stops with the first {{EX:<what>}} 225selector that matches the entry and/or attribute. The corresponding 226access directive is the one slapd will use to evaluate access. 227 228Next, slapd compares the entity requesting access to the {{EX:<who>}} 229selectors within the access directive selected above in the order 230in which they appear. It stops with the first {{EX:<who>}} selector 231that matches the requester. This determines the access the entity 232requesting access has to the entry and/or attribute. 233 234Finally, slapd compares the access granted in the selected 235{{EX:<access>}} clause to the access requested by the client. If 236it allows greater or equal access, access is granted. Otherwise, 237access is denied. 238 239The order of evaluation of access directives makes their placement 240in the configuration file important. If one access directive is 241more specific than another in terms of the entries it selects, it 242should appear first in the config file. Similarly, if one {{EX:<who>}} 243selector is more specific than another it should come first in the 244access directive. The access control examples given below should 245help make this clear. 246 247 248 249H3: Access Control Examples 250 251The access control facility described above is quite powerful. This 252section shows some examples of its use for descriptive purposes. 253 254A simple example: 255 256> access to * by * read 257 258This access directive grants read access to everyone. 259 260> access to * 261> by self write 262> by anonymous auth 263> by * read 264 265This directive allows the user to modify their entry, allows anonymous 266to authentication against these entries, and allows all others to 267read these entries. Note that only the first {{EX:by <who>}} clause 268which matches applies. Hence, the anonymous users are granted 269{{EX:auth}}, not {{EX:read}}. The last clause could just as well 270have been "{{EX:by users read}}". 271 272It is often desirable to restrict operations based upon the level 273of protection in place. The following shows how security strength 274factors (SSF) can be used. 275 276> access to * 277> by ssf=128 self write 278> by ssf=64 anonymous auth 279> by ssf=64 users read 280 281This directive allows users to modify their own entries if security 282protections have of strength 128 or better have been established, 283allows authentication access to anonymous users, and read access 284when 64 or better security protections have been established. If 285client has not establish sufficient security protections, the 286implicit {{EX:by * none}} clause would be applied. 287 288The following example shows the use of a style specifiers to select 289the entries by DN in two access directives where ordering is 290significant. 291 292> access to dn.children="dc=example,dc=com" 293> by * search 294> access to dn.children="dc=com" 295> by * read 296 297Read access is granted to entries under the {{EX:dc=com}} subtree, 298except for those entries under the {{EX:dc=example,dc=com}} subtree, 299to which search access is granted. No access is granted to 300{{EX:dc=com}} as neither access directive matches this DN. If the 301order of these access directives was reversed, the trailing directive 302would never be reached, since all entries under {{EX:dc=example,dc=com}} 303are also under {{EX:dc=com}} entries. 304 305Also note that if no {{EX:access to}} directive matches or no {{EX:by 306<who>}} clause, {{B:access is denied}}. That is, every {{EX:access 307to}} directive ends with an implicit {{EX:by * none}} clause and 308every access list ends with an implicit {{EX:access to * by * none}} 309directive. 310 311The next example again shows the importance of ordering, both of 312the access directives and the {{EX:by <who>}} clauses. It also 313shows the use of an attribute selector to grant access to a specific 314attribute and various {{EX:<who>}} selectors. 315 316> access to dn.subtree="dc=example,dc=com" attrs=homePhone 317> by self write 318> by dn.children="dc=example,dc=com" search 319> by peername.regex=IP:10\..+ read 320> access to dn.subtree="dc=example,dc=com" 321> by self write 322> by dn.children="dc=example,dc=com" search 323> by anonymous auth 324 325This example applies to entries in the "{{EX:dc=example,dc=com}}" 326subtree. To all attributes except {{EX:homePhone}}, an entry can 327write to itself, entries under {{EX:example.com}} entries can search 328by them, anybody else has no access (implicit {{EX:by * none}}) 329excepting for authentication/authorization (which is always done 330anonymously). The {{EX:homePhone}} attribute is writable by the 331entry, searchable by entries under {{EX:example.com}}, readable by 332clients connecting from network 10, and otherwise not readable 333(implicit {{EX:by * none}}). All other access is denied by the 334implicit {{EX:access to * by * none}}. 335 336Sometimes it is useful to permit a particular DN to add or 337remove itself from an attribute. For example, if you would like to 338create a group and allow people to add and remove only 339their own DN from the member attribute, you could accomplish 340it with an access directive like this: 341 342> access to attrs=member,entry 343> by dnattr=member selfwrite 344 345The dnattr {{EX:<who>}} selector says that the access applies to 346entries listed in the {{EX:member}} attribute. The {{EX:selfwrite}} access 347selector says that such members can only add or delete their 348own DN from the attribute, not other values. The addition of 349the entry attribute is required because access to the entry is 350required to access any of the entry's attributes. 351 352!if 0 353For more details on how to use the {{EX:access}} directive, 354consult the {{Advanced Access Control}} chapter. 355!endif 356 357 358H3: Configuration File Example 359 360The following is an example configuration file, interspersed 361with explanatory text. It defines two databases to handle 362different parts of the {{TERM:X.500}} tree; both are {{TERM:BDB}} 363database instances. The line numbers shown are provided for 364reference only and are not included in the actual file. First, the 365global configuration section: 366 367E: 1. # example config file - global configuration section 368E: 2. include /usr/local/etc/schema/core.schema 369E: 3. referral ldap://root.openldap.org 370E: 4. access to * by * read 371 372Line 1 is a comment. Line 2 includes another config file 373which contains {{core}} schema definitions. 374The {{EX:referral}} directive on line 3 375means that queries not local to one of the databases defined 376below will be referred to the LDAP server running on the 377standard port (389) at the host {{EX:root.openldap.org}}. 378 379Line 4 is a global access control. It applies to all 380entries (after any applicable database-specific access 381controls). 382 383The next section of the configuration file defines a BDB 384backend that will handle queries for things in the 385"dc=example,dc=com" portion of the tree. The 386database is to be replicated to two slave slapds, one on 387truelies, the other on judgmentday. Indices are to be 388maintained for several attributes, and the {{EX:userPassword}} 389attribute is to be protected from unauthorized access. 390 391E: 5. # BDB definition for the example.com 392E: 6. database bdb 393E: 7. suffix "dc=example,dc=com" 394E: 8. directory /usr/local/var/openldap-data 395E: 9. rootdn "cn=Manager,dc=example,dc=com" 396E: 10. rootpw secret 397E: 11. # indexed attribute definitions 398E: 12. index uid pres,eq 399E: 13. index cn,sn,uid pres,eq,approx,sub 400E: 14. index objectClass eq 401E: 15. # database access control definitions 402E: 16. access to attrs=userPassword 403E: 17. by self write 404E: 18. by anonymous auth 405E: 19. by dn.base="cn=Admin,dc=example,dc=com" write 406E: 20. by * none 407E: 21. access to * 408E: 22. by self write 409E: 23. by dn.base="cn=Admin,dc=example,dc=com" write 410E: 24. by * read 411 412Line 5 is a comment. The start of the database definition is marked 413by the database keyword on line 6. Line 7 specifies the DN suffix 414for queries to pass to this database. Line 8 specifies the directory 415in which the database files will live. 416 417Lines 9 and 10 identify the database {{super-user}} entry and associated 418password. This entry is not subject to access control or size or 419time limit restrictions. 420 421Lines 12 through 14 indicate the indices to maintain for various 422attributes. 423 424Lines 16 through 24 specify access control for entries in this 425database. As this is the first database, the controls also apply 426to entries not held in any database (such as the Root DSE). For 427all applicable entries, the {{EX:userPassword}} attribute is writable 428by the entry itself and by the "admin" entry. It may be used for 429authentication/authorization purposes, but is otherwise not readable. 430All other attributes are writable by the entry and the "admin" 431entry, but may be read by all users (authenticated or not). 432 433The next section of the example configuration file defines another 434BDB database. This one handles queries involving the 435{{EX:dc=example,dc=net}} subtree but is managed by the same entity 436as the first database. Note that without line 39, the read access 437would be allowed due to the global access rule at line 4. 438 439E: 33. # BDB definition for example.net 440E: 34. database bdb 441E: 35. suffix "dc=example,dc=net" 442E: 36. directory /usr/local/var/openldap-data-net 443E: 37. rootdn "cn=Manager,dc=example,dc=com" 444E: 38. index objectClass eq 445E: 39. access to * by users read 446 447H2: Access Control via Dynamic Configuration 448 449Access to slapd entries and attributes is controlled by the 450olcAccess attribute, whose values are a sequence of access directives. 451The general form of the olcAccess configuration is: 452 453> olcAccess: <access directive> 454> <access directive> ::= to <what> 455> [by <who> [<access>] [<control>] ]+ 456> <what> ::= * | 457> [dn[.<basic-style>]=<regex> | dn.<scope-style>=<DN>] 458> [filter=<ldapfilter>] [attrs=<attrlist>] 459> <basic-style> ::= regex | exact 460> <scope-style> ::= base | one | subtree | children 461> <attrlist> ::= <attr> [val[.<basic-style>]=<regex>] | <attr> , <attrlist> 462> <attr> ::= <attrname> | entry | children 463> <who> ::= * | [anonymous | users | self 464> | dn[.<basic-style>]=<regex> | dn.<scope-style>=<DN>] 465> [dnattr=<attrname>] 466> [group[/<objectclass>[/<attrname>][.<basic-style>]]=<regex>] 467> [peername[.<basic-style>]=<regex>] 468> [sockname[.<basic-style>]=<regex>] 469> [domain[.<basic-style>]=<regex>] 470> [sockurl[.<basic-style>]=<regex>] 471> [set=<setspec>] 472> [aci=<attrname>] 473> <access> ::= [self]{<level>|<priv>} 474> <level> ::= none | disclose | auth | compare | search | read | write | manage 475> <priv> ::= {=|+|-}{m|w|r|s|c|x|d|0}+ 476> <control> ::= [stop | continue | break] 477 478where the <what> part selects the entries and/or attributes to which 479the access applies, the {{EX:<who>}} part specifies which entities 480are granted access, and the {{EX:<access>}} part specifies the 481access granted. Multiple {{EX:<who> <access> <control>}} triplets 482are supported, allowing many entities to be granted different access 483to the same set of entries and attributes. Not all of these access 484control options are described here; for more details see the 485{{slapd.access}}(5) man page. 486 487 488H3: What to control access to 489 490The <what> part of an access specification determines the entries 491and attributes to which the access control applies. Entries are 492commonly selected in two ways: by DN and by filter. The following 493qualifiers select entries by DN: 494 495> to * 496> to dn[.<basic-style>]=<regex> 497> to dn.<scope-style>=<DN> 498 499The first form is used to select all entries. The second form may 500be used to select entries by matching a regular expression against 501the target entry's {{normalized DN}}. (The second form is not 502discussed further in this document.) The third form is used to 503select entries which are within the requested scope of DN. The 504<DN> is a string representation of the Distinguished Name, as 505described in {{REF:RFC4514}}. 506 507The scope can be either {{EX:base}}, {{EX:one}}, {{EX:subtree}}, 508or {{EX:children}}. Where {{EX:base}} matches only the entry with 509provided DN, {{EX:one}} matches the entries whose parent is the 510provided DN, {{EX:subtree}} matches all entries in the subtree whose 511root is the provided DN, and {{EX:children}} matches all entries 512under the DN (but not the entry named by the DN). 513 514For example, if the directory contained entries named: 515 516> 0: o=suffix 517> 1: cn=Manager,o=suffix 518> 2: ou=people,o=suffix 519> 3: uid=kdz,ou=people,o=suffix 520> 4: cn=addresses,uid=kdz,ou=people,o=suffix 521> 5: uid=hyc,ou=people,o=suffix 522 523\Then: 524. {{EX:dn.base="ou=people,o=suffix"}} match 2; 525. {{EX:dn.one="ou=people,o=suffix"}} match 3, and 5; 526. {{EX:dn.subtree="ou=people,o=suffix"}} match 2, 3, 4, and 5; and 527. {{EX:dn.children="ou=people,o=suffix"}} match 3, 4, and 5. 528 529 530Entries may also be selected using a filter: 531 532> to filter=<ldap filter> 533 534where <ldap filter> is a string representation of an LDAP 535search filter, as described in {{REF:RFC4515}}. For example: 536 537> to filter=(objectClass=person) 538 539Note that entries may be selected by both DN and filter by 540including both qualifiers in the <what> clause. 541 542> to dn.one="ou=people,o=suffix" filter=(objectClass=person) 543 544Attributes within an entry are selected by including a comma-separated 545list of attribute names in the <what> selector: 546 547> attrs=<attribute list> 548 549A specific value of an attribute is selected by using a single 550attribute name and also using a value selector: 551 552> attrs=<attribute> val[.<style>]=<regex> 553 554There are two special {{pseudo}} attributes {{EX:entry}} and 555{{EX:children}}. To read (and hence return) a target entry, the 556subject must have {{EX:read}} access to the target's {{entry}} 557attribute. To perform a search, the subject must have 558{{EX:search}} access to the search base's {{entry}} attribute. 559To add or delete an entry, the subject must have 560{{EX:write}} access to the entry's {{EX:entry}} attribute AND must 561have {{EX:write}} access to the entry's parent's {{EX:children}} 562attribute. To rename an entry, the subject must have {{EX:write}} 563access to entry's {{EX:entry}} attribute AND have {{EX:write}} 564access to both the old parent's and new parent's {{EX:children}} 565attributes. The complete examples at the end of this section should 566help clear things up. 567 568Lastly, there is a special entry selector {{EX:"*"}} that is used to 569select any entry. It is used when no other {{EX:<what>}} 570selector has been provided. It's equivalent to "{{EX:dn=.*}}" 571 572 573H3: Who to grant access to 574 575The <who> part identifies the entity or entities being granted 576access. Note that access is granted to "entities" not "entries." 577The following table summarizes entity specifiers: 578 579!block table; align=Center; coltags="EX,N"; \ 580 title="Table 5.3: Access Entity Specifiers" 581Specifier|Entities 582*|All, including anonymous and authenticated users 583anonymous|Anonymous (non-authenticated) users 584users|Authenticated users 585self|User associated with target entry 586dn[.<basic-style>]=<regex>|Users matching a regular expression 587dn.<scope-style>=<DN>|Users within scope of a DN 588!endblock 589 590The DN specifier behaves much like <what> clause DN specifiers. 591 592Other control factors are also supported. For example, a {{EX:<who>}} 593can be restricted by an entry listed in a DN-valued attribute in 594the entry to which the access applies: 595 596> dnattr=<dn-valued attribute name> 597 598The dnattr specification is used to give access to an entry 599whose DN is listed in an attribute of the entry (e.g., give 600access to a group entry to whoever is listed as the owner of 601the group entry). 602 603Some factors may not be appropriate in all environments (or any). 604For example, the domain factor relies on IP to domain name lookups. 605As these can easily be spoofed, the domain factor should be avoided. 606 607 608H3: The access to grant 609 610The kind of <access> granted can be one of the following: 611 612!block table; colaligns="LRL"; coltags="EX,EX,N"; align=Center; \ 613 title="Table 5.4: Access Levels" 614Level Privileges Description 615none =0 no access 616disclose =d needed for information disclosure on error 617auth =dx needed to authenticate (bind) 618compare =cdx needed to compare 619search =scdx needed to apply search filters 620read =rscdx needed to read search results 621write =wrscdx needed to modify/rename 622manage =mwrscdx needed to manage 623!endblock 624 625Each level implies all lower levels of access. So, for example, 626granting someone {{EX:write}} access to an entry also grants them 627{{EX:read}}, {{EX:search}}, {{EX:compare}}, {{EX:auth}} and 628{{EX:disclose}} access. However, one may use the privileges specifier 629to grant specific permissions. 630 631 632H3: Access Control Evaluation 633 634When evaluating whether some requester should be given access to 635an entry and/or attribute, slapd compares the entry and/or attribute 636to the {{EX:<what>}} selectors given in the configuration. For 637each entry, access controls provided in the database which holds 638the entry (or the first database if not held in any database) apply 639first, followed by the global access directives (which are held in 640the {{EX:frontend}} database definition). Within this priority, 641access directives are examined in the order in which they appear 642in the configuration attribute. Slapd stops with the first 643{{EX:<what>}} selector that matches the entry and/or attribute. The 644corresponding access directive is the one slapd will use to evaluate 645access. 646 647Next, slapd compares the entity requesting access to the {{EX:<who>}} 648selectors within the access directive selected above in the order 649in which they appear. It stops with the first {{EX:<who>}} selector 650that matches the requester. This determines the access the entity 651requesting access has to the entry and/or attribute. 652 653Finally, slapd compares the access granted in the selected 654{{EX:<access>}} clause to the access requested by the client. If 655it allows greater or equal access, access is granted. Otherwise, 656access is denied. 657 658The order of evaluation of access directives makes their placement 659in the configuration file important. If one access directive is 660more specific than another in terms of the entries it selects, it 661should appear first in the configuration. Similarly, if one {{EX:<who>}} 662selector is more specific than another it should come first in the 663access directive. The access control examples given below should 664help make this clear. 665 666 667 668H3: Access Control Examples 669 670The access control facility described above is quite powerful. This 671section shows some examples of its use for descriptive purposes. 672 673A simple example: 674 675> olcAccess: to * by * read 676 677This access directive grants read access to everyone. 678 679> olcAccess: to * 680> by self write 681> by anonymous auth 682> by * read 683 684This directive allows the user to modify their entry, allows anonymous 685to authenticate against these entries, and allows all others to 686read these entries. Note that only the first {{EX:by <who>}} clause 687which matches applies. Hence, the anonymous users are granted 688{{EX:auth}}, not {{EX:read}}. The last clause could just as well 689have been "{{EX:by users read}}". 690 691It is often desirable to restrict operations based upon the level 692of protection in place. The following shows how security strength 693factors (SSF) can be used. 694 695> olcAccess: to * 696> by ssf=128 self write 697> by ssf=64 anonymous auth 698> by ssf=64 users read 699 700This directive allows users to modify their own entries if security 701protections of strength 128 or better have been established, 702allows authentication access to anonymous users, and read access 703when strength 64 or better security protections have been established. If 704the client has not establish sufficient security protections, the 705implicit {{EX:by * none}} clause would be applied. 706 707The following example shows the use of style specifiers to select 708the entries by DN in two access directives where ordering is 709significant. 710 711> olcAccess: to dn.children="dc=example,dc=com" 712> by * search 713> olcAccess: to dn.children="dc=com" 714> by * read 715 716Read access is granted to entries under the {{EX:dc=com}} subtree, 717except for those entries under the {{EX:dc=example,dc=com}} subtree, 718to which search access is granted. No access is granted to 719{{EX:dc=com}} as neither access directive matches this DN. If the 720order of these access directives was reversed, the trailing directive 721would never be reached, since all entries under {{EX:dc=example,dc=com}} 722are also under {{EX:dc=com}} entries. 723 724Also note that if no {{EX:olcAccess: to}} directive matches or no {{EX:by 725<who>}} clause, {{B:access is denied}}. That is, every {{EX:olcAccess: 726to}} directive ends with an implicit {{EX:by * none}} clause and 727every access list ends with an implicit {{EX:olcAccess: to * by * none}} 728directive. 729 730The next example again shows the importance of ordering, both of 731the access directives and the {{EX:by <who>}} clauses. It also 732shows the use of an attribute selector to grant access to a specific 733attribute and various {{EX:<who>}} selectors. 734 735> olcAccess: to dn.subtree="dc=example,dc=com" attrs=homePhone 736> by self write 737> by dn.children=dc=example,dc=com" search 738> by peername.regex=IP:10\..+ read 739> olcAccess: to dn.subtree="dc=example,dc=com" 740> by self write 741> by dn.children="dc=example,dc=com" search 742> by anonymous auth 743 744This example applies to entries in the "{{EX:dc=example,dc=com}}" 745subtree. To all attributes except {{EX:homePhone}}, an entry can 746write to itself, entries under {{EX:example.com}} entries can search 747by them, anybody else has no access (implicit {{EX:by * none}}) 748excepting for authentication/authorization (which is always done 749anonymously). The {{EX:homePhone}} attribute is writable by the 750entry, searchable by entries under {{EX:example.com}}, readable by 751clients connecting from network 10, and otherwise not readable 752(implicit {{EX:by * none}}). All other access is denied by the 753implicit {{EX:access to * by * none}}. 754 755Sometimes it is useful to permit a particular DN to add or 756remove itself from an attribute. For example, if you would like to 757create a group and allow people to add and remove only 758their own DN from the member attribute, you could accomplish 759it with an access directive like this: 760 761> olcAccess: to attrs=member,entry 762> by dnattr=member selfwrite 763 764The dnattr {{EX:<who>}} selector says that the access applies to 765entries listed in the {{EX:member}} attribute. The {{EX:selfwrite}} access 766selector says that such members can only add or delete their 767own DN from the attribute, not other values. The addition of 768the entry attribute is required because access to the entry is 769required to access any of the entry's attributes. 770 771 772 773H3: Access Control Ordering 774 775Since the ordering of {{EX:olcAccess}} directives is essential to their 776proper evaluation, but LDAP attributes normally do not preserve the 777ordering of their values, OpenLDAP uses a custom schema extension to 778maintain a fixed ordering of these values. This ordering is maintained 779by prepending a {{EX:"{X}"}} numeric index to each value, similarly to 780the approach used for ordering the configuration entries. These index 781tags are maintained automatically by slapd and do not need to be specified 782when originally defining the values. For example, when you create the 783settings 784 785> olcAccess: to attrs=member,entry 786> by dnattr=member selfwrite 787> olcAccess: to dn.children="dc=example,dc=com" 788> by * search 789> olcAccess: to dn.children="dc=com" 790> by * read 791 792when you read them back using slapcat or ldapsearch they will contain 793 794> olcAccess: {0}to attrs=member,entry 795> by dnattr=member selfwrite 796> olcAccess: {1}to dn.children="dc=example,dc=com" 797> by * search 798> olcAccess: {2}to dn.children="dc=com" 799> by * read 800 801The numeric index may be used to specify a particular value to change 802when using ldapmodify to edit the access rules. This index can be used 803instead of (or in addition to) the actual access value. Using this 804numeric index is very helpful when multiple access rules are being managed. 805 806For example, if we needed to change the second rule above to grant 807write access instead of search, we could try this LDIF: 808 809> changetype: modify 810> delete: olcAccess 811> olcAccess: to dn.children="dc=example,dc=com" by * search 812> - 813> add: olcAccess 814> olcAccess: to dn.children="dc=example,dc=com" by * write 815> - 816 817But this example {{B:will not}} guarantee that the existing values remain in 818their original order, so it will most likely yield a broken security 819configuration. Instead, the numeric index should be used: 820 821> changetype: modify 822> delete: olcAccess 823> olcAccess: {1} 824> - 825> add: olcAccess 826> olcAccess: {1}to dn.children="dc=example,dc=com" by * write 827> - 828 829This example deletes whatever rule is in value #1 of the {{EX:olcAccess}} 830attribute (regardless of its value) and adds a new value that is 831explicitly inserted as value #1. The result will be 832 833> olcAccess: {0}to attrs=member,entry 834> by dnattr=member selfwrite 835> olcAccess: {1}to dn.children="dc=example,dc=com" 836> by * write 837> olcAccess: {2}to dn.children="dc=com" 838> by * read 839 840which is exactly what was intended. 841 842!if 0 843For more details on how to use the {{EX:access}} directive, 844consult the {{Advanced Access Control}} chapter. 845!endif 846 847 848H3: Configuration Example 849 850The following is an example configuration, interspersed 851with explanatory text. It defines two databases to handle 852different parts of the {{TERM:X.500}} tree; both are {{TERM:BDB}} 853database instances. The line numbers shown are provided for 854reference only and are not included in the actual file. First, the 855global configuration section: 856 857E: 1. # example config file - global configuration entry 858E: 2. dn: cn=config 859E: 3. objectClass: olcGlobal 860E: 4. cn: config 861E: 5. olcReferral: ldap://root.openldap.org 862E: 6. 863 864Line 1 is a comment. Lines 2-4 identify this as the global 865configuration entry. 866The {{EX:olcReferral:}} directive on line 5 867means that queries not local to one of the databases defined 868below will be referred to the LDAP server running on the 869standard port (389) at the host {{EX:root.openldap.org}}. 870Line 6 is a blank line, indicating the end of this entry. 871 872E: 7. # internal schema 873E: 8. dn: cn=schema,cn=config 874E: 9. objectClass: olcSchemaConfig 875E: 10. cn: schema 876E: 11. 877 878Line 7 is a comment. Lines 8-10 identify this as the root of 879the schema subtree. The actual schema definitions in this entry 880are hardcoded into slapd so no additional attributes are specified here. 881Line 11 is a blank line, indicating the end of this entry. 882 883E: 12. # include the core schema 884E: 13. include: file:///usr/local/etc/openldap/schema/core.ldif 885E: 14. 886 887Line 12 is a comment. Line 13 is an LDIF include directive which 888accesses the {{core}} schema definitions in LDIF format. Line 14 889is a blank line. 890 891Next comes the database definitions. The first database is the 892special {{EX:frontend}} database whose settings are applied globally 893to all the other databases. 894 895E: 15. # global database parameters 896E: 16. dn: olcDatabase=frontend,cn=config 897E: 17. objectClass: olcDatabaseConfig 898E: 18. olcDatabase: frontend 899E: 19. olcAccess: to * by * read 900E: 20. 901 902Line 15 is a comment. Lines 16-18 identify this entry as the global 903database entry. Line 19 is a global access control. It applies to all 904entries (after any applicable database-specific access controls). 905 906The next entry defines a BDB backend that will handle queries for things 907in the "dc=example,dc=com" portion of the tree. Indices are to be maintained 908for several attributes, and the {{EX:userPassword}} attribute is to be 909protected from unauthorized access. 910 911E: 21. # BDB definition for example.com 912E: 22. dn: olcDatabase=bdb,cn=config 913E: 23. objectClass: olcDatabaseConfig 914E: 24. objectClass: olcBdbConfig 915E: 25. olcDatabase: bdb 916E: 26. olcSuffix: "dc=example,dc=com" 917E: 27. olcDbDirectory: /usr/local/var/openldap-data 918E: 28. olcRootDN: "cn=Manager,dc=example,dc=com" 919E: 29. olcRootPW: secret 920E: 30. olcDbIndex: uid pres,eq 921E: 31. olcDbIndex: cn,sn,uid pres,eq,approx,sub 922E: 32. olcDbIndex: objectClass eq 923E: 33. olcAccess: to attrs=userPassword 924E: 34. by self write 925E: 35. by anonymous auth 926E: 36. by dn.base="cn=Admin,dc=example,dc=com" write 927E: 37. by * none 928E: 38. olcAccess: to * 929E: 39. by self write 930E: 40. by dn.base="cn=Admin,dc=example,dc=com" write 931E: 41. by * read 932E: 42. 933 934Line 21 is a comment. Lines 22-25 identify this entry as a BDB database 935configuration entry. Line 26 specifies the DN suffix 936for queries to pass to this database. Line 27 specifies the directory 937in which the database files will live. 938 939Lines 28 and 29 identify the database {{super-user}} entry and associated 940password. This entry is not subject to access control or size or 941time limit restrictions. 942 943Lines 30 through 32 indicate the indices to maintain for various 944attributes. 945 946Lines 33 through 41 specify access control for entries in this 947database. As this is the first database, the controls also apply 948to entries not held in any database (such as the Root DSE). For 949all applicable entries, the {{EX:userPassword}} attribute is writable 950by the entry itself and by the "admin" entry. It may be used for 951authentication/authorization purposes, but is otherwise not readable. 952All other attributes are writable by the entry and the "admin" 953entry, but may be read by all users (authenticated or not). 954 955Line 42 is a blank line, indicating the end of this entry. 956 957The next section of the example configuration file defines another 958BDB database. This one handles queries involving the 959{{EX:dc=example,dc=net}} subtree but is managed by the same entity 960as the first database. Note that without line 52, the read access 961would be allowed due to the global access rule at line 19. 962 963E: 43. # BDB definition for example.net 964E: 44. dn: olcDatabase=bdb,cn=config 965E: 45. objectClass: olcDatabaseConfig 966E: 46. objectClass: olcBdbConfig 967E: 47. olcDatabase: bdb 968E: 48. olcSuffix: "dc=example,dc=net" 969E: 49. olcDbDirectory: /usr/local/var/openldap-data-net 970E: 50. olcRootDN: "cn=Manager,dc=example,dc=com" 971E: 51. olcDbIndex: objectClass eq 972E: 52. olcAccess: to * by users read 973 974 975H3: Converting from {{slapd.conf}}(5) to a {{B:cn=config}} directory format 976 977Discuss slap* -f slapd.conf -F slapd.d/ (man slapd-config) 978 979 980H2: Access Control Common Examples 981 982H3: Basic ACLs 983 984Generally one should start with some basic ACLs such as: 985 986> access to attr=userPassword 987> by self =xw 988> by anonymous auth 989> by * none 990> 991> 992> access to * 993> by self write 994> by users read 995> by * none 996 997The first ACL allows users to update (but not read) their passwords, anonymous 998users to authenticate against this attribute, and (implicitly) denying all 999access to others. 1000 1001The second ACL allows users full access to their entry, authenticated users read 1002access to anything, and (implicitly) denying all access to others (in this case, 1003anonymous users). 1004 1005 1006H3: Matching Anonymous and Authenticated users 1007 1008An anonymous user has a empty DN. While the {{dn.exact=""}} or {{dn.regex="^$"}} 1009 could be used, {{slapd}}(8)) offers an anonymous shorthand which should be 1010used instead. 1011 1012> access to * 1013> by anonymous none 1014> by * read 1015 1016denies all access to anonymous users while granting others read. 1017 1018Authenticated users have a subject DN. While {{dn.regex=".+"}} will match any 1019authenticated user, OpenLDAP provides the users short hand which should be used 1020instead. 1021 1022> access to * 1023> by users read 1024> by * none 1025 1026This ACL grants read permissions to authenticated users while denying others 1027(i.e.: anonymous users). 1028 1029 1030H3: Controlling rootdn access 1031 1032You could specify the {{rootdn}} in {{slapd.conf}}(5) or {[slapd.d}} without 1033specifying a {{rootpw}}. Then you have to add an actual directory entry with 1034the same dn, e.g.: 1035 1036> dn: cn=Manager,o=MyOrganization 1037> cn: Manager 1038> sn: Manager 1039> objectClass: person 1040> objectClass: top 1041> userPassword: {SSHA}someSSHAdata 1042 1043Then binding as the {{rootdn}} will require a regular bind to that DN, which 1044in turn requires auth access to that entry's DN and {{userPassword}}, and this 1045can be restricted via ACLs. E.g.: 1046 1047> access to dn.base="cn=Manager,o=MyOrganization" 1048> by peername.regex=127\.0\.0\.1 auth 1049> by peername.regex=192\.168\.0\..* auth 1050> by users none 1051> by * none 1052 1053The ACLs above will only allow binding using rootdn from localhost and 1054192.168.0.0/24. 1055 1056 1057H3: Managing access with Groups 1058 1059There are a few ways to do this. One approach is illustrated here. Consider the 1060following DIT layout: 1061 1062> +-dc=example,dc=com 1063> +---cn=administrators,dc=example,dc=com 1064> +---cn=fred blogs,dc=example,dc=com 1065 1066and the following group object (in LDIF format): 1067 1068> dn: cn=administrators,dc=example,dc=com 1069> cn: administrators of this region 1070> objectclass: groupOfNames (important for the group acl feature) 1071> member: cn=fred blogs,dc=example,dc=com 1072> member: cn=somebody else,dc=example,dc=com 1073 1074One can then grant access to the members of this this group by adding appropriate 1075{{by group}} clause to an access directive in {{slapd.conf}}(5). For instance, 1076 1077> access to dn.children="dc=example,dc=com" 1078> by self write 1079> by group.exact="cn=Administrators,dc=example,dc=com" write 1080> by * auth 1081 1082Like by {[dn}} clauses, one can also use {{expand}} to expand the group name 1083based upon the regular expression matching of the target, that is, the to {{dn.regex}}). 1084For instance, 1085 1086> access to dn.regex="(.+,)?ou=People,(dc=[^,]+,dc=[^,]+)$" 1087> attrs=children,entry,uid 1088> by group.expand="cn=Managers,$2" write 1089> by users read 1090> by * auth 1091 1092 1093The above illustration assumed that the group members are to be found in the 1094{{member}} attribute type of the {{groupOfNames}} object class. If you need to 1095use a different group object and/or a different attribute type then use the 1096following {{slapd.conf}}(5) (abbreviated) syntax: 1097 1098> access to <what> 1099> by group/<objectclass>/<attributename>=<DN> <access> 1100 1101For example: 1102 1103> access to * 1104> by group/organizationalRole/roleOccupant="cn=Administrator,dc=example,dc=com" write 1105 1106In this case, we have an ObjectClass {{organizationalRole}} which contains the 1107administrator DN's in the {{roleOccupant}} attribute. For instance: 1108 1109> dn: cn=Administrator,dc=example,dc=com 1110> cn: Administrator 1111> objectclass: organizationalRole 1112> roleOccupant: cn=Jane Doe,dc=example,dc=com 1113 1114Note: the specified member attribute type MUST be of DN or {{NameAndOptionalUID}} syntax, 1115and the specified object class SHOULD allow the attribute type. 1116 1117Dynamic Groups are also supported in Access Control. Please see {{slapo-dynlist}}(5) 1118and the {{SECT:Dynamic Lists}} overlay section. 1119 1120 1121H3: Granting access to a subset of attributes 1122 1123You can grant access to a set of attributes by specifying a list of attribute names 1124in the ACL {{to}} clause. To be useful, you also need to grant access to the 1125{{entry}} itself. Also note how {{children}} controls the ability to add, delete, 1126and rename entries. 1127 1128> # mail: self may write, authenticated users may read 1129> access to attrs=mail 1130> by self write 1131> by users read 1132> by * none 1133> 1134> # cn, sn: self my write, all may read 1135> access to attrs=cn,sn 1136> by self write 1137> by * read 1138> 1139> # immediate children: only self can add/delete entries under this entry 1140> access to attrs=children 1141> by self write 1142> 1143> # entry itself: self may write, all may read 1144> access to attrs=entry 1145> by self write 1146> by * read 1147> 1148> # other attributes: self may write, others have no access 1149> access to * 1150> by self write 1151> by * none 1152 1153ObjectClass names may also be specified in this list, which will affect 1154all the attributes that are required and/or allowed by that {{objectClass}}. 1155Actually, names in {{attrlist}} that are prefixed by {{@}} are directly treated 1156as objectClass names. A name prefixed by {{!}} is also treated as an objectClass, 1157but in this case the access rule affects the attributes that are not required 1158nor allowed by that {{objectClass}}. 1159 1160 1161H3: Allowing a user write to all entries below theirs 1162 1163For a setup where a user can write to its own record and to all of its children: 1164 1165> access to dn.regex="(.+,)?(uid=[^,]+,o=Company)$" 1166> by dn.exact,expand="$2" write 1167> by anonymous auth 1168 1169(Add more examples for above) 1170 1171 1172H3: Allowing entry creation 1173 1174Let's say, you have it like this: 1175 1176> o=<basedn> 1177> ou=domains 1178> associatedDomain=<somedomain> 1179> ou=users 1180> uid=<someuserid> 1181> uid=<someotheruserid> 1182> ou=addressbooks 1183> uid=<someuserid> 1184> cn=<someone> 1185> cn=<someoneelse> 1186 1187and, for another domain <someotherdomain>: 1188 1189> o=<basedn> 1190> ou=domains 1191> associatedDomain=<someotherdomain> 1192> ou=users 1193> uid=<someuserid> 1194> uid=<someotheruserid> 1195> ou=addressbooks 1196> uid=<someotheruserid> 1197> cn=<someone> 1198> cn=<someoneelse> 1199 1200then, if you wanted user {{uid=<someuserid>}} to {{B:ONLY}} create an entry 1201for its own thing, you could write an ACL like this: 1202 1203> # this rule lets users of "associatedDomain=<matcheddomain>" 1204> # write under "ou=addressbook,associatedDomain=<matcheddomain>,ou=domains,o=<basedn>", 1205> # i.e. a user can write ANY entry below its domain's address book; 1206> # this permission is necessary, but not sufficient, the next 1207> # will restrict this permission further 1208> 1209> 1210> access to dn.regex="^ou=addressbook,associatedDomain=([^,]+),ou=domains,o=<basedn>$" attrs=children 1211> by dn.regex="^uid=([^,]+),ou=users,associatedDomain=$1,ou=domains,o=<basedn>$$" write 1212> by * none 1213> 1214> 1215> # Note that above the "by" clause needs a "regex" style to make sure 1216> # it expands to a DN that starts with a "uid=<someuserid>" pattern 1217> # while substituting the associatedDomain submatch from the "what" clause. 1218> 1219> 1220> # This rule lets a user with "uid=<matcheduid>" of "<associatedDomain=matcheddomain>" 1221> # write (i.e. add, modify, delete) the entry whose DN is exactly 1222> # "uid=<matcheduid>,ou=addressbook,associatedDomain=<matcheddomain>,ou=domains,o=<basedn>" 1223> # and ANY entry as subtree of it 1224> 1225> 1226> access to dn.regex="^(.+,)?uid=([^,]+),ou=addressbook,associatedDomain=([^,]+),ou=domains,o=<basedn>$" 1227> by dn.exact,expand="uid=$2,ou=users,associatedDomain=$3,ou=domains,o=<basedn>" write 1228> by * none 1229> 1230> 1231> # Note that above the "by" clause uses the "exact" style with the "expand" 1232> # modifier because now the whole pattern can be rebuilt by means of the 1233> # submatches from the "what" clause, so a "regex" compilation and evaluation 1234> # is no longer required. 1235 1236 1237H3: Tips for using regular expressions in Access Control 1238 1239Always use {{dn.regex=<pattern>}} when you intend to use regular expression 1240matching. {{dn=<pattern>}} alone defaults to {{dn.exact<pattern>}}. 1241 1242Use {{(.+)}} instead of {{(.*)}} when you want at least one char to be matched. 1243{{(.*)}} matches the empty string as well. 1244 1245Don't use regular expressions for matches that can be done otherwise in a safer 1246and cheaper manner. Examples: 1247 1248> dn.regex=".*dc=example,dc=com" 1249 1250is unsafe and expensive: 1251 1252 * unsafe because any string containing {{dc=example,dc=com }}will match, 1253not only those that end with the desired pattern; use {{.*dc=example,dc=com$}} instead. 1254 * unsafe also because it would allow any {{attributeType}} ending with {{dc}} 1255 as naming attribute for the first RDN in the string, e.g. a custom attributeType 1256{{mydc}} would match as well. If you really need a regular expression that allows 1257just {{dc=example,dc=com}} or any of its subtrees, use {{^(.+,)?dc=example,dc=com$}}, 1258which means: anything to the left of dc=..., if any (the question mark after the 1259pattern within brackets), must end with a comma; 1260 * expensive because if you don't need submatches, you could use scoping styles, e.g. 1261 1262> dn.subtree="dc=example,dc=com" 1263 1264to include {{dc=example,dc=com}} in the matching patterns, 1265 1266> dn.children="dc=example,dc=com" 1267 1268to exclude {{dc=example,dc=com}} from the matching patterns, or 1269 1270> dn.onelevel="dc=example,dc=com" 1271 1272to allow exactly one sublevel matches only. 1273 1274Always use {{^}} and {{$}} in regexes, whenever appropriate, because 1275{{ou=(.+),ou=(.+),ou=addressbooks,o=basedn}} will match 1276{{something=bla,ou=xxx,ou=yyy,ou=addressbooks,o=basedn,ou=addressbooks,o=basedn,dc=some,dc=org}} 1277 1278Always use {{([^,]+)}} to indicate exactly one RDN, because {{(.+)}} can 1279include any number of RDNs; e.g. {{ou=(.+),dc=example,dc=com}} will match 1280{{ou=My,o=Org,dc=example,dc=com}}, which might not be what you want. 1281 1282Never add the rootdn to the by clauses. ACLs are not even processed for operations 1283performed with rootdn identity (otherwise there would be no reason to define a 1284rootdn at all). 1285 1286Use shorthands. The user directive matches authenticated users and the anonymous 1287directive matches anonymous users. 1288 1289Don't use the {{dn.regex}} form for <by> clauses if all you need is scoping 1290and/or substring replacement; use scoping styles (e.g. {{exact}}, {{onelevel}}, 1291{{children}} or {{subtree}}) and the style modifier expand to cause substring expansion. 1292 1293For instance, 1294 1295> access to dn.regex=".+,dc=([^,]+),dc=([^,]+)$" 1296> by dn.regex="^[^,],ou=Admin,dc=$1,dc=$2$$" write 1297 1298although correct, can be safely and efficiently replaced by 1299 1300> access to dn.regex=".+,(dc=[^,]+,dc=[^,]+)$" 1301> by dn.onelevel,expand="ou=Admin,$1" write 1302 1303where the regex in the {{<what>}} clause is more compact, and the one in the {{<by>}} 1304clause is replaced by a much more efficient scoping style of onelevel with substring expansion. 1305 1306 1307H3: Granting and Denying access based on security strength factors (ssf) 1308 1309You can restrict access based on the security strength factor (SSF) 1310 1311> access to dn="cn=example,cn=edu" 1312> by * ssf=256 read 1313 13140 (zero) implies no protection, 13151 implies integrity protection only, 131656 DES or other weak ciphers, 1317112 triple DES and other strong ciphers, 1318128 RC4, Blowfish and other modern strong ciphers. 1319 1320Other possibilities: 1321 1322> transport_ssf=<n> 1323> tls_ssf=<n> 1324> sasl_ssf=<n> 1325 1326256 is recommended. 1327 1328See {{slapd.conf}}(5) for information on {{ssf}}. 1329 1330 1331H3: When things aren't working as expected 1332 1333Consider this example: 1334 1335> access to * 1336> by anonymous auth 1337> 1338> access to * 1339> by self write 1340> 1341> access to * 1342> by users read 1343 1344You may think this will allow any user to login, to read everything and change 1345his own data if he is logged in. But in this example only the login works and 1346an ldapsearch returns no data. The Problem is that SLAPD goes through its access 1347config line by line and stops as soon as it finds a match in the part of the 1348access rule.(here: {{to *}}) 1349 1350To get what we wanted the file has to read: 1351 1352> access to * 1353> by anonymous auth 1354> by self write 1355> by users read 1356 1357The general rule is: "special access rules first, generic access rules last" 1358 1359See also {{slapd.access}}(8), loglevel 128 and {{slapacl}}(8) for debugging 1360information. 1361 1362 1363H2: Sets - Granting rights based on relationships 1364 1365Sets are best illustrated via examples. The following sections will present 1366a few set ACL examples in order to facilitate their understanding. 1367 1368(Sets in Access Controls FAQ Entry: {{URL:http://www.openldap.org/faq/data/cache/1133.html}}) 1369 1370Note: Sets are considered experimental. 1371 1372 1373H3: Groups of Groups 1374 1375The OpenLDAP ACL for groups doesn't expand groups within groups, which are 1376groups that have another group as a member. For example: 1377 1378> dn: cn=sudoadm,ou=group,dc=example,dc=com 1379> cn: sudoadm 1380> objectClass: groupOfNames 1381> member: uid=john,ou=people,dc=example,dc=com 1382> member: cn=accountadm,ou=group,dc=example,dc=com 1383> 1384> dn: cn=accountadm,ou=group,dc=example,dc=com 1385> cn: accountadm 1386> objectClass: groupOfNames 1387> member: uid=mary,ou=people,dc=example,dc=com 1388 1389If we use standard group ACLs with the above entries and allow members of the 1390{{F:sudoadm}} group to write somewhere, {{F:mary}} won't be included: 1391 1392> access to dn.subtree="ou=sudoers,dc=example,dc=com" 1393> by group.exact="cn=sudoadm,ou=group,dc=example,dc=com" write 1394> by * read 1395 1396With sets we can make the ACL be recursive and consider group within groups. So 1397for each member that is a group, it is further expanded: 1398 1399> access to dn.subtree="ou=sudoers,dc=example,dc=com" 1400> by set="[cn=sudoadm,ou=group,dc=example,dc=com]/member* & user" write 1401> by * read 1402 1403This set ACL means: take the {{F:cn=sudoadm}} DN, check its {{F:member}} 1404attribute(s) (where the "{{F:*}}" means recursively) and intersect the result 1405with the authenticated user's DN. If the result is non-empty, the ACL is 1406considered a match and write access is granted. 1407 1408The following drawing explains how this set is built: 1409!import "set-recursivegroup.png"; align="center"; title="Building a recursive group" 1410FT[align="Center"] Figure X.Y: Populating a recursive group set 1411 1412First we get the {{F:uid=john}} DN. This entry doesn't have a {{F:member}} 1413attribute, so the expansion stops here. Now we get to {{F:cn=accountadm}}. 1414This one does have a {{F:member}} attribute, which is {{F:uid=mary}}. The 1415{{F:uid=mary}} entry, however, doesn't have member, so we stop here again. The 1416end comparison is: 1417 1418> {"uid=john,ou=people,dc=example,dc=com","uid=mary,ou=people,dc=example,dc=com"} & user 1419 1420If the authenticated user's DN is any one of those two, write access is 1421granted. So this set will include {{F:mary}} in the {{F:sudoadm}} group and she 1422will be allowed the write access. 1423 1424H3: Group ACLs without DN syntax 1425 1426The traditional group ACLs, and even the previous example about recursive groups, require 1427that the members are specified as DNs instead of just usernames. 1428 1429With sets, however, it's also possible to use simple names in group ACLs, as this example will 1430show. 1431 1432Let's say we want to allow members of the {{F:sudoadm}} group to write to the 1433{{F:ou=suders}} branch of our tree. But our group definition now is using {{F:memberUid}} for 1434the group members: 1435 1436> dn: cn=sudoadm,ou=group,dc=example,dc=com 1437> cn: sudoadm 1438> objectClass: posixGroup 1439> gidNumber: 1000 1440> memberUid: john 1441 1442With this type of group, we can't use group ACLs. But with a set ACL we can 1443grant the desired access: 1444 1445> access to dn.subtree="ou=sudoers,dc=example,dc=com" 1446> by set="[cn=sudoadm,ou=group,dc=example,dc=com]/memberUid & user/uid" write 1447> by * read 1448 1449We use a simple intersection where we compare the {{F:uid}} attribute 1450of the connecting (and authenticated) user with the {{F:memberUid}} attributes 1451of the group. If they match, the intersection is non-empty and the ACL will 1452grant write access. 1453 1454This drawing illustrates this set when the connecting user is authenticated as 1455{{F:uid=john,ou=people,dc=example,dc=com}}: 1456!import "set-memberUid.png"; align="center"; title="Sets with memberUid" 1457FT[align="Center"] Figure X.Y: Sets with {{F:memberUid}} 1458 1459In this case, it's a match. If it were {{F:mary}} authenticating, however, she 1460would be denied write access to {{F:ou=sudoers}} because her {{F:uid}} 1461attribute is not listed in the group's {{F:memberUid}}. 1462 1463H3: Following references 1464 1465We will now show a quite powerful example of what can be done with sets. This 1466example tends to make OpenLDAP administrators smile after they have understood 1467it and its implications. 1468 1469Let's start with an user entry: 1470 1471> dn: uid=john,ou=people,dc=example,dc=com 1472> uid: john 1473> objectClass: inetOrgPerson 1474> givenName: John 1475> sn: Smith 1476> cn: john 1477> manager: uid=mary,ou=people,dc=example,dc=com 1478 1479Writing an ACL to allow the manager to update some attributes is quite simple 1480using sets: 1481 1482> access to dn.exact="uid=john,ou=people,dc=example,dc=com" 1483> attrs=carLicense,homePhone,mobile,pager,telephoneNumber 1484> by self write 1485> by set="this/manager & user" write 1486> by * read 1487 1488In that set, {{F:this}} expands to the entry being accessed, so that 1489{{F:this/manager}} expands to {{F:uid=mary,ou=people,dc=example,dc=com}} when 1490john's entry is accessed. If the manager herself is accessing John's entry, 1491the ACL will match and write access to those attributes will be granted. 1492 1493So far, this same behavior can be obtained with the {{F:dnattr}} keyword. With 1494sets, however, we can further enhance this ACL. Let's say we want to allow the 1495secretary of the manager to also update these attributes. This is how we do it: 1496 1497> access to dn.exact="uid=john,ou=people,dc=example,dc=com" 1498> attrs=carLicense,homePhone,mobile,pager,telephoneNumber 1499> by self write 1500> by set="this/manager & user" write 1501> by set="this/manager/secretary & user" write 1502> by * read 1503 1504Now we need a picture to help explain what is happening here (entries shortened 1505for clarity): 1506 1507!import "set-following-references.png"; align="center"; title="Sets jumping through entries" 1508FT[align="Center"] Figure X.Y: Sets jumping through entries 1509 1510In this example, Jane is the secretary of Mary, which is the manager of John. 1511This whole relationship is defined with the {{F:manager}} and {{F:secretary}} 1512attributes, which are both of the distinguishedName syntax (i.e., full DNs). 1513So, when the {{F:uid=john}} entry is being accessed, the 1514{{F:this/manager/secretary}} set becomes 1515{{F:{"uid=jane,ou=people,dc=example,dc=com"}}} (follow the references in the 1516picture): 1517 1518> this = [uid=john,ou=people,dc=example,dc=com] 1519> this/manager = \ 1520> [uid=john,ou=people,dc=example,dc=com]/manager = uid=mary,ou=people,dc=example,dc=com 1521> this/manager/secretary = \ 1522> [uid=mary,ou=people,dc=example,dc=com]/secretary = uid=jane,ou=people,dc=example,dc=com 1523 1524The end result is that when Jane accesses John's entry, she will be granted 1525write access to the specified attributes. Better yet, this will happen to any 1526entry she accesses which has Mary as the manager. 1527 1528This is all cool and nice, but perhaps gives to much power to secretaries. Maybe we need to further 1529restrict it. For example, let's only allow executive secretaries to have this power: 1530 1531> access to dn.exact="uid=john,ou=people,dc=example,dc=com" 1532> attrs=carLicense,homePhone,mobile,pager,telephoneNumber 1533> by self write 1534> by set="this/manager & user" write 1535> by set="this/manager/secretary & 1536> [cn=executive,ou=group,dc=example,dc=com]/member* & 1537> user" write 1538> by * read 1539 1540It's almost the same ACL as before, but we now also require that the connecting user be a member 1541of the (possibly nested) {{F:cn=executive}} group. 1542 1543 1544