On 2.9.2015 07:26, Endi Sukma Dewata wrote:
On 9/1/2015 10:22 AM, Simo Sorce wrote:
On Tue, 2015-09-01 at 17:15 +0200, Petr Vobornik wrote:
On 09/01/2015 04:39 PM, Jan Cholasta wrote:
On 1.9.2015 16:26, Jan Cholasta wrote:
On 26.8.2015 13:22, Petr Vobornik wrote:
On 08/25/2015 08:04 PM, Petr Vobornik wrote:
adds commands:
* vaultcontainer-show [--service <service>|--user <user> ]
* vaultcontainer-add-owner
       [--service <service>|--user <user> ]
       [--users <users>]  [--groups <groups>] [--services
<services>]
* vaultcontainer-remove-owner
       [--service <service>|--user <user> ]
       [--users <users>]  [--groups <groups>] [--services
<services>]

https://fedorahosted.org/freeipa/ticket/5250

Use cases:
1. When user/service is deleted, associated vault container looses
owner. There was no API command to set the owner.
2. Change owner of container by admin to manage access.

Show command was added to show current owners.

Find command was not added, should it be?



There is also a design for vault container ownership handling
created by
Endi - it's for future Vault 2.0.

http://www.freeipa.org/page/V4/Password_Vault_2.0#Adding_container_owner


This patch has a different API than the proposed - different way of
specifying the container. The design page uses path e.g.
/users/foobar.
This patch uses the same way as vaults e.g. --user=foobar. This means
that the implementation in this patch cannot manage ownership of
parent
vault containers e.g. cn=users,cn=vaults,cn=kra,$SUFFIX.

Do we want to go with this approach in 4.2?

Attaching also new path which removes setting of owner which doesn't
exist so that integrity is OK and that it is consistent with
removing of
user.

Updated patch attached - output fix.

We had a long discussion about this with Petr and we think the best
approach is as follows:

    * Add new "Vault administrators" privilege. Vault
administrators will
have unrestricted access to vaults and vault containers, including the
power to add/remove owners of vaults and vault containers.

    * Remove the ability of vault owners to add/remove other vault
owners. If vault owner needs to be changed, vault administrator has to
do it. Note that vault owners will still have the ability to
add/remove
vault members.

    * When adding new vault container, set owner to the current
user. If
vault container owner needs to be changed, vault administrator has
to do
it.

    * Allow adding vaults and vault containers only if the owner is
set
to the current user.

    * Introduce commands to modify vault container owner and to delete
vault container, so the administrator has a choice between assigning
ownership or deleting an unowned container.

Also:

    * Control access to vault data using an ipaProtectedOperation ACI.
Users which have read access to "ipaProtectedOperation;accessKRA" on a
vault can retrieve data from the vault and users which have write
access
to "ipaProtectedOperation;accessKRA" on a vault can archive data in the
vault.

Honza


+1

CCing Simo and Endi to check the proposal.

