Exemplo n.º 1
0
 def check_domain(self, role, nameserver):
     result = {}
     if role == 'ad':
         try:
             ad_domain_info = lookup_adds_dc(nameserver)
             dc = ad_domain_info['DC DNS Name']
             if dc:
                 result['dc_name'] = dc
                 domain = ad_domain_info['Domain']
                 result['domain'] = domain
                 result['ucs_master'] = util.is_ucs_domain(
                     nameserver, domain)
                 ucs_master_fqdn = util.resolve_domaincontroller_master_srv_record(
                     nameserver, domain)
                 result['ucs_master_fqdn'] = ucs_master_fqdn
                 result['ucs_master_reachable'] = util.is_ssh_reachable(
                     ucs_master_fqdn)
         except (failedADConnect, connectionFailed) as exc:
             MODULE.warn('ADDS DC lookup failed: %s' % (exc, ))
     elif role == 'nonmaster':
         domain = util.get_ucs_domain(nameserver)
         if domain:
             fqdn = util.resolve_domaincontroller_master_srv_record(
                 nameserver, domain)
         else:
             fqdn = util.get_fqdn(nameserver)
         if fqdn:
             result['dc_name'] = fqdn
             domain = '.'.join(fqdn.split('.')[1:])
             result['ucs_master'] = util.is_ucs_domain(nameserver, domain)
     return result
    def check_domain(self, username, password, ad_server_address, mode):
        ad_domain_info = {}
        try:
            if mode == 'admember':
                admember.check_server_role()
            ad_domain_info = admember.lookup_adds_dc(ad_server_address)

            ad_server_ip = ad_domain_info['DC IP']
            if mode == 'admember':
                admember.check_domain(ad_domain_info)
            admember.check_connection(ad_domain_info, username, password)
            admember.check_ad_account(ad_domain_info, username, password)
        except admember.invalidUCSServerRole as exc:  # check_server_role()
            MODULE.warn('Failure: %s' % exc)
            raise UMC_Error(
                _('The AD member mode can only be configured on a DC master server.'
                  ))
        except admember.failedADConnect as exc:  # lookup_adds_dc()
            MODULE.warn('Failure: %s' % exc)
            raise UMC_Error(
                _('Could not connect to AD Server %s. Please verify that the specified address is correct. (%s)'
                  ) % (ad_server_address, 'check_domain: %s' % (exc, )))
        except admember.domainnameMismatch as exc:  # check_domain()
            MODULE.warn('Failure: %s' % exc)
            raise UMC_Error(
                _('The domain name of the AD Server (%(ad_domain)s) does not match the local UCS domain name (%(ucs_domain)s). For the AD member mode, it is necessary to setup a UCS system with the same domain name as the AD Server.'
                  ) % {
                      'ad_domain': ad_domain_info.get("Domain"),
                      'ucs_domain': ucr['domainname']
                  })
        except admember.connectionFailed as exc:  # check_connection()
            MODULE.warn('Failure: %s' % exc)
            raise UMC_Error(
                _('Could not connect to AD Server %s. Please verify that username and password are correct. (Details:\n%s)'
                  ) % (ad_domain_info.get('DC DNS Name'), exc))
        except admember.notDomainAdminInAD as exc:  # check_ad_account()
            MODULE.warn('Failure: %s' % exc)
            raise UMC_Error(
                _('The given user is not member of the Domain Admins group in Active Directory. This is a requirement for the Active Directory domain join.'
                  ))

        # final info dict that is returned... replace spaces in the keys with '_'
        MODULE.info('Preparing info dict...')
        info = dict([(key.replace(' ', '_'), value)
                     for key, value in ad_domain_info.iteritems()])
        info['ssl_supported'] = admember.server_supports_ssl(ad_server_ip)
        # try to get binddn
        info['LDAP_BindDN'] = get_ad_binddn_from_name(info['LDAP_Base'],
                                                      ad_server_ip, username,
                                                      password)
        MODULE.info(str(info))
        return info
Exemplo n.º 3
0
		def guess_domain(obj):
			for nameserver in ('nameserver1', 'nameserver2', 'nameserver3'):
				nameserver = obj.get(nameserver)
				if nameserver:
					guessed_domain = None
					if obj.get('ad/member') and obj.get('ad/address'):
						try:
							ad_domain_info = lookup_adds_dc(obj.get('ad/address'), ucr={'nameserver1': nameserver})
						except failedADConnect:
							pass
						else:
							guessed_domain = ad_domain_info['Domain']
					else:
						guessed_domain = util.get_ucs_domain(nameserver)
					if guessed_domain:
						return guessed_domain
