[Date Prev][Date Next] [Chronological] [Thread] [Top]

Re: ACL: access to all values vs. to value



Gavin Henry wrote:
is there a possibility to create an acl statement that grants access to any
(unknown) value of an attribute but denys access to all values of the same
attribute?

Can you explain that again?

BTW: Your answer didn't find its way into the openldap-technical archive:
http://www.openldap.org/lists/openldap-technical/201208/threads.html


Nevertheless, please let me try to explain using a short (but complete) example:



Sample slapd.conf:
==================
include         /openldap/schema/core.schema
pidfile         /openldap/schema/slapd.pid
argsfile        /openldap/schema/slapd.args

access to *
 by self write
 by users read
 by anonymous auth

database        mdb
suffix          "o=test"
rootdn          "cn=Manager,o=test"
rootpw          secret
directory       /openldap/var/openldap-data/test
index   objectClass     eq

access to dn.one="ou=persons,o=test" attrs=description
 by users write
 by * none


Sample val.ldif:
================
dn: o=test
objectClass: organization
objectClass: top
o: test

dn: ou=persons,o=test
objectClass: organizationalUnit
objectClass: top
ou: persons

dn: cn=PersonA,ou=persons,o=test
objectClass: person
objectClass: top
cn: PersonA
sn: PersonA
userPassword:: UGVyc29uQQ==


Sample modifications.ldif:
==========================
#mod 1 (should succeed)
dn: cn=PersonA,ou=persons,o=test
changetype: modify
add: description
description: Description of A

#mod 2 (should succeed)
dn: cn=PersonA,ou=persons,o=test
changetype: modify
add: description
description: Another description of A
description: Just another description of A

#mod 3 (should succeed)
dn: cn=PersonA,ou=persons,o=test
changetype: modify
delete: description
description: Another description of A
description: Just another description of A

#mod 4 (should fail)
dn: cn=PersonA,ou=persons,o=test
changetype: modify
delete: description


