mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-01-26 16:16:31 -06:00
Add knob to limit hostname length
On Linux systems the length limit for hostnames is hardcoded at 64 in MAXHOSTNAMELEN Solaris, for example, allows 255 characters, and DNS allows the total length to be up to 255 (with each label < 64). Add a knob to allow configuring the maximum hostname length (FQDN) The same validators are used between hosts and DNS to apply the knob only when dealing with a FQDN as a hostname. The maxlen option is included so installers can limit the length of allowed hostnames when the --hostname option is used. https://pagure.io/freeipa/issue/2018 Signed-off-by: Rob Crittenden <rcritten@redhat.com> Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com> Reviewed-By: Christian Heimes <cheimes@redhat.com>
This commit is contained in:
parent
7fe10d9903
commit
6662e99e17
2
ACI.txt
2
ACI.txt
@ -61,7 +61,7 @@ aci: (targetattr = "cn || description || ipacertprofilestoreissued")(targetfilte
|
||||
dn: cn=certprofiles,cn=ca,dc=ipa,dc=example
|
||||
aci: (targetattr = "cn || createtimestamp || description || entryusn || ipacertprofilestoreissued || modifytimestamp || objectclass")(targetfilter = "(objectclass=ipacertprofile)")(version 3.0;acl "permission:System: Read Certificate Profiles";allow (compare,read,search) userdn = "ldap:///all";)
|
||||
dn: cn=ipaconfig,cn=etc,dc=ipa,dc=example
|
||||
aci: (targetattr = "cn || createtimestamp || entryusn || ipacertificatesubjectbase || ipaconfigstring || ipacustomfields || ipadefaultemaildomain || ipadefaultloginshell || ipadefaultprimarygroup || ipadomainresolutionorder || ipagroupobjectclasses || ipagroupsearchfields || ipahomesrootdir || ipakrbauthzdata || ipamaxusernamelength || ipamigrationenabled || ipapwdexpadvnotify || ipasearchrecordslimit || ipasearchtimelimit || ipaselinuxusermapdefault || ipaselinuxusermaporder || ipauserauthtype || ipauserobjectclasses || ipausersearchfields || modifytimestamp || objectclass")(targetfilter = "(objectclass=ipaguiconfig)")(version 3.0;acl "permission:System: Read Global Configuration";allow (compare,read,search) userdn = "ldap:///all";)
|
||||
aci: (targetattr = "cn || createtimestamp || entryusn || ipacertificatesubjectbase || ipaconfigstring || ipacustomfields || ipadefaultemaildomain || ipadefaultloginshell || ipadefaultprimarygroup || ipadomainresolutionorder || ipagroupobjectclasses || ipagroupsearchfields || ipahomesrootdir || ipakrbauthzdata || ipamaxhostnamelength || ipamaxusernamelength || ipamigrationenabled || ipapwdexpadvnotify || ipasearchrecordslimit || ipasearchtimelimit || ipaselinuxusermapdefault || ipaselinuxusermaporder || ipauserauthtype || ipauserobjectclasses || ipausersearchfields || modifytimestamp || objectclass")(targetfilter = "(objectclass=ipaguiconfig)")(version 3.0;acl "permission:System: Read Global Configuration";allow (compare,read,search) userdn = "ldap:///all";)
|
||||
dn: cn=costemplates,cn=accounts,dc=ipa,dc=example
|
||||
aci: (targetfilter = "(objectclass=costemplate)")(version 3.0;acl "permission:System: Add Group Password Policy costemplate";allow (add) groupdn = "ldap:///cn=System: Add Group Password Policy costemplate,cn=permissions,cn=pbac,dc=ipa,dc=example";)
|
||||
dn: cn=costemplates,cn=accounts,dc=ipa,dc=example
|
||||
|
3
API.txt
3
API.txt
@ -1075,7 +1075,7 @@ args: 0,1,1
|
||||
option: Str('version?')
|
||||
output: Output('result')
|
||||
command: config_mod/1
|
||||
args: 0,27,3
|
||||
args: 0,28,3
|
||||
option: Str('addattr*', cli_name='addattr')
|
||||
option: Flag('all', autofill=True, cli_name='all', default=False)
|
||||
option: Str('ca_renewal_master_server?', autofill=False)
|
||||
@ -1089,6 +1089,7 @@ option: Str('ipagroupobjectclasses*', autofill=False, cli_name='groupobjectclass
|
||||
option: IA5Str('ipagroupsearchfields?', autofill=False, cli_name='groupsearch')
|
||||
option: IA5Str('ipahomesrootdir?', autofill=False, cli_name='homedirectory')
|
||||
option: StrEnum('ipakrbauthzdata*', autofill=False, cli_name='pac_type', values=[u'MS-PAC', u'PAD', u'nfs:NONE'])
|
||||
option: Int('ipamaxhostnamelength?', autofill=False, cli_name='maxhostname')
|
||||
option: Int('ipamaxusernamelength?', autofill=False, cli_name='maxusername')
|
||||
option: Bool('ipamigrationenabled?', autofill=False, cli_name='enable_migration')
|
||||
option: Int('ipapwdexpadvnotify?', autofill=False, cli_name='pwdexpnotify')
|
||||
|
@ -83,8 +83,8 @@ define(IPA_DATA_VERSION, 20100614120000)
|
||||
# #
|
||||
########################################################
|
||||
define(IPA_API_VERSION_MAJOR, 2)
|
||||
define(IPA_API_VERSION_MINOR, 231)
|
||||
# Last change: Added admin creds to trust-fetch-domains
|
||||
define(IPA_API_VERSION_MINOR, 232)
|
||||
# Last change: Add ipamaxhostnamelength to config
|
||||
|
||||
|
||||
########################################################
|
||||
|
@ -43,11 +43,13 @@ attributeTypes: ( 2.16.840.1.113730.3.8.3.23 NAME 'ipaCertificateSubjectBase' SY
|
||||
attributeTypes: (2.16.840.1.113730.3.8.3.16 NAME 'ipaConfigString' DESC 'Generic configuration stirng' EQUALITY caseIgnoreMatch ORDERING caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'IPA v2' )
|
||||
attributeTypes: ( 2.16.840.1.113730.3.8.3.26 NAME 'ipaSELinuxUserMapDefault' DESC 'Default SELinux user' EQUALITY caseIgnoreMatch ORDERING caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'IPA v3')
|
||||
attributeTypes: ( 2.16.840.1.113730.3.8.3.27 NAME 'ipaSELinuxUserMapOrder' DESC 'Available SELinux user context ordering' EQUALITY caseIgnoreMatch ORDERING caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'IPA v3')
|
||||
## ipaMaxHostnameLength - maximum hostname length to allow
|
||||
attributeTypes: ( 2.16.840.1.113730.3.8.1.28 NAME 'ipaMaxHostnameLength' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE)
|
||||
###############################################
|
||||
##
|
||||
## ObjectClasses
|
||||
##
|
||||
## ipaGuiConfig - GUI config parameters objectclass
|
||||
objectClasses: ( 2.16.840.1.113730.3.8.2.1 NAME 'ipaGuiConfig' AUXILIARY MAY ( ipaUserSearchFields $ ipaGroupSearchFields $ ipaSearchTimeLimit $ ipaSearchRecordsLimit $ ipaCustomFields $ ipaHomesRootDir $ ipaDefaultLoginShell $ ipaDefaultPrimaryGroup $ ipaMaxUsernameLength $ ipaPwdExpAdvNotify $ ipaUserObjectClasses $ ipaGroupObjectClasses $ ipaDefaultEmailDomain $ ipaMigrationEnabled $ ipaCertificateSubjectBase $ ipaSELinuxUserMapDefault $ ipaSELinuxUserMapOrder $ ipaKrbAuthzData ) )
|
||||
objectClasses: ( 2.16.840.1.113730.3.8.2.1 NAME 'ipaGuiConfig' AUXILIARY MAY ( ipaUserSearchFields $ ipaGroupSearchFields $ ipaSearchTimeLimit $ ipaSearchRecordsLimit $ ipaCustomFields $ ipaHomesRootDir $ ipaDefaultLoginShell $ ipaDefaultPrimaryGroup $ ipaMaxUsernameLength $ ipaPwdExpAdvNotify $ ipaUserObjectClasses $ ipaGroupObjectClasses $ ipaDefaultEmailDomain $ ipaMigrationEnabled $ ipaCertificateSubjectBase $ ipaSELinuxUserMapDefault $ ipaSELinuxUserMapOrder $ ipaKrbAuthzData $ ipaMaxHostnameLength) )
|
||||
## ipaConfigObject - Generic config strings object holder
|
||||
objectClasses: (2.16.840.1.113730.3.8.4.13 NAME 'ipaConfigObject' DESC 'generic config object for IPA' AUXILIARY MAY ( ipaConfigString ) X-ORIGIN 'IPA v2' )
|
||||
|
@ -405,6 +405,7 @@ ipaHomesRootDir: /home
|
||||
ipaDefaultLoginShell: /bin/sh
|
||||
ipaDefaultPrimaryGroup: ipausers
|
||||
ipaMaxUsernameLength: 32
|
||||
ipaMaxHostnameLength: 64
|
||||
ipaPwdExpAdvNotify: 4
|
||||
ipaGroupObjectClasses: top
|
||||
ipaGroupObjectClasses: groupofnames
|
||||
|
@ -5,3 +5,4 @@ add:ipaUserObjectClasses: ipasshuser
|
||||
remove:ipaConfigString:AllowLMhash
|
||||
add:objectClass: ipaUserAuthTypeClass
|
||||
add:objectClass: ipaNameResolutionData
|
||||
addifnew:ipamaxhostnamelength: 64
|
||||
|
@ -33,7 +33,7 @@ from configparser import RawConfigParser
|
||||
from urllib.parse import urlparse, urlunparse
|
||||
|
||||
from ipalib import api, errors, x509
|
||||
from ipalib.constants import IPAAPI_USER
|
||||
from ipalib.constants import IPAAPI_USER, MAXHOSTNAMELEN
|
||||
from ipalib.install import certmonger, certstore, service, sysrestore
|
||||
from ipalib.install import hostname as hostname_
|
||||
from ipalib.install.kinit import kinit_keytab, kinit_password
|
||||
@ -42,6 +42,7 @@ from ipalib.rpc import delete_persistent_client_session_data
|
||||
from ipalib.util import (
|
||||
normalize_hostname,
|
||||
no_matching_interface_for_ip_address_warning,
|
||||
validate_hostname,
|
||||
verify_host_resolvable,
|
||||
)
|
||||
from ipaplatform import services
|
||||
@ -2119,6 +2120,13 @@ def install_check(options):
|
||||
"Invalid hostname, '{}' must not be used.".format(hostname),
|
||||
rval=CLIENT_INSTALL_ERROR)
|
||||
|
||||
try:
|
||||
validate_hostname(hostname, maxlen=MAXHOSTNAMELEN)
|
||||
except ValueError as e:
|
||||
raise ScriptError(
|
||||
'invalid hostname: {}'.format(e),
|
||||
rval=CLIENT_INSTALL_ERROR)
|
||||
|
||||
# --no-sssd is not supported any more for rhel-based distros
|
||||
if not tasks.is_nosssd_supported() and not options.sssd:
|
||||
raise ScriptError(
|
||||
|
@ -289,6 +289,9 @@ RENEWAL_REUSE_CA_NAME = 'dogtag-ipa-ca-renew-agent-reuse'
|
||||
# How long dbus clients should wait for CA certificate RPCs [seconds]
|
||||
CA_DBUS_TIMEOUT = 120
|
||||
|
||||
# Maximum hostname length in Linux
|
||||
MAXHOSTNAMELEN = 64
|
||||
|
||||
# regexp definitions
|
||||
PATTERN_GROUPUSER_NAME = (
|
||||
'(?!^[0-9]+$)^[a-zA-Z0-9_.][a-zA-Z0-9_.-]*[a-zA-Z0-9_.$-]?$'
|
||||
|
@ -434,14 +434,28 @@ def validate_zonemgr_str(zonemgr):
|
||||
zonemgr = DNSName(zonemgr)
|
||||
return validate_zonemgr(zonemgr)
|
||||
|
||||
def validate_hostname(hostname, check_fqdn=True, allow_underscore=False, allow_slash=False):
|
||||
|
||||
def validate_hostname(hostname, check_fqdn=True, allow_underscore=False,
|
||||
allow_slash=False, maxlen=255):
|
||||
""" See RFC 952, 1123
|
||||
|
||||
Length limit of 64 imposed by MAXHOSTNAMELEN on Linux.
|
||||
|
||||
DNS and other operating systems has a max length of 255. Default to
|
||||
the theoretical max unless explicitly told to limit. The cases
|
||||
where a limit would be set might include:
|
||||
* *-install --hostname
|
||||
* ipa host-add
|
||||
|
||||
The *-install commands by definition are executed on Linux hosts so
|
||||
the maximum length needs to be limited.
|
||||
|
||||
:param hostname Checked value
|
||||
:param check_fqdn Check if hostname is fully qualified
|
||||
"""
|
||||
if len(hostname) > 255:
|
||||
raise ValueError(_('cannot be longer that 255 characters'))
|
||||
if len(hostname) > maxlen:
|
||||
raise ValueError(_('cannot be longer that {} characters'.format(
|
||||
maxlen)))
|
||||
|
||||
if hostname.endswith('.'):
|
||||
hostname = hostname[:-1]
|
||||
@ -1029,9 +1043,16 @@ def normalize_hostname(hostname):
|
||||
return hostname
|
||||
|
||||
|
||||
def hostname_validator(ugettext, value):
|
||||
def hostname_validator(ugettext, value, maxlen=255):
|
||||
"""Validator used by plugins to ensure hostname compliance.
|
||||
|
||||
In Linux the maximum hostname length is 64. In DNS and
|
||||
other operaring systems (Solaris) it is 255. If not explicitly
|
||||
checking a Linux hostname (e.g. the server) use the DNS
|
||||
default.
|
||||
"""
|
||||
try:
|
||||
validate_hostname(value)
|
||||
validate_hostname(value, maxlen=maxlen)
|
||||
except ValueError as e:
|
||||
return _('invalid domain-name: %s') % unicode(e)
|
||||
|
||||
|
@ -50,6 +50,7 @@ import ipaplatform
|
||||
from ipapython import ipautil, admintool, version, ipaldap
|
||||
from ipapython.admintool import ScriptError, SERVER_NOT_CONFIGURED # noqa: E402
|
||||
from ipapython.certdb import EXTERNAL_CA_TRUST_FLAGS
|
||||
from ipalib.constants import MAXHOSTNAMELEN
|
||||
from ipalib.util import validate_hostname
|
||||
from ipalib import api, errors, x509
|
||||
from ipapython.dn import DN
|
||||
@ -154,7 +155,7 @@ def verify_fqdn(host_name, no_host_dns=False, local_hostname=True):
|
||||
|
||||
try:
|
||||
# make sure that the host name meets the requirements in ipalib
|
||||
validate_hostname(host_name)
|
||||
validate_hostname(host_name, maxlen=MAXHOSTNAMELEN)
|
||||
except ValueError as e:
|
||||
raise BadHostError("Invalid hostname '%s', %s" % (host_name, unicode(e)))
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
from ipalib import api
|
||||
from ipalib import Bool, Int, Str, IA5Str, StrEnum, DNParam
|
||||
from ipalib import errors
|
||||
from ipalib.constants import MAXHOSTNAMELEN
|
||||
from ipalib.plugable import Registry
|
||||
from ipalib.util import validate_domain_name
|
||||
from .baseldap import (
|
||||
@ -59,6 +60,12 @@ Password plug-in features: currently defines additional hashes that the
|
||||
When setting the order list for mapping SELinux users you may need to
|
||||
quote the value so it isn't interpreted by the shell.
|
||||
|
||||
The maximum length of a hostname in Linux is controlled by
|
||||
MAXHOSTNAMELEN in the kernel and defaults to 64. Some other operating
|
||||
systems, Solaris for example, allows hostnames up to 255 characters.
|
||||
This option will allow flexibility in length but by default limiting
|
||||
to the Linux maximum length.
|
||||
|
||||
EXAMPLES:
|
||||
|
||||
Show basic server configuration:
|
||||
@ -70,6 +77,9 @@ EXAMPLES:
|
||||
Change maximum username length to 99 characters:
|
||||
ipa config-mod --maxusername=99
|
||||
|
||||
Change maximum host name length to 255 characters:
|
||||
ipa config-mod --maxhostname=255
|
||||
|
||||
Increase default time and size limits for maximum IPA server search:
|
||||
ipa config-mod --searchtimelimit=10 --searchrecordslimit=2000
|
||||
|
||||
@ -110,7 +120,7 @@ class config(LDAPObject):
|
||||
'ipamigrationenabled', 'ipacertificatesubjectbase',
|
||||
'ipapwdexpadvnotify', 'ipaselinuxusermaporder',
|
||||
'ipaselinuxusermapdefault', 'ipaconfigstring', 'ipakrbauthzdata',
|
||||
'ipauserauthtype', 'ipadomainresolutionorder'
|
||||
'ipauserauthtype', 'ipadomainresolutionorder', 'ipamaxhostnamelength',
|
||||
]
|
||||
container_dn = DN(('cn', 'ipaconfig'), ('cn', 'etc'))
|
||||
permission_filter_objectclasses = ['ipaguiconfig']
|
||||
@ -132,6 +142,7 @@ class config(LDAPObject):
|
||||
'ipasearchrecordslimit', 'ipasearchtimelimit',
|
||||
'ipauserauthtype', 'ipauserobjectclasses',
|
||||
'ipausersearchfields', 'ipacustomfields',
|
||||
'ipamaxhostnamelength',
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -146,6 +157,11 @@ class config(LDAPObject):
|
||||
minvalue=1,
|
||||
maxvalue=255,
|
||||
),
|
||||
Int('ipamaxhostnamelength',
|
||||
cli_name='maxhostname',
|
||||
label=_('Maximum hostname length'),
|
||||
minvalue=MAXHOSTNAMELEN,
|
||||
maxvalue=255,),
|
||||
IA5Str('ipahomesrootdir',
|
||||
cli_name='homedirectory',
|
||||
label=_('Home directory base'),
|
||||
|
@ -653,6 +653,15 @@ class host_add(LDAPCreate):
|
||||
|
||||
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
config = ldap.get_ipa_config()
|
||||
if 'ipamaxhostnamelength' in config:
|
||||
maxlen = int(config.get('ipamaxhostnamelength')[0])
|
||||
if len(keys[-1]) > maxlen:
|
||||
raise errors.ValidationError(
|
||||
name=self.obj.primary_key.cli_name,
|
||||
error=_('can be at most %(len)d characters' %
|
||||
dict(len=maxlen))
|
||||
)
|
||||
if options.get('ip_address') and dns_container_exists(ldap):
|
||||
parts = keys[-1].split('.')
|
||||
host = parts[0]
|
||||
@ -762,7 +771,9 @@ class host_del(LDAPDelete):
|
||||
def pre_callback(self, ldap, dn, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
# If we aren't given a fqdn, find it
|
||||
if hostname_validator(None, keys[-1]) is not None:
|
||||
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:
|
||||
|
Loading…
Reference in New Issue
Block a user