Exemplo n.º 4
0
def check_credentials_ad(nameserver, address, username, password):
	try:
		ad_domain_info = lookup_adds_dc(address, ucr={'nameserver1': nameserver})
		check_connection(ad_domain_info, username, password)
		do_time_sync(address)
		check_ad_account(ad_domain_info, username, password)
	except failedADConnect:
		# Not checked... no AD!
		raise UMC_Error(_('The connection to the Active Directory server failed. Please recheck the address.'))
	except connectionFailed:
		# checked: failed!
		raise UMC_Error(_('The connection to the Active Directory server was refused. Please recheck the password.'))
	except notDomainAdminInAD:  # check_ad_account()
		# checked: Not a Domain Administrator!
		raise UMC_Error(_("The given user is not member of the Domain Admins group in Active Directory. This is a requirement for the Active Directory domain join."))
	else:
		return ad_domain_info['Domain']
Exemplo n.º 5
0
	def admember_join(self, username, password, ad_server_address, progress):
		progress.title = _('Joining UCS into Active Directory domain')
		progress.total = 100.0
		progress.warnings = []
		overall_success = False
		MODULE.process(progress.title)

		def _progress(steps, msg):
			progress.current = float(steps)
			progress.message = msg
			MODULE.process(msg)
			time.sleep(0.2)

		def _err(exc=None, msg=None):

			exc_str = ''
			if exc is not None:
				exc_str = str(exc) or exc.__doc__  # if no message, take the doc string
				exc_class_name = exc.__class__.__name__
				MODULE.error('Join process failed [%s]: %s' % (exc_class_name, exc_str))

			if msg:
				MODULE.error(msg)
			else:
				msg = _('An unexpected error occurred: %s') % exc_str

			progress.finish_with_result({
				'success': False,
				'error': msg,
				'warnings': progress.warnings,
			})

		ad_domain_info = {}
		try:
			admember.check_server_role()
			ad_domain_info = admember.lookup_adds_dc(ad_server_address)
			ad_server_ip = ad_domain_info['DC IP']

			_progress(5, _('Configuring time synchronization...'))
			admember.time_sync(ad_server_ip)
			admember.set_timeserver(ad_server_ip)

			_progress(10, _('Configuring DNS server...'))
			admember.set_nameserver([ad_server_ip])
			admember.prepare_ucr_settings()

			_progress(15, _('Configuring Kerberos settings...'))
			admember.disable_local_heimdal()
			admember.disable_local_samba4()

			_progress(20, _('Configuring reverse DNS settings...'))
			admember.prepare_dns_reverse_settings(ad_domain_info)

			_progress(25, _('Configuring software components...'))

			_step_offset = 30.0
			_nsteps = 35.0

			def _step_handler(step):
				MODULE.process('Package manager progress: %.1f' % step)
				progress.current = (step / 100.0) * _nsteps + _step_offset

			def _err_handler(err):
				MODULE.warn(err)
				progress.warnings.append(err)

			success = admember.remove_install_univention_samba(info_handler=MODULE.process, error_handler=_err_handler, step_handler=_step_handler)
			if not success:
				raise RuntimeError(_('An error occurred while installing necessary software components.'))

			_progress(65, _('Configuring synchronization from AD...'))
			admember.prepare_connector_settings(username, password, ad_domain_info)
			admember.disable_ssl()

			_progress(70, _('Renaming well known SID objects...'))
			admember.rename_well_known_sid_objects(username, password)

			_progress(75, _('Configuring Administrator account...'))
			admember.prepare_administrator(username, password)

			_progress(80, _('Running Samba join script...'))
			admember.run_samba_join_script(username, password)

			_progress(85, _('Configuring DNS entries...'))
			admember.add_domaincontroller_srv_record_in_ad(ad_server_ip, username, password)
			admember.add_host_record_in_ad(uid=username, bindpw=password, sso=True)

			admember.make_deleted_objects_readable_for_this_machine(username, password)
			admember.synchronize_account_position(ad_domain_info, username, password)

			_progress(90, _('Starting Active Directory connection service...'))
			admember.start_service('univention-ad-connector')

			_progress(95, _('Registering LDAP service entry...'))
			admember.add_admember_service_to_localhost()

			overall_success = True
			_progress(100, _('Join has been finished successfully.'))

		# error handling...
		except admember.invalidUCSServerRole as exc:
			_err(exc, _('The AD member mode can only be configured on a DC master server.'))
		except admember.failedADConnect as exc:
			_err(exc, _('Could not connect to AD Server %s. Please verify that the specified address is correct. (%s)') % (ad_domain_info.get('DC DNS Name'), 'admember_join: %s' % (exc,)))
		except admember.domainnameMismatch as exc:
			_err(exc, _('The domain name of the AD Server (%(ad_domain)s) does not match the local UCS domain name (%(ucs_domain)s). For the AD member mode, it is necessary to setup a UCS system with the same domain name as the AD Server.') % {'ad_domain': ad_domain_info["Domain"], 'ucs_domain': ucr['domainname']})
		except admember.connectionFailed as exc:
			_err(exc, _('Could not connect to AD Server %s. Please verify that username and password are correct. (Details:\n%s)') % (ad_domain_info.get('DC DNS Name'), exc))
		except admember.failedToSetAdministratorPassword as exc:
			_err(exc, _('Failed to set the password of the UCS Administrator to the Active Directory Administrator password.'))
		except admember.failedToCreateAdministratorAccount as exc:
			_err(exc, _('Failed to create the Administrator account in UCS.'))
		except admember.sambaSidNotSetForAdministratorAccount as exc:
			_err(exc, _('The sambaSID could not set for the Administrator account in UCS.'))
		except admember.failedToSearchForWellKnownSid as exc:
			_err(exc, _('Failed to search for the well known SID.'))
		except admember.failedToAddAdministratorAccountToDomainAdmins as exc:
			_err(exc, _('Failed to add the Administrator account to the Domain Admins group.'))
		except admember.timeSyncronizationFailed as exc:
			_err(exc, _('Could not synchronize the time between the UCS system and the Active Directory domain controller: %s') % exc)
		except RuntimeError as exc:
			_err(exc)
		except Exception as exc:
			# catch all other errors that are unlikely to occur
			_err(exc)
			MODULE.error('Traceback:\n%s' % traceback.format_exc())

		if not overall_success:
			_progress(100, _('Join has been finished with errors.'))
			admember.revert_ucr_settings()
			admember.revert_connector_settings()

		if hasattr(progress, 'result'):
			# some error probably occurred -> return the result in the progress
			return progress.result

		return {'success': success}
