host: try to resolve FQDN before command execution

Trying to resolve the FQDN before command execution (during
pre-callback) helps detect cases where the host specified by the user
does not exist, saving execution time. Aside from this, resolving the
FQDN is useful when only the shortname of the host is passed, as this
would cause issues when trying to update the DNS records during
modification of the entry.

Fixes: https://pagure.io/freeipa/issue/8726
Fixes: https://pagure.io/freeipa/issue/8884
Signed-off-by: Antonio Torres <antorres@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
This commit is contained in:
Antonio Torres 2021-06-15 12:47:43 +02:00 committed by Rob Crittenden
parent 50306cc636
commit 3a4939fa39

View File

@ -252,6 +252,11 @@ def validate_ipaddr(ugettext, ipaddr):
return None return None
def resolve_fqdn(name):
hostentry = api.Command['host_show'](name)['result']
return hostentry['fqdn'][0]
class HostPassword(Str): class HostPassword(Str):
""" """
A data type for host passwords to not log password values A data type for host passwords to not log password values
@ -795,14 +800,7 @@ class host_del(LDAPDelete):
def pre_callback(self, ldap, dn, *keys, **options): def pre_callback(self, ldap, dn, *keys, **options):
assert isinstance(dn, DN) assert isinstance(dn, DN)
# If we aren't given a fqdn, find it fqdn = resolve_fqdn(keys[-1])
config = ldap.get_ipa_config()
maxlen = int(config.get('ipamaxhostnamelength')[0])
if hostname_validator(None, keys[-1], maxlen=maxlen) is not None:
hostentry = api.Command['host_show'](keys[-1])['result']
fqdn = hostentry['fqdn'][0]
else:
fqdn = keys[-1]
host_is_master(ldap, fqdn) host_is_master(ldap, fqdn)
# Remove all service records for this host # Remove all service records for this host
truncated = True truncated = True
@ -894,6 +892,7 @@ class host_mod(LDAPUpdate):
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options): def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
assert isinstance(dn, DN) assert isinstance(dn, DN)
fqdn = resolve_fqdn(keys[-1])
# Allow an existing OTP to be reset but don't allow a OTP to be # Allow an existing OTP to be reset but don't allow a OTP to be
# added to an enrolled host. # added to an enrolled host.
if options.get('userpassword') or options.get('random'): if options.get('userpassword') or options.get('random'):
@ -959,7 +958,7 @@ class host_mod(LDAPUpdate):
entry_attrs['objectclass'] = obj_classes entry_attrs['objectclass'] = obj_classes
if options.get('updatedns', False) and dns_container_exists(ldap): if options.get('updatedns', False) and dns_container_exists(ldap):
parts = keys[-1].split('.') parts = fqdn.split('.')
domain = unicode('.'.join(parts[1:])) domain = unicode('.'.join(parts[1:]))
try: try:
result = api.Command['dnszone_show'](domain)['result'] result = api.Command['dnszone_show'](domain)['result']
@ -1190,13 +1189,7 @@ class host_disable(LDAPQuery):
def execute(self, *keys, **options): def execute(self, *keys, **options):
ldap = self.obj.backend ldap = self.obj.backend
# If we aren't given a fqdn, find it fqdn = resolve_fqdn(keys[-1])
if hostname_validator(None, keys[-1]) is not None:
hostentry = api.Command['host_show'](keys[-1])['result']
fqdn = hostentry['fqdn'][0]
else:
fqdn = keys[-1]
host_is_master(ldap, fqdn) host_is_master(ldap, fqdn)
# See if we actually do anthing here, and if not raise an exception # See if we actually do anthing here, and if not raise an exception