slapd startup: (version: git master)
====================================
deepee@test:~$ /openldap/libexec/slapd -f slapd.conf.acl -u openldap -g openldap -d 128 -h "ldap://0.0.0.0:1389/ ldapi://%2Ftmp%2Fldapi_acl/"
50258437 @(#) $OpenLDAP: slapd 2.X (Aug 10 2012 20:44:06) $
        deepee@test:/.../slapd
Backend ACL: access to *
        by self write
        by users read
        by anonymous auth

Backend ACL: access to dn.one="ou=persons,o=test"
 attrs=description
        by users write
        by * none

Backend ACL: access to *
        by * none

50258437 config_back_db_open: line 0: warning: cannot assess the validity of the ACL scope within backend naming context 50258437 mdb_monitor_db_open: monitoring disabled; configure monitor database to enable
50258437 slapd starting


ldapmodify:
===========
deepee@test:~$ cat /tmp/val.ldif | /openldap/bin/ldapmodify -c -x -H "ldap://localhost:1389"; -D "cn=PersonA,ou=persons,o=test" -w PersonA
modifying entry "cn=PersonA,ou=persons,o=test"

modifying entry "cn=PersonA,ou=persons,o=test"

modifying entry "cn=PersonA,ou=persons,o=test"

modifying entry "cn=PersonA,ou=persons,o=test"



slapd.log (level 128):
======================
50258ca0 => access_allowed: result not in cache (userPassword)
50258ca0 => access_allowed: auth access to "cn=PersonA,ou=persons,o=test" "userPassword" requested
50258ca0 => dn: [1] ou=persons,o=test
50258ca0 => acl_get: [1] matched
50258ca0 => acl_get: [2] attr userPassword
50258ca0 => acl_mask: access to entry "cn=PersonA,ou=persons,o=test", attr "userPassword" requested
50258ca0 => acl_mask: to value by "", (=0)
50258ca0 <= check a_dn_pat: self
50258ca0 <= check a_dn_pat: users
50258ca0 <= check a_dn_pat: anonymous
50258ca0 <= acl_mask: [3] applying auth(=xd) (stop)
50258ca0 <= acl_mask: [3] mask: auth(=xd)
50258ca0 => slap_access_allowed: auth access granted by auth(=xd)
50258ca0 => access_allowed: auth access granted by auth(=xd)
50258ca0 => access_allowed: result not in cache (description)
50258ca0 => access_allowed: add access to "cn=PersonA,ou=persons,o=test" "description" requested
50258ca0 => dn: [1] ou=persons,o=test
50258ca0 => acl_get: [1] matched
50258ca0 => acl_get: [1] attr description
50258ca0 => acl_mask: access to entry "cn=PersonA,ou=persons,o=test", attr "description" requested
50258ca0 => acl_mask: to value by "cn=persona,ou=persons,o=test", (=0)
50258ca0 <= check a_dn_pat: users
50258ca0 <= acl_mask: [1] applying write(=wrscxd) (stop)
50258ca0 <= acl_mask: [1] mask: write(=wrscxd)
50258ca0 => slap_access_allowed: add access granted by write(=wrscxd)
50258ca0 => access_allowed: add access granted by write(=wrscxd)
50258ca0 acl: internal mod entryCSN: modify access granted
50258ca0 acl: internal mod modifiersName: modify access granted
50258ca0 acl: internal mod modifyTimestamp: modify access granted
50258ca0 => access_allowed: result not in cache (description)
50258ca0 => access_allowed: add access to "cn=PersonA,ou=persons,o=test" "description" requested
50258ca0 => dn: [1] ou=persons,o=test
50258ca0 => acl_get: [1] matched
50258ca0 => acl_get: [1] attr description
50258ca0 => acl_mask: access to entry "cn=PersonA,ou=persons,o=test", attr "description" requested
50258ca0 => acl_mask: to value by "cn=persona,ou=persons,o=test", (=0)
50258ca0 <= check a_dn_pat: users
50258ca0 <= acl_mask: [1] applying write(=wrscxd) (stop)
50258ca0 <= acl_mask: [1] mask: write(=wrscxd)
50258ca0 => slap_access_allowed: add access granted by write(=wrscxd)
50258ca0 => access_allowed: add access granted by write(=wrscxd)
50258ca0 => access_allowed: result was in cache (description)
50258ca0 acl: internal mod entryCSN: modify access granted
50258ca0 acl: internal mod modifiersName: modify access granted
50258ca0 acl: internal mod modifyTimestamp: modify access granted
50258ca0 => access_allowed: result not in cache (description)
50258ca0 => access_allowed: delete access to "cn=PersonA,ou=persons,o=test" "description" requested
50258ca0 => dn: [1] ou=persons,o=test
50258ca0 => acl_get: [1] matched
50258ca0 => acl_get: [1] attr description
50258ca0 => acl_mask: access to entry "cn=PersonA,ou=persons,o=test", attr "description" requested
50258ca0 => acl_mask: to value by "cn=persona,ou=persons,o=test", (=0)
50258ca0 <= check a_dn_pat: users
50258ca0 <= acl_mask: [1] applying write(=wrscxd) (stop)
50258ca0 <= acl_mask: [1] mask: write(=wrscxd)
50258ca0 => slap_access_allowed: delete access granted by write(=wrscxd)
50258ca0 => access_allowed: delete access granted by write(=wrscxd)
50258ca0 => access_allowed: result was in cache (description)
50258ca0 acl: internal mod entryCSN: modify access granted
50258ca0 acl: internal mod modifiersName: modify access granted
50258ca0 acl: internal mod modifyTimestamp: modify access granted
50258ca0 => access_allowed: result not in cache (description)
50258ca0 => access_allowed: delete access to "cn=PersonA,ou=persons,o=test" "description" requested
50258ca0 => dn: [1] ou=persons,o=test
50258ca0 => acl_get: [1] matched
50258ca0 => acl_get: [1] attr description
50258ca0 => acl_mask: access to entry "cn=PersonA,ou=persons,o=test", attr "description" requested
50258ca0 => acl_mask: to all values by "cn=persona,ou=persons,o=test", (=0)
50258ca0 <= check a_dn_pat: users
50258ca0 <= acl_mask: [1] applying write(=wrscxd) (stop)
50258ca0 <= acl_mask: [1] mask: write(=wrscxd)
50258ca0 => slap_access_allowed: delete access granted by write(=wrscxd)
50258ca0 => access_allowed: delete access granted by write(=wrscxd)
50258ca0 acl: internal mod entryCSN: modify access granted
50258ca0 acl: internal mod modifiersName: modify access granted
50258ca0 acl: internal mod modifyTimestamp: modify access granted


So far so good, all four modification operations succeeded. That's slapd's known default behavior and completely correct in regard to the above defined acl.

My intention is to let the first three operations (to value(s)) succeed and the last operation (to all values) fail by "Insufficient access (50)".

After studying the documentation, doing some (unstructured, trial and error) testing with various combinations of acl statements, I finally had a closer look into slapd's source: Am I right, that slapd's acl engine currently does not offer a chance to differentiate between these two types of modification?