You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@directory.apache.org by David Jencks <da...@yahoo.com> on 2006/12/23 23:33:30 UTC

Triplesec... storing permissions in ldap

Right now triplesec is basically using strings as permissions, and  
they are stored as multi-valued attributes like so:

objectclass ( 1.2.6.1.4.1.22555.1.1.1.4.203 NAME 'policyRole'
     SUP top
     AUXILIARY
     MUST ( roleName )
     MAY  ( grants $ denials $ description ) )

objectclass ( 1.2.6.1.4.1.22555.1.1.1.4.204 NAME 'policyProfile'
     SUP top
     AUXILIARY
     MUST ( profileId $ user )
     MAY  ( grants $ denials $ roles $ userPassword $ description $  
safehausDisabled ) )


or as a bit of ldif:

dn:  
roleName=mockRole5,ou=roles,appName=mockApplication,ou=applications,dc=e 
xample,dc=com
objectClass: top
objectClass: policyRole
grants: mockPerm9
grants: mockPerm7
grants: mockPerm5
grants: mockPerm4
denials: mockPerm6
roleName: mockRole5

(this includes my local modification so roles can have denials).

After looking around at java.security.Permissions I think we can  
store 99% of them with 3 strings:
className
permissionName
action

and possibly depending on how ldap datamodels work
grant/deny

Within a role or profile, these 3 or 4 strings are needed to get a  
unique permission.

I've been trying to learn about ldap schemas, the data model, ldif,  
etc by figuring out how to fit this info into ldap but I'm pretty  
bewildered and maybe someone with non-zero experience could review  
and improve my suggestion below or suggest how to proceed.

It looks to me as if one way to proceed would be to have the  
className with permissionNames grouped under each labelled grant or  
deny, then with the actions as attributes on the permission.  Does  
the following schema do this?

attributetype ( 1.2.6.1.4.1.22555.1.1.1.3.abc
         NAME 'action'
         DESC 'action for a permission'
         EQUALITY caseExactMatch
         SUBSTR caseExactSubstringsMatch
         SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )

