summaryrefslogtreecommitdiffstats
path: root/ipaserver/plugins/certmap.py
diff options
context:
space:
mode:
Diffstat (limited to 'ipaserver/plugins/certmap.py')
-rw-r--r--ipaserver/plugins/certmap.py391
1 files changed, 391 insertions, 0 deletions
diff --git a/ipaserver/plugins/certmap.py b/ipaserver/plugins/certmap.py
new file mode 100644
index 000000000..c37eae38e
--- /dev/null
+++ b/ipaserver/plugins/certmap.py
@@ -0,0 +1,391 @@
+# Authors:
+# Florence Blanc-Renaud <flo@redhat.com>
+#
+# Copyright (C) 2017 Red Hat
+# see file 'COPYING' for use and warranty information
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import six
+
+from ipalib import api, errors
+from ipalib.parameters import Bool, DNSNameParam, Flag, Int, Str
+from ipalib.plugable import Registry
+from .baseldap import (
+ LDAPCreate,
+ LDAPDelete,
+ LDAPObject,
+ LDAPQuery,
+ LDAPRetrieve,
+ LDAPSearch,
+ LDAPUpdate,
+ pkey_to_value)
+from ipalib import _, ngettext
+from ipalib import output
+
+
+if six.PY3:
+ unicode = str
+
+__doc__ = _("""
+Certificate Identity Mapping
+""") + _("""
+Manage Certificate Identity Mapping configuration and rules.
+""") + _("""
+IPA supports the use of certificates for authentication. Certificates can
+either be stored in the user entry (full certificate in the usercertificate
+attribute), or simply linked to the user entry through a mapping.
+This code enables the management of the rules allowing to link a
+certificate to a user entry.
+""") + _("""
+EXAMPLES:
+""") + _("""
+ Display the Certificate Identity Mapping global configuration:
+ ipa certmapconfig-show
+""") + _("""
+ Modify Certificate Identity Mapping global configuration:
+ ipa certmapconfig-mod --promptusername=TRUE
+""") + _("""
+ Create a new Certificate Identity Mapping Rule:
+ ipa certmaprule-add rule1 --desc="Link certificate with subject and issuer"
+""") + _("""
+ Modify a Certificate Identity Mapping Rule:
+ ipa certmaprule-mod rule1 --maprule="<ALT-SEC-ID-I-S:altSecurityIdentities>"
+""") + _("""
+ Disable a Certificate Identity Mapping Rule:
+ ipa certmaprule-disable rule1
+""") + _("""
+ Enable a Certificate Identity Mapping Rule:
+ ipa certmaprule-enable rule1
+""") + _("""
+ Display information about a Certificate Identity Mapping Rule:
+ ipa certmaprule-show rule1
+""") + _("""
+ Find all Certificate Identity Mapping Rules with the specified domain:
+ ipa certmaprule-find --domain example.com
+""") + _("""
+ Delete a Certificate Identity Mapping Rule:
+ ipa certmaprule-del rule1
+""")
+
+register = Registry()
+
+
+def check_associateddomain_is_trusted(api_inst, options):
+ """
+ Check that the associateddomain in options are either IPA domain or
+ a trusted domain.
+
+ :param api_inst: API instance
+ :param associateddomain: domains to be checked
+
+ :raises: ValidationError if the domain is neither IPA domain nor trusted
+ """
+ domains = options.get('associateddomain')
+ if domains:
+ trust_suffix_namespace = set()
+ trust_suffix_namespace.add(api_inst.env.domain.lower())
+
+ trust_objects = api_inst.Command.trust_find(sizelimit=0)['result']
+ for obj in trust_objects:
+ trustdomains = api_inst.Command.trustdomain_find(
+ obj['cn'][0], sizelimit=0)['result']
+ for domain in trustdomains:
+ trust_suffix_namespace.add(domain['cn'][0].lower())
+
+ for dom in domains:
+ if not str(dom).lower() in trust_suffix_namespace:
+ raise errors.ValidationError(
+ name=_('domain'),
+ error=_('The domain %s is neither IPA domain nor a trusted'
+ 'domain.') % dom
+ )
+
+
+@register()
+class certmapconfig(LDAPObject):
+ """
+ Certificate Identity Mapping configuration object
+ """
+ object_name = _('Certificate Identity Mapping configuration options')
+ default_attributes = ['ipacertmappromptusername']
+
+ container_dn = api.env.container_certmap
+
+ label = _('Certificate Identity Mapping Global Configuration')
+ label_singular = _('Certificate Identity Mapping Global Configuration')
+
+ takes_params = (
+ Bool(
+ 'ipacertmappromptusername',
+ cli_name='promptusername',
+ label=_('Prompt for the username'),
+ doc=_('Prompt for the username when multiple identities'
+ ' are mapped to a certificate'),
+ ),
+ )
+
+ permission_filter_objectclasses = ['ipacertmapconfigobject']
+ managed_permissions = {
+ 'System: Read Certmap Configuration': {
+ 'replaces_global_anonymous_aci': True,
+ 'ipapermbindruletype': 'all',
+ 'ipapermright': {'read', 'search', 'compare'},
+ 'ipapermdefaultattr': {
+ 'ipacertmappromptusername',
+ 'cn',
+ },
+ },
+ 'System: Modify Certmap Configuration': {
+ 'replaces_global_anonymous_aci': True,
+ 'ipapermright': {'write'},
+ 'ipapermdefaultattr': {
+ 'ipacertmappromptusername',
+ },
+ 'default_privileges': {
+ 'Certificate Identity Mapping Administrators'},
+ },
+ }
+
+
+@register()
+class certmapconfig_mod(LDAPUpdate):
+ __doc__ = _('Modify Certificate Identity Mapping configuration.')
+
+
+@register()
+class certmapconfig_show(LDAPRetrieve):
+ __doc__ = _('Show the current Certificate Identity Mapping configuration.')
+
+
+@register()
+class certmaprule(LDAPObject):
+ """
+ Certificate Identity Mapping Rules
+ """
+
+ label = _('Certificate Identity Mapping Rules')
+ label_singular = _('Certificate Identity Mapping Rule')
+
+ object_name = _('Certificate Identity Mapping Rule')
+ object_name_plural = _('Certificate Identity Mapping Rules')
+ object_class = ['ipacertmaprule']
+
+ container_dn = api.env.container_certmaprules
+ default_attributes = [
+ 'cn', 'description',
+ 'ipacertmapmaprule',
+ 'ipacertmapmatchrule',
+ 'associateddomain',
+ 'ipacertmappriority',
+ 'ipaenabledflag'
+ ]
+ search_attributes = [
+ 'cn', 'description',
+ 'ipacertmapmaprule',
+ 'ipacertmapmatchrule',
+ 'associateddomain',
+ 'ipacertmappriority',
+ 'ipaenabledflag'
+ ]
+
+ takes_params = (
+ Str(
+ 'cn',
+ cli_name='rulename',
+ primary_key=True,
+ label=_('Rule name'),
+ doc=_('Certificate Identity Mapping Rule name'),
+ ),
+ Str(
+ 'description?',
+ cli_name='desc',
+ label=_('Description'),
+ doc=_('Certificate Identity Mapping Rule description'),
+ ),
+ Str(
+ 'ipacertmapmaprule?',
+ cli_name='maprule',
+ label=_('Mapping rule'),
+ doc=_('Rule used to map the certificate with a user entry'),
+ ),
+ Str(
+ 'ipacertmapmatchrule?',
+ cli_name='matchrule',
+ label=_('Matching rule'),
+ doc=_('Rule used to check if a certificate can be used for'
+ ' authentication'),
+ ),
+ DNSNameParam(
+ 'associateddomain*',
+ cli_name='domain',
+ label=_('Domain name'),
+ doc=_('Domain where the user entry will be searched'),
+ ),
+ Int(
+ 'ipacertmappriority?',
+ cli_name='priority',
+ label=_('Priority'),
+ doc=_('Priority of the rule (higher number means lower priority'),
+ minvalue=0,
+ ),
+ Flag(
+ 'ipaenabledflag?',
+ label=_('Enabled'),
+ flags=['no_option'],
+ default=True
+ ),
+ )
+
+ permission_filter_objectclasses = ['ipacertmaprule']
+ managed_permissions = {
+ 'System: Add Certmap Rules': {
+ 'replaces_global_anonymous_aci': True,
+ 'ipapermright': {'add'},
+ 'default_privileges': {
+ 'Certificate Identity Mapping Administrators'},
+ },
+ 'System: Read Certmap Rules': {
+ 'replaces_global_anonymous_aci': True,
+ 'ipapermbindruletype': 'all',
+ 'ipapermright': {'read', 'search', 'compare'},
+ 'ipapermdefaultattr': {
+ 'objectclass', 'cn', 'description',
+ 'ipacertmapmaprule', 'ipacertmapmatchrule', 'associateddomain',
+ 'ipacertmappriority', 'ipaenabledflag',
+ },
+ },
+ 'System: Delete Certmap Rules': {
+ 'replaces_global_anonymous_aci': True,
+ 'ipapermright': {'delete'},
+ 'default_privileges': {
+ 'Certificate Identity Mapping Administrators'},
+ },
+ 'System: Modify Certmap Rules': {
+ 'replaces_global_anonymous_aci': True,
+ 'ipapermright': {'write'},
+ 'ipapermdefaultattr': {
+ 'objectclass', 'cn', 'description',
+ 'ipacertmapmaprule', 'ipacertmapmatchrule', 'associateddomain',
+ 'ipacertmappriority', 'ipaenabledflag',
+ },
+ 'default_privileges': {
+ 'Certificate Identity Mapping Administrators'},
+ },
+ }
+
+
+@register()
+class certmaprule_add(LDAPCreate):
+ __doc__ = _('Create a new Certificate Identity Mapping Rule.')
+
+ msg_summary = _('Added Certificate Identity Mapping Rule "%(value)s"')
+
+ def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys,
+ **options):
+ check_associateddomain_is_trusted(self.api, options)
+ return dn
+
+
+@register()
+class certmaprule_mod(LDAPUpdate):
+ __doc__ = _('Modify a Certificate Identity Mapping Rule.')
+
+ msg_summary = _('Modified Certificate Identity Mapping Rule "%(value)s"')
+
+ def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys,
+ **options):
+ check_associateddomain_is_trusted(self.api, options)
+ return dn
+
+
+@register()
+class certmaprule_find(LDAPSearch):
+ __doc__ = _('Search for Certificate Identity Mapping Rules.')
+
+ msg_summary = ngettext(
+ '%(count)d Certificate Identity Mapping Rule matched',
+ '%(count)d Certificate Identity Mapping Rules matched', 0
+ )
+
+
+@register()
+class certmaprule_show(LDAPRetrieve):
+ __doc__ = _('Display information about a Certificate Identity Mapping'
+ ' Rule.')
+
+
+@register()
+class certmaprule_del(LDAPDelete):
+ __doc__ = _('Delete a Certificate Identity Mapping Rule.')
+
+ msg_summary = _('Deleted Certificate Identity Mapping Rule "%(value)s"')
+
+
+@register()
+class certmaprule_enable(LDAPQuery):
+ __doc__ = _('Enable a Certificate Identity Mapping Rule.')
+
+ msg_summary = _('Enabled Certificate Identity Mapping Rule "%(value)s"')
+ has_output = output.standard_value
+
+ def execute(self, cn, **options):
+ ldap = self.obj.backend
+
+ dn = self.obj.get_dn(cn)
+ try:
+ entry_attrs = ldap.get_entry(dn, ['ipaenabledflag'])
+ except errors.NotFound:
+ self.obj.handle_not_found(cn)
+
+ entry_attrs['ipaenabledflag'] = ['TRUE']
+
+ try:
+ ldap.update_entry(entry_attrs)
+ except errors.EmptyModlist:
+ pass
+
+ return dict(
+ result=True,
+ value=pkey_to_value(cn, options),
+ )
+
+
+@register()
+class certmaprule_disable(LDAPQuery):
+ __doc__ = _('Disable a Certificate Identity Mapping Rule.')
+
+ msg_summary = _('Disabled Certificate Identity Mapping Rule "%(value)s"')
+ has_output = output.standard_value
+
+ def execute(self, cn, **options):
+ ldap = self.obj.backend
+
+ dn = self.obj.get_dn(cn)
+ try:
+ entry_attrs = ldap.get_entry(dn, ['ipaenabledflag'])
+ except errors.NotFound:
+ self.obj.handle_not_found(cn)
+
+ entry_attrs['ipaenabledflag'] = ['FALSE']
+
+ try:
+ ldap.update_entry(entry_attrs)
+ except errors.EmptyModlist:
+ pass
+
+ return dict(
+ result=True,
+ value=pkey_to_value(cn, options),
+ )