[openstack-dev] [Keystone] LDAP support for groups

David Chadwick d.w.chadwick at kent.ac.uk
Tue Dec 18 22:30:39 UTC 2012


How you structure the LDAP tree should be orthogonal and independent 
from the mapping function. So you can start with a simple group 
structure first in which only OpenStack level groups are allowed, then 
go more granular with groups per domain, then down to the org level. You 
would only need to change the code for adding and retrieving the groups 
values without changing the code for mapping to roles and tenants

regards

David


On 18/12/2012 21:03, Adam Young wrote:
> On 12/18/2012 12:34 PM, David Chadwick wrote:
>> Hi Adam
>>
>> considering the structuring of groups in LDAP one more time, I think
>> you need something like the following
>>
>> 1. Each organisation that defines groups for its users should have an
>> organisational entry
> This makes sense, but it is likely a "next version" LDAP backend.
>
>
>> 2. Beneath this Org entry there should be a set of gON entries, each
>> with the name of the group it represents e.g. CN=managers,
>> CN=engineers etc
>
> I could see an approach based on this general idea to pull multiple
> identity providers together. Right now, I would be tempted to do it as
> the domain level.
>
>> 3. The member attribute of each gON entry holds the group members.
>>
>> You then use the mapping function to map from the group attribute
>> (Cn=managers) to the roles/projects you want this group to have
>
> Sounds logical.  I think for a first implementation we do the degenerate
> case, which is one tree for groups, but with an eye to addingthe
> "organization" piece, but ideally fitting into one of the abstractions
> of the current Keystone design.
>
>>
>> regards
>>
>> David
>>
>>
>> On 16/12/2012 02:46, Adam Young wrote:
>>> On 12/15/2012 03:34 AM, David Chadwick wrote:
>>>> Hi Adam
>>>>
>>>> in order to conform to the existing X.521/LDAP schema we have to make
>>>> the following change to your proposal
>>>>
>>>> On 15/12/2012 02:26, Adam Young wrote:
>>>>> For the sake of argument, let say the we do the following:
>>>>>
>>>>> roles continue to be organizationalRoles underneath the projects (I am
>>>>> working really hard to drop the term tenant)
>>>>> groups are groupOfNames
>>>>>
>>>>> user assignment is done by adding the user dn to the roleOccupant
>>>>> attribute of the organizationalRole object.
>>>>>
>>>>> Now we add the rule that group assignement is done in the same
>>>>> attribute.
>>>>
>>>> No, we use the existing rule that group assignment is done via the
>>>> existing member attribute (which is also of type DN). The roleOccupant
>>>> attribute does not exist in the gON object class so you cant use this.
>>>> The other thing to note is that you can have nested groups using gON
>>>> since member can be the DN of a user or the DN of another gON object.
>>>> (I dont know if you want this feature or not, but it is allowed in the
>>>> schema)
>>>
>>> I think you misunderstand what I was proposing.
>>>
>>>
>>> Groups are implemented groupOfNames.  Group membership is done by
>>> appending the users DN to membership attribute.  That is pretty much
>>> what you just wrote, and I think it is the only way to do group
>>> membership that makes sense.
>>
>> OK we are on the same songsheet
>>
>>>
>>> roles are implemented as organizationalRole. They are collected under
>>> the project object, which is implementated as a groupOfNames object.
>>
>> so the project is a gON object and it has multiple children which are
>> the roles that can be used with this project. Is that correct?
>>
>>
>>   A
>>> user is assigned roll by being appended to the roleOccupant attribute of
>>> the organizationalROle.  My guess is that this is a bit of abuse of the
>>> organizationalRole object as all of the documentation I have seen shows
>>> it to assume only one DN, the user filling the role, but we do it as a
>>> list.
>>
>> No its not abuse. Its the standard use of the roleOccupant attribute
>> which is multi-valued. Its quite common to have multiple people with
>> the same roles e.g. Manager, team leader, professor etc. are all roles
>> usually held by many people.
>>
>>
>>>
>>> So to add groups to the role, we append the DN of the group to the
>>> roleOccupant field.  This is on the organizationalRole object, not the
>>> groupOfNames.
>>>
>>
>> Yes this sounds OK. YOu are effectively saying that a whole group of
>> people have a particular role.
>>
>>>
>>>
>>>> organizationalRole
>>>>
>>>>>
>>>>> Now, to determine the roles for a user/project, we need to:
>>>>>
>>>>> iterate through all of the users of the orgRole.roleOcc attribute.
>>>>> If the user is there, they have that role.
>>>>>
>>>>> If there are any groups in there, we need to iterate through each
>>>>> of the
>>>>> groups to find out if the user is a member of that group. If they are,
>>>>> they have that role.
>>>>
>>>> and you could recursively do this, if you find that another group is
>>>> also a member of the group
>>> Yeah, FreeIPA does this, but it is kindof non-standard for Unix/Posix
>>> groups.
>>>>
>>>>>
>>>>> Does this sound right?
>>>>
>>>> with the above changes yes. However you could also use attribute
>>>> mapping instead since this code will be available for you by Tuesday
>>>> :-)
>>> I'll take a look, but I think mapping falls into "neither necessary nor
>>> sufficient" for groups.
>>
>> agreed. YOu still have to say which groups people are in. So using
>> Keystone's backend LDAP is the obvious place to do this.
>>
>> But once you add federation, this will no longer be via Keystone's
>> backend LDAP, but rather in the IDP's own database.
>>
>> So the point I was trying to make (rather badly) is that how you map
>> from group membership to role membership should be done in a way that
>> is independent of whether Keystone is federated or not, ie. it should
>> not depend upon how groups are actually stored. Thus you should not
>> assume that group DNs are stored in roleOccupant attributes,  because
>> in the federated case they wont be. So any code you write that assumes
>> this will be useless once you move to federation. Since you need to
>> map from groups to roles in both cases, then have an independent
>> mapping function that works equally well in both cases. I.e. given a
>> group or groups that a user is a member of, have a function (API) that
>> returns his projects and roles. Then you can use this API for both the
>> federated and non-federated cases. In the federated case each
>> organisational admin will add groups to his own local IDP-LDAP which
>> is external to Keystone. In the non-federated case each organisational
>> admin will need permissions to add groups and their memberships to
>> Keystone's backend LDAP. In both cases the organisational admin will
>> use the mapping API to do the mapping.
>>
>>
>>   Yes, it could be implemented that way, but we
>>> would still need a way to deal with storing group information in LDAP
>>> that aligns with current LDAP deployments.
>>
>> Agreed.
>>
>>   With mapping Keystone would
>>> be able to map to an existing Group structure and make that work.
>>
>> map from, not map to
>>
>>    But
>>> in the cases where the is no group structure, we would need to provide a
>>> baseline, and the entities to manipulate it.
>>
>> I dont follow you here, sorry.
>>
>>>
>>> Put another way, I see Mapping as an Aspect, a way of implementing cross
>>> cutting concerns.  I see Groups as part of the domain model, and
>>> something we need to support as a first class object.  I think that,
>>> even if we were to implement via mapping, we would still need a group
>>> schema.
>>
>> Since I dont really fully appreciate the domain model yet I dont know
>> how you think groups will fit into this. Do you have some blueprint
>> that describes this?
>>
>> regards
>>
>> David
>>
>>>
>>>>
>>>> regards
>>>>
>>>> David
>>>>
>>>>
>>>>>
>>>>> It seems to me that this is a lot of across the Wire LDAP calls, I
>>>>> suspect that there are LDAP controls to support it.
>>>>>
>>>>>
>>>>> This would be the default approach.  I am not sure that it maps to how
>>>>> people are setting up their LDAP servers.  If it is not, what kind of
>>>>> flexibility do we need to build in?  Does this map at all to how AD
>>>>> forces the LDAP schema to look?
>>>>>
>>>>>
>>>>> On 12/14/2012 02:39 PM, David Chadwick wrote:
>>>>>> Yes you can do this, but you still have to define the group
>>>>>> membership
>>>>>> somewhere. This was the point I was addressing. You have to have a
>>>>>> group object analogous to existing role objects, and the OC of the
>>>>>> group object should tell you it is a gON and not a role
>>>>>>
>>>>>> David
>>>>>>
>>>>>>
>>>>>> On 14/12/2012 19:27, Yee, Guang wrote:
>>>>>>> What I meant was you should be able to stash both user and group in
>>>>>>> roleOccupant. During token creation, we still need to resolve the
>>>>>>> groups to
>>>>>>> find out the user roles anyway. Everything in LDAP is identified by
>>>>>>> DN and
>>>>>>> you should know what you are dealing with by looking at its
>>>>>>> objectclasses.
>>>>>>>
>>>>>>>
>>>>>>> Guang
>>>>>>>
>>>>>>>
>>>>>>> -----Original Message-----
>>>>>>> From: David Chadwick [mailto:d.w.chadwick at kent.ac.uk]
>>>>>>> Sent: Friday, December 14, 2012 11:04 AM
>>>>>>> To: OpenStack Development Mailing List
>>>>>>> Cc: Yee, Guang
>>>>>>> Subject: Re: [openstack-dev] [Keystone] LDAP support for groups
>>>>>>>
>>>>>>> You could create separate branches of the LDAP tree for groups and
>>>>>>> roles, and then use the orgRole OC for entries in both branches,
>>>>>>> providing the client has the built in intelligence to know which
>>>>>>> branch
>>>>>>> is the role branch and which branch is the group branch.
>>>>>>> Otherwise you
>>>>>>> can mix groups and roles in the same branch if you use different
>>>>>>> OCs to
>>>>>>> signify the two different types of entry ie. orgRole OC and gON OC.
>>>>>>> But I dont see how you can mix groups and roles in the same
>>>>>>> branch and
>>>>>>> use the same OC for both, as nothing can tell the difference
>>>>>>> between the
>>>>>>> two.
>>>>>>>
>>>>>>> regards
>>>>>>>
>>>>>>> David
>>>>>>>
>>>>>>>
>>>>>>> On 14/12/2012 18:43, Yee, Guang wrote:
>>>>>>>> Having both in a single field should be fine. LDAP group members
>>>>>>>> can be
>>>>>>>> both users and groups (nested groups). At the end, you still
>>>>>>>> need to
>>>>>>>> walk the tree to resolve unique user membership anyway as token
>>>>>>>> doesn't
>>>>>>>> contain any group information.
>>>>>>>>
>>>>>>>> Guang
>>>>>>>>
>>>>>>>> *From:*Adam Young [mailto:ayoung at redhat.com]
>>>>>>>> *Sent:* Friday, December 14, 2012 10:04 AM
>>>>>>>> *To:* OpenStack Development Mailing List
>>>>>>>> *Subject:* [openstack-dev] [Keystone] LDAP support for groups
>>>>>>>>
>>>>>>>> We are close to getting Groups done in the SQL back end, but we
>>>>>>>> still
>>>>>>>> need a schema for  LDAP, and it is not super apparent how to close
>>>>>>>> the
>>>>>>>> gap on it.
>>>>>>>>
>>>>>>>>
>>>>>>>> The schema for role assignment is:
>>>>>>>>
>>>>>>>> 1.   #
>>>>>>>>
>>>>>>>> 2.   olcObjectClasses: ( 2.5.6.8 NAME 'organizationalRole'
>>>>>>>>
>>>>>>>> 3.      DESC 'RFC2256: an organizational role'
>>>>>>>>
>>>>>>>> 4.      SUP top STRUCTURAL
>>>>>>>>
>>>>>>>> 5.      MUST cn
>>>>>>>>
>>>>>>>> 6.      MAY ( x121Address $ registeredAddress $
>>>>>>>> destinationIndicator $
>>>>>>>>
>>>>>>>> 7.      preferredDeliveryMethod $ telexNumber $
>>>>>>>> teletexTerminalIdentifier
>>>>>>> $
>>>>>>>>
>>>>>>>> 8.      telephoneNumber $ internationaliSDNNumber $
>>>>>>> facsimileTelephoneNumber $
>>>>>>>>
>>>>>>>> 9.      !
>>>>>>>>
>>>>>>>> 10.  seeAlso $
>>>>>>>>
>>>>>>>> 11.
>>>>>>>>
>>>>>>>> 12.roleOccupant $ preferredDeliveryMethod $ street $
>>>>>>>>
>>>>>>>> 13.   postOfficeBox $ postalCode $ postalAddress $
>>>>>>>>
>>>>>>>> 14.   physicalDeliveryOfficeName $ ou $ st $ l $ description ) )
>>>>>>>>
>>>>>>>>
>>>>>>>> And the users are in the roleOccupant field.
>>>>>>>>
>>>>>>>> We want to be able to make the roleOccupant included members of
>>>>>>>> groups.
>>>>>>>> But I am not sure that having both in a single field is
>>>>>>>> advisable.  I
>>>>>>>> would rather have a deliberate fields for group members. This was
>>>>>>>> what
>>>>>>>> we did in FreeIPA, and I think it is the right approach.
>>>>>>>>
>>>>>>>> We could extend roleOccupant with an other object class, but there
>>>>>>>> is no
>>>>>>>> obvious class to use.
>>>>>>>>
>>>>>>>> We could replace roleOccupant with a different object class. While
>>>>>>>> that
>>>>>>>> would make a painful transition, it might be preferable. But again,
>>>>>>>> there is no obvious replacement.
>>>>>>>>
>>>>>>>> We could make groups a collection underneath organizationalRoles
>>>>>>>>
>>>>>>>>
>>>>>>>> Feedback is welcome.
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> _______________________________________________
>>>>>>>> OpenStack-dev mailing list
>>>>>>>> OpenStack-dev at lists.openstack.org
>>>>>>>> http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
>>>>>>>>
>>>>>>
>>>>>> _______________________________________________
>>>>>> OpenStack-dev mailing list
>>>>>> OpenStack-dev at lists.openstack.org
>>>>>> http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> OpenStack-dev mailing list
>>>>> OpenStack-dev at lists.openstack.org
>>>>> http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
>>>
>



More information about the OpenStack-dev mailing list