objectclass ( 1.2.6.1.4.1.22555.1.1.1.4.abc NAME 'className'
     SUP top
     AUXILIARY

objectclass ( 1.2.6.1.4.1.22555.1.1.1.4.def NAME 'grant'
     SUP top
     AUXILIARY
     MAY  ( action )

objectclass ( 1.2.6.1.4.1.22555.1.1.1.4.ghi NAME 'deny'
     SUP top
     AUXILIARY
     MAY  ( action )

I'm imagining a dn something like

grant=/servlet/ 
*,permissionClass=javax.security.jacc.WebResourcePermission,roleName=peo 
n,applicationName=foo,....

with attributes like
action=POST,GET
action=INDEX

Some of my other questions are...  AUXILIARY or STRUCTURAL?
What if anything ties the object classes together in a tree, so e.g.  
grant and deny occur "inside" className?  Should there be MAY ( grant  
$ deny) in the className objectclass?
The actions and possibly the grant/deny are likely to have lots of  
bizarre punctuation, such as the commas in the example above.  How  
does one deal with that in ldap?

Many thanks for any help, and I hope this isn't too much of a user  
list question :-)

thanks
david jencks







Re: Triplesec... storing permissions in ldap

Posted by Emmanuel Lecharny <el...@gmail.com>.
David Jencks a écrit :

> Right now triplesec is basically using strings as permissions, and  
> they are stored as multi-valued attributes like so:
>
> objectclass ( 1.2.6.1.4.1.22555.1.1.1.4.203 NAME 'policyRole'
>     SUP top
>     AUXILIARY
>     MUST ( roleName )
>     MAY  ( grants $ denials $ description ) )
>
> objectclass ( 1.2.6.1.4.1.22555.1.1.1.4.204 NAME 'policyProfile'
>     SUP top
>     AUXILIARY
>     MUST ( profileId $ user )
>     MAY  ( grants $ denials $ roles $ userPassword $ description $  
> safehausDisabled ) )
>
>
> or as a bit of ldif:
>
> dn:  
> roleName=mockRole5,ou=roles,appName=mockApplication,ou=applications,dc=e 
> xample,dc=com
> objectClass: top
> objectClass: policyRole
> grants: mockPerm9
> grants: mockPerm7
> grants: mockPerm5
> grants: mockPerm4
> denials: mockPerm6
> roleName: mockRole5
>
> (this includes my local modification so roles can have denials).
>
> After looking around at java.security.Permissions I think we can  
> store 99% of them with 3 strings:
> className
> permissionName
> action
>
> and possibly depending on how ldap datamodels work
> grant/deny
>
> Within a role or profile, these 3 or 4 strings are needed to get a  
> unique permission.
>
> I've been trying to learn about ldap schemas, the data model, ldif,  
> etc by figuring out how to fit this info into ldap but I'm pretty  
> bewildered and maybe someone with non-zero experience could review  
> and improve my suggestion below or suggest how to proceed.
>
> It looks to me as if one way to proceed would be to have the  
> className with permissionNames grouped under each labelled grant or  
> deny, then with the actions as attributes on the permission.  Does  
> the following schema do this?
>
> attributetype ( 1.2.6.1.4.1.22555.1.1.1.3.abc
>         NAME 'action'
>         DESC 'action for a permission'
>         EQUALITY caseExactMatch
>         SUBSTR caseExactSubstringsMatch
>         SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
>
> objectclass ( 1.2.6.1.4.1.22555.1.1.1.4.abc NAME 'className'
>     SUP top
>     AUXILIARY
>
> objectclass ( 1.2.6.1.4.1.22555.1.1.1.4.def NAME 'grant'
>     SUP top
>     AUXILIARY
>     MAY  ( action )
>
> objectclass ( 1.2.6.1.4.1.22555.1.1.1.4.ghi NAME 'deny'
>     SUP top
>     AUXILIARY
>     MAY  ( action )
>
> I'm imagining a dn something like
>
> grant=/servlet/ 
> *,permissionClass=javax.security.jacc.WebResourcePermission,roleName=peo 
> n,applicationName=foo,....

>
> with attributes like
> action=POST,GET
> action=INDEX
>
> Some of my other questions are...  AUXILIARY or STRUCTURAL?

Well, not easy... AUXILIARY is use for ObjectClasses that extends a 
SRUCTURAL ObjectClass. Entries should implement a STRUCTURAL 
ObjectClass. You are not supposed to instanciate an AUXILIARY 
ObjectClass. So, basically, STRUCTURAL if you want to instanciate 
entries from it.

> What if anything ties the object classes together in a tree, so e.g.  
> grant and deny occur "inside" className?  Should there be MAY ( grant  
> $ deny) in the className objectclass?

If Grant and Deny are ObjectClass, they can't be declared in MAY or 
MUST, becuase MAY and MUST only contains attributes, not ObjectClasses

> The actions and possibly the grant/deny are likely to have lots of  
> bizarre punctuation, such as the commas in the example above.  How  
> does one deal with that in ldap?

It depends. Just pick the syntax that best fit your needs, and here, it 
should be something like IA5String, OctetString or PrintableString. You 
have a list of all syntaxes here : 
http://cwiki.apache.org/confluence/display/DIRxSRVx11/Schema+Checking. 
If you have commas, you will have to escape them using \ in a DN. You 
can also use " " around the dn to avoid escaping special chars like , 
and + and ;

>
> Many thanks for any help, and I hope this isn't too much of a user  
> list question :-)

np, and I hope it helps :)

>
> thanks
> david jencks
>
>
>
>
>
>
>


Re: [TRIPLESEC]Re: Triplesec... storing permissions in ldap

Posted by David Jencks <da...@yahoo.com>.
On Dec 28, 2006, at 1:55 PM, David Jencks wrote:
<big snip>

>
> Not entirely.
>
> First of all, I don't think I explained one of my thoughts, which  
> is that keeping a list of all permissions used in an application  
> doesn't really have any value.  In general there's an infinite set  
> of possible permissions for an application and there's no practical  
> way to enumerate all of them.  To my eyes the only thing the  
> permissions are currently used for is to construct the admin role,  
> and this is not something that is generally useful: it certainly  
> has no universal definition in jacc or j2ee.  I would prefer to  
> have some button on a gui to collect all the permissions in defined  
> roles and profiles and add them to a particular role (or profile)
>
> Assuming you agree with this, we will be storing permissions  
> associated with role and profile.  To construct a permission  
> instance we need:
>
> permission class
> permission name
> permission action
> grant/deny
>
> In relational terms, these are all part of the primary key.  IIUC  
> to directly express this in ldap you get dns with something like  
> a=foo+b=bar+c=baz,ou=groupId,....... which I have not yet seen in  
> practice and looks confusing to me.  I thought it would be easier  
> to deal with if instead we treated it as several levels:
>
> role or profile
>
> permission class
>
> [grant,deny]= permission name
> with actions as a multivalued attribute for the permission name.
>
> This results IIUC in the ldif to install a StringPermission with no  
> actions looking something like:
>
>
> dn:  
> roleName=mockRole1,ou=roles,appName=mockApplication,ou=applications,dc 
> =example, dc=com
> objectClass: top
> objectClass: policyRole
> roleName: mockRole1
>
> dn: permClassName=org.safehaus.triplesec.guardian.StringPermission,  
> roleName=mockRole1,ou=roles,appName=mockApplication,ou=applications,dc 
> =example, dc=com
> objectClass: top
> objectClass: permClass
> permClassName: org.safehaus.triplesec.guardian.StringPermission
>
> dn: grant=mockPerm0,  
> permClassName=org.safehaus.triplesec.guardian.StringPermission,  
> roleName=mockRole1,ou=roles,appName=mockApplication,ou=applications,dc 
> =example, dc=com
> objectClass: top
> objectClass: permGrant
> grant: mockPerm0
>
> It might be clearer to look at the schema and code to handle this  
> in guardian-ldap and admin-api in sandbox/triplesec-jacc.  It's  
> entirely possible I've missing something basic and there's a better  
> way to handle this.... but (obviously :-) I haven't seen it yet.
>

so the schema for the above is

attributetype ( 1.2.6.1.4.1.22555.1.1.1.3.208
         NAME 'permClassName'
         DESC 'java class for a set of permission'
         EQUALITY caseExactMatch
         SUBSTR caseExactSubstringsMatch
         SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )

attributetype ( 1.2.6.1.4.1.22555.1.1.1.3.209
         NAME 'grant'
         DESC 'name for a granted permission'
         EQUALITY caseExactMatch
         SUBSTR caseExactSubstringsMatch
         SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )

attributetype ( 1.2.6.1.4.1.22555.1.1.1.3.210
         NAME 'deny'
         DESC 'name for a denied permission'
         EQUALITY caseExactMatch
         SUBSTR caseExactSubstringsMatch
         SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )

attributetype ( 1.2.6.1.4.1.22555.1.1.1.3.211
         NAME 'action'
         DESC 'action for a permission'
         EQUALITY caseExactMatch
         SUBSTR caseExactSubstringsMatch
         SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )

objectclass ( 1.2.6.1.4.1.22555.1.1.1.4.205 NAME 'permClass'
     SUP top
     AUXILIARY
     MUST ( permClassName )
     )

objectclass ( 1.2.6.1.4.1.22555.1.1.1.4.206 NAME 'permGrant'
     SUP top
     AUXILIARY
     MUST ( grant )
     MAY  ( action )
     )

objectclass ( 1.2.6.1.4.1.22555.1.1.1.4.207 NAME 'permDeny'
     SUP top
     AUXILIARY
     MUST ( deny )
     MAY  ( action )
     )


Note that there are two objectClasses that are the same structure,  
permGrant and permDeny.  This doesn't thrill me.

I guess another way to handle this is with another component in the  
dn, something like:

dn:  
roleName=mockRole1,ou=roles,appName=mockApplication,ou=applications,dc=e 
xample, dc=com
objectClass: top
objectClass: policyRole
roleName: mockRole1

dn: permClassName=org.safehaus.triplesec.guardian.StringPermission,  
roleName=mockRole1,ou=roles,appName=mockApplication,ou=applications,dc=e 
xample, dc=com
objectClass: top
objectClass: permClass
permClassName: org.safehaus.triplesec.guardian.StringPermission

dn: permName=mockPerm0, ou=grants,  
permClassName=org.safehaus.triplesec.guardian.StringPermission,  
roleName=mockRole1,ou=roles,appName=mockApplication,ou=applications,dc=e 
xample, dc=com
objectClass: top
objectClass: permName
grant: mockPerm0


with schema something like

attributetype ( 1.2.6.1.4.1.22555.1.1.1.3.208
         NAME 'permClassName'
         DESC 'java class for a set of permission'
         EQUALITY caseExactMatch
         SUBSTR caseExactSubstringsMatch
         SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )

attributetype ( 1.2.6.1.4.1.22555.1.1.1.3.209
         NAME 'permName'
         DESC 'name of a permission'
         EQUALITY caseExactMatch
         SUBSTR caseExactSubstringsMatch
         SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )

attributetype ( 1.2.6.1.4.1.22555.1.1.1.3.211
         NAME 'action'
         DESC 'action for a permission'
         EQUALITY caseExactMatch
         SUBSTR caseExactSubstringsMatch
         SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )

objectclass ( 1.2.6.1.4.1.22555.1.1.1.4.205 NAME 'permClass'
     SUP top
     AUXILIARY
     MUST ( permClassName )
     )

objectclass ( 1.2.6.1.4.1.22555.1.1.1.4.206 NAME 'permName'
     SUP top
     AUXILIARY
     MUST ( permName )
     MAY  ( action )
     )

Is this a better design?  I'm not convinced:

- it has the same number of object classes (we've replaced one of  
permGrant and permDeny with the already existing ou)
- there's one more part in the dn
- there's nothing constraining ou to be grants or denials
- we're leaning on an object class we don't control (ou)

However since I'm a complete beginner here I'd certainly like to hear  
more opinions.

many thanks
david jencks


<another big snip>



[TRIPLESEC]Re: Triplesec... storing permissions in ldap

Posted by David Jencks <da...@yahoo.com>.
On Dec 28, 2006, at 8:23 AM, Alex Karasulu wrote:

> David Jencks wrote:
>> Right now triplesec is basically using strings as permissions, and  
>> they
>> are stored as multi-valued attributes like so:
>>
>> objectclass ( 1.2.6.1.4.1.22555.1.1.1.4.203 NAME 'policyRole'
>>     SUP top
>>     AUXILIARY
>>     MUST ( roleName )
>>     MAY  ( grants $ denials $ description ) )
>>
>> objectclass ( 1.2.6.1.4.1.22555.1.1.1.4.204 NAME 'policyProfile'
>>     SUP top
>>     AUXILIARY
>>     MUST ( profileId $ user )
>>     MAY  ( grants $ denials $ roles $ userPassword $ description $
>> safehausDisabled ) )
>>
>>
>> or as a bit of ldif:
>>
>> dn:
>> roleName=mockRole5,ou=roles,appName=mockApplication,ou=applications,d 
>> c=example,dc=com
>>
>> objectClass: top
>> objectClass: policyRole
>> grants: mockPerm9
>> grants: mockPerm7
>> grants: mockPerm5
>> grants: mockPerm4
>> denials: mockPerm6
>> roleName: mockRole5
>>
>> (this includes my local modification so roles can have denials).
>
> FYI now with denials in roles the set wise calculation of effective
> permissions will need to account for denials in roles.  This also  
> brings
> about the issue of permission precedence since some denials may now
> clash with grants.  A policy around how this will be handled is  
> needed.

I figure that in guardian both role and policy need a grant  
Permissions and a deny Permissions.  For either one, a permission is  
implied if the grant Permissions implies it AND the denies  
Permissions doesn't imply it

grants.implies(p) && !denies.implies(p)


>
>> After looking around at java.security.Permissions I think we can  
>> store
>> 99% of them with 3 strings:
>> className
>> permissionName
>> action
>
> I think we can create a special permission type (objectClass) called a
> javaPermission that adds the extra className and action attributes:
> permissionName is already present.  This new javaPermission basically
> extends the existing string permission objectClass.

I think it makes more sense to model the existing string permissions  
as a kind of java permission and look for a good datamodel for java  
permissions.
>
>> and possibly depending on how ldap datamodels work
>> grant/deny
>
> Why would you add a grant and deny attribute to a permission?
>
>> Within a role or profile, these 3 or 4 strings are needed to get a
>> unique permission.
>
> Ahh ok I see the confusion.  You mean a grant or deny on a Role or a
> Profile and not in the permission object itself.
>
> Basically the Role or Profile (in ldap) will refer to the permission
> that it grants or denies.  In the API there may be a reference to the
> actual Permission object.
>
>> I've been trying to learn about ldap schemas, the data model,  
>> ldif, etc
>> by figuring out how to fit this info into ldap but I'm pretty  
>> bewildered
>> and maybe someone with non-zero experience could review and  
>> improve my
>> suggestion below or suggest how to proceed.
>
> No problem let me take a look ...
>
>> It looks to me as if one way to proceed would be to have the  
>> className
>> with permissionNames grouped under each labelled grant or deny, then
>> with the actions as attributes on the permission.  Does the following
>> schema do this?
>>
>> attributetype ( 1.2.6.1.4.1.22555.1.1.1.3.abc
>>         NAME 'action'
>>         DESC 'action for a permission'
>>         EQUALITY caseExactMatch
>>         SUBSTR caseExactSubstringsMatch
>>         SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
>
> Ok defining an action attribute ... this looks ok minus the need for a
> good OID.  Also you might want the attribute to be actions  
> (plaural) if
> it can be multivalued?
>
>> objectclass ( 1.2.6.1.4.1.22555.1.1.1.4.abc NAME 'className'
>>     SUP top
>>     AUXILIARY
>>
>> objectclass ( 1.2.6.1.4.1.22555.1.1.1.4.def NAME 'grant'
>>     SUP top
>>     AUXILIARY
>>     MAY  ( action )
>>
>> objectclass ( 1.2.6.1.4.1.22555.1.1.1.4.ghi NAME 'deny'
>>     SUP top
>>     AUXILIARY
>>     MAY  ( action )
>
> Hmmm this is not a good idea.  I would design the grants and  
> denials as
> attributes that can be included within the objectClass of a Role and a
> Profile.  These attributes should just associate a permission with the
> Role or Profile as would a foreign key into another table in RDBMS  
> land.
>
> So let's say you define a ldap objectClass called javaPermission for
> your permission like so:
>
> objectclass ( TBD NAME 'javaPermission'
> 	SUP policyPermission
>         AUXILIARY
>         MUST ( className )
> 	MAY ( action )
>
>> I'm imagining a dn something like
>>
>> grant=/servlet/ 
>> *,permissionClass=javax.security.jacc.WebResourcePermission,roleName= 
>> peon,applicationName=foo,....
>
> Hmmm I think you may have a slight missunderstanding on how to use  
> a DN
> in designing the directory.  NP though I don't think we need to mess
> with the directory's hierarchy that much.  The organization we have  
> will
> work.
>
>> with attributes like
>> action=POST,GET
>> action=INDEX
>
> Ok you need to make action into a multivalued attribute and perhaps  
> call
> it actions but your whole view of how to organize the DIT needs some
> work.  Let's take it step by step.  For now our current structure is
> well formulated which in turn effects the DN used.  Just keep in mind
> the DN is merely like a primary key for looking stuff up.  So when you
> look up a permission the DN need not have all the aspects of the
> permission listed within it.
>
> If the permission name uniquely identifies the permission within a
> context of the system then we can simply keep that permission under a
> context and use the permission name as the relative name of the
> permission entry.
>
> Does this make sense?

Not entirely.

First of all, I don't think I explained one of my thoughts, which is  
that keeping a list of all permissions used in an application doesn't  
really have any value.  In general there's an infinite set of  
possible permissions for an application and there's no practical way  
to enumerate all of them.  To my eyes the only thing the permissions  
are currently used for is to construct the admin role, and this is  
not something that is generally useful: it certainly has no universal  
definition in jacc or j2ee.  I would prefer to have some button on a  
gui to collect all the permissions in defined roles and profiles and  
add them to a particular role (or profile)

Assuming you agree with this, we will be storing permissions  
associated with role and profile.  To construct a permission instance  
we need:

permission class
permission name
permission action
grant/deny

In relational terms, these are all part of the primary key.  IIUC to  
directly express this in ldap you get dns with something like a=foo 
+b=bar+c=baz,ou=groupId,....... which I have not yet seen in practice  
and looks confusing to me.  I thought it would be easier to deal with  
if instead we treated it as several levels:

role or profile

permission class

[grant,deny]= permission name
with actions as a multivalued attribute for the permission name.

This results IIUC in the ldif to install a StringPermission with no  
actions looking something like:


dn:  
roleName=mockRole1,ou=roles,appName=mockApplication,ou=applications,dc=e 
xample, dc=com
objectClass: top
objectClass: policyRole
roleName: mockRole1

dn: permClassName=org.safehaus.triplesec.guardian.StringPermission,  
roleName=mockRole1,ou=roles,appName=mockApplication,ou=applications,dc=e 
xample, dc=com
objectClass: top
objectClass: permClass
permClassName: org.safehaus.triplesec.guardian.StringPermission

dn: grant=mockPerm0,  
permClassName=org.safehaus.triplesec.guardian.StringPermission,  
roleName=mockRole1,ou=roles,appName=mockApplication,ou=applications,dc=e 
xample, dc=com
objectClass: top
objectClass: permGrant
grant: mockPerm0

It might be clearer to look at the schema and code to handle this in  
guardian-ldap and admin-api in sandbox/triplesec-jacc.  It's entirely  
possible I've missing something basic and there's a better way to  
handle this.... but (obviously :-) I haven't seen it yet.

>
>> Some of my other questions are...  AUXILIARY or STRUCTURAL?
>
> AUXILIARY is best I would warn against using STRUCTURAL  
> objectClasses in
> general but sometimes you have to.  Here I think we may need to use
> STRUCTURAL objectClasses for permissions when we really used  
> AUXILIARY.
>  This is because an entry needs at least one STRUCTURAL  
> objectClass.  An
> entry can have any number of AUXILIARY objectClasses.
>
> This would take too long to explain but here's the gist of it in a
> manner easily understood by Java programmers ...
>
> ObjectClasses are like Java classes and Interfaces.  Certain  
> inheritance
> rules are similar.  AUXILIARY objectClasses are like interfaces, where
> an entry can actually have several AUXILIARY objectClasses in use for
> it.  STRUCTURAL objectClasses are like concrete classes where an entry
> can really have only one STRUCTURAL objectClass.  An entry must have a
> STRUCTURAL objectClass defined for it.
>
> An ABSTRACT objectClass is like an abstract Java class.  You cannot
> create an object from and ABSTRACT objectClass and hence you cannot  
> have
> an entry with just an ABSTRACT objectClass.
>
>> What if anything ties the object classes together in a tree, so e.g.
>> grant and deny occur "inside" className?  Should there be MAY  
>> ( grant $
>> deny) in the className objectclass?
>
> I think you are confusing a few concepts.  The structure of the  
> tree is
> governed by other kinds of complex schema constructs like
> dITStructureRules and nameForms however we need not talk about these
> right now.
>
>> The actions and possibly the grant/deny are likely to have lots of
>> bizarre punctuation, such as the commas in the example above.  How  
>> does
>> one deal with that in ldap?
>
> This is not a problem unless we start using those attributes within  
> the
> DN of the entry which we should not.  Basically the syntax of the  
> action
> attribute will determine the valid values for these attributes that we
> define.

I think that the permission name (which I am thinking will be more or  
less as it is today modelled as grant=permissionName or  
deny=permissionName) can also have bizarre punctuation and need to be  
part of a dn.  Maybe you can find some other way.... I sure haven't  
seen how to associate a set of values except using an objectclass.
>
>> Many thanks for any help, and I hope this isn't too much of a user  
>> list
>> question :-)
>
> No problem at all.  Let's just step carefully on some of your changes
> until we all have a grasp of what they entail overall wrt schema  
> changes
> and other things they will impact.

I think hammering this out in the sandbox will be a good idea.

many thanks
david jencks

>
> Alex
> <akarasulu.vcf>


Re: Triplesec... storing permissions in ldap

Posted by Alex Karasulu <ak...@apache.org>.
David Jencks wrote:
> Right now triplesec is basically using strings as permissions, and they
> are stored as multi-valued attributes like so:
> 
> objectclass ( 1.2.6.1.4.1.22555.1.1.1.4.203 NAME 'policyRole'
>     SUP top
>     AUXILIARY
>     MUST ( roleName )
>     MAY  ( grants $ denials $ description ) )
> 
> objectclass ( 1.2.6.1.4.1.22555.1.1.1.4.204 NAME 'policyProfile'
>     SUP top
>     AUXILIARY
>     MUST ( profileId $ user )
>     MAY  ( grants $ denials $ roles $ userPassword $ description $
> safehausDisabled ) )
> 
> 
> or as a bit of ldif:
> 
> dn:
> roleName=mockRole5,ou=roles,appName=mockApplication,ou=applications,dc=example,dc=com
> 
> objectClass: top
> objectClass: policyRole
> grants: mockPerm9
> grants: mockPerm7
> grants: mockPerm5
> grants: mockPerm4
> denials: mockPerm6
> roleName: mockRole5
> 
> (this includes my local modification so roles can have denials).

FYI now with denials in roles the set wise calculation of effective
permissions will need to account for denials in roles.  This also brings
about the issue of permission precedence since some denials may now
clash with grants.  A policy around how this will be handled is needed.

> After looking around at java.security.Permissions I think we can store
> 99% of them with 3 strings:
> className
> permissionName
> action

I think we can create a special permission type (objectClass) called a
javaPermission that adds the extra className and action attributes:
permissionName is already present.  This new javaPermission basically
extends the existing string permission objectClass.

> and possibly depending on how ldap datamodels work
> grant/deny

Why would you add a grant and deny attribute to a permission?

> Within a role or profile, these 3 or 4 strings are needed to get a
> unique permission.

Ahh ok I see the confusion.  You mean a grant or deny on a Role or a
Profile and not in the permission object itself.

Basically the Role or Profile (in ldap) will refer to the permission
that it grants or denies.  In the API there may be a reference to the
actual Permission object.

> I've been trying to learn about ldap schemas, the data model, ldif, etc
> by figuring out how to fit this info into ldap but I'm pretty bewildered
> and maybe someone with non-zero experience could review and improve my
> suggestion below or suggest how to proceed.

No problem let me take a look ...

> It looks to me as if one way to proceed would be to have the className
> with permissionNames grouped under each labelled grant or deny, then
> with the actions as attributes on the permission.  Does the following
> schema do this?
> 
> attributetype ( 1.2.6.1.4.1.22555.1.1.1.3.abc
>         NAME 'action'
>         DESC 'action for a permission'
>         EQUALITY caseExactMatch
>         SUBSTR caseExactSubstringsMatch
>         SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )

Ok defining an action attribute ... this looks ok minus the need for a
good OID.  Also you might want the attribute to be actions (plaural) if
it can be multivalued?

> objectclass ( 1.2.6.1.4.1.22555.1.1.1.4.abc NAME 'className'
>     SUP top
>     AUXILIARY
> 
> objectclass ( 1.2.6.1.4.1.22555.1.1.1.4.def NAME 'grant'
>     SUP top
>     AUXILIARY
>     MAY  ( action )
> 
> objectclass ( 1.2.6.1.4.1.22555.1.1.1.4.ghi NAME 'deny'
>     SUP top
>     AUXILIARY
>     MAY  ( action )

Hmmm this is not a good idea.  I would design the grants and denials as
attributes that can be included within the objectClass of a Role and a
Profile.  These attributes should just associate a permission with the
Role or Profile as would a foreign key into another table in RDBMS land.

So let's say you define a ldap objectClass called javaPermission for
your permission like so:

objectclass ( TBD NAME 'javaPermission'
	SUP policyPermission
        AUXILIARY
        MUST ( className )
	MAY ( action )

> I'm imagining a dn something like
> 
> grant=/servlet/*,permissionClass=javax.security.jacc.WebResourcePermission,roleName=peon,applicationName=foo,....

Hmmm I think you may have a slight missunderstanding on how to use a DN
in designing the directory.  NP though I don't think we need to mess
with the directory's hierarchy that much.  The organization we have will
work.

> with attributes like
> action=POST,GET
> action=INDEX

Ok you need to make action into a multivalued attribute and perhaps call
it actions but your whole view of how to organize the DIT needs some
work.  Let's take it step by step.  For now our current structure is
well formulated which in turn effects the DN used.  Just keep in mind
the DN is merely like a primary key for looking stuff up.  So when you
look up a permission the DN need not have all the aspects of the
permission listed within it.

If the permission name uniquely identifies the permission within a
context of the system then we can simply keep that permission under a
context and use the permission name as the relative name of the
permission entry.

Does this make sense?

> Some of my other questions are...  AUXILIARY or STRUCTURAL?

AUXILIARY is best I would warn against using STRUCTURAL objectClasses in
general but sometimes you have to.  Here I think we may need to use
STRUCTURAL objectClasses for permissions when we really used AUXILIARY.
 This is because an entry needs at least one STRUCTURAL objectClass.  An
entry can have any number of AUXILIARY objectClasses.

This would take too long to explain but here's the gist of it in a
manner easily understood by Java programmers ...

ObjectClasses are like Java classes and Interfaces.  Certain inheritance
rules are similar.  AUXILIARY objectClasses are like interfaces, where
an entry can actually have several AUXILIARY objectClasses in use for
it.  STRUCTURAL objectClasses are like concrete classes where an entry
can really have only one STRUCTURAL objectClass.  An entry must have a
STRUCTURAL objectClass defined for it.

An ABSTRACT objectClass is like an abstract Java class.  You cannot
create an object from and ABSTRACT objectClass and hence you cannot have
an entry with just an ABSTRACT objectClass.

> What if anything ties the object classes together in a tree, so e.g.
> grant and deny occur "inside" className?  Should there be MAY ( grant $
> deny) in the className objectclass?

I think you are confusing a few concepts.  The structure of the tree is
governed by other kinds of complex schema constructs like
dITStructureRules and nameForms however we need not talk about these
right now.

> The actions and possibly the grant/deny are likely to have lots of
> bizarre punctuation, such as the commas in the example above.  How does
> one deal with that in ldap?

This is not a problem unless we start using those attributes within the
DN of the entry which we should not.  Basically the syntax of the action
attribute will determine the valid values for these attributes that we
define.

> Many thanks for any help, and I hope this isn't too much of a user list
> question :-)

No problem at all.  Let's just step carefully on some of your changes
until we all have a grasp of what they entail overall wrt schema changes
and other things they will impact.

Alex