Exemplo n.º 6
0
    def validate(self, values=None, flavor=None):
        '''Validate the specified values given in the dict as option named "values".
		Return a dict (with variable names as key) of dicts with the structure:
		{ "valid": True/False, "message": "..." }'''

        # init variables
        messages = []
        values = values or {}
        orgValues = util.load_values()
        is_wizard_mode = flavor == 'wizard'

        # determine new system role
        newrole = values.get('server/role', orgValues.get('server/role', ''))
        ad_member = values.get('ad/member', orgValues.get('ad/member', ''))

        # mix original and new values
        allValues = copy.copy(values)
        for ikey, ival in orgValues.iteritems():
            if ikey not in allValues:
                allValues[ikey] = ival

        # helper functions
        # TODO: 'valid' is not correctly evaluated in frontend
        # i.e. if valid you may continue without getting message
        def _check(key, check, message, critical=True):
            if key not in values:
                return
            if not check(values[key]):
                messages.append({
                    'message': message,
                    'valid': not critical,
                    'key': key
                })

        def _append(key, message):
            MODULE.warn('Validation failed for key %s: %s' % (key, message))
            messages.append({'key': key, 'valid': False, 'message': message})

        # host and domain name
        packages = set(values.get('components', []))
        _check(
            'hostname', util.is_hostname,
            _('The hostname or the hostname part of the fully qualified domain name is invalid. Please go back to the host setting and make sure, that the hostname only contains letter (a-zA-Z) and digits (0-9).'
              ))

        hostname_length_critical = ad_member or 'univention-samba' in packages or 'univention-samba4' in packages
        appliance_str = _('the UCS system')
        if ucr['umc/web/appliance/name']:
            appliance_str = _('the %s appliance') % (
                ucr['umc/web/appliance/name'], )
        hostname_length_message = _(
            'A valid NetBIOS name can not be longer than 13 characters. If Samba is installed, the hostname should be shortened.'
        ) if hostname_length_critical else _(
            'The hostname %s is longer than 13 characters. It will not be possible to install an Active Directory compatible Domaincontroller (Samba 4) or UCS@school. The hostname cannot be changed after the installation of %s. It is recommended to shorten the hostname to maximal 13 characters.'
        ) % (
            values.get('hostname', ''),
            appliance_str,
        )
        _check('hostname',
               lambda x: len(x) <= 13,
               hostname_length_message,
               critical=hostname_length_critical)

        _check(
            'domainname', util.is_domainname,
            _("Please enter a valid fully qualified domain name (e.g. host.example.com)."
              ))
        hostname = allValues.get('hostname', '')
        domainname = allValues.get('domainname', '')
        if hostname or domainname:
            if len('%s%s' % (hostname, domainname)) >= 63:
                _append(
                    'domainname',
                    _('The length of fully qualified domain name is greater than 63 characters.'
                      ))
            if hostname == domainname.split('.')[0]:
                _append('domainname', _("Hostname is equal to domain name."))
        if is_wizard_mode and not util.is_system_joined():
            if newrole == 'domaincontroller_master' and not values.get(
                    'domainname'):
                _append(
                    'domainname',
                    _("No fully qualified domain name has been specified for the system."
                      ))
            elif not values.get('hostname'):
                _append('hostname',
                        _("No hostname has been specified for the system."))

        # windows domain
        _check(
            'windows/domain', lambda x: x == x.upper(),
            _("The windows domain name can only consist of upper case characters."
              ))
        _check(
            'windows/domain', lambda x: len(x) <= 15,
            _("The windows domain name cannot be longer than 15 characters."))
        _check('windows/domain', util.is_windowsdomainname,
               _("The windows domain name is not valid."))

        # LDAP base
        _check(
            'ldap/base', util.is_ldap_base,
            _("The LDAP base may neither contain blanks nor any special characters. Its structure needs to consist of at least two relative distinguished names (RDN) which may only use the attribute tags 'dc', 'cn', 'c', 'o', or 'l' (e.g., dc=test,dc=net)."
              ))

        # root password
        _check(
            'root_password', lambda x: len(x) >= 8,
            _("The root password is too short. For security reasons, your password must contain at least 8 characters."
              ))
        _check('root_password', util.is_ascii,
               _("The root password may only contain ascii characters."))

        # ssl + email
        labels = {
            'ssl/country': _('Country'),
            'ssl/state': _('State'),
            'ssl/locality': _('Location'),
            'ssl/organization': _('Organization'),
            'organization': _('Organization'),
            'ssl/organizationalunit': _('Business unit'),
            'ssl/email': _('Email address'),
            'email_address': _('Email address'),
            'ssl/common': _('Common name for the root SSL certificate'),
        }
        for maxlenth, keys in [
            (2, ('ssl/country', )), (128, (
                'ssl/state',
                'ssl/locality',
            )),
            (64, ('organization', 'ssl/organization', 'ssl/organizationalunit',
                  'ssl/email', 'email_address', 'ssl/common'))
        ]:
            for ikey in keys:
                _check(
                    ikey, lambda x: len(x) <= maxlenth,
                    _('The following value is too long, only %(max)s characters allowed: %(name)s'
                      ) % {
                          'max': maxlenth,
                          'name': labels[ikey]
                      })

        for ikey in ('ssl/country', 'ssl/state', 'ssl/locality',
                     'ssl/organization', 'ssl/organizationalunit', 'ssl/email',
                     'ssl/common'):
            for table in (stringprep.in_table_c21_c22, stringprep.in_table_a1,
                          stringprep.in_table_c8, stringprep.in_table_c3,
                          stringprep.in_table_c4, stringprep.in_table_c5,
                          lambda c: c == u'\ufffd'):
                _check(
                    ikey, lambda x: not any(map(table, unicode(x))),
                    _('The value for %s contains invalid characters.') %
                    (labels[ikey], ))

        _check('ssl/country', lambda x: len(x) == 2,
               _('Country must be a country code consisting of 2 characters.'))
        for ikey in ['ssl/email', 'email_address']:
            _check(ikey, lambda x: x.find('@') > 0,
                   _("Please enter a valid email address"))

        # net
        try:
            interfaces = network.Interfaces()
            interfaces.from_dict(allValues.get('interfaces', {}))
            interfaces.check_consistency()
        except network.DeviceError as exc:
            _append('interfaces', str(exc))

        # validate the primary network interface
        _check('interfaces/primary', lambda x: not x or x in interfaces,
               _('The primary network device must exist.'))

        # check nameservers
        for ikey, iname in [('nameserver[1-3]', _('Domain name server')),
                            ('dns/forwarder[1-3]', _('External name server'))]:
            reg = re.compile('^(%s)$' % ikey)
            for jkey, jval in values.iteritems():
                if reg.match(jkey):
                    if not values.get(jkey):
                        # allow empty value
                        continue
                    _check(
                        jkey, util.is_ipaddr,
                        _('The specified IP address (%(name)s) is not valid: %(value)s'
                          ) % {
                              'name': iname,
                              'value': jval
                          })

        if is_wizard_mode and not util.is_system_joined() and (
                newrole not in ['domaincontroller_master', 'basesystem']
                or ad_member):
            if all(nameserver in values and not values[nameserver]
                   for nameserver in ('nameserver1', 'nameserver2',
                                      'nameserver3')):
                # 'nameserver1'-key exists → widget is displayed → = not in UCS/debian installer mode
                if not any(interface.ip4dynamic or interface.ip6dynamic
                           for interface in interfaces.values()):
                    _append('nameserver1',
                            _('A domain name server needs to be specified.'))
                    # _append('nameserver1', _('At least one domain name server needs to be given if DHCP or SLAAC is not specified.'))

            # see whether the domain can be determined automatically
            ucr.load()
            guessed_domain = None
            for obj in [values, ucr]:
                for nameserver in ('nameserver1', 'nameserver2',
                                   'nameserver3'):
                    nameserver = obj.get(nameserver)
                    if nameserver:
                        guessed_domain = None
                        if obj.get('ad/member') and obj.get('ad/address'):
                            try:
                                ad_domain_info = lookup_adds_dc(
                                    obj.get('ad/address'),
                                    ucr={'nameserver1': nameserver})
                            except failedADConnect:
                                pass
                            else:
                                guessed_domain = ad_domain_info['Domain']
                        else:
                            guessed_domain = util.get_ucs_domain(nameserver)
                        if guessed_domain:
                            differing_domain_name = values.get(
                                'domainname') and values['domainname'].lower(
                                ) != guessed_domain.lower()
                            if differing_domain_name:
                                _append(
                                    'domainname',
                                    _('The specified domain name is different to the %s domain name found via the configured DNS server: %s'
                                      ) % (
                                          _('Active Directory')
                                          if ad_member else _('UCS'),
                                          guessed_domain,
                                      ))
                            else:
                                # communicate guessed domainname to frontend
                                messages.append({
                                    'valid': True,
                                    'key': 'domainname',
                                    'value': guessed_domain,
                                })
                            break
                if guessed_domain:
                    break
            if not guessed_domain:
                if not values.get('domainname'):
                    _append(
                        'domainname',
                        _('Cannot automatically determine the domain. Please specify the server\'s fully qualified domain name.'
                          ))

                if values.get('nameserver1') and values.get('start/join'):
                    _append(
                        'nameserver1',
                        _('The specified nameserver %s is not part of a valid UCS domain.'
                          ) % (values['nameserver1'], ))

        # check gateways
        if values.get('gateway'):  # allow empty value
            _check(
                'gateway', util.is_ipv4addr,
                _('The specified gateway IPv4 address is not valid: %s') %
                values.get('gateway'))
        if values.get('ipv6/gateway'):  # allow empty value
            _check(
                'ipv6/gateway', util.is_ipv6addr,
                _('The specified gateway IPv6 address is not valid: %s') %
                values.get('ipv6/gateway'))

        # proxy
        _check(
            'proxy/http', util.is_proxy,
            _('The specified proxy address is not valid (e.g., http://10.201.1.1:8080): %s'
              ) % allValues.get('proxy/http', ''))

        # software checks
        if 'univention-virtual-machine-manager-node-kvm' in packages and 'univention-virtual-machine-manager-node-xen' in packages:
            _append(
                'components',
                _('It is not possible to install KVM and XEN components on one system. Please select only one of these components.'
                  ))
        if 'univention-samba' in packages and 'univention-samba4' in packages:
            _append(
                'components',
                _('It is not possible to install Samba 3 and Samba 4 on one system. Please select only one of these components.'
                  ))

        return messages