And Scott (related to #5216, #5215)

Sounds reasonable to me.
I can see that allowing owners to hand over vaults w/o admin
intervention may have some appeal in some use cases, but I also see it
can bring downsides with it, so all in all I think I agree with the
above points.

Simo.


Not a total objection, but if many people in unrelated groups are using
vaults, and they are sharing the vaults only with members of each group,
having to ask a Vault Administrator for each ownership change sounds a
bit cumbersome. Since the Vault Adminstrator will have access to all
vaults in all groups, only a small number of people can be trusted to
hold that role. If there are many ownership changes the Vault
Administrator will have to handle all those requests, and the vault
users may have to wait until the change is completed.

If owners are allowed to add others as owners, the vaults will be pretty
much maintenance free to the admin.

Owners can still manage members, which is IMO good enough for sharing a vault with other users.


Regardless, please update the wiki page to describe the new behavior
when it's implemented:
http://www.freeipa.org/page/V4/Password_Vault_1.1

Sure.

I have updated and rebased Petr's patch 916.

Patch 488 obsoletes Petr's patch 918.

Patch for vault data access control is not included, because I was not able to make GER work correctly with "ipaProtectedOperation;accessKRA".

--
Jan Cholasta
From d9a3cfa7cfcf4402f5d83a61d2a7745a71d8cca3 Mon Sep 17 00:00:00 2001
From: Petr Vobornik <pvobo...@redhat.com>
Date: Tue, 25 Aug 2015 19:56:00 +0200
Subject: [PATCH 1/4] vault: add vault container commands

adds commands:
* vaultcontainer-show [--service <service>|--user <user>|--shared ]
* vaultcontainer-del [--service <service>|--user <user>|--shared ]
* vaultcontainer-add-owner
     [--service <service>|--user <user>|--shared ]
     [--users <users>]  [--groups <groups>] [--services <services>]
* vaultcontainer-remove-owner
     [--service <service>|--user <user>|--shared ]
     [--users <users>]  [--groups <groups>] [--services <services>]

https://fedorahosted.org/freeipa/ticket/5250
---
 API.txt                 |  53 +++++++++++
 VERSION                 |   4 +-
 ipalib/plugins/vault.py | 241 +++++++++++++++++++++++++++++++++++++++++++-----
 3 files changed, 275 insertions(+), 23 deletions(-)

diff --git a/API.txt b/API.txt
index a4c947a..cf54461 100644
--- a/API.txt
+++ b/API.txt
@@ -5667,6 +5667,59 @@ option: Str('version?', exclude='webui')
 output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDAP entry', domain='ipa', localedir=None))
 output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
 output: PrimaryKey('value', None, None)
+command: vaultcontainer_add_owner
+args: 0,10,3
+option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
+option: Str('group*', alwaysask=True, cli_name='groups', csv=True)
+option: Flag('no_members', autofill=True, default=False, exclude='webui')
+option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
+option: Str('service?')
+option: Str('services', alwaysask=True, cli_name='services', csv=True, multivalue=True, required=False)
+option: Flag('shared?', autofill=True, default=False)
+option: Str('user*', alwaysask=True, cli_name='users', csv=True)
+option: Str('username?', cli_name='user')
+option: Str('version?', exclude='webui')
+output: Output('completed', <type 'int'>, None)
+output: Output('failed', <type 'dict'>, None)
+output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDAP entry', domain='ipa', localedir=None))
+command: vaultcontainer_del
+args: 0,5,3
+option: Flag('continue', autofill=True, cli_name='continue', default=False)
+option: Str('service?')
+option: Flag('shared?', autofill=True, default=False)
+option: Str('username?', cli_name='user')
+option: Str('version?', exclude='webui')
+output: Output('result', <type 'dict'>, None)
+output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
+output: ListOfPrimaryKeys('value', None, None)
+command: vaultcontainer_remove_owner
+args: 0,10,3
+option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
+option: Str('group*', alwaysask=True, cli_name='groups', csv=True)
+option: Flag('no_members', autofill=True, default=False, exclude='webui')
+option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
+option: Str('service?')
+option: Str('services', alwaysask=True, cli_name='services', csv=True, multivalue=True, required=False)
+option: Flag('shared?', autofill=True, default=False)
+option: Str('user*', alwaysask=True, cli_name='users', csv=True)
+option: Str('username?', cli_name='user')
+option: Str('version?', exclude='webui')
+output: Output('completed', <type 'int'>, None)
+output: Output('failed', <type 'dict'>, None)
+output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDAP entry', domain='ipa', localedir=None))
+command: vaultcontainer_show
+args: 0,8,3
+option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
+option: Flag('no_members', autofill=True, default=False, exclude='webui')
+option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
+option: Flag('rights', autofill=True, default=False)
+option: Str('service?')
+option: Flag('shared?', autofill=True, default=False)
+option: Str('username?', cli_name='user')
+option: Str('version?', exclude='webui')
+output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDAP entry', domain='ipa', localedir=None))
+output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
+output: PrimaryKey('value', None, None)
 capability: messages 2.52
 capability: optional_uid_params 2.54
 capability: permissions2 2.69
diff --git a/VERSION b/VERSION
index 0a2de6e..a14b89f 100644
--- a/VERSION
+++ b/VERSION
@@ -90,5 +90,5 @@ IPA_DATA_VERSION=20100614120000
 #                                                      #
 ########################################################
 IPA_API_VERSION_MAJOR=2
-IPA_API_VERSION_MINOR=155
-# Last change: ftweedal - remove certprofile 'rename' option
+IPA_API_VERSION_MINOR=156
+# Last change: pvoborni - add vault container commands
diff --git a/ipalib/plugins/vault.py b/ipalib/plugins/vault.py
index a933198..97f8aa0 100644
--- a/ipalib/plugins/vault.py
+++ b/ipalib/plugins/vault.py
@@ -258,6 +258,226 @@ vault_options = (
 )
 
 
+class VaultModMember(LDAPModMember):
+    def get_options(self):
+        for param in super(VaultModMember, self).get_options():
+            if param.name == 'service' and param not in vault_options:
+                param = param.clone_rename('services')
+            yield param
+
+    def get_member_dns(self, **options):
+        if 'services' in options:
+            options['service'] = options.pop('services')
+        else:
+            options.pop('service', None)
+        return super(VaultModMember, self).get_member_dns(**options)
+
+    def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
+        for fail in failed.itervalues():
+            fail['services'] = fail.pop('service', [])
+        self.obj.get_container_attribute(entry_attrs, options)
+        return completed, dn
+
+
+@register()
+class vaultcontainer(LDAPObject):
+    __doc__ = _("""
+    Vault Container object.
+    """)
+
+    container_dn = api.env.container_vault
+
+    object_name = _('vaultcontainer')
+    object_name_plural = _('vaultcontainers')
+    object_class = ['ipaVaultContainer']
+
+    attribute_members = {
+        'owner': ['user', 'group', 'service'],
+    }
+
+    label = _('Vault Containers')
+    label_singular = _('Vault Container')
+
+    takes_params = (
+        Str(
+            'owner_user?',
+            label=_('Owner users'),
+        ),
+        Str(
+            'owner_group?',
+            label=_('Owner groups'),
+        ),
+        Str(
+            'owner_service?',
+            label=_('Owner services'),
+        ),
+        Str(
+            'owner?',
+            label=_('Failed owners'),
+        ),
+        Str(
+            'service?',
+            label=_('Vault service'),
+            flags={'virtual_attribute'},
+        ),
+        Flag(
+            'shared?',
+            label=_('Shared vault'),
+            flags={'virtual_attribute'},
+        ),
+        Str(
+            'username?',
+            label=_('Vault user'),
+            flags={'virtual_attribute'},
+        ),
+    )
+
+    def get_dn(self, *keys, **options):
+        """
+        Generates vault DN from parameters.
+        """
+        service = options.get('service')
+        shared = options.get('shared')
+        user = options.get('username')
+
+        count = (bool(service) + bool(shared) + bool(user))
+        if count > 1:
+            raise errors.MutuallyExclusiveError(
+                reason=_('Service, shared and user options ' +
+                         'cannot be specified simultaneously'))
+
+        parent_dn = super(vaultcontainer, self).get_dn(*keys, **options)
+
+        if not count:
+            principal = getattr(context, 'principal')
+
+            if principal.startswith('host/'):
+                raise errors.NotImplementedError(
+                    reason=_('Host is not supported'))
+
+            (name, realm) = split_principal(principal)
+            if '/' in name:
+                service = name
+            else:
+                user = name
+
+        if service:
+            dn = DN(('cn', service), ('cn', 'services'), parent_dn)
+        elif shared:
+            dn = DN(('cn', 'shared'), parent_dn)
+        elif user:
+            dn = DN(('cn', user), ('cn', 'users'), parent_dn)
+        else:
+            raise RuntimeError
+
+        return dn
+
+    def get_container_attribute(self, entry, options):
+        if options.get('raw', False):
+            return
+        container_dn = DN(self.container_dn, self.api.env.basedn)
+        if entry.dn.endswith(DN(('cn', 'services'), container_dn)):
+            entry['service'] = entry.dn[0]['cn']
+        elif entry.dn.endswith(DN(('cn', 'shared'), container_dn)):
+            entry['shared'] = True
+        elif entry.dn.endswith(DN(('cn', 'users'), container_dn)):
+            entry['username'] = entry.dn[0]['cn']
+
+
+@register()
+class vaultcontainer_show(LDAPRetrieve):
+    __doc__ = _('Display information about a vault.')
+
+    takes_options = LDAPRetrieve.takes_options + vault_options
+
+    has_output_params = LDAPRetrieve.has_output_params
+
+    def pre_callback(self, ldap, dn, attrs_list, *keys, **options):
+        assert isinstance(dn, DN)
+
+        if not self.api.Command.kra_is_enabled()['result']:
+            raise errors.InvocationError(
+                format=_('KRA service is not enabled'))
+
+        return dn
+
+    def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
+        self.obj.get_container_attribute(entry_attrs, options)
+        return dn
+
+
+@register()
+class vaultcontainer_del(LDAPDelete):
+    __doc__ = _('Delete a vault container.')
+
+    takes_options = LDAPDelete.takes_options + vault_options
+
+    msg_summary = _('Deleted vault container "%(value)s"')
+
+    def pre_callback(self, ldap, dn, *keys, **options):
+        assert isinstance(dn, DN)
+
+        if not self.api.Command.kra_is_enabled()['result']:
+            raise errors.InvocationError(
+                format=_('KRA service is not enabled'))
+
+        return dn
+
+    def execute(self, *keys, **options):
+        keys = keys + (u'',)
+        return super(vaultcontainer_del, self).execute(*keys, **options)
+
+
+@register()
+class vaultcontainer_add_owner(VaultModMember, LDAPAddMember):
+    __doc__ = _('Add owners to a vault container.')
+
+    takes_options = LDAPAddMember.takes_options + vault_options
+
+    member_attributes = ['owner']
+    member_param_label = _('owner %s')
+    member_count_out = ('%i owner added.', '%i owners added.')
+
+    has_output = (
+        output.Entry('result'),
+        output.Output(
+            'failed',
+            type=dict,
+            doc=_('Owners that could not be added'),
+        ),
+        output.Output(
+            'completed',
+            type=int,
+            doc=_('Number of owners added'),
+        ),
+    )
+
+
+@register()
+class vaultcontainer_remove_owner(VaultModMember, LDAPRemoveMember):
+    __doc__ = _('Remove owners from a vault container.')
+
+    takes_options = LDAPRemoveMember.takes_options + vault_options
+
+    member_attributes = ['owner']
+    member_param_label = _('owner %s')
+    member_count_out = ('%i owner removed.', '%i owners removed.')
+
+    has_output = (
+        output.Entry('result'),
+        output.Output(
+            'failed',
+            type=dict,
+            doc=_('Owners that could not be removed'),
+        ),
+        output.Output(
+            'completed',
+            type=int,
+            doc=_('Number of owners removed'),
+        ),
+    )
+
+
 @register()
 class vault(LDAPObject):
     __doc__ = _("""
@@ -1730,27 +1950,6 @@ class vault_retrieve_internal(PKQuery):
         return response
 
 
-class VaultModMember(LDAPModMember):
-    def get_options(self):
-        for param in super(VaultModMember, self).get_options():
-            if param.name == 'service' and param not in vault_options:
-                param = param.clone_rename('services')
-            yield param
-
-    def get_member_dns(self, **options):
-        if 'services' in options:
-            options['service'] = options.pop('services')
-        else:
-            options.pop('service', None)
-        return super(VaultModMember, self).get_member_dns(**options)
-
-    def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
-        for fail in failed.itervalues():
-            fail['services'] = fail.pop('service', [])
-        self.obj.get_container_attribute(entry_attrs, options)
-        return completed, dn
-
-
 @register()
 class vault_add_owner(VaultModMember, LDAPAddMember):
     __doc__ = _('Add owners to a vault.')
-- 
2.4.3

From 8b35ec98ac017ccec821d42b725f68bbafb1ca7f Mon Sep 17 00:00:00 2001
From: Jan Cholasta <jchol...@redhat.com>
Date: Thu, 3 Sep 2015 08:46:59 +0200
Subject: [PATCH 2/4] vault: set owner to current user on container creation

This reverts commit 419754b1c11139435ae5b5082a51026da0d5e730.

https://fedorahosted.org/freeipa/ticket/5250
---
 ipalib/plugins/vault.py | 21 +--------------------
 1 file changed, 1 insertion(+), 20 deletions(-)

diff --git a/ipalib/plugins/vault.py b/ipalib/plugins/vault.py
index 97f8aa0..dddd73c 100644
--- a/ipalib/plugins/vault.py
+++ b/ipalib/plugins/vault.py
@@ -980,27 +980,8 @@ class vault_add_internal(LDAPCreate):
 
         parent_dn = DN(*dn[1:])
 
-        container_dn = DN(self.api.Object.vault.container_dn,
-                          self.api.env.basedn)
-
-        services_dn = DN(('cn', 'services'), container_dn)
-        users_dn = DN(('cn', 'users'), container_dn)
-
-        if dn.endswith(services_dn):
-            # service container should be owned by the service
-            service = parent_dn[0]['cn']
-            parent_owner_dn = self.api.Object.service.get_dn(service)
-
-        elif dn.endswith(users_dn):
-            # user container should be owned by the user
-            user = parent_dn[0]['cn']
-            parent_owner_dn = self.api.Object.user.get_dn(user)
-
-        else:
-            parent_owner_dn = owner_dn
-
         try:
-            self.obj.create_container(parent_dn, parent_owner_dn)
+            self.obj.create_container(parent_dn, owner_dn)
         except errors.DuplicateEntry as e:
             pass
 
-- 
2.4.3

From 156c983d863cac2dd7b4df3b7319855f75b47f67 Mon Sep 17 00:00:00 2001
From: Jan Cholasta <jchol...@redhat.com>
Date: Thu, 3 Sep 2015 09:02:41 +0200
Subject: [PATCH 3/4] vault: update access control

Do not allow vault and container owners to manage owners. Allow adding vaults
and containers only if owner is set to the current user.

https://fedorahosted.org/freeipa/ticket/5250
---
 install/share/vault.update | 22 ++++++++++++++--------
 1 file changed, 14 insertions(+), 8 deletions(-)

diff --git a/install/share/vault.update b/install/share/vault.update
index 14421b5..4f00238 100644
--- a/install/share/vault.update
+++ b/install/share/vault.update
@@ -7,14 +7,20 @@ dn: cn=vaults,cn=kra,$SUFFIX
 default: objectClass: top
 default: objectClass: ipaVaultContainer
 default: cn: vaults
-default: aci: (target="ldap:///cn=*,cn=users,cn=vaults,cn=kra,$SUFFIX";)(version 3.0; acl "Allow users to create private container"; allow (add) userdn = "ldap:///uid=($$attr.cn),cn=users,cn=accounts,$SUFFIX";)
-default: aci: (target="ldap:///cn=*,cn=services,cn=vaults,cn=kra,$SUFFIX";)(version 3.0; acl "Allow services to create private container"; allow (add) userdn = "ldap:///krbprincipalname=($$attr.cn)@$REALM,cn=services,cn=accounts,$SUFFIX";)
-default: aci: (targetfilter="(objectClass=ipaVault)")(targetattr="*")(version 3.0; acl "Container owners can manage vaults in the container"; allow(read, search, compare, add, delete) userattr="parent[1].owner#USERDN";)
-default: aci: (targetfilter="(objectClass=ipaVault)")(targetattr="*")(version 3.0; acl "Indirect container owners can manage vaults in the container"; allow(read, search, compare, add, delete) userattr="parent[1].owner#GROUPDN";)
-default: aci: (targetfilter="(objectClass=ipaVault)")(targetattr="*")(version 3.0; acl "Vault members can access the vault"; allow(read, search, compare) userattr="member#USERDN";)
-default: aci: (targetfilter="(objectClass=ipaVault)")(targetattr="*")(version 3.0; acl "Indirect vault members can access the vault"; allow(read, search, compare) userattr="member#GROUPDN";)
-default: aci: (targetfilter="(objectClass=ipaVault)")(targetattr="*")(version 3.0; acl "Vault owners can manage the vault"; allow(read, search, compare, write) userattr="owner#USERDN";)
-default: aci: (targetfilter="(objectClass=ipaVault)")(targetattr="*")(version 3.0; acl "Indirect vault owners can manage the vault"; allow(read, search, compare, write) userattr="owner#GROUPDN";)
+default: aci: (target="ldap:///cn=*,cn=users,cn=vaults,cn=kra,$SUFFIX";)(targetfilter="(objectClass=ipaVaultContainer)")(version 3.0; acl "Allow users to create private container"; allow(add) userdn="ldap:///uid=($$attr.cn),cn=users,cn=accounts,$SUFFIX" and userattr="owner#SELFDN";)
+default: aci: (target="ldap:///cn=*,cn=services,cn=vaults,cn=kra,$SUFFIX";)(targetfilter="(objectClass=ipaVaultContainer)")(version 3.0; acl "Allow services to create private container"; allow(add) userdn="ldap:///krbprincipalname=($$attr.cn)@$REALM,cn=services,cn=accounts,$SUFFIX" and userattr="owner#SELFDN";)
+default: aci: (targetfilter="(objectClass=ipaVaultContainer)")(targetattr="objectClass || cn || description || owner")(version 3.0; acl "Container owners can access the container"; allow(read, search, compare) userattr="owner#USERDN";)
+default: aci: (targetfilter="(objectClass=ipaVaultContainer)")(targetattr="objectClass || cn || description || owner")(version 3.0; acl "Indirect container owners can access the container"; allow(read, search, compare) userattr="owner#GROUPDN";)
+default: aci: (targetfilter="(objectClass=ipaVaultContainer)")(targetattr="objectClass || cn || description")(version 3.0; acl "Container owners can manage the container"; allow(write, delete) userattr="owner#USERDN";)
+default: aci: (targetfilter="(objectClass=ipaVaultContainer)")(targetattr="objectClass || cn || description")(version 3.0; acl "Indirect container owners can manage the container"; allow(write, delete) userattr="owner#GROUPDN";)
+default: aci: (targetfilter="(objectClass=ipaVault)")(version 3.0; acl "Container owners can add vaults in the container"; allow(add) userattr="parent[1].owner#USERDN" and userattr="owner#SELFDN";)
+default: aci: (targetfilter="(objectClass=ipaVault)")(version 3.0; acl "Indirect container owners can add vaults in the container"; allow(add) userattr="parent[1].owner#GROUPDN" and userattr="owner#SELFDN";)
+default: aci: (targetfilter="(objectClass=ipaVault)")(targetattr="objectClass || cn || description || ipaVaultType || ipaVaultSalt || ipaVaultPublicKey || owner || member")(version 3.0; acl "Vault owners can access the vault"; allow(read, search, compare) userattr="owner#USERDN";)
+default: aci: (targetfilter="(objectClass=ipaVault)")(targetattr="objectClass || cn || description || ipaVaultType || ipaVaultSalt || ipaVaultPublicKey || owner || member")(version 3.0; acl "Indirect vault owners can access the vault"; allow(read, search, compare) userattr="owner#GROUPDN";)
+default: aci: (targetfilter="(objectClass=ipaVault)")(targetattr="objectClass || cn || description || ipaVaultType || ipaVaultSalt || ipaVaultPublicKey || owner || member")(version 3.0; acl "Vault members can access the vault"; allow(read, search, compare) userattr="member#USERDN";)
+default: aci: (targetfilter="(objectClass=ipaVault)")(targetattr="objectClass || cn || description || ipaVaultType || ipaVaultSalt || ipaVaultPublicKey || owner || member")(version 3.0; acl "Indirect vault members can access the vault"; allow(read, search, compare) userattr="member#GROUPDN";)
+default: aci: (targetfilter="(objectClass=ipaVault)")(targetattr="objectClass || cn || description || ipaVaultType || ipaVaultSalt || ipaVaultPublicKey || member")(version 3.0; acl "Vault owners can manage the vault"; allow(write, delete) userattr="owner#USERDN";)
+default: aci: (targetfilter="(objectClass=ipaVault)")(targetattr="objectClass || cn || description || ipaVaultType || ipaVaultSalt || ipaVaultPublicKey || member")(version 3.0; acl "Indirect vault owners can manage the vault"; allow(write, delete) userattr="owner#GROUPDN";)
 
 dn: cn=services,cn=vaults,cn=kra,$SUFFIX
 default: objectClass: top
-- 
2.4.3

From 7a022ecb06680a4dd545c6ebe246408a505d761d Mon Sep 17 00:00:00 2001
From: Jan Cholasta <jchol...@redhat.com>
Date: Thu, 3 Sep 2015 09:32:11 +0200
Subject: [PATCH 4/4] vault: add permissions and administrator privilege

https://fedorahosted.org/freeipa/ticket/5250
---
 ACI.txt                              | 22 ++++++++
 install/updates/40-delegation.update |  8 +++
 ipalib/plugins/vault.py              | 98 ++++++++++++++++++++++++++++++++++++
 3 files changed, 128 insertions(+)

diff --git a/ACI.txt b/ACI.txt
index 9909927..40fa822 100644
--- a/ACI.txt
+++ b/ACI.txt
@@ -338,6 +338,28 @@ dn: cn=users,cn=accounts,dc=ipa,dc=example
 aci: (targetfilter = "(objectclass=posixaccount)")(version 3.0;acl "permission:System: Remove Users";allow (delete) groupdn = "ldap:///cn=System: Remove Users,cn=permissions,cn=pbac,dc=ipa,dc=example";)
 dn: cn=users,cn=accounts,dc=ipa,dc=example
 aci: (targetattr = "krblastadminunlock || krbloginfailedcount || nsaccountlock")(targetfilter = "(objectclass=posixaccount)")(version 3.0;acl "permission:System: Unlock User";allow (write) groupdn = "ldap:///cn=System: Unlock User,cn=permissions,cn=pbac,dc=ipa,dc=example";)
+dn: dc=ipa,dc=example
+aci: (target = "ldap:///cn=vaults,cn=kra,dc=ipa,dc=example";)(targetfilter = "(objectclass=ipaVault)")(version 3.0;acl "permission:System: Add Vaults";allow (add) groupdn = "ldap:///cn=System: Add Vaults,cn=permissions,cn=pbac,dc=ipa,dc=example";)
+dn: dc=ipa,dc=example
+aci: (target = "ldap:///cn=vaults,cn=kra,dc=ipa,dc=example";)(targetfilter = "(objectclass=ipaVault)")(version 3.0;acl "permission:System: Delete Vaults";allow (delete) groupdn = "ldap:///cn=System: Delete Vaults,cn=permissions,cn=pbac,dc=ipa,dc=example";)
+dn: dc=ipa,dc=example
+aci: (targetattr = "member")(target = "ldap:///cn=vaults,cn=kra,dc=ipa,dc=example";)(targetfilter = "(objectclass=ipaVault)")(version 3.0;acl "permission:System: Manage Vault Membership";allow (write) groupdn = "ldap:///cn=System: Manage Vault Membership,cn=permissions,cn=pbac,dc=ipa,dc=example";)
+dn: dc=ipa,dc=example
+aci: (targetattr = "owner")(target = "ldap:///cn=vaults,cn=kra,dc=ipa,dc=example";)(targetfilter = "(objectclass=ipaVault)")(version 3.0;acl "permission:System: Manage Vault Ownership";allow (write) groupdn = "ldap:///cn=System: Manage Vault Ownership,cn=permissions,cn=pbac,dc=ipa,dc=example";)
+dn: dc=ipa,dc=example
+aci: (targetattr = "cn || description || ipavaultpublickey || ipavaultsalt || ipavaulttype || objectclass")(target = "ldap:///cn=vaults,cn=kra,dc=ipa,dc=example";)(targetfilter = "(objectclass=ipaVault)")(version 3.0;acl "permission:System: Modify Vaults";allow (write) groupdn = "ldap:///cn=System: Modify Vaults,cn=permissions,cn=pbac,dc=ipa,dc=example";)
+dn: dc=ipa,dc=example
+aci: (targetattr = "cn || createtimestamp || description || entryusn || ipavaultpublickey || ipavaultsalt || ipavaulttype || member || memberhost || memberuser || modifytimestamp || objectclass || owner")(target = "ldap:///cn=vaults,cn=kra,dc=ipa,dc=example";)(targetfilter = "(objectclass=ipaVault)")(version 3.0;acl "permission:System: Read Vaults";allow (compare,read,search) groupdn = "ldap:///cn=System: Read Vaults,cn=permissions,cn=pbac,dc=ipa,dc=example";)
+dn: dc=ipa,dc=example
+aci: (target = "ldap:///cn=vaults,cn=kra,dc=ipa,dc=example";)(targetfilter = "(objectclass=ipaVaultContainer)")(version 3.0;acl "permission:System: Add Vault Containers";allow (add) groupdn = "ldap:///cn=System: Add Vault Containers,cn=permissions,cn=pbac,dc=ipa,dc=example";)
+dn: dc=ipa,dc=example
+aci: (target = "ldap:///cn=vaults,cn=kra,dc=ipa,dc=example";)(targetfilter = "(objectclass=ipaVaultContainer)")(version 3.0;acl "permission:System: Delete Vault Containers";allow (delete) groupdn = "ldap:///cn=System: Delete Vault Containers,cn=permissions,cn=pbac,dc=ipa,dc=example";)
+dn: dc=ipa,dc=example
+aci: (targetattr = "owner")(target = "ldap:///cn=vaults,cn=kra,dc=ipa,dc=example";)(targetfilter = "(objectclass=ipaVaultContainer)")(version 3.0;acl "permission:System: Manage Vault Container Ownership";allow (write) groupdn = "ldap:///cn=System: Manage Vault Container Ownership,cn=permissions,cn=pbac,dc=ipa,dc=example";)
+dn: dc=ipa,dc=example
+aci: (targetattr = "cn || description || objectclass")(target = "ldap:///cn=vaults,cn=kra,dc=ipa,dc=example";)(targetfilter = "(objectclass=ipaVaultContainer)")(version 3.0;acl "permission:System: Modify Vault Containers";allow (write) groupdn = "ldap:///cn=System: Modify Vault Containers,cn=permissions,cn=pbac,dc=ipa,dc=example";)
+dn: dc=ipa,dc=example
+aci: (targetattr = "cn || createtimestamp || description || entryusn || modifytimestamp || objectclass || owner")(target = "ldap:///cn=vaults,cn=kra,dc=ipa,dc=example";)(targetfilter = "(objectclass=ipaVaultContainer)")(version 3.0;acl "permission:System: Read Vault Containers";allow (compare,read,search) groupdn = "ldap:///cn=System: Read Vault Containers,cn=permissions,cn=pbac,dc=ipa,dc=example";)
 dn: cn=ca_renewal,cn=ipa,cn=etc,dc=ipa,dc=example
 aci: (target = "ldap:///cn=caSigningCert cert-pki-ca,cn=ca_renewal,cn=ipa,cn=etc,dc=ipa,dc=example")(targetfilter = "(objectclass=pkiuser)")(version 3.0;acl "permission:System: Add CA Certificate For Renewal";allow (add) groupdn = "ldap:///cn=System: Add CA Certificate For Renewal,cn=permissions,cn=pbac,dc=ipa,dc=example";)
 dn: cn=certificates,cn=ipa,cn=etc,dc=ipa,dc=example
diff --git a/install/updates/40-delegation.update b/install/updates/40-delegation.update
index 8d4f629..08906a6 100644
--- a/install/updates/40-delegation.update
+++ b/install/updates/40-delegation.update
@@ -260,3 +260,11 @@ default:objectClass: groupofnames
 default:objectClass: top
 default:cn: CA Administrator
 default:description: CA Administrator
+
+# Vault Administrators
+dn: cn=Vault Administrators,cn=privileges,cn=pbac,$SUFFIX
+default:objectClass: nestedgroup
+default:objectClass: groupofnames
+default:objectClass: top
+default:cn: Vault Administrators
+default:description: Vault Administrators
diff --git a/ipalib/plugins/vault.py b/ipalib/plugins/vault.py
index dddd73c..6bdee24 100644
--- a/ipalib/plugins/vault.py
+++ b/ipalib/plugins/vault.py
@@ -290,6 +290,7 @@ class vaultcontainer(LDAPObject):
     object_name = _('vaultcontainer')
     object_name_plural = _('vaultcontainers')
     object_class = ['ipaVaultContainer']
+    permission_filter_objectclasses = ['ipaVaultContainer']
 
     attribute_members = {
         'owner': ['user', 'group', 'service'],
@@ -298,6 +299,48 @@ class vaultcontainer(LDAPObject):
     label = _('Vault Containers')
     label_singular = _('Vault Container')
 
+    managed_permissions = {
+        'System: Read Vault Containers': {
+            'ipapermlocation': api.env.basedn,
+            'ipapermtarget': DN(api.env.container_vault, api.env.basedn),
+            'ipapermright': {'read', 'search', 'compare'},
+            'ipapermdefaultattr': {
+                'objectclass', 'cn', 'description', 'owner',
+            },
+            'default_privileges': {'Vault Administrators'},
+        },
+        'System: Add Vault Containers': {
+            'ipapermlocation': api.env.basedn,
+            'ipapermtarget': DN(api.env.container_vault, api.env.basedn),
+            'ipapermright': {'add'},
+            'default_privileges': {'Vault Administrators'},
+        },
+        'System: Delete Vault Containers': {
+            'ipapermlocation': api.env.basedn,
+            'ipapermtarget': DN(api.env.container_vault, api.env.basedn),
+            'ipapermright': {'delete'},
+            'default_privileges': {'Vault Administrators'},
+        },
+        'System: Modify Vault Containers': {
+            'ipapermlocation': api.env.basedn,
+            'ipapermtarget': DN(api.env.container_vault, api.env.basedn),
+            'ipapermright': {'write'},
+            'ipapermdefaultattr': {
+                'objectclass', 'cn', 'description',
+            },
+            'default_privileges': {'Vault Administrators'},
+        },
+        'System: Manage Vault Container Ownership': {
+            'ipapermlocation': api.env.basedn,
+            'ipapermtarget': DN(api.env.container_vault, api.env.basedn),
+            'ipapermright': {'write'},
+            'ipapermdefaultattr': {
+                'owner',
+            },
+            'default_privileges': {'Vault Administrators'},
+        },
+    }
+
     takes_params = (
         Str(
             'owner_user?',
@@ -490,6 +533,7 @@ class vault(LDAPObject):
     object_name_plural = _('vaults')
 
     object_class = ['ipaVault']
+    permission_filter_objectclasses = ['ipaVault']
     default_attributes = [
         'cn',
         'description',
@@ -512,6 +556,60 @@ class vault(LDAPObject):
     label = _('Vaults')
     label_singular = _('Vault')
 
+    managed_permissions = {
+        'System: Read Vaults': {
+            'ipapermlocation': api.env.basedn,
+            'ipapermtarget': DN(api.env.container_vault, api.env.basedn),
+            'ipapermright': {'read', 'search', 'compare'},
+            'ipapermdefaultattr': {
+                'objectclass', 'cn', 'description', 'ipavaulttype',
+                'ipavaultsalt', 'ipavaultpublickey', 'owner', 'member',
+                'memberuser', 'memberhost',
+            },
+            'default_privileges': {'Vault Administrators'},
+        },
+        'System: Add Vaults': {
+            'ipapermlocation': api.env.basedn,
+            'ipapermtarget': DN(api.env.container_vault, api.env.basedn),
+            'ipapermright': {'add'},
+            'default_privileges': {'Vault Administrators'},
+        },
+        'System: Delete Vaults': {
+            'ipapermlocation': api.env.basedn,
+            'ipapermtarget': DN(api.env.container_vault, api.env.basedn),
+            'ipapermright': {'delete'},
+            'default_privileges': {'Vault Administrators'},
+        },
+        'System: Modify Vaults': {
+            'ipapermlocation': api.env.basedn,
+            'ipapermtarget': DN(api.env.container_vault, api.env.basedn),
+            'ipapermright': {'write'},
+            'ipapermdefaultattr': {
+                'objectclass', 'cn', 'description', 'ipavaulttype',
+                'ipavaultsalt', 'ipavaultpublickey',
+            },
+            'default_privileges': {'Vault Administrators'},
+        },
+        'System: Manage Vault Ownership': {
+            'ipapermlocation': api.env.basedn,
+            'ipapermtarget': DN(api.env.container_vault, api.env.basedn),
+            'ipapermright': {'write'},
+            'ipapermdefaultattr': {
+                'owner',
+            },
+            'default_privileges': {'Vault Administrators'},
+        },
+        'System: Manage Vault Membership': {
+            'ipapermlocation': api.env.basedn,
+            'ipapermtarget': DN(api.env.container_vault, api.env.basedn),
+            'ipapermright': {'write'},
+            'ipapermdefaultattr': {
+                'member',
+            },
+            'default_privileges': {'Vault Administrators'},
+        },
+    }
+
     takes_params = (
         Str(
             'cn',
-- 
2.4.3

-- 
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code

Reply via email to