mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
Add 'ca' plugin
This commit adds the 'ca' plugin for creating and managing lightweight CAs. The initial implementation supports a single level of sub-CAs underneath the IPA CA. This commit also: - adds the container for FreeIPA CA objects - adds schema for the FreeIPA CA objects - updates ipa-pki-proxy.conf to allow access to the Dogtag lightweight CAs REST API. Part of: https://fedorahosted.org/freeipa/ticket/4559 Reviewed-By: Jan Cholasta <jcholast@redhat.com> Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
This commit is contained in:
committed by
Jan Cholasta
parent
8135651abb
commit
3d4db834ca
8
ACI.txt
8
ACI.txt
@@ -22,6 +22,14 @@ dn: cn=automount,dc=ipa,dc=example
|
||||
aci: (targetattr = "automountmapname || description")(targetfilter = "(objectclass=automountmap)")(version 3.0;acl "permission:System: Modify Automount Maps";allow (write) groupdn = "ldap:///cn=System: Modify Automount Maps,cn=permissions,cn=pbac,dc=ipa,dc=example";)
|
||||
dn: cn=automount,dc=ipa,dc=example
|
||||
aci: (targetfilter = "(objectclass=automountmap)")(version 3.0;acl "permission:System: Remove Automount Maps";allow (delete) groupdn = "ldap:///cn=System: Remove Automount Maps,cn=permissions,cn=pbac,dc=ipa,dc=example";)
|
||||
dn: cn=cas,cn=ca,dc=ipa,dc=example
|
||||
aci: (targetfilter = "(objectclass=ipaca)")(version 3.0;acl "permission:System: Add CA";allow (add) groupdn = "ldap:///cn=System: Add CA,cn=permissions,cn=pbac,dc=ipa,dc=example";)
|
||||
dn: cn=cas,cn=ca,dc=ipa,dc=example
|
||||
aci: (targetfilter = "(objectclass=ipaca)")(version 3.0;acl "permission:System: Delete CA";allow (delete) groupdn = "ldap:///cn=System: Delete CA,cn=permissions,cn=pbac,dc=ipa,dc=example";)
|
||||
dn: cn=cas,cn=ca,dc=ipa,dc=example
|
||||
aci: (targetattr = "cn || description")(targetfilter = "(objectclass=ipaca)")(version 3.0;acl "permission:System: Modify CA";allow (write) groupdn = "ldap:///cn=System: Modify CA,cn=permissions,cn=pbac,dc=ipa,dc=example";)
|
||||
dn: cn=cas,cn=ca,dc=ipa,dc=example
|
||||
aci: (targetattr = "cn || createtimestamp || description || entryusn || ipacaid || ipacaissuerdn || ipacasubjectdn || modifytimestamp || objectclass")(targetfilter = "(objectclass=ipaca)")(version 3.0;acl "permission:System: Read CAs";allow (compare,read,search) userdn = "ldap:///all";)
|
||||
dn: cn=caacls,cn=ca,dc=ipa,dc=example
|
||||
aci: (targetfilter = "(objectclass=ipacaacl)")(version 3.0;acl "permission:System: Add CA ACL";allow (add) groupdn = "ldap:///cn=System: Add CA ACL,cn=permissions,cn=pbac,dc=ipa,dc=example";)
|
||||
dn: cn=caacls,cn=ca,dc=ipa,dc=example
|
||||
|
||||
64
API.txt
64
API.txt
@@ -450,12 +450,76 @@ arg: Any('methods*')
|
||||
option: Str('version?')
|
||||
output: Output('count', type=[<type 'int'>])
|
||||
output: Output('results', type=[<type 'list'>, <type 'tuple'>])
|
||||
command: ca_add
|
||||
args: 1,7,3
|
||||
arg: Str('cn', cli_name='name')
|
||||
option: Str('addattr*', cli_name='addattr')
|
||||
option: Flag('all', autofill=True, cli_name='all', default=False)
|
||||
option: Str('description?', cli_name='desc')
|
||||
option: DNParam('ipacasubjectdn', cli_name='subject')
|
||||
option: Flag('raw', autofill=True, cli_name='raw', default=False)
|
||||
option: Str('setattr*', cli_name='setattr')
|
||||
option: Str('version?')
|
||||
output: Entry('result')
|
||||
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
|
||||
output: PrimaryKey('value')
|
||||
command: ca_del
|
||||
args: 1,2,3
|
||||
arg: Str('cn+', cli_name='name')
|
||||
option: Flag('continue', autofill=True, cli_name='continue', default=False)
|
||||
option: Str('version?')
|
||||
output: Output('result', type=[<type 'dict'>])
|
||||
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
|
||||
output: ListOfPrimaryKeys('value')
|
||||
command: ca_find
|
||||
args: 1,11,4
|
||||
arg: Str('criteria?')
|
||||
option: Flag('all', autofill=True, cli_name='all', default=False)
|
||||
option: Str('cn?', autofill=False, cli_name='name')
|
||||
option: Str('description?', autofill=False, cli_name='desc')
|
||||
option: Str('ipacaid?', autofill=False, cli_name='id')
|
||||
option: DNParam('ipacaissuerdn?', autofill=False, cli_name='issuer')
|
||||
option: DNParam('ipacasubjectdn?', autofill=False, cli_name='subject')
|
||||
option: Flag('pkey_only?', autofill=True, default=False)
|
||||
option: Flag('raw', autofill=True, cli_name='raw', default=False)
|
||||
option: Int('sizelimit?', autofill=False)
|
||||
option: Int('timelimit?', autofill=False)
|
||||
option: Str('version?')
|
||||
output: Output('count', type=[<type 'int'>])
|
||||
output: ListOfEntries('result')
|
||||
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
|
||||
output: Output('truncated', type=[<type 'bool'>])
|
||||
command: ca_is_enabled
|
||||
args: 0,1,3
|
||||
option: Str('version?')
|
||||
output: Output('result', type=[<type 'bool'>])
|
||||
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
|
||||
output: PrimaryKey('value')
|
||||
command: ca_mod
|
||||
args: 1,9,3
|
||||
arg: Str('cn', cli_name='name')
|
||||
option: Str('addattr*', cli_name='addattr')
|
||||
option: Flag('all', autofill=True, cli_name='all', default=False)
|
||||
option: Str('delattr*', cli_name='delattr')
|
||||
option: Str('description?', autofill=False, cli_name='desc')
|
||||
option: Flag('raw', autofill=True, cli_name='raw', default=False)
|
||||
option: Str('rename?', cli_name='rename')
|
||||
option: Flag('rights', autofill=True, default=False)
|
||||
option: Str('setattr*', cli_name='setattr')
|
||||
option: Str('version?')
|
||||
output: Entry('result')
|
||||
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
|
||||
output: PrimaryKey('value')
|
||||
command: ca_show
|
||||
args: 1,4,3
|
||||
arg: Str('cn', cli_name='name')
|
||||
option: Flag('all', autofill=True, cli_name='all', default=False)
|
||||
option: Flag('raw', autofill=True, cli_name='raw', default=False)
|
||||
option: Flag('rights', autofill=True, default=False)
|
||||
option: Str('version?')
|
||||
output: Entry('result')
|
||||
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
|
||||
output: PrimaryKey('value')
|
||||
command: caacl_add
|
||||
args: 1,12,3
|
||||
arg: Str('cn', cli_name='name')
|
||||
|
||||
4
VERSION
4
VERSION
@@ -90,5 +90,5 @@ IPA_DATA_VERSION=20100614120000
|
||||
# #
|
||||
########################################################
|
||||
IPA_API_VERSION_MAJOR=2
|
||||
IPA_API_VERSION_MINOR=180
|
||||
# Last change: mbabink - Server Roles: provide an API for setting CA renewal master
|
||||
IPA_API_VERSION_MINOR=181
|
||||
# Last change: ftweedal - add lightweight CAs plugin
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# VERSION 8 - DO NOT REMOVE THIS LINE
|
||||
# VERSION 9 - DO NOT REMOVE THIS LINE
|
||||
|
||||
ProxyRequests Off
|
||||
|
||||
@@ -27,7 +27,7 @@ ProxyRequests Off
|
||||
</LocationMatch>
|
||||
|
||||
# matches for CA REST API
|
||||
<LocationMatch "^/ca/rest/account/login|^/ca/rest/account/logout|^/ca/rest/installer/installToken|^/ca/rest/securityDomain/domainInfo|^/ca/rest/securityDomain/installToken|^/ca/rest/profiles|^/ca/rest/admin/kraconnector/remove">
|
||||
<LocationMatch "^/ca/rest/account/login|^/ca/rest/account/logout|^/ca/rest/installer/installToken|^/ca/rest/securityDomain/domainInfo|^/ca/rest/securityDomain/installToken|^/ca/rest/profiles|^/ca/rest/authorities|^/ca/rest/admin/kraconnector/remove">
|
||||
NSSOptions +StdEnvVars +ExportCertData +StrictRequire +OptRenegotiate
|
||||
NSSVerifyClient optional
|
||||
ProxyPassMatch ajp://localhost:$DOGTAG_PORT
|
||||
|
||||
@@ -4,5 +4,9 @@ attributeTypes: (2.16.840.1.113730.3.8.21.1.2 NAME 'ipaMemberCa' DESC 'Reference
|
||||
attributeTypes: (2.16.840.1.113730.3.8.21.1.3 NAME 'ipaMemberCertProfile' DESC 'Reference to a certificate profile member' SUP distinguishedName EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'IPA v4.2' )
|
||||
attributeTypes: (2.16.840.1.113730.3.8.21.1.4 NAME 'ipaCaCategory' DESC 'Additional classification for CAs' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'IPA v4.2' )
|
||||
attributeTypes: (2.16.840.1.113730.3.8.21.1.5 NAME 'ipaCertProfileCategory' DESC 'Additional classification for certificate profiles' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'IPA v4.2' )
|
||||
attributeTypes: (2.16.840.1.113730.3.8.21.1.6 NAME 'ipaCaId' DESC 'Dogtag Authority ID' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'IPA v4.4 Lightweight CAs' )
|
||||
attributeTypes: (2.16.840.1.113730.3.8.21.1.7 NAME 'ipaCaIssuerDN' DESC 'Issuer DN' SUP distinguishedName X-ORIGIN 'IPA v4.4 Lightweight CAs' )
|
||||
attributeTypes: (2.16.840.1.113730.3.8.21.1.8 NAME 'ipaCaSubjectDN' DESC 'Subject DN' SUP distinguishedName X-ORIGIN 'IPA v4.4 Lightweight CAs' )
|
||||
objectClasses: (2.16.840.1.113730.3.8.21.2.1 NAME 'ipaCertProfile' SUP top STRUCTURAL MUST ( cn $ description $ ipaCertProfileStoreIssued ) X-ORIGIN 'IPA v4.2' )
|
||||
objectClasses: (2.16.840.1.113730.3.8.21.2.2 NAME 'ipaCaAcl' SUP ipaAssociation STRUCTURAL MUST cn MAY ( ipaCaCategory $ ipaCertProfileCategory $ userCategory $ hostCategory $ serviceCategory $ ipaMemberCa $ ipaMemberCertProfile $ memberService ) X-ORIGIN 'IPA v4.2' )
|
||||
objectClasses: (2.16.840.1.113730.3.8.21.2.3 NAME 'ipaCa' SUP top STRUCTURAL MUST ( cn $ ipaCaId $ ipaCaSubjectDN $ ipaCaIssuerDN ) MAY description X-ORIGIN 'IPA v4.4 Lightweight CAs' )
|
||||
|
||||
@@ -476,3 +476,9 @@ changetype: add
|
||||
objectClass: nsContainer
|
||||
objectClass: top
|
||||
cn: caacls
|
||||
|
||||
dn: cn=cas,cn=ca,$SUFFIX
|
||||
changetype: add
|
||||
objectClass: nsContainer
|
||||
objectClass: top
|
||||
cn: cas
|
||||
|
||||
4
install/updates/41-lightweight-cas.update
Normal file
4
install/updates/41-lightweight-cas.update
Normal file
@@ -0,0 +1,4 @@
|
||||
dn: cn=cas,cn=ca,$SUFFIX
|
||||
default: objectClass: nsContainer
|
||||
default: objectClass: top
|
||||
default: cn: cas
|
||||
@@ -39,6 +39,7 @@ app_DATA = \
|
||||
40-otp.update \
|
||||
40-vault.update \
|
||||
41-caacl.update \
|
||||
41-lightweight-cas.update \
|
||||
45-roles.update \
|
||||
50-7_bit_check.update \
|
||||
50-dogtag10-migration.update \
|
||||
|
||||
@@ -122,6 +122,7 @@ DEFAULT_CONFIG = (
|
||||
('container_topology', DN(('cn', 'topology'), ('cn', 'ipa'), ('cn', 'etc'))),
|
||||
('container_caacl', DN(('cn', 'caacls'), ('cn', 'ca'))),
|
||||
('container_locations', DN(('cn', 'locations'), ('cn', 'etc'))),
|
||||
('container_ca', DN(('cn', 'cas'), ('cn', 'ca'))),
|
||||
|
||||
# Ports, hosts, and URIs:
|
||||
('xmlrpc_uri', 'http://localhost:8888/ipa/xml'),
|
||||
@@ -265,3 +266,4 @@ REPL_AGMT_STRIP_ATTRS = ('modifiersName',
|
||||
DOMAIN_SUFFIX_NAME = 'domain'
|
||||
CA_SUFFIX_NAME = 'ca'
|
||||
PKI_GSSAPI_SERVICE_NAME = 'dogtag'
|
||||
IPA_CA_CN = u'ipa'
|
||||
|
||||
@@ -1629,6 +1629,13 @@ def ensure_ldap_profiles_container():
|
||||
ou=['certificateProfiles'],
|
||||
)
|
||||
|
||||
def ensure_lightweight_cas_container():
|
||||
ensure_entry(
|
||||
DN(('ou', 'authorities'), ('ou', 'ca'), ('o', 'ipaca')),
|
||||
objectclass=['top', 'organizationalUnit'],
|
||||
ou=['authorities'],
|
||||
)
|
||||
|
||||
|
||||
def ensure_entry(dn, **attrs):
|
||||
server_id = installutils.realm_to_serverid(api.env.realm)
|
||||
|
||||
@@ -345,6 +345,16 @@ def ca_import_included_profiles(ca):
|
||||
return cainstance.import_included_profiles()
|
||||
|
||||
|
||||
def ca_ensure_lightweight_cas_container(ca):
|
||||
root_logger.info('[Ensuring Lightweight CAs container exists in Dogtag database]')
|
||||
|
||||
if not ca.is_configured():
|
||||
root_logger.info('CA is not configured')
|
||||
return False
|
||||
|
||||
return cainstance.ensure_lightweight_cas_container()
|
||||
|
||||
|
||||
def upgrade_ca_audit_cert_validity(ca):
|
||||
"""
|
||||
Update the Dogtag audit signing certificate.
|
||||
@@ -1438,7 +1448,10 @@ def ca_upgrade_schema(ca):
|
||||
root_logger.info('CA is not configured')
|
||||
return False
|
||||
|
||||
schema_files=['/usr/share/pki/server/conf/schema-certProfile.ldif']
|
||||
schema_files=[
|
||||
'/usr/share/pki/server/conf/schema-certProfile.ldif',
|
||||
'/usr/share/pki/server/conf/schema-authority.ldif',
|
||||
]
|
||||
try:
|
||||
modified = schemaupdate.update_schema(schema_files, ldapi=True)
|
||||
except Exception as e:
|
||||
@@ -1698,6 +1711,7 @@ def upgrade_configuration():
|
||||
except ipautil.CalledProcessError as e:
|
||||
root_logger.error("Failed to restart %s: %s", ca.service_name, e)
|
||||
|
||||
ca_ensure_lightweight_cas_container(ca)
|
||||
ca_enable_ldap_profile_subsystem(ca)
|
||||
|
||||
# This step MUST be done after ca_enable_ldap_profile_subsystem and
|
||||
|
||||
217
ipaserver/plugins/ca.py
Normal file
217
ipaserver/plugins/ca.py
Normal file
@@ -0,0 +1,217 @@
|
||||
#
|
||||
# Copyright (C) 2016 FreeIPA Contributors see COPYING for license
|
||||
#
|
||||
|
||||
from ipalib import api, errors, DNParam, Str
|
||||
from ipalib.constants import IPA_CA_CN
|
||||
from ipalib.plugable import Registry
|
||||
from ipaserver.plugins.baseldap import (
|
||||
LDAPObject, LDAPSearch, LDAPCreate, LDAPDelete,
|
||||
LDAPUpdate, LDAPRetrieve)
|
||||
from ipaserver.plugins.cert import ca_enabled_check
|
||||
from ipalib import _, ngettext
|
||||
|
||||
|
||||
__doc__ = _("""
|
||||
Manage Certificate Authorities
|
||||
|
||||
Subordinate Certificate Authorities (Sub-CAs) can be added for scoped issuance
|
||||
of X.509 certificates.
|
||||
|
||||
EXAMPLES:
|
||||
|
||||
Create new CA, subordinate to the IPA CA.
|
||||
|
||||
ipa ca-add puppet --desc "Puppet" \\
|
||||
--subject "CN=Puppet CA,O=EXAMPLE.COM"
|
||||
|
||||
""")
|
||||
|
||||
|
||||
register = Registry()
|
||||
|
||||
|
||||
@register()
|
||||
class ca(LDAPObject):
|
||||
"""
|
||||
Lightweight CA Object
|
||||
"""
|
||||
container_dn = api.env.container_ca
|
||||
object_name = _('Certificate Authority')
|
||||
object_name_plural = _('Certificate Authorities')
|
||||
object_class = ['ipaca']
|
||||
permission_filter_objectclasses = ['ipaca']
|
||||
default_attributes = [
|
||||
'cn', 'description', 'ipacaid', 'ipacaissuerdn', 'ipacasubjectdn',
|
||||
]
|
||||
rdn_attribute = 'cn'
|
||||
rdn_is_primary_key = True
|
||||
label = _('Certificate Authorities')
|
||||
label_singular = _('Certificate Authority')
|
||||
|
||||
takes_params = (
|
||||
Str('cn',
|
||||
primary_key=True,
|
||||
cli_name='name',
|
||||
label=_('Name'),
|
||||
doc=_('Name for referencing the CA'),
|
||||
),
|
||||
Str('description?',
|
||||
cli_name='desc',
|
||||
label=_('Description'),
|
||||
doc=_('Description of the purpose of the CA'),
|
||||
),
|
||||
Str('ipacaid',
|
||||
cli_name='id',
|
||||
label=_('Authority ID'),
|
||||
doc=_('Dogtag Authority ID'),
|
||||
flags=['no_create', 'no_update'],
|
||||
),
|
||||
DNParam('ipacasubjectdn',
|
||||
cli_name='subject',
|
||||
label=_('Subject DN'),
|
||||
doc=_('Subject Distinguished Name'),
|
||||
flags=['no_update'],
|
||||
),
|
||||
DNParam('ipacaissuerdn',
|
||||
cli_name='issuer',
|
||||
label=_('Issuer DN'),
|
||||
doc=_('Issuer Distinguished Name'),
|
||||
flags=['no_create', 'no_update'],
|
||||
),
|
||||
)
|
||||
|
||||
permission_filter_objectclasses = ['ipaca']
|
||||
managed_permissions = {
|
||||
'System: Read CAs': {
|
||||
'replaces_global_anonymous_aci': True,
|
||||
'ipapermbindruletype': 'all',
|
||||
'ipapermright': {'read', 'search', 'compare'},
|
||||
'ipapermdefaultattr': {
|
||||
'cn',
|
||||
'description',
|
||||
'ipacaid',
|
||||
'ipacaissuerdn',
|
||||
'ipacasubjectdn',
|
||||
'objectclass',
|
||||
},
|
||||
},
|
||||
'System: Add CA': {
|
||||
'ipapermright': {'add'},
|
||||
'replaces': [
|
||||
'(target = "ldap:///cn=*,cn=cas,cn=ca,$SUFFIX")(version 3.0;acl "permission:Add CA";allow (add) groupdn = "ldap:///cn=Add CA,cn=permissions,cn=pbac,$SUFFIX";)',
|
||||
],
|
||||
'default_privileges': {'CA Administrator'},
|
||||
},
|
||||
'System: Delete CA': {
|
||||
'ipapermright': {'delete'},
|
||||
'replaces': [
|
||||
'(target = "ldap:///cn=*,cn=cas,cn=ca,$SUFFIX")(version 3.0;acl "permission:Delete CA";allow (delete) groupdn = "ldap:///cn=Delete CA,cn=permissions,cn=pbac,$SUFFIX";)',
|
||||
],
|
||||
'default_privileges': {'CA Administrator'},
|
||||
},
|
||||
'System: Modify CA': {
|
||||
'ipapermright': {'write'},
|
||||
'ipapermdefaultattr': {
|
||||
'cn',
|
||||
'description',
|
||||
},
|
||||
'replaces': [
|
||||
'(targetattr = "cn || description")(target = "ldap:///cn=*,cn=cas,cn=ca,$SUFFIX")(version 3.0;acl "permission:Modify CA";allow (write) groupdn = "ldap:///cn=Modify CA,cn=permissions,cn=pbac,$SUFFIX";)',
|
||||
],
|
||||
'default_privileges': {'CA Administrator'},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@register()
|
||||
class ca_find(LDAPSearch):
|
||||
__doc__ = _("Search for CAs.")
|
||||
msg_summary = ngettext(
|
||||
'%(count)d CA matched', '%(count)d CAs matched', 0
|
||||
)
|
||||
|
||||
def execute(self, *keys, **options):
|
||||
ca_enabled_check()
|
||||
return super(ca_find, self).execute(*keys, **options)
|
||||
|
||||
|
||||
@register()
|
||||
class ca_show(LDAPRetrieve):
|
||||
__doc__ = _("Display the properties of a CA.")
|
||||
|
||||
def execute(self, *args, **kwargs):
|
||||
ca_enabled_check()
|
||||
return super(ca_show, self).execute(*args, **kwargs)
|
||||
|
||||
|
||||
@register()
|
||||
class ca_add(LDAPCreate):
|
||||
__doc__ = _("Create a CA.")
|
||||
msg_summary = _('Created CA "%(value)s"')
|
||||
|
||||
def pre_callback(self, ldap, dn, entry, entry_attrs, *keys, **options):
|
||||
ca_enabled_check()
|
||||
if not ldap.can_add(dn[1:]):
|
||||
raise errors.ACIError(
|
||||
info=_("Insufficient 'add' privilege for entry '%s'.") % dn)
|
||||
|
||||
# check for name collision before creating CA in Dogtag
|
||||
try:
|
||||
api.Object.ca.get_dn_if_exists(keys[-1])
|
||||
self.obj.handle_duplicate_entry(*keys)
|
||||
except errors.NotFound:
|
||||
pass
|
||||
|
||||
# Create the CA in Dogtag.
|
||||
with self.api.Backend.ra_lightweight_ca as ca_api:
|
||||
resp = ca_api.create_ca(options['ipacasubjectdn'])
|
||||
entry['ipacaid'] = [resp['id']]
|
||||
entry['ipacaissuerdn'] = [resp['issuerDN']]
|
||||
|
||||
# In the event that the issued certificate's subject DN
|
||||
# differs from what was requested, record the actual DN.
|
||||
#
|
||||
entry['ipacasubjectdn'] = [resp['dn']]
|
||||
return dn
|
||||
|
||||
|
||||
@register()
|
||||
class ca_del(LDAPDelete):
|
||||
__doc__ = _('Delete a CA.')
|
||||
|
||||
msg_summary = _('Deleted CA "%(value)s"')
|
||||
|
||||
def pre_callback(self, ldap, dn, *keys, **options):
|
||||
ca_enabled_check()
|
||||
|
||||
if keys[0] == IPA_CA_CN:
|
||||
raise errors.ProtectedEntryError(
|
||||
label=_("CA"),
|
||||
key=keys[0],
|
||||
reason=_("IPA CA cannot be deleted"))
|
||||
|
||||
ca_id = self.api.Command.ca_show(keys[0])['result']['ipacaid'][0]
|
||||
with self.api.Backend.ra_lightweight_ca as ca_api:
|
||||
ca_api.disable_ca(ca_id)
|
||||
ca_api.delete_ca(ca_id)
|
||||
|
||||
return dn
|
||||
|
||||
|
||||
@register()
|
||||
class ca_mod(LDAPUpdate):
|
||||
__doc__ = _("Modify CA configuration.")
|
||||
msg_summary = _('Modified CA "%(value)s"')
|
||||
|
||||
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
|
||||
ca_enabled_check()
|
||||
|
||||
if 'rename' in options or 'cn' in entry_attrs:
|
||||
if keys[0] == IPA_CA_CN:
|
||||
raise errors.ProtectedEntryError(
|
||||
label=_("CA"),
|
||||
key=keys[0],
|
||||
reason=u'IPA CA cannot be renamed')
|
||||
|
||||
return dn
|
||||
@@ -2073,7 +2073,10 @@ class RestClient(Backend):
|
||||
headers = headers or {}
|
||||
headers['Cookie'] = self.cookie
|
||||
|
||||
resource = os.path.join('/ca/rest', self.path, path)
|
||||
if path is not None:
|
||||
resource = os.path.join('/ca/rest', self.path, path)
|
||||
else:
|
||||
resource = os.path.join('/ca/rest', self.path)
|
||||
|
||||
# perform main request
|
||||
status, resp_headers, resp_body = dogtag.https_request(
|
||||
@@ -2147,3 +2150,52 @@ class ra_certprofile(RestClient):
|
||||
Delete the profile from Dogtag
|
||||
"""
|
||||
self._ssldo('DELETE', profile_id, headers={'Accept': 'application/json'})
|
||||
|
||||
|
||||
@register()
|
||||
class ra_lightweight_ca(RestClient):
|
||||
"""
|
||||
Lightweight CA management backend plugin.
|
||||
"""
|
||||
path = 'authorities'
|
||||
|
||||
def create_ca(self, dn):
|
||||
"""Create CA with the given DN.
|
||||
|
||||
New CA is issued by IPA CA. Nested sub-CAs and unrelated
|
||||
root CAs are not yet supported.
|
||||
|
||||
Return the (parsed) JSON response from server.
|
||||
|
||||
"""
|
||||
|
||||
assert isinstance(dn, DN)
|
||||
status, resp_headers, resp_body = self._ssldo(
|
||||
'POST', None,
|
||||
headers={
|
||||
'Content-type': 'application/json',
|
||||
'Accept': 'application/json',
|
||||
},
|
||||
body=json.dumps({"parentID": "host-authority", "dn": unicode(dn)}),
|
||||
)
|
||||
try:
|
||||
return json.loads(resp_body)
|
||||
except:
|
||||
raise errors.RemoteRetrieveError(reason=_("Response from CA was not valid JSON"))
|
||||
|
||||
def read_ca(self, ca_id):
|
||||
status, resp_headers, resp_body = self._ssldo(
|
||||
'GET', ca_id, headers={'Accept': 'application/json'})
|
||||
try:
|
||||
return json.loads(resp_body)
|
||||
except:
|
||||
raise errors.RemoteRetrieveError(reason=_("Response from CA was not valid JSON"))
|
||||
|
||||
def disable_ca(self, ca_id):
|
||||
self._ssldo(
|
||||
'POST', ca_id + '/disable',
|
||||
headers={'Accept': 'application/json'},
|
||||
)
|
||||
|
||||
def delete_ca(self, ca_id):
|
||||
self._ssldo('DELETE', ca_id)
|
||||
|
||||
Reference in New Issue
Block a user