2

So, I am attempting to write some LDAP rules that will allow certain people the ability to write some subtrees.

Let's say we have this user:

dn: uid=minion1,o=mycompany,ou=cust,dc=some,dc=domain
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
isAdmin: TRUE

And this user:

dn: uid=minion2,o=mycompany,ou=cust,dc=some,dc=domain
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
isAdmin: FALSE

Oh, and this user:

dn: uid=minion3,o=notmycompany,ou=cust,dc=some,dc=domain
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
isAdmin: FALSE

I'm attempting to set permissions for minion1 to modify minion2's account, but not minion3 (if you look, minion3 is in a different organization "notmycompany" where the other two are in "mycompany").

The basic rule is that a user should have the ability to add/modify/delete entries in its organization based on if the "isAdmin" property set to TRUE, AND if the object is in the same organization as the user he/she wishes to modify.

My partially working ACL is:

to dn.regex="^.+o=([^,]+),ou=cust,dc=some,dc=domain$" 
by set="user/isAdmin & [TRUE]" write 

This will of course allow them to modify minion3's account as well. I would like to add

"[^.+,o=$1,ou=cust,dc=some,dc=domain$]"

to the by line above, but so far I have failed miserably. Does anyone have any good ideas I might try? (Did I explain what I'm attempting to do here adequately)?

Thanks in advance;

2

I've spent some time looking through the documentation on sets, and the problem you've got is that set operators (like &) really only work on data of the same type...so you can ask for the intersection of a DN and a DN, or an attribute value and a string, but intersections of things of different types doesn't make sense.

So, we build a string using the isAdmin attribute and the wonders of string concatenation, like this:

olcAccess: {1}to dn.regex="o=([^,]+),ou=cust,dc=some,dc=domain$" 
    by set.expand="([admin=] + user/isAdmin + [,] + user/-1) & ([admin=TRUE] + [,o=$1,ou=cust,dc=some,dc=domain])" write 
    by * break

Note the user of set.expand, because we want to use $1 in the set definition, and note the use of [...] to put literal values into the strings we're evaluating.

For someone logged in as minion1, this will ask for the intersection of:

admin=TRUE,o=mycompany,ou=cust,dc=some,dc=domain

and the literal value:

admin=TRUE,o=mycompany,ou=cust,dc=some,dc=domain

Which is a nonempty set, so it works. For someone with isAdmin=FALSE (or no isAdmin attribute), the comparison would be with admin=FALSE,... or admin=,.... Similarly, for someone not in the same organization o=... as the target, the intersection will produce an empty set.

If you're interested, this is what I actually used for testing. I'm using employeeType instead of isAdmin because I didn't want to muck about with adding a new attribute to my schema.

Also: slapd -dacl ... is your friend.

3
  • While it smells like a bit of hack this was totally fun to figure out.
    – larsks
    Aug 13 '13 at 3:05
  • That was a great answer. I did modify your example above because [admin]=user/isAdmin was not turning out to match [admin=TRUE]. So, I just modified it to read: set.expand="(user/isAdmin + [,] + user/-1) & ([TRUE] + [,o=$1,ou=cust,dc=some,dc=domain])" and viola. Thanks again for the great answer!
    – Eirik Toft
    Aug 13 '13 at 15:49
  • Whoops, that's because there should be a + in there; I've updated the answer.
    – larsks
    Aug 13 '13 at 15:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.