summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--install/share/default-aci.ldif2
-rw-r--r--ipalib/plugins/host.py209
-rw-r--r--ipalib/plugins/service.py130
-rw-r--r--tests/test_xmlrpc/test_host_plugin.py24
-rw-r--r--tests/test_xmlrpc/test_service_plugin.py7
5 files changed, 276 insertions, 96 deletions
diff --git a/install/share/default-aci.ldif b/install/share/default-aci.ldif
index 935dcd504..2ca300693 100644
--- a/install/share/default-aci.ldif
+++ b/install/share/default-aci.ldif
@@ -4,7 +4,7 @@ dn: $SUFFIX
changetype: modify
add: aci
aci: (targetattr != "userPassword || krbPrincipalKey || sambaLMPassword || sambaNTPassword || passwordHistory || krbMKey")(version 3.0; acl "Enable Anonymous access"; allow (read, search, compare) userdn = "ldap:///anyone";)
-aci: (targetattr != "userPassword || krbPrincipalKey || sambaLMPassword || sambaNTPassword || passwordHistory || krbMKey || ipaUniqueId || memberOf || serverHostName || enrolledBy")(version 3.0; acl "Admin can manage any entry"; allow (all) groupdn = "ldap:///cn=admins,cn=groups,cn=accounts,$SUFFIX";)
+aci: (targetattr != "userPassword || krbPrincipalKey || sambaLMPassword || sambaNTPassword || passwordHistory || krbMKey || ipaUniqueId || memberOf || serverHostName")(version 3.0; acl "Admin can manage any entry"; allow (all) groupdn = "ldap:///cn=admins,cn=groups,cn=accounts,$SUFFIX";)
aci: (targetattr = "userPassword || krbPrincipalKey || sambaLMPassword || sambaNTPassword")(version 3.0; acl "Self can write own password"; allow (write) userdn="ldap:///self";)
aci: (targetattr = "userPassword || krbPrincipalKey || sambaLMPassword || sambaNTPassword || passwordHistory")(version 3.0; acl "Admins can write passwords"; allow (add,delete,write) groupdn="ldap:///cn=admins,cn=groups,cn=accounts,$SUFFIX";)
aci: (targetattr = "userPassword || krbPrincipalKey || sambaLMPassword || sambaNTPassword || passwordHistory")(version 3.0; acl "Password change service can read/write passwords"; allow (read, write) userdn="ldap:///krbprincipalname=kadmin/changepw@$REALM,cn=$REALM,cn=kerberos,$SUFFIX";)
diff --git a/ipalib/plugins/host.py b/ipalib/plugins/host.py
index 6b95738a2..23728fadc 100644
--- a/ipalib/plugins/host.py
+++ b/ipalib/plugins/host.py
@@ -76,6 +76,8 @@ from ipalib import Str, Flag, Bytes
from ipalib.plugins.baseldap import *
from ipalib.plugins.service import split_principal
from ipalib.plugins.service import validate_certificate
+from ipalib.plugins.service import normalize_certificate
+from ipalib.plugins.service import set_certificate_attrs
from ipalib import _, ngettext
from ipalib import x509
from ipapython.ipautil import ipa_generate_password
@@ -92,6 +94,36 @@ def validate_host(ugettext, fqdn):
return _('Fully-qualified hostname required')
return None
+host_output_params = (
+ Flag('has_keytab',
+ label=_('Keytab'),
+ ),
+ Str('subject',
+ label=_('Subject'),
+ ),
+ Str('serial_number',
+ label=_('Serial Number'),
+ ),
+ Str('issuer',
+ label=_('Issuer'),
+ ),
+ Str('valid_not_before',
+ label=_('Not Before'),
+ ),
+ Str('valid_not_after',
+ label=_('Not After'),
+ ),
+ Str('md5_fingerprint',
+ label=_('Fingerprint (MD5)'),
+ ),
+ Str('sha1_fingerprint',
+ label=_('Fingerprint (SHA1)'),
+ ),
+ Str('revocation_reason?',
+ label=_('Revocation reason'),
+ )
+)
+
class host(LDAPObject):
"""
Host object.
@@ -199,6 +231,7 @@ class host_add(LDAPCreate):
Add a new host.
"""
+ has_output_params = LDAPCreate.has_output_params + host_output_params
msg_summary = _('Added host "%(value)s"')
takes_options = (
Flag('force',
@@ -241,6 +274,7 @@ class host_add(LDAPCreate):
# On the off-chance some other extension deletes this from the
# context, don't crash.
pass
+ set_certificate_attrs(entry_attrs)
return dn
api.register(host_add)
@@ -275,6 +309,31 @@ class host_del(LDAPDelete):
(service, hostname, realm) = split_principal(principal)
if hostname.lower() == fqdn:
api.Command['service_del'](principal)
+ (dn, entry_attrs) = ldap.get_entry(dn, ['usercertificate'])
+ if 'usercertificate' in entry_attrs:
+ cert = normalize_certificate(entry_attrs.get('usercertificate')[0])
+ try:
+ serial = unicode(x509.get_serial_number(cert, x509.DER))
+ try:
+ result = api.Command['cert_show'](unicode(serial))['result'
+]
+ if 'revocation_reason' not in result:
+ try:
+ api.Command['cert_revoke'](unicode(serial), revocation_reason=4)
+ except errors.NotImplementedError:
+ # some CA's might not implement revoke
+ pass
+ except errors.NotImplementedError:
+ # some CA's might not implement revoke
+ pass
+ except NSPRError, nsprerr:
+ if nsprerr.errno == -8183:
+ # If we can't decode the cert them proceed with
+ # removing the host.
+ self.log.info("Problem decoding certificate %s" % nsprerr.args[1])
+ else:
+ raise nsprerr
+
return dn
api.register(host_del)
@@ -285,6 +344,7 @@ class host_mod(LDAPUpdate):
Modify information about a host.
"""
+ has_output_params = LDAPUpdate.has_output_params + host_output_params
msg_summary = _('Modified host "%(value)s"')
takes_options = LDAPUpdate.takes_options + (
@@ -312,17 +372,33 @@ class host_mod(LDAPUpdate):
if 'krbprincipalaux' not in obj_classes:
obj_classes.append('krbprincipalaux')
entry_attrs['objectclass'] = obj_classes
- cert = entry_attrs.get('usercertificate')
+ cert = normalize_certificate(entry_attrs.get('usercertificate'))
if cert:
(dn, entry_attrs_old) = ldap.get_entry(dn, ['usercertificate'])
if 'usercertificate' in entry_attrs_old:
- # FIXME: what to do here? do we revoke the old cert?
- fmt = 'entry already has a certificate, serial number: %s' % (
- x509.get_serial_number(entry_attrs_old['usercertificate'][0], x509.DER)
- )
- raise errors.GenericError(format=fmt)
- # FIXME: decoding should be in normalizer; see service_add
- entry_attrs['usercertificate'] = base64.b64decode(cert)
+ oldcert = normalize_certificate(entry_attrs_old.get('usercertificate')[0])
+ try:
+ serial = unicode(x509.get_serial_number(oldcert, x509.DER))
+ try:
+ result = api.Command['cert_show'](unicode(serial))['result']
+ if 'revocation_reason' not in result:
+ try:
+ api.Command['cert_revoke'](unicode(serial), revocation_reason=4)
+ except errors.NotImplementedError:
+ # some CA's might not implement revoke
+ pass
+ except errors.NotImplementedError:
+ # some CA's might not implement revoke
+ pass
+ except NSPRError, nsprerr:
+ if nsprerr.errno == -8183:
+ # If we can't decode the cert them proceed with
+ # modifying the host.
+ self.log.info("Problem decoding certificate %s" % nsprerr.args[1])
+ else:
+ raise nsprerr
+
+ entry_attrs['usercertificate'] = cert
if 'random' in options:
if options.get('random'):
entry_attrs['userpassword'] = ipa_generate_password()
@@ -335,6 +411,7 @@ class host_mod(LDAPUpdate):
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
if options.get('random', False):
entry_attrs['randompassword'] = unicode(getattr(context, 'randompassword'))
+ set_certificate_attrs(entry_attrs)
return dn
api.register(host_mod)
@@ -345,6 +422,7 @@ class host_find(LDAPSearch):
Search for hosts.
"""
+ has_output_params = LDAPSearch.has_output_params + host_output_params
msg_summary = ngettext(
'%(count)d host matched', '%(count)d hosts matched'
)
@@ -355,6 +433,11 @@ class host_find(LDAPSearch):
attrs_list.append('l')
return filter.replace('locality', 'l')
+ def post_callback(self, ldap, entries, truncated, *args, **options):
+ for entry in entries:
+ entry_attrs = entry[1]
+ set_certificate_attrs(entry_attrs)
+
api.register(host_find)
@@ -362,35 +445,7 @@ class host_show(LDAPRetrieve):
"""
Display information about a host.
"""
- has_output_params = (
- Flag('has_keytab',
- label=_('Keytab'),
- ),
- Str('subject',
- label=_('Subject'),
- ),
- Str('serial_number',
- label=_('Serial Number'),
- ),
- Str('issuer',
- label=_('Issuer'),
- ),
- Str('valid_not_before',
- label=_('Not Before'),
- ),
- Str('valid_not_after',
- label=_('Not After'),
- ),
- Str('md5_fingerprint',
- label=_('Fingerprint (MD5)'),
- ),
- Str('sha1_fingerprint',
- label=_('Fingerprint (SHA1)'),
- ),
- Str('revocation_reason?',
- label=_('Revocation reason'),
- )
- )
+ has_output_params = LDAPRetrieve.has_output_params + host_output_params
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
if 'krblastpwdchange' in entry_attrs:
@@ -400,15 +455,7 @@ class host_show(LDAPRetrieve):
else:
entry_attrs['has_keytab'] = False
- if 'usercertificate' in entry_attrs:
- cert = x509.load_certificate(entry_attrs['usercertificate'][0], datatype=x509.DER)
- entry_attrs['subject'] = unicode(cert.subject)
- entry_attrs['serial_number'] = unicode(cert.serial_number)
- entry_attrs['issuer'] = unicode(cert.issuer)
- entry_attrs['valid_not_before'] = unicode(cert.valid_not_before_str)
- entry_attrs['valid_not_after'] = unicode(cert.valid_not_after_str)
- entry_attrs['md5_fingerprint'] = unicode(nss.data_to_hex(nss.md5_digest(cert.der_data), 64)[0])
- entry_attrs['sha1_fingerprint'] = unicode(nss.data_to_hex(nss.sha1_digest(cert.der_data), 64)[0])
+ set_certificate_attrs(entry_attrs)
return dn
@@ -420,19 +467,77 @@ class host_disable(LDAPQuery):
Disable the kerberos key of a host.
"""
has_output = output.standard_value
- msg_summary = _('Removed kerberos key from "%(value)s"')
+ msg_summary = _('Removed kerberos key and disabled all services for "%(value)s"')
def execute(self, *keys, **options):
ldap = self.obj.backend
+ # If we aren't given a fqdn, find it
+ if validate_host(None, keys[-1]) is not None:
+ hostentry = api.Command['host_show'](keys[-1])['result']
+ fqdn = hostentry['fqdn'][0]
+ else:
+ fqdn = keys[-1]
+
+ # See if we actually do anthing here, and if not raise an exception
+ done_work = False
+
dn = self.obj.get_dn(*keys, **options)
- (dn, entry_attrs) = ldap.get_entry(dn, ['krblastpwdchange'])
+ (dn, entry_attrs) = ldap.get_entry(dn, ['krblastpwdchange', 'usercertificate'])
- if 'krblastpwdchange' not in entry_attrs:
- error_msg = _('Host principal has no kerberos key')
- raise errors.NotFound(reason=error_msg)
+ truncated = True
+ while truncated:
+ try:
+ ret = api.Command['service_find'](fqdn)
+ truncated = ret['truncated']
+ services = ret['result']
+ except errors.NotFound:
+ break
+ else:
+ for entry_attrs in services:
+ principal = entry_attrs['krbprincipalname'][0]
+ (service, hostname, realm) = split_principal(principal)
+ if hostname.lower() == fqdn:
+ try:
+ api.Command['service_disable'](principal)
+ done_work = True
+ except errors.AlreadyInactive:
+ pass
+ if 'usercertificate' in entry_attrs:
+ cert = normalize_certificate(entry_attrs.get('usercertificate')[0])
+ try:
+ serial = unicode(x509.get_serial_number(cert, x509.DER))
+ try:
+ result = api.Command['cert_show'](unicode(serial))['result'
+]
+ if 'revocation_reason' not in result:
+ try:
+ api.Command['cert_revoke'](unicode(serial), revocation_reason=4)
+ except errors.NotImplementedError:
+ # some CA's might not implement revoke
+ pass
+ except errors.NotImplementedError:
+ # some CA's might not implement revoke
+ pass
+ except NSPRError, nsprerr:
+ if nsprerr.errno == -8183:
+ # If we can't decode the cert them proceed with
+ # disabling the host.
+ self.log.info("Problem decoding certificate %s" % nsprerr.args[1])
+ else:
+ raise nsprerr
+
+ # Remove the usercertificate altogether
+ ldap.update_entry(dn, {'usercertificate': None})
+ done_work = True
+
+ if 'krblastpwdchange' in entry_attrs:
+ ldap.remove_principal_key(dn)
+ api.Command['host_mod'](fqdn=keys[-1], setattr=u'enrolledby=')
+ done_work = True
- ldap.remove_principal_key(dn)
+ if not done_work:
+ raise errors.AlreadyInactive()
return dict(
result=True,
diff --git a/ipalib/plugins/service.py b/ipalib/plugins/service.py
index 8ccdaeac7..c65a7a4ac 100644
--- a/ipalib/plugins/service.py
+++ b/ipalib/plugins/service.py
@@ -87,6 +87,30 @@ output_params = (
Str('managedby_host',
label='Managed by',
),
+ Str('subject',
+ label=_('Subject'),
+ ),
+ Str('serial_number',
+ label=_('Serial Number'),
+ ),
+ Str('issuer',
+ label=_('Issuer'),
+ ),
+ Str('valid_not_before',
+ label=_('Not Before'),
+ ),
+ Str('valid_not_after',
+ label=_('Not After'),
+ ),
+ Str('md5_fingerprint',
+ label=_('Fingerprint (MD5)'),
+ ),
+ Str('sha1_fingerprint',
+ label=_('Fingerprint (SHA1)'),
+ ),
+ Str('revocation_reason?',
+ label=_('Revocation reason'),
+ )
)
def split_principal(principal):
@@ -171,6 +195,30 @@ def normalize_certificate(cert):
return cert
+def set_certificate_attrs(entry_attrs):
+ """
+ Set individual attributes from some values from a certificate.
+
+ entry_attrs is a dict of an entry
+
+ returns nothing
+ """
+ if not 'usercertificate' in entry_attrs:
+ return
+ if type(entry_attrs['usercertificate']) in (list, tuple):
+ cert = entry_attrs['usercertificate'][0]
+ else:
+ cert = entry_attrs['usercertificate']
+ cert = normalize_certificate(cert)
+ cert = x509.load_certificate(cert, datatype=x509.DER)
+ entry_attrs['subject'] = unicode(cert.subject)
+ entry_attrs['serial_number'] = unicode(cert.serial_number)
+ entry_attrs['issuer'] = unicode(cert.issuer)
+ entry_attrs['valid_not_before'] = unicode(cert.valid_not_before_str)
+ entry_attrs['valid_not_after'] = unicode(cert.valid_not_after_str)
+ entry_attrs['md5_fingerprint'] = unicode(nss.data_to_hex(nss.md5_digest(cert.der_data), 64)[0])
+ entry_attrs['sha1_fingerprint'] = unicode(nss.data_to_hex(nss.sha1_digest(cert.der_data), 64)[0])
+
class service(LDAPObject):
"""
@@ -313,6 +361,9 @@ class service_mod(LDAPUpdate):
entry_attrs['usercertificate'] = None
return dn
+ def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
+ set_certificate_attrs(entry_attrs)
+
api.register(service_mod)
@@ -348,6 +399,7 @@ class service_find(LDAPSearch):
del entry_attrs['krblastpwdchange']
else:
entry_attrs['has_keytab'] = False
+ set_certificate_attrs(entry_attrs)
api.register(service_find)
@@ -359,33 +411,6 @@ class service_show(LDAPRetrieve):
member_attributes = ['managedby']
takes_options = LDAPRetrieve.takes_options
- has_output_params = LDAPRetrieve.has_output_params + output_params + (
- Str('subject',
- label=_('Subject'),
- ),
- Str('serial_number',
- label=_('Serial Number'),
- ),
- Str('issuer',
- label=_('Issuer'),
- ),
- Str('valid_not_before',
- label=_('Not Before'),
- ),
- Str('valid_not_after',
- label=_('Not After'),
- ),
- Str('md5_fingerprint',
- label=_('Fingerprint (MD5)'),
- ),
- Str('sha1_fingerprint',
- label=_('Fingerprint (SHA1)'),
- ),
- Str('revocation_reason?',
- label=_('Revocation reason'),
- )
- )
-
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
if 'krblastpwdchange' in entry_attrs:
entry_attrs['has_keytab'] = True
@@ -394,15 +419,7 @@ class service_show(LDAPRetrieve):
else:
entry_attrs['has_keytab'] = False
- if 'usercertificate' in entry_attrs:
- cert = x509.load_certificate(entry_attrs['usercertificate'][0], datatype=x509.DER)
- entry_attrs['subject'] = unicode(cert.subject)
- entry_attrs['serial_number'] = unicode(cert.serial_number)
- entry_attrs['issuer'] = unicode(cert.issuer)
- entry_attrs['valid_not_before'] = unicode(cert.valid_not_before_str)
- entry_attrs['valid_not_after'] = unicode(cert.valid_not_after_str)
- entry_attrs['md5_fingerprint'] = unicode(nss.data_to_hex(nss.md5_digest(cert.der_data), 64)[0])
- entry_attrs['sha1_fingerprint'] = unicode(nss.data_to_hex(nss.sha1_digest(cert.der_data), 64)[0])
+ set_certificate_attrs(entry_attrs)
return dn
@@ -440,13 +457,44 @@ class service_disable(LDAPQuery):
ldap = self.obj.backend
dn = self.obj.get_dn(*keys, **options)
- (dn, entry_attrs) = ldap.get_entry(dn, ['krblastpwdchange'])
+ (dn, entry_attrs) = ldap.get_entry(dn, ['krblastpwdchange', 'usercertificate'])
+
+ # See if we do any work at all here and if not raise an exception
+ done_work = False
- if 'krblastpwdchange' not in entry_attrs:
- error_msg = _('Service principal has no kerberos key')
- raise errors.NotFound(reason=error_msg)
+ if 'usercertificate' in entry_attrs:
+ cert = normalize_certificate(entry_attrs.get('usercertificate')[0])
+ try:
+ serial = unicode(x509.get_serial_number(cert, x509.DER))
+ try:
+ result = api.Command['cert_show'](unicode(serial))['result']
+ if 'revocation_reason' not in result:
+ try:
+ api.Command['cert_revoke'](unicode(serial), revocation_reason=4)
+ except errors.NotImplementedError:
+ # some CA's might not implement revoke
+ pass
+ except errors.NotImplementedError:
+ # some CA's might not implement revoke
+ pass
+ except NSPRError, nsprerr:
+ if nsprerr.errno == -8183:
+ # If we can't decode the cert them proceed with
+ # disabling the service
+ self.log.info("Problem decoding certificate %s" % nsprerr.args[1])
+ else:
+ raise nsprerr
+
+ # Remove the usercertificate altogether
+ ldap.update_entry(dn, {'usercertificate': None})
+ done_work = True
+
+ if 'krblastpwdchange' in entry_attrs:
+ ldap.remove_principal_key(dn)
+ done_work = True
- ldap.remove_principal_key(dn)
+ if not done_work:
+ raise errors.AlreadyInactive()
return dict(
result=True,
diff --git a/tests/test_xmlrpc/test_host_plugin.py b/tests/test_xmlrpc/test_host_plugin.py
index 631a5de7d..283674c20 100644
--- a/tests/test_xmlrpc/test_host_plugin.py
+++ b/tests/test_xmlrpc/test_host_plugin.py
@@ -25,6 +25,7 @@ Test the `ipalib.plugins.host` module.
from ipalib import api, errors
from tests.test_xmlrpc.xmlrpc_test import Declarative, fuzzy_uuid
from tests.test_xmlrpc import objectclasses
+import base64
fqdn1 = u'testhost1.%s' % api.env.domain
@@ -35,6 +36,8 @@ service1dn = u'krbprincipalname=%s,cn=services,cn=accounts,%s' % (service1.lower
fqdn2 = u'shouldnotexist.%s' % api.env.domain
dn2 = u'fqdn=%s,cn=computers,cn=accounts,%s' % (fqdn2, api.env.basedn)
+servercert = 'MIICbzCCAdigAwIBAgICA/4wDQYJKoZIhvcNAQEFBQAwKTEnMCUGA1UEAxMeSVBBIFRlc3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTEwMDgwOTE1MDIyN1oXDTIwMDgwOTE1MDIyN1owKTEMMAoGA1UEChMDSVBBMRkwFwYDVQQDExBwdW1hLmdyZXlvYWsuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwYbfEOQPgGenPn9vt1JFKvWm/Je3y2tawGWA3LXDuqfFJyYtZ8ib3TcBUOnLk9WK5g2qCwHaNlei7bj8ggIfr5hegAVe10cun+wYErjnYo7hsHYd+57VZezeipWrXu+7NoNd4+c4A5lk4A/xJay9j3bYx2oOM8BEox4xWYoWge1ljPrc5JK46f0X7AGW4F2VhnKPnf8rwSuzI1U8VGjutyM9TWNy3m9KMWeScjyG/ggIpOjUDMV7HkJL0Di61lznR9jXubpiEC7gWGbTp84eGl/Nn9bgK1AwHfJ2lHwfoY4uiL7ge1gyP6EvuUlHoBzdb7pekiX28iePjW3iEG9IawIDAQABoyIwIDARBglghkgBhvhCAQEEBAMCBkAwCwYDVR0PBAQDAgUgMA0GCSqGSIb3DQEBBQUAA4GBACRESLemRV9BPxfEgbALuxH5oE8jQm8WZ3pm2pALbpDlAd9wQc3yVf6RtkfVthyDnM18bg7IhxKpd77/p3H8eCnS8w5MLVRda6ktUC6tGhFTS4QKAf0WyDGTcIgkXbeDw0OPAoNHivoXbIXIIRxlw/XgaSaMzJQDBG8iROsN4kCv'
+
class test_host(Declarative):
@@ -201,7 +204,8 @@ class test_host(Declarative):
dict(
desc='Update %r' % fqdn1,
- command=('host_mod', [fqdn1], dict(description=u'Updated host 1')),
+ command=('host_mod', [fqdn1], dict(description=u'Updated host 1',
+ usercertificate=servercert)),
expected=dict(
value=fqdn1,
summary=u'Modified host "%s"' % fqdn1,
@@ -210,6 +214,14 @@ class test_host(Declarative):
fqdn=[fqdn1],
l=[u'Undisclosed location 1'],
krbprincipalname=[u'host/%s@%s' % (fqdn1, api.env.realm)],
+ usercertificate=[base64.b64decode(servercert)],
+ valid_not_before=u'Mon Aug 09 15:02:27 2010 UTC',
+ valid_not_after=u'Sun Aug 09 15:02:27 2020 UTC',
+ subject=u'CN=puma.greyoak.com,O=IPA',
+ serial_number=u'1022',
+ md5_fingerprint=u'ef:63:31:e4:33:54:8d:fd:fe:c8:66:57:09:03:5f:09',
+ sha1_fingerprint=u'e3:33:2c:d9:7c:e9:77:74:2a:ac:3b:b8:76:b0:86:29:98:43:58:11',
+ issuer=u'CN=IPA Test Certificate Authority',
),
),
),
@@ -227,7 +239,15 @@ class test_host(Declarative):
description=[u'Updated host 1'],
l=[u'Undisclosed location 1'],
krbprincipalname=[u'host/%s@%s' % (fqdn1, api.env.realm)],
- has_keytab=False
+ has_keytab=False,
+ usercertificate=[base64.b64decode(servercert)],
+ valid_not_before=u'Mon Aug 09 15:02:27 2010 UTC',
+ valid_not_after=u'Sun Aug 09 15:02:27 2020 UTC',
+ subject=u'CN=puma.greyoak.com,O=IPA',
+ serial_number=u'1022',
+ md5_fingerprint=u'ef:63:31:e4:33:54:8d:fd:fe:c8:66:57:09:03:5f:09',
+ sha1_fingerprint=u'e3:33:2c:d9:7c:e9:77:74:2a:ac:3b:b8:76:b0:86:29:98:43:58:11',
+ issuer=u'CN=IPA Test Certificate Authority',
),
),
),
diff --git a/tests/test_xmlrpc/test_service_plugin.py b/tests/test_xmlrpc/test_service_plugin.py
index 1427169e1..fc8e08e9e 100644
--- a/tests/test_xmlrpc/test_service_plugin.py
+++ b/tests/test_xmlrpc/test_service_plugin.py
@@ -234,6 +234,13 @@ class test_host(Declarative):
usercertificate=[base64.b64decode(servercert)],
krbprincipalname=[service1],
managedby_host=[fqdn1],
+ valid_not_before=u'Mon Aug 09 15:02:27 2010 UTC',
+ valid_not_after=u'Sun Aug 09 15:02:27 2020 UTC',
+ subject=u'CN=puma.greyoak.com,O=IPA',
+ serial_number=u'1022',
+ md5_fingerprint=u'ef:63:31:e4:33:54:8d:fd:fe:c8:66:57:09:03:5f:09',
+ sha1_fingerprint=u'e3:33:2c:d9:7c:e9:77:74:2a:ac:3b:b8:76:b0:86:29:98:43:58:11',
+ issuer=u'CN=IPA Test Certificate Authority',
),
),
),