Rich Megginson wrote:
> Rob Crittenden wrote:
>> Dmitri Pal wrote:
>>> Hello,
>>>
>>> For some background see: http://www.freeipa.com/page/Access_Control
>>>
>>> I took a look at the ACIs in DS. An ACI consists of 6 parts:
>>> 1) Name
>>> 2) Users and Groups that the permission is granted to
>>> 3) The right (read, write, add, delete etc)
>>> 4) Target - an object against which the operation is performed
>>> effectively an LDAP filter
>>> 5) Host - to have different rules for different clients (not
>>> interesting
>>> for now)
>>> 6) Time when the rule is active (we will assume all).
>>
>> I don't agree with this simplification. I'll try to comment in-line.
>>
>> An ACI has 3 parts: the target, the permissions and who are you
>> granting the rights to (the bind rule). They affect more than just
>> users and groups. They affect anything in the system, or everything
>> in the system. They can control any object in the tree: users,
>> groups, hosts, hostgroups, netgroups, services, hbac, sudo, etc. or
>> attributes in any object.
>>
>> There is also the placement of the ACI which controls what it
>> affects. We currently place all ACIs in the basedn of the tree (a
>> necessary simplification for now).
>>
>>> Our goal is to provide and easy to was to specify and manage ACIs vi UI
>>> and CLI.
>>> To accomplish this goal we need to provide a much simple abstraction
>>> that can be reused  for CLI and UI.
>>> But first let us limit the ACI itself and leave only the parts that are
>>> really needed.
>>> We really need Name, User/Group, Right and Target. We will not do
>>> anything about Host and Time.
>>> The right can be limited to:
>>> write, add, delete.
>>> Assume that any authenticated user can read, search and compare. We
>>> should also assume that every user can manage a predefined subset of
>>> the
>>> attributes in his entry. So we actually talking about three rights
>>> here:
>>> add, delete and modify. For the sake of IPA v2 I am willing to go even
>>> further in simplifying ACIs and say that there are three kinds of
>>> rights:
>>> * full control which translates into add an object, delete an object
>>> and
>>> modify any attribute (this is a superuser mode)
>>> * operational control which translates into add an object, delete an
>>> object and modify a predefined subset of the attributes
>>> * tuneup control which translates into add an object, delete an object
>>> and modify a predefined subset of the attributes
>>
>> Read is rather important, particularly for things like userPassword.
>> But yes, most acis will use either add, delete or write.
>>
>> Don't assume that users can manage their own entries. This in itself
>> is an ACI that people will want to control.
>>
>> I know we have to start somewhere with the rights abstractions but I
>> think these controls will be misunderstood and lead to problems.
>>
>>>
>>> Target is the most complex one it consists from the attributes and
>>> filters. This is where an abstraction will be really helpful.
>>> For this I suggest we create an ACI helper object class. The object
>>> class will consist of the following attributes
>>> name - a unique name of the helper like: User - full control, User -
>>> standard management, User - limited access, etc
>>> filter - single value string attribute that denotes a filter that
>>> allows
>>> to identify the object the helper applies to
>>> right - a multi value attribute that specifies rights, in out cases
>>> based on the three operations above it will be either triplet add,
>>> modify, delete or just modify
>>> attributes - a multi value string attribute that stores the set of
>>> attributes the ACI applies to
>>> negation - a boolean flag that specified how to interpret the attribute
>>> list i.e. are those the attributes that the rule applies to or they are
>>> the attributes excluded from the rule.
>>>
>>> here is the example:
>>>
>>> dn: cn=User - full control, cn=ipaconfig, dc=somewhere, dc=com
>>> objectclass: ipaACIHelper
>>> cn: User - full control
>>> filter: ...
>>> attributes: password
>>> nagation: true
>>
>> I can see what you are trying to do but I am really, very strongly
>> against this. We can manage this data internally just as easily. I
>> think this is a recipe for getting the acis out of sync.
>>
>> We actually have most of this implemented today. What it lacks is a
>> way to *output* an aci so it can be easily represented in a UI or on
>> the command line. That is where our focus should be.
>>
>> I'm not sure I agree with the full/object/etc abstractions, I think
>> they would be easily abused/misunderstood because the definitions of
>> these aren't obvious (and don't actually grant what you might expect
>> them to).
>>
>> You also have to understand how the tree is put together and how we
>> use it. For example, to add a user you need 3 acis:
>> - an aci to add a user to the tree
>> - an aci granting permission to write the password
>> - an aci granting permission to add a member to a group
>>
>> Also, the 389-ds team has very strong recommended against using deny
>> ACIs in the past which is why I don't support them in the current
>> plugin.
>>
>>>
>>> This is just an example and we can sort out the right names so do not
>>> pick me if the attribute already exists and we should reuse it. It is
>>> semantics at the moment.
>>>
>>> Any ACI has a name. We need to allow advanced administrators (and
>>> ourselves) to manage raw ACIs. On the other hand we need to allow
>>> managing "simplified" ACIs in CLI and UI.
>>> For this I suggest we use the following linking between the actual ACIs
>>> and helper object:
>>> The ACI name will store a DN of the helper object.
>>>
>>> Let us look at the commands that associate ACIs with a "taskgroup":
>>>
>>> ipa aci-add -aci='User - full control ' taskgroup
>>>
>>> for this command the management plugin will will lookup helper object
>>> and create an ACI based on the data stored in the helper object.
>>>
>>> ipa aci-del -aci='User - full control' taskgroup
>>>
>>> for this command the management plugin will find the aci that has the
>>> name equal to the DN of the specified helper object.
>>>
>>> ipa aci-find -aci='User - full control' taskgroup
>>>
>>> will find the helper object by name, find an ACI by the DN of the
>>> helper
>>> object.
>>>
>>> ipa aci-list  taskgroup
>>
>>>
>>> will list the ACIs for the taskgroup. If the ACI name is a DN of a
>>> helper object the contents of the helper object will be displayed. If
>>> the ACI doe not map to the helper object then it will not be shown.
>>>
>>> This way only the ACIs that are attached to helper objects will be
>>> visible through the UI and CLI and custom CLIs created by IPA at the
>>> installation or CLIs created manually by admins will be accessible
>>> via LDAP.
>>>
>>> The helper object will be preloaded and predefined and thus not
>>> replicated. This means that each new extension to IPA will need to add
>>> its own helper entries. For SUDO for example it will be probably couple
>>> entries. One to do everything and another to modify a subset of the
>>> attributes in the rule.
>>
>> ACIs are ACIs. There is nothing a plugin would add except perhaps a
>> part of the DIT. See the type enum currently in the plugin.
>>
>>> What is good about this approach is that later we can add an interface
>>> to create helper objects. Those are much better structured and would be
>>> easier to manage. For example instead of actually typing filter we can
>>> have a selectable list of the objects like "user", "group", "sudo",
>>> "hbac rule" etc. (The mapping between name and actual filter might be
>>> stored in another kind of the helper object - but we will get there
>>> later). Yes that would mean that the admin would have to create a
>>> helper
>>> object then to create ACI using this object, then combine the task into
>>> role but it is manageable because the complex task is decomposed into
>>> logical parts. I do not suggest that we do it in v2 but I think it is a
>>> way to go in general in future.
>>
>> We actually have these objects implemented in the current plugin. The
>> following aci commands all work today:
>>
>> You can say "This taskgroup can add users":
>>
>> ipa aci-add 'Add Users' --type=user --taskgroup=add_users
>> --permissions=add
>>
>> This creates the aci:
>>
>> (target =
>> "ldap:///uid=*,cn=users,cn=accounts,dc=example,dc=com";)(version
>> 3.0;acl "Add Users";allow (add) groupdn =
>> "ldap:///cn=add_users,cn=taskgroups,cn=accounts,dc=example,dc=com";;)
>>
>> It will even create the taskgroup for you if it doesn't already exist.
>>
>> Right now I just have defined users, groups and hosts but it is
>> trivial to add the others. I couldn't think of a reason the would
>> want this since we supply pre-canned versions of add/delete/modify
>> for those on install, but I can add them as options if desired.
>>
>> We also need to cover v1-style delegation: group A can write
>> attributes of group B.
>>
>> Secretaries can write the mailing address of engineers:
>>
>> ipa aci-add --attrs=streetAddress,postalCode,c,l,st
>> --memberof=engineering --group=secretaries --permissions=write
>> "Secretaries can write engineering addresses"
>>
>> (targetattr = "streetAddress || postalCode || c || l ||
>> st")(targetfilter =
>> "(memberOf=cn=secretaries,cn=groups,cn=accounts,dc=example,dc=com)")(version
>> 3.0;acl "Secretaries can write engineering addresses";allow (write)
>> groupdn =
>> "ldap:///cn=secretaries,cn=groups,cn=accounts,dc=example,dc=com";;)
>>
>> Or even simple things like "I want my engineers to be able to add hosts"
>>
>> ipa aci-add --type=host --permissions=write --group=engineering
>> 'Engineers can add hosts'
>>
>> (target =
>> "ldap:///fqdn=*,cn=computers,cn=accounts,dc=example,dc=com";)(version
>> 3.0;acl "Engineers can add hosts";allow (write) groupdn =
>> "ldap:///cn=engineering,cn=groups,cn=accounts,dc=example,dc=com";;)
>>
>> Ideally these would be mostly done through existing taskgroups instead:
>>
>> ipa taskgroup-add-member --groups=engineering addhosts
>>
>> Or even more preferably via rolegroups:
>>
>> ipa rolegroup-add-member --groups=engineering hostadmin
>>
>> The aci's here are actual output from the plugin. This is where we
>> need the work. I already have an internal abstraction of the acis so
>> I can operate on them. I merely need to display this instead of the
>> aci string and I think we'll be good to go. Some way to manage the
>> attribute list without requiring one to type the whole thing would be
>> nice too.
>>
>>>
>>> Hope this approach does not have much flaws. Yes it will require some
>>> work in the ACI space but I hope it is not a huge rework.
>>>
>>
>> This would represent a tremendous amount of work. I think we would be
>> better served fixing the way that acis are output so the UI (and by
>> extension cli) can better represent the data to users. The --raw
>> option can display the raw aci.
>>
>> Working with acis is always going to be a bit of a nasty business
>> because by definition you have to deal directly with LDAP attribute
>> names, the DIT and how we create and manage objects in the framework.
> Might I suggest looking at the ACI editor in the 389-console - IMHO it
> hides as much as it can - one big problem is the fact that we do not
> have a client side ACI parser.

Actually the whole thing was inspired by the ACI UI from the LDAP book
that is based on Netscape DS.
Rob you say "What it lacks is a way to *output* an aci so it can be
easily represented in a UI or on the command line. That is where our
focus should be." But I do not understand what the problem is. You
either have to display a raw ACI or some abstraction. But how you map
the abstraction that you need to show to the raw ACI you have in the
system? I was trying to solve exactly this problem. And I really do not
see a way to do it differently. Do you?

Thanks
Dmitri



_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel

Reply via email to