Dear OpenLDAP technical list,
I‘ve been running into a little problem with my permission structures – and was
wondering if you could help me with it.
I want the members of a group to administer a tree structure, the group is
member of it. I've tried some acl settings – I'll post my trials below the
basic structure.
Basic structure
The structure is somehow like that tree – behind an # symbol, there is a brief
description what the entries are meant for.
> dc=example,dc=com
> │
> ├── cn=admin # OpenLDAP default admin user
> │
> ├── ou=entities # organisational entities
> │ │
> │ ├── o=e1 # first of these entities
> │ │ │
> │ │ ├── cn=admin # groupOfNames – see bullet points below
> │ │ │ ┆
> │ │ │ └ ┄▸ member: cn=admin,dc=example,dc=com
> │ │ │ └ ┄▸ member: uid=j.doe,ou=people,dc=example,dc=com
> │ │ │
> │ │ ├── cn=role1 # groupOfNames to be reused below
> │ │ │ ┆ as recursive group members within
> │ │ │ ┆ permission groups
> │ │ │ ┆
> │ │ │ └ ┄▸ member: cn=admin,o=e1,ou=entities,dc=example,dc=com
> │ │ │
> │ │ └── cn=role2
> │ │ ┆
> │ │ └ ┄▸ member: cn=admin,o=e1,ou=entities,dc=example,dc=com
> │ │
> │ └── o=e2
> │ ├── cn=admin
> │ ├── cn=role1
> │ └── cn=role2
> │
> ├── ou=groups # permission groups for applications
> │ │ that authenticate against OpenLDAP
> │ │
> │ ├── cn=globaladmins # groupOfNames – superusers in all applications
> │ │ ┆
> │ │ └ ┄▸ member: cn=admin,dc=example,dc=com
> │ │
> │ ├── cn=ldapadmins # groupOfNames – same rights as admin user
> │ │ ┆
> │ │ └ ┄▸ member: cn=globaladmins,ou=groups,dc=example,dc=com
> │ │ └ ┄▸ member: uid=l.dap,ou=people,dc=example,dc=com
> │ │
> │ ├── cn=permissiongroup1 # groupOfNames – authentication group
> │ │ ┆ for specific application
> │ │ ┆
> │ │ └ ┄▸ member: cn=globaladmins,ou=groups,dc=example,dc=com
> │ │ └ ┄▸ member: cn=role1,o=e1,ou=entities,dc=example,dc=com
> │ │ └ ┄▸ member: cn=role1,o=e2,ou=entities,dc=example,dc=com
> │ │
> │ └── cn=permissiongroup2
> │ ┆
> │ └ ┄▸ member: cn=globaladmins,ou=groups,dc=example,dc=com
> │ └ ┄▸ member: cn=role2,o=e1,ou=entities,dc=example,dc=com
> │ └ ┄▸ member: cn=role2,o=e2,ou=entities,dc=example,dc=com
> │
> └── ou=people # finally the "real people" accounts
> │
> ├── uid=j.doe
> ├── uid=l.dap
> └── uid=m.muster
cn=admin,dc=example,dc=com is basic member of the admin groups (since every
group needs at least one member).
uid=l.dap,ou=people,dc=example,dc=com is member of the
cn=ldapadmins,ou=groups,dc=example,dc=com group. Therefor every member should
have same rights within LDAP structure as cn=admin,dc=example,dc=com
ou=people is the only structure, (personal) accounts are maintained
ou=groups is the only structure, authentication groups for (web)applications
are maintained (with nested members)
The cn=admin,o=e1,ou=entities,dc=example,dc=com DN members should be able to
admin everything below o=e1,ou=entities,dc=example,dc=com.
e1 should be dynamic.
The entity admins should not be able to administer other entities than the
ones, they are admins from.
Permission LDIF
I've tried some different things ... and none Regex was successful :(
Since I'll post some fragments, I put every LDIF fragment within such a bash
fragment:
> touch /permissions.ldif
>
> cat >/permissions.ldif <<EOF
> # first of all delete all permissions
> dn: olcDatabase={1}mdb,cn=config
> changetype: modify
> delete: olcAccess
> -
>
> ########
> ## LDIF blocks from below
> ########
>
> -
> # add general permissions
> add: olcAccess
> olcAccess: to *
> by self write
> by dn="cn=admin,dc=example,dc=com" write
> by set="[cn=ldapadmins,ou=groups,dc=example,dc=com]/member* &
> user" write
> by users read
> by * none
> EOF
>
> ldapmodify -Q -Y EXTERNAL -H ldapi:/// <ldapi:///> -f /permissions.ldif
trial 1
> # add administrative access to LVe admin subgroups
> add: olcAccess
> olcAccess: to dn.regex="([^,]+,)?o=([^,]+),ou=entities,dc=example,dc=com"
> by self write
> by dn="cn=admin,dc=example,dc=com" write
> by set="[cn=ldapadmins,ou=groups,dc=example,dc=com]/member* &
> user" write
> by
> set.expand="[cn=admin,o=$2,ou=entities,dc=example,dc=com]/member* & user"
> write
> by set="this/member* & user" read
> by * none
The result is, that admin and any member of ldapadminscan edit, the members of
specific entity admin subgroups cannot edit.
The specific admin subgroups cannot even see the entities subtree.
trial 2
> # add administrative access to LVe admin subgroups
> add: olcAccess
> olcAccess: to dn.regex="o=([^,]+),ou=entities,dc=example,dc=com"
> by self write
> by dn="cn=admin,dc=example,dc=com" write
> by set="[cn=ldapadmins,ou=groups,dc=example,dc=com]/member* &
> user" write
> by
> set.expand="[cn=admin,o=$1,ou=entities,dc=example,dc=com]/member* & user"
> write
> by set="this/member* & user" read
> by * none
The same result as with trial 1 ...
trial 3
Additional groups – as a tree:
> dc=example,dc=com
> ┆
> └── ou=entity_admins
> │
> ├── cn=e1
> │ ┆
> │ └ ┄▸ member: cn=admin,o=e1,ou=entities,dc=example,dc=com
> │
> └── cn=e2
And the LDIF:
> # add administrative access to LVe admin subgroups
> add: olcAccess
> olcAccess: to dn.regex="o=([^,]+),ou=entities,dc=example,dc=com"
> by self write
> by dn="cn=admin,dc=example,dc=com" write
> by set="[cn=ldapadmins,ou=groups,dc=example,dc=com]/member* &
> user" write
> by set.expand="[cn=$1,ou=entity_admins,dc=example,dc=com]/member*
> & user" write
> by set="this/member* & user" read
> by * none
The result is again: admin and any member of ldapadminscan edit, entity_admins
subgroups user cannot edit – even not their "owned" entities.
trial 4
If I put an by set="[cn=admin,o=e1,ou=entities,dc=example,dc=com]/member* &
user" write for EVERY single olcAccess: to
dn.regex="([^,]+,)?o=jpbay,ou=entities,dc=example,dc=com" (with all the other
stuff from trial 1), everything works fine.
BUT: that's not maintainable or dynamic. So that's no solution, I can accept.
I do not know why set.expand doesn't work as expected (as explained within
different online examples on openldap.com <http://openldap.com/>) – and was not
able to find a proper documentation that could explain why. Or if there has to
be some enablement of an OpenLDAP module?
If you could support me with that problem – probably with a solution – it would
be great =)
Thanks a lot,
Martin