Hello,
studying the slapd.access man page left me with an open question regarding the control of object creation:
* How to allow the creation of objects with a specific objectclass only?
For example, I want to prevent that an object with a object class other than 'foobar' is created.
Assumming the following LDIF should be valid for an "add" operation:
dn: uid=anton1,cn=settings,dc=ldap,dc=base objectClass: foobar uid: anton1
And this one to be invalid:
dn: uid=anton1,cn=settings,dc=ldap,dc=base objectClass: CourierMailAccount objectClass: univentionAdminUserSettings uid: anton1 uidNumber: 0 gidNumber: 0
All of the following examples aren't doing their job when *creating* an entry. Most of them (and even more simple ones) work fine when *modifying* an entry:
## 1. a attribute blacklist ## access to dn="cn=settings,dc=ldap,dc=base" attrs="entry,children" by users write by * +0 break access to dn.regex="^uid=([^,]+),cn=settings,dc=ldap,dc=base$" filter="objectClass=foobar" attrs=!foobar by dn.regex="^uid=$1,.*dc=ldap,dc=base$$" none by * +0 break access to dn.regex="^uid=([^,]+),cn=settings,dc=ldap,dc=base$" filter="objectClass=foobar" attrs=entry,@foobar by dn.regex="^uid=$1,.*dc=ldap,dc=base$$" write by * none ################## → does probably not work because "!foobar" also disallows "objectClass"?
## 2. a negative regex blacklist ## access to dn="cn=settings,dc=ldap,dc=base" attrs="entry,children" by users write by * +0 break access to dn.regex="^uid=([^,]+),cn=settings,dc=ldap,dc=base$" attrs=objectClass val.regex="^([^f]|f[^o]|fo[^o]|foo[^b]|foob[^a]|fooba[^r])$" by dn.regex="^uid=$1,.*dc=ldap,dc=base$$" none by * +0 break access to dn.regex="^uid=([^,]+),cn=settings,dc=ldap,dc=base$" filter="objectClass=foobar" attrs=entry,@foobar by dn.regex="^uid=$1,.*dc=ldap,dc=base$$" write by * none ##################
## 3. a whitelist ## access to dn="cn=settings,dc=ldap,dc=base" attrs="entry,children" by users write by * +0 break access to dn.regex="^uid=([^,]+),cn=settings,dc=ldap,dc=base$" attrs=objectClass value="foobar" by dn.regex="^uid=$1,.*dc=ldap,dc=base$$" write by * +0 break access to dn.regex="^uid=([^,]+),cn=settings,dc=ldap,dc=base$" attrs=objectClass by dn.regex="^uid=$1,.*dc=ldap,dc=base$$" none by * +0 break access to dn.regex="^uid=([^,]+),cn=settings,dc=ldap,dc=base$" filter="objectClass=foobar" attrs=entry,@foobar by dn.regex="^uid=$1,.*dc=ldap,dc=base$$" write by * none ##################
* Is the filter="…" in the "to" clause of an ACL evaluated when "adding" an entry?
* Is the filter="…" when modifying an entry also applied against the modified result or only against the current state of the object?
* the manpage says the syntax is "attrs=<attrlist>[ val[/matchingRule][.<attrstyle>]=<attrval>]" → The hardcoded "val" can also be "value"
* no multiple value-lists can be used in a single defintion (e.g. access to attrs="objectClass val=foo" attrs="someAttribute val="bar" or attrs="objectClass val=foo,someAttribute val=bar")
* "matchingRule" is nowhere defined in the manpage
Some further suggestions for the development are:
* It would reduce a lot of redundancy if multiple "to" statements could be used in one ACL definition (so that the different by clauses doesn't always need to be copied).
* If the "by" clause would also have a filter="" one wouldn't need to use "set"s anymore - sets are slower and doesn't even work with all things (e.g. if you have special characters in the DN). There is no way to escape "]" / "[" and urlencode things which are e.g. used in a LDAP URI filter. This can even lead to security issues.
* ACL rules can't be bound to the ldap operation (search, auth, add, modify, delete, ...), you can only remove e.g. some of the permission bits (e.g. access to if-operation="search" ...)
* Using backreferences of the DN in the filter="" or attrs="" would also be very handy (how to restrict e.g. the "uid" value to be only what's in the DN of the target/operating user?)
Best regards Florian