[Date Prev][Date Next]
[Chronological]
[Thread]
[Top]
Re: Granting rights based on relationships
- To: openldap-devel@OpenLDAP.org
- Subject: Re: Granting rights based on relationships
- From: Mark Valence <kurash@sassafras.com>
- Date: Thu, 8 Jun 2000 10:59:04 -0400
- In-reply-to: <3.0.5.32.20000608073426.009324b0@infidel.boolean.net>
- References: <3.0.5.32.20000608072026.00935760@infidel.boolean.net> <Your message of "Wed, 07 Jun 2000 13:57:41 PDT." <3.0.5.32.20000607135741.0092e880@infidel.boolean.net> <3.0.5.32.20000608072026.00935760@infidel.boolean.net> <3.0.5.32.20000608073426.009324b0@infidel.boolean.net>
Here's the syntax for what I'll call "Sets" for lack of a better
term. Look at it as an overview, as the details are easy to change.
For example, I'm using "." where it might be better to use "/", as
then OIDs (which have .'s in them) can be used in place of attribute
names. Also, the literal op ("[ ]") below can hold any value, but
maybe we want to limit it to DNs, or provide some way to specify the
syntax of the literal.
In the examples, I've abbreviated DNs for readability. You should be
able to get the idea, though.
Pardon the pseudo-BNF:
<set> := <base>
| "(" <set> ")"
| <set> <conj> <set>
| <set> "." <attribute> "*"
| <set> "." <attribute>
<base> := "this"
| "user"
| "[" <any text> "]"
<conj> := "&" | "|"
<attribute> := any attribute name
The base "this" refers to the target directory object to which the
set applies. The base "user" refers to the directory object for the
currently connected user. The base "[xxx]" can be arbitrary text, or
can refer to an object by its DN.
Use parentheses to override the usual operator precedence. The
operator "*" has the highest precedence, followed by ".". "&" and
"|" have the lowest, and equal precedence. Operations of equal
precedence are evaluated left-to-right unless parentheses dictate
otherwise.
The conjunction operators, "&" and "|", combine the sets that are
described by their operands. "&" will produce the intersection of
the two operand sets, while "|" will produce the union.
The operator "." produces the set of all values for the given
attribute for all objects in the given set. The closure operator "*"
will recursively add the values of the attributes for the given set.
For example, say the target object ("this") is "cn=Resource" and the
user object is "cn=User". Then:
user | this : resolves to the set { "cn=User", "cn=Resource" }
If there is a group "cn=Group" with members "cn=User" and "cn=Other", then:
[cn=Group].member & user : resolves to the set { "cn=User" }
If another group, "cn=Group2" has members "cn=Group" and "cn=Person", then
[cn=Group2].members* : resolves to { "cn=User", "cn=Other", "cn=Person" }
Note that literal bases (things enclosed in [ ]) do not have to be
DNs. So, to test if the current user speaks English:
user.language & [English]
which resolves to the empty set if the user does not speak English,
otherwise it resolves to the set { "English" }. Of course, when the
target object is something like a document, a more useful template
would be:
this.language & user.language
Here's a way to specify all of the immediate managers of the target
object's owner who are in either of the (possibly nested) groups
"cn=Marketing" or "cn=Sales":
this.owner.manager & ([cn=Marketing].member* | [cn=Sales].member*)
Normally, for access permissions, we care only if there is some
relationship of the current user to the resulting set. So, the above
set would be more useful as:
this.owner.manager & ([cn=Marketing].member* | [cn=Sales].member*) & user
We could make this more power (and more complex and costly to
compute) by allowing base sets to be built from LDAP filters. This
is something to consider, because the combination of filters and sets
(which have little overlap in what they can express) is very powerful.
Questions and comments welcomed.
Mark.