I'm trying to get access control for writing to groups as automated as possible, in as much as I would like LDAP to be able to determine who is able to write based on other attributes.
I've been able to successfully do this if I only need to grant access to one or a few individuals, by specifying their DN as a value to an attribute, and then using this ACL:
add: olcAccess
olcAccess: {2}to dn.sub="ou=groups,dc=example,dc=com" by dnattr="owner" write by users read by * none
That works really well - I just add the owner attribute to an object, specify the owner's DN and they can then write to the object.
However, for larger scale permissions, I need to be able to use the membership of a group. Now I've read http://www.openldap.org/faq/data/cache/52.html and seen that you can specify:
access to <what> by group/<objectclass>/<attributename>=<DN> <access>
However, that would require me to explicitly set the DN of the group in the access control itself.
What I want/need to be able to do is for LDAP to read the DN of the group that has permission, in the same what that it does with dnattr. I thought that I had read something about this being possible with sets, but slapd.access says that "The statement set=<pattern> is undocumented yet." so I'm not clear if that is the most appropriate way to proceed.
Can someone please advise on how this might be accomplished?
Thanks.
Philip
On Thu, Jan 24, 2013 at 12:22:18PM +0000, Philip Colmer wrote:
What I want/need to be able to do is for LDAP to read the DN of the group that has permission, in the same what that it does with dnattr. I thought that I had read something about this being possible with sets, but slapd.access says that "The statement set=<pattern> is undocumented yet." so I'm not clear if that is the most appropriate way to proceed.
Can someone please advise on how this might be accomplished?
Sets are indeed the answer. The documentation only exists in the OpenLDAP FAQ-o-matic at present, but you need something like this:
access to dn.sub="ou=groups,dc=example,dc=com" by set="this/manager/member & user" write by users read by * none
That ACL would give write access to members of any group whose DN is listed in the "manager" attribute.
The basic idea is that "this/manager/member" produces a set of DNs, "user" produces a set containing the DN of the bound user, and "&" generates the intersection of the two sets. If the result is a non-empty set then the "by" clause applies.
Andrew
Thank you, Andrew, for that clear example and explanation. I have successfully implemented this now.
Regards
Philip
On 30 January 2013 08:00, Andrew Findlay andrew.findlay@skills-1st.co.ukwrote:
On Thu, Jan 24, 2013 at 12:22:18PM +0000, Philip Colmer wrote:
What I want/need to be able to do is for LDAP to read the DN of the
group that
has permission, in the same what that it does with dnattr. I thought
that I had
read something about this being possible with sets, but slapd.access
says that
"The statement set=<pattern> is undocumented yet." so I'm not clear if
that is
the most appropriate way to proceed.
Can someone please advise on how this might be accomplished?
Sets are indeed the answer. The documentation only exists in the OpenLDAP FAQ-o-matic at present, but you need something like this:
access to dn.sub="ou=groups,dc=example,dc=com" by set="this/manager/member & user" write by users read by * none
That ACL would give write access to members of any group whose DN is listed in the "manager" attribute.
The basic idea is that "this/manager/member" produces a set of DNs, "user" produces a set containing the DN of the bound user, and "&" generates the intersection of the two sets. If the result is a non-empty set then the "by" clause applies.
Andrew
| From Andrew Findlay, Skills 1st Ltd | | Consultant in large-scale systems, networks, and directory services | | http://www.skills-1st.co.uk/ +44 1628 782565 |
I have a followup requirement where I need to be able to restrict read access to the groups as well as write access. I only want the owners of an object to be able to read and write that object.
The reason for wanting to do this is to ensure that a user only sees the groups that they can edit when they are using LDAP Account Manager. We have quite a large number of groups and I am trying to head off users complaining that they can't find the group they need to edit.
I've been experimenting with the ACLs to try to get it to work but I can only get it to work if the owner is explicitly mentioned, rather than indirectly mentioned as per the "member of a group" approach.
The ACLs so far are:
access to dn.one="dc=example,dc=com" by users read by * none
access to dn.one="ou=groups,dc=example,dc=com" by users read by * none
access to dn.sub="ou=groups,dc=example,dc=com" attrs=objectClass,uniqueMember by users read by * none
access to dn.sub="ou=groups,dc=example,dc=com" by dnattr="owner" write by users none by * none
access to dn.sub="ou=groups,dc=example,dc=com" by set="this/owner/uniqueMember & user" write by users none by * none
(I know that having 'by users none' is redundant but it is there to be explicit)
The purpose of the ACLs is
1. Allow everyone to see the OU structure in the domain. 2. Allow everyone to see the OUs within the groups OU. 3. The intention here is to grant enough access to the attributes of a group so that slapd can then evaluate the uniqueMember attribute. It isn't entirely clear to me whether slapd needs a rule like this or should be able to evaluate membership etc before it applies acls for the user. 4. Allow directly mentioned owners to write, nothing to everyone else. 5. Allow indirectly mentioned owners to write, nothing to everyone else.
Thanks for any suggestions/observations.
Philip
On 30 January 2013 08:00, Andrew Findlay andrew.findlay@skills-1st.co.ukwrote:
On Thu, Jan 24, 2013 at 12:22:18PM +0000, Philip Colmer wrote:
What I want/need to be able to do is for LDAP to read the DN of the
group that
has permission, in the same what that it does with dnattr. I thought
that I had
read something about this being possible with sets, but slapd.access
says that
"The statement set=<pattern> is undocumented yet." so I'm not clear if
that is
the most appropriate way to proceed.
Can someone please advise on how this might be accomplished?
Sets are indeed the answer. The documentation only exists in the OpenLDAP FAQ-o-matic at present, but you need something like this:
access to dn.sub="ou=groups,dc=example,dc=com" by set="this/manager/member & user" write by users read by * none
That ACL would give write access to members of any group whose DN is listed in the "manager" attribute.
The basic idea is that "this/manager/member" produces a set of DNs, "user" produces a set containing the DN of the bound user, and "&" generates the intersection of the two sets. If the result is a non-empty set then the "by" clause applies.
Andrew
| From Andrew Findlay, Skills 1st Ltd | | Consultant in large-scale systems, networks, and directory services | | http://www.skills-1st.co.uk/ +44 1628 782565 |
On Fri, Feb 01, 2013 at 04:56:18PM +0000, Philip Colmer wrote:
I have a followup requirement where I need to be able to restrict read access to the groups as well as write access. I only want the owners of an object to be able to read and write that object.
The reason for wanting to do this is to ensure that a user only sees the groups that they can edit when they are using LDAP Account Manager. We have quite a large number of groups and I am trying to head off users complaining that they can't find the group they need to edit.
I've been experimenting with the ACLs to try to get it to work but I can only get it to work if the owner is explicitly mentioned, rather than indirectly mentioned as per the "member of a group" approach.
The ACLs so far are:
access to dn.one="dc=example,dc=com" by users read by * none
If your users are also stored in a subtree of dc=example,dc=com then you may need to give anonymous users a bit more access to this node. It depends on how your login process works, in particular the stage that maps from a username to a DN.
access to dn.one="ou=groups,dc=example,dc=com" by users read by * none
OK so far.
access to dn.sub="ou=groups,dc=example,dc=com" attrs=objectClass,uniqueMember by users read by * none
I assume this is to support point (3) below - probably not needed.
access to dn.sub="ou=groups,dc=example,dc=com" by dnattr="owner" write by users none by * none
access to dn.sub="ou=groups,dc=example,dc=com" by set="this/owner/uniqueMember & user" write by users none by * none
Here you have a problem, as the second clause will never be used.
If you want to allow both direct owners and ownership via groups then you should merge these two - something like this:
access to dn.sub="ou=groups,dc=example,dc=com" by dnattr="owner" write by set="this/owner/uniqueMember & user" write by * none
I am always a bit wary of putting both direct and indirect references in the same attribute, just in case some entry that you think is a user ends up with a uniqueMember attribute somehow.
(I know that having 'by users none' is redundant but it is there to be explicit)
OK - and you can add it to the merged version if you like.
The purpose of the ACLs is
- Allow everyone to see the OU structure in the domain.
- Allow everyone to see the OUs within the groups OU.
It may not do that. Do you want everyone to see all the OUs, or only those that they are 'owner' of? Is there a layer of OUs under ou=groups,dc=example,dc=com with the actual groups further down? If so, you may need to add a clause to give access to the intermediate OUs.
- The intention here is to grant enough access to the attributes of a group so
that slapd can then evaluate the uniqueMember attribute. It isn't entirely clear to me whether slapd needs a rule like this or should be able to evaluate membership etc before it applies acls for the user.
Slapd will read whatever it needs for internal use in evaluating ACLs so don't worry about it here. On the other hand, you *do* need to grant adequate (auth) access to *user* entries so that anon can authenticate.
- Allow directly mentioned owners to write, nothing to everyone else.
- Allow indirectly mentioned owners to write, nothing to everyone else.
With the change given above, that bit should work.
Andrew
Thank you, Andrew. Combining the two ACLs that allowed writing solved the problem! As you correctly observed, I then didn't need the earlier ACL granting access to objectClass and uniqueMember.
Best regards
Philip
On 1 February 2013 19:27, Andrew Findlay andrew.findlay@skills-1st.co.ukwrote:
On Fri, Feb 01, 2013 at 04:56:18PM +0000, Philip Colmer wrote:
I have a followup requirement where I need to be able to restrict read
access
to the groups as well as write access. I only want the owners of an
object to
be able to read and write that object.
The reason for wanting to do this is to ensure that a user only sees the
groups
that they can edit when they are using LDAP Account Manager. We have
quite a
large number of groups and I am trying to head off users complaining
that they
can't find the group they need to edit.
I've been experimenting with the ACLs to try to get it to work but I can
only
get it to work if the owner is explicitly mentioned, rather than
indirectly
mentioned as per the "member of a group" approach.
The ACLs so far are:
access to dn.one="dc=example,dc=com" by users read by * none
If your users are also stored in a subtree of dc=example,dc=com then you may need to give anonymous users a bit more access to this node. It depends on how your login process works, in particular the stage that maps from a username to a DN.
access to dn.one="ou=groups,dc=example,dc=com" by users read by * none
OK so far.
access to dn.sub="ou=groups,dc=example,dc=com" attrs=objectClass,uniqueMember by users read by * none
I assume this is to support point (3) below - probably not needed.
access to dn.sub="ou=groups,dc=example,dc=com" by dnattr="owner" write by users none by * none
access to dn.sub="ou=groups,dc=example,dc=com" by set="this/owner/uniqueMember & user" write by users none by * none
Here you have a problem, as the second clause will never be used.
If you want to allow both direct owners and ownership via groups then you should merge these two - something like this:
access to dn.sub="ou=groups,dc=example,dc=com" by dnattr="owner" write by set="this/owner/uniqueMember & user" write by * none
I am always a bit wary of putting both direct and indirect references in the same attribute, just in case some entry that you think is a user ends up with a uniqueMember attribute somehow.
(I know that having 'by users none' is redundant but it is there to be explicit)
OK - and you can add it to the merged version if you like.
The purpose of the ACLs is
- Allow everyone to see the OU structure in the domain.
- Allow everyone to see the OUs within the groups OU.
It may not do that. Do you want everyone to see all the OUs, or only those that they are 'owner' of? Is there a layer of OUs under ou=groups,dc=example,dc=com with the actual groups further down? If so, you may need to add a clause to give access to the intermediate OUs.
- The intention here is to grant enough access to the attributes of a
group so
that slapd can then evaluate the uniqueMember attribute. It isn't
entirely
clear to me whether slapd needs a rule like this or should be able to
evaluate
membership etc before it applies acls for the user.
Slapd will read whatever it needs for internal use in evaluating ACLs so don't worry about it here. On the other hand, you *do* need to grant adequate (auth) access to *user* entries so that anon can authenticate.
- Allow directly mentioned owners to write, nothing to everyone else.
- Allow indirectly mentioned owners to write, nothing to everyone else.
With the change given above, that bit should work.
Andrew
| From Andrew Findlay, Skills 1st Ltd | | Consultant in large-scale systems, networks, and directory services | | http://www.skills-1st.co.uk/ +44 1628 782565 |
openldap-technical@openldap.org