From 133a0f07976e56323ffb8d4996d4cf21c3263a91 Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Mar 19 2012 15:09:20 +0000 Subject: Don't allow hosts and services of IPA masters to be disabled. https://fedorahosted.org/freeipa/ticket/2487 --- diff --git a/ipalib/plugins/baseldap.py b/ipalib/plugins/baseldap.py index 9562ff9..92540d8 100644 --- a/ipalib/plugins/baseldap.py +++ b/ipalib/plugins/baseldap.py @@ -396,7 +396,7 @@ def host_is_master(ldap, fqdn): master_dn = str(DN('cn=%s' % fqdn, 'cn=masters,cn=ipa,cn=etc', api.env.basedn)) try: (dn, entry_attrs) = ldap.get_entry(master_dn, ['objectclass']) - raise errors.ValidationError(name='hostname', error=_('An IPA master host cannot be deleted')) + raise errors.ValidationError(name='hostname', error=_('An IPA master host cannot be deleted or disabled')) except errors.NotFound: # Good, not a master return diff --git a/ipalib/plugins/host.py b/ipalib/plugins/host.py index 9db98e7..662cff3 100644 --- a/ipalib/plugins/host.py +++ b/ipalib/plugins/host.py @@ -850,6 +850,8 @@ class host_disable(LDAPQuery): else: fqdn = keys[-1] + host_is_master(ldap, fqdn) + # See if we actually do anthing here, and if not raise an exception done_work = False diff --git a/ipalib/plugins/service.py b/ipalib/plugins/service.py index e75d71f..7c563b3 100644 --- a/ipalib/plugins/service.py +++ b/ipalib/plugins/service.py @@ -200,6 +200,18 @@ def set_certificate_attrs(entry_attrs): 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]) +def check_required_principal(ldap, hostname, service): + """ + Raise an error if the host of this prinicipal is an IPA master and one + of the principals required for proper execution. + """ + try: + host_is_master(ldap, hostname) + except errors.ValidationError, e: + service_types = ['HTTP', 'ldap', 'DNS' 'dogtagldap'] + if service in service_types: + raise errors.ValidationError(name='principal', error=_('This principal is required by the IPA master')) + class service(LDAPObject): """ Service object. @@ -296,12 +308,7 @@ class service_del(LDAPDelete): # deleted. This is a limited few though. If the user has their own # custom services allow them to manage them. (service, hostname, realm) = split_principal(keys[-1]) - try: - host_is_master(ldap, hostname) - except errors.ValidationError, e: - service_types = ['HTTP', 'ldap', 'DNS' 'dogtagldap'] - if service in service_types: - raise errors.ValidationError(name='principal', error=_('This principal is required by the IPA master')) + check_required_principal(ldap, hostname, service) if self.api.env.enable_ra: (dn, entry_attrs) = ldap.get_entry(dn, ['usercertificate']) cert = entry_attrs.get('usercertificate') @@ -465,6 +472,9 @@ class service_disable(LDAPQuery): dn = self.obj.get_dn(*keys, **options) (dn, entry_attrs) = ldap.get_entry(dn, ['usercertificate']) + (service, hostname, realm) = split_principal(keys[-1]) + check_required_principal(ldap, hostname, service) + # See if we do any work at all here and if not raise an exception done_work = False diff --git a/tests/test_xmlrpc/test_host_plugin.py b/tests/test_xmlrpc/test_host_plugin.py index 7068d9a..8f5bd7c 100644 --- a/tests/test_xmlrpc/test_host_plugin.py +++ b/tests/test_xmlrpc/test_host_plugin.py @@ -673,9 +673,17 @@ class test_host(Declarative): dict( desc='Delete the current host (master?) %s should be caught' % api.env.host, command=('host_del', [api.env.host], {}), - expected=errors.ValidationError(name='fqdn', error='An IPA master host cannot be deleted'), + expected=errors.ValidationError(name='fqdn', error='An IPA master host cannot be deleted or disabled'), ), + + dict( + desc='Disable the current host (master?) %s should be caught' % api.env.host, + command=('host_disable', [api.env.host], {}), + expected=errors.ValidationError(name='fqdn', error='An IPA master host cannot be deleted or disabled'), + ), + + dict( desc='Test that validation is enabled on adds', command=('host_add', [invalidfqdn1], {}), diff --git a/tests/test_xmlrpc/test_service_plugin.py b/tests/test_xmlrpc/test_service_plugin.py index 7eccd20..501cf02 100644 --- a/tests/test_xmlrpc/test_service_plugin.py +++ b/tests/test_xmlrpc/test_service_plugin.py @@ -487,4 +487,18 @@ class test_service(Declarative): ), + dict( + desc='Disable the current host (master?) %s HTTP service, should be caught' % api.env.host, + command=('service_disable', ['HTTP/%s' % api.env.host], {}), + expected=errors.ValidationError(name='principal', error='This principal is required by the IPA master'), + ), + + + dict( + desc='Disable the current host (master?) %s ldap service, should be caught' % api.env.host, + command=('service_disable', ['ldap/%s' % api.env.host], {}), + expected=errors.ValidationError(name='principal', error='This principal is required by the IPA master'), + ), + + ]