summaryrefslogtreecommitdiffstats
path: root/ipaserver/plugins/caacl.py
diff options
context:
space:
mode:
authorFraser Tweedale <ftweedal@redhat.com>2016-05-06 10:36:22 +1000
committerJan Cholasta <jcholast@redhat.com>2016-06-15 07:13:38 +0200
commit9c93015e7877c27a573a5090f7c1c36130bb017b (patch)
tree8979dbb74a03c8972d6bd1241a06074e504c0203 /ipaserver/plugins/caacl.py
parent7d8699580d44fc65ca50982107d7037f2a64aa60 (diff)
downloadfreeipa-9c93015e7877c27a573a5090f7c1c36130bb017b.tar.gz
freeipa-9c93015e7877c27a573a5090f7c1c36130bb017b.tar.xz
freeipa-9c93015e7877c27a573a5090f7c1c36130bb017b.zip
Update 'caacl' plugin to support lightweight CAs
For backwards compatibility, an ACL that has no CAs and no CA category allows access to the IPA CA (host authority) only. Part of: https://fedorahosted.org/freeipa/ticket/4559 Reviewed-By: Jan Cholasta <jcholast@redhat.com> Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
Diffstat (limited to 'ipaserver/plugins/caacl.py')
-rw-r--r--ipaserver/plugins/caacl.py100
1 files changed, 66 insertions, 34 deletions
diff --git a/ipaserver/plugins/caacl.py b/ipaserver/plugins/caacl.py
index 60eeb5a33..a543a1de7 100644
--- a/ipaserver/plugins/caacl.py
+++ b/ipaserver/plugins/caacl.py
@@ -6,6 +6,7 @@ import pyhbac
from ipalib import api, errors, output
from ipalib import Bool, Str, StrEnum
+from ipalib.constants import IPA_CA_CN
from ipalib.plugable import Registry
from .baseldap import (
LDAPObject, LDAPSearch, LDAPCreate, LDAPDelete, LDAPQuery,
@@ -32,14 +33,16 @@ and followed by a sequence of letters, digits or underscore ("_").
EXAMPLES:
Create a CA ACL "test" that grants all users access to the
- "UserCert" profile:
- ipa caacl-add test --usercat=all
+ "UserCert" profile on all CAs:
+ ipa caacl-add test --usercat=all --cacat=all
ipa caacl-add-profile test --certprofiles UserCert
Display the properties of a named CA ACL:
ipa caacl-show test
- Create a CA ACL to let user "alice" use the "DNP3" profile:
+ Create a CA ACL to let user "alice" use the "DNP3" profile on "DNP3-CA":
+ ipa caacl-add alice_dnp3
+ ipa caacl-add-ca alice_dnp3 --cas DNP3-CA
ipa caacl-add-profile alice_dnp3 --certprofiles DNP3
ipa caacl-add-user alice_dnp3 --user=alice
@@ -53,12 +56,12 @@ EXAMPLES:
register = Registry()
-def _acl_make_request(principal_type, principal, ca_ref, profile_id):
+def _acl_make_request(principal_type, principal, ca_id, profile_id):
"""Construct HBAC request for the given principal, CA and profile"""
service, name, realm = split_any_principal(principal)
req = pyhbac.HbacRequest()
- req.targethost.name = ca_ref
+ req.targethost.name = ca_id
req.service.name = profile_id
if principal_type == 'user':
req.user.name = name
@@ -90,12 +93,12 @@ def _acl_make_rule(principal_type, obj):
rule.srchosts.category = {pyhbac.HBAC_CATEGORY_ALL}
# add CA(s)
- # Hardcoded until caacl plugin arrives
- rule.targethosts.category = {pyhbac.HBAC_CATEGORY_ALL}
- #if 'ipacacategory' in obj and obj['ipacacategory'][0].lower() == 'all':
- # rule.targethosts.category = {pyhbac.HBAC_CATEGORY_ALL}
- #else:
- # rule.targethosts.names = obj.get('ipacaaclcaref', [])
+ if 'ipacacategory' in obj and obj['ipacacategory'][0].lower() == 'all':
+ rule.targethosts.category = {pyhbac.HBAC_CATEGORY_ALL}
+ else:
+ # For compatibility with pre-lightweight-CAs CA ACLs,
+ # no CA members implies the host authority (only)
+ rule.targethosts.names = obj.get('ipamemberca_ca', [IPA_CA_CN])
# add profiles
if ('ipacertprofilecategory' in obj
@@ -120,8 +123,8 @@ def _acl_make_rule(principal_type, obj):
return rule
-def acl_evaluate(principal_type, principal, ca_ref, profile_id):
- req = _acl_make_request(principal_type, principal, ca_ref, profile_id)
+def acl_evaluate(principal_type, principal, ca_id, profile_id):
+ req = _acl_make_request(principal_type, principal, ca_id, profile_id)
acls = api.Command.caacl_find(no_members=False)['result']
rules = [_acl_make_rule(principal_type, obj) for obj in acls]
return req.evaluate(rules) == pyhbac.HBAC_EVAL_ALLOW
@@ -151,6 +154,7 @@ class caacl(LDAPObject):
'memberuser': ['user', 'group'],
'memberhost': ['host', 'hostgroup'],
'memberservice': ['service'],
+ 'ipamemberca': ['ca'],
'ipamembercertprofile': ['certprofile'],
}
managed_permissions = {
@@ -226,13 +230,12 @@ class caacl(LDAPObject):
label=_('Enabled'),
flags=['no_option'],
),
- # Commented until subca plugin arrives
- #StrEnum('ipacacategory?',
- # cli_name='cacat',
- # label=_('CA category'),
- # doc=_('CA category the ACL applies to'),
- # values=(u'all', ),
- #),
+ StrEnum('ipacacategory?',
+ cli_name='cacat',
+ label=_('CA category'),
+ doc=_('CA category the ACL applies to'),
+ values=(u'all', ),
+ ),
StrEnum('ipacertprofilecategory?',
cli_name='profilecat',
label=_('Profile category'),
@@ -257,11 +260,10 @@ class caacl(LDAPObject):
doc=_('Service category the ACL applies to'),
values=(u'all', ),
),
- # Commented until subca plugin arrives
- #Str('ipamemberca_subca?',
- # label=_('CAs'),
- # flags=['no_create', 'no_update', 'no_search'],
- #),
+ Str('ipamemberca_ca?',
+ label=_('CAs'),
+ flags=['no_create', 'no_update', 'no_search'],
+ ),
Str('ipamembercertprofile_certprofile?',
label=_('Profiles'),
flags=['no_create', 'no_update', 'no_search'],
@@ -330,11 +332,10 @@ class caacl_mod(LDAPUpdate):
except errors.NotFound:
self.obj.handle_not_found(*keys)
- # Commented until subca plugin arrives
- #if is_all(options, 'ipacacategory') and 'ipamemberca' in entry_attrs:
- # raise errors.MutuallyExclusiveError(reason=_(
- # "CA category cannot be set to 'all' "
- # "while there are allowed CAs"))
+ if is_all(options, 'ipacacategory') and 'ipamemberca' in entry_attrs:
+ raise errors.MutuallyExclusiveError(reason=_(
+ "CA category cannot be set to 'all' "
+ "while there are allowed CAs"))
if (is_all(options, 'ipacertprofilecategory')
and 'ipamembercertprofile' in entry_attrs):
raise errors.MutuallyExclusiveError(reason=_(
@@ -523,10 +524,9 @@ caacl_output_params = global_output_params + (
Str('ipamembercertprofile',
label=_('Failed profiles'),
),
- # Commented until caacl plugin arrives
- #Str('ipamemberca',
- # label=_('Failed CAs'),
- #),
+ Str('ipamemberca',
+ label=_('Failed CAs'),
+ ),
)
@@ -560,3 +560,35 @@ class caacl_remove_profile(LDAPRemoveMember):
member_attributes = ['ipamembercertprofile']
member_count_out = (_('%i profile removed.'), _('%i profiles removed.'))
+
+
+@register()
+class caacl_add_ca(LDAPAddMember):
+ __doc__ = _('Add CAs to a CA ACL.')
+
+ has_output_params = caacl_output_params
+
+ member_attributes = ['ipamemberca']
+ member_count_out = (_('%i CA added.'), _('%i CAs added.'))
+
+ def pre_callback(self, ldap, dn, found, not_found, *keys, **options):
+ assert isinstance(dn, DN)
+ try:
+ entry_attrs = ldap.get_entry(dn, self.obj.default_attributes)
+ dn = entry_attrs.dn
+ except errors.NotFound:
+ self.obj.handle_not_found(*keys)
+ if is_all(entry_attrs, 'ipacacategory'):
+ raise errors.MutuallyExclusiveError(reason=_(
+ "CAs cannot be added when CA category='all'"))
+ return dn
+
+
+@register()
+class caacl_remove_ca(LDAPRemoveMember):
+ __doc__ = _('Remove CAs from a CA ACL.')
+
+ has_output_params = caacl_output_params
+
+ member_attributes = ['ipamemberca']
+ member_count_out = (_('%i CA removed.'), _('%i CAs removed.'))