Exemplo n.º 7
0
def auto_complete_values_for_join(newValues, current_locale=None):
    # try to automatically determine the domain, except on a dcmaster and basesystem
    if newValues[
            'server/role'] != 'domaincontroller_master' and not newValues.get(
                'domainname') and newValues['server/role'] != 'basesystem':
        ucr.load()
        for nameserver in ('nameserver1', 'nameserver2', 'nameserver3'):
            if newValues.get('domainname'):
                break
            newValues['domainname'] = get_ucs_domain(
                newValues.get(nameserver, ucr.get(nameserver)))
        if not newValues['domainname']:
            raise Exception(
                _('Cannot automatically determine the domain. Please specify the server\'s fully qualified domain name.'
                  ))

    # The check "and 'domainname' in newValues" is solely for basesystems
    isAdMember = 'ad/member' in newValues and 'ad/address' in newValues
    if 'windows/domain' not in newValues:
        if isAdMember:
            MODULE.process('Searching for NETBIOS domain in AD')
            for nameserver in ('nameserver1', 'nameserver2', 'nameserver3'):
                ns = newValues.get(nameserver, ucr.get(nameserver))
                if ns:
                    try:
                        ad_domain_info = lookup_adds_dc(
                            newValues.get('ad/address'),
                            ucr={'nameserver1': ns})
                    except failedADConnect:
                        pass
                    else:
                        newValues['windows/domain'] = ad_domain_info[
                            'Netbios Domain']
                        MODULE.process(
                            'Setting NETBIOS domain to AD value: %s' %
                            newValues['windows/domain'])
                        break

    if 'windows/domain' not in newValues and 'domainname' in newValues:
        newValues['windows/domain'] = domain2windowdomain(
            newValues.get('domainname'))
        MODULE.process('Setting NETBIOS domain to default: %s' %
                       newValues['windows/domain'])

    # make sure that AD connector package is installed if AD member mode is chosen
    selectedComponents = set(newValues.get('components', []))
    if isAdMember and newValues['server/role'] == 'domaincontroller_master':
        selectedComponents.add('univention-ad-connector')

    # make sure to install the memberof overlay if it is installed on the DC Master
    if newValues['server/role'] not in ('domaincontroller_master',
                                        'basesystem', 'memberserver'):
        if newValues.pop('install_memberof_overlay', None):
            selectedComponents.add('univention-ldap-overlay-memberof')

    # add lists with all packages that should be removed/installed on the system
    if selectedComponents:
        currentComponents = set()
        for iapp in get_apps():
            if iapp['is_installed']:
                for ipackages in (iapp['default_packages'],
                                  iapp['default_packages_master']):
                    currentComponents = currentComponents.union(ipackages)

        # set of all available software packages
        allComponents = set(['univention-ldap-overlay-memberof'])
        for iapp in get_apps():
            for ipackages in (iapp['default_packages'],
                              iapp['default_packages_master']):
                allComponents = allComponents.union(ipackages)

        # get all packages that shall be removed
        removeComponents = list(allComponents
                                & (currentComponents - selectedComponents))
        newValues['packages_remove'] = ' '.join(removeComponents)

        # get all packages that shall be installed
        installComponents = list(allComponents
                                 & (selectedComponents - currentComponents))
        newValues['packages_install'] = ' '.join(installComponents)

    current_locale = Locale(ucr.get('locale/default', 'en_US.UTF-8:UTF-8'))
    if newValues['server/role'] == 'domaincontroller_master':
        # add newValues for SSL UCR variables
        default_locale = current_locale
        if 'locale/default' in newValues:
            default_locale = Locale(newValues['locale/default'])
        newValues['ssl/state'] = default_locale.territory
        newValues['ssl/locality'] = default_locale.territory
        newValues['ssl/organization'] = newValues.get('organization',
                                                      default_locale.territory)
        newValues['ssl/organizationalunit'] = 'Univention Corporate Server'
        newValues['ssl/email'] = 'ssl@{domainname}'.format(**newValues)

    # make sure that the locale of the current session is also supported
    # ... otherwise the setup scripts will fail after regenerating the
    # locale data (in 20_language/10language) with some strange python
    # exceptions about unsupported locale strings...
    if 'locale' not in newValues:
        newValues['locale'] = newValues.get('locale/default', '')
    forcedLocales = ['en_US.UTF-8:UTF-8', 'de_DE.UTF-8:UTF-8'
                     ]  # we need en_US and de_DE locale as default language
    if current_locale:
        current_locale = '{0}:{1}'.format(str(current_locale),
                                          current_locale.codeset)
        forcedLocales.append(current_locale)
    for ilocale in forcedLocales:
        if ilocale not in newValues['locale']:
            newValues['locale'] = '%s %s' % (newValues['locale'], ilocale)

    return newValues