def __init__(self): ucr.load() self._is_master = ucr.get('server/role') == 'domaincontroller_master' self._updates_available = ucr.is_true('update/available') self._fqdn = '%s.%s' % (ucr.get('hostname'), ucr.get('domainname')) message = '\n'.join(self._error_msg()) super(LDAP_ServerDown, self).__init__(message, status=503)
def query_maintenance_information(self): ucr.load() if ucr.is_true('license/extended_maintenance/disable_warning'): return {'show_warning': False} version = self.uu.get_ucs_version() try: url = 'http://updates.software-univention.de/download/ucs-maintenance/{}.yaml'.format( version) response = requests.get(url, timeout=10) if not response.ok: response.raise_for_status() status = yaml.load(response.content) if not isinstance(status, dict): raise yaml.YAMLError(repr(status)) # the yaml file contains for maintained either false, true or extended as value. # yaml.load converts true and false into booleans but extended into string. _maintained_status = status.get('maintained') maintenance_extended = _maintained_status == 'extended' show_warning = maintenance_extended or not _maintained_status except yaml.YAMLError as exc: MODULE.error('The YAML format is malformed: %s' % (exc, )) return {'show_warning': False} except requests.exceptions.RequestException as exc: MODULE.error("Querying maintenance information failed: %s" % (exc, )) return {'show_warning': False} return { 'ucs_version': version, 'show_warning': show_warning, 'maintenance_extended': maintenance_extended, 'base_dn': ucr.get('license/base') }
def run(_umc_instance): ucr.load() failed = [] fqdn = ".".join((ucr['hostname'], ucr['domainname'])) hostnames = { 'www.univention.de': ('dns/forwarder1', 'dns/forwarder2', 'dns/forwarder3'), fqdn: ('nameserver1', 'nameserver2', 'nameserver3') } for hostname, nameservers in hostnames.items(): for nameserver in nameservers: if not ucr.get(nameserver): continue MODULE.process("Trying %s to resolve %s" % (ucr[nameserver], hostname)) MODULE.process("Similar to running: dig +short %s @%s" % (hostname, ucr[nameserver])) try: query_dns_server(ucr[nameserver], hostname) except DNSException as exc: msgs = ['\n', _('The nameserver %(nameserver)s (UCR variable %(var)r) is not responsive:') % {'nameserver': ucr[nameserver], 'var': nameserver}] if isinstance(exc, Timeout): msgs.append(_('A timeout occurred while reaching the nameserver (is it online?).')) else: msgs.append('%s' % (exc,)) failed.append('\n'.join(msgs)) if failed: MODULE.error('%s%s' % (description % (len(failed),), '\n'.join(failed))) raise Warning('%s%s' % (description % (len(failed),), '\n'.join(failed)))
def query_releases(self): """ Returns a list of system releases suitable for the corresponding ComboBox """ # be as current as possible. self.uu.ucr_reinit() ucr.load() appliance_mode = ucr.is_true('server/appliance') available_versions, blocking_components = self.uu.get_all_available_release_updates( ) result = [{ 'id': rel, 'label': 'UCS %s' % (rel, ) } for rel in available_versions] # # appliance_mode=no ; blocking_comp=no → add "latest version" # appliance_mode=no ; blocking_comp=yes → no "latest version" # appliance_mode=yes; blocking_comp=no → add "latest version" # appliance_mode=yes; blocking_comp=yes → add "latest version" # if result and (appliance_mode or not blocking_components): # UniventionUpdater returns available version in ascending order, so # the last returned entry is the one to be flagged as 'latest' if there's # no blocking component. result[-1]['label'] = '%s (%s)' % (result[-1]['label'], _('latest version')) return result
def send_verification_token(self, username): MODULE.info("send_verification_token(): username: {}".format(username)) ucr.load() if ucr.is_false('umc/self-service/account-verification/backend/enabled', True): msg = _('The account verification was disabled via the Univention Configuration Registry.') MODULE.error('send_verification_token(): {}'.format(msg)) raise UMC_Error(msg) invalid_information = { 'success': False, 'failType': 'INVALID_INFORMATION' } users_mod = UDM.machine().version(2).get('users/user') try: user = users_mod.get_by_id(username) except NoObject: return invalid_information try: email = user.props.PasswordRecoveryEmail except AttributeError: return invalid_information else: if not email: return invalid_information self.send_message(username, 'verify_email', email, raise_on_success=False) return { 'success': True, 'data': { 'username': username, } }
def run(_umc_instance): if util.is_service_active('LDAP'): ucr.load() if not ucr.is_true('ldap/overlay/memberof'): MODULE.error(warning_message) raise Warning(description=warning_message) return
def get_registration_attributes(self): ucr.load() property_ids = ['PasswordRecoveryEmail', 'password'] for id_ in [attr.strip() for attr in ucr.get('umc/self-service/account-registration/udm_attributes', '').split(',') if attr.strip()]: if id_ not in property_ids: property_ids.append(id_) lo, po = get_machine_connection() users_mod = UDM_Module('users/user', True, lo, po) properties = {prop['id']: prop for prop in users_mod.properties(None)} not_existing = set(property_ids) - set(properties.keys()) properties = {k: v for (k, v) in properties.items() if 'dynamicValues' not in v and 'udm' not in v['type']} # filter out not supported props not_supported = set(property_ids) - set(properties.keys()) - not_existing if 'PasswordRecoveryEmail' in properties: properties['PasswordRecoveryEmail']['label'] = _('Email') properties['PasswordRecoveryEmail']['description'] = '' self._update_required_attr_of_props_for_registration(properties) properties = [properties[id_] for id_ in property_ids if id_ in properties] if not_existing: MODULE.warn("get_registration_attributes(): the following attributes defined by umc/self-service/account-registration/udm_attributes do not exist on users/user: {}".format(", ".join(not_existing))) if not_supported: MODULE.warn("get_registration_attributes(): the following attributes defined by umc/self-service/account-registration/udm_attributes are not supported: {}".format(", ".join(not_supported))) return { 'widget_descriptions': properties, 'layout': [prop['id'] for prop in properties], }
def run(_umc_instance): ucr.load() if ucr.is_true('diagnostic/check/disable/59_ldap_server_name') or ucr.get('server/role') != 'memberserver': return ldap_server_name = ucr.get('ldap/server/name') domainname = ucr.get('domainname') lo = univention.uldap.getMachineConnection() master = lo.search(base=ucr.get('ldap/base'), filter='(univentionServerRole=master)', attr=['cn']) try: master_cn = master[0][1].get('cn')[0].decode('UTF-8') except IndexError: raise Critical('Could not find a Primary Directory Node %s' % (master,)) master_fqdn = '.'.join([master_cn, domainname]) if master_fqdn == ldap_server_name: res = lo.searchDn(base=ucr.get('ldap/base'), filter='univentionServerRole=backup') # Case: ldap/server/name is the Primary Directory Node and there are Backup Directory Nodes available. if res: button = [{ 'action': 'deactivate_test', 'label': _('Deactivate test'), }] warn = (_('The primary LDAP Server of this System (UCR ldap/server/name) is set to the Primary Directory Node of this UCS domain (%s).\nSince this environment provides further LDAP Servers, we recommend a different configuration to reduce the load on the Primary Directory Node.\nPlease see {sdb} for further information.') % (master_fqdn,)) raise Warning(warn, buttons=button)
def query(self, pattern): ucr.load() srvs = ServiceInfo() lang = _.im_self.locale.language if lang in (None, 'C'): lang = 'en' result = [] for name, srv in srvs.services.items(): key = srv.get('start_type', '%s/autostart' % (name, )) entry = { 'service': name, 'description': srv.get('description[%s]' % (lang, ), srv.get('description')), 'autostart': ucr.get(key, 'yes'), 'isRunning': srv.running, } if entry['autostart'] not in ('yes', 'no', 'manually'): entry['autostart'] = 'yes' for value in entry.values(): if pattern.match(str(value)): result.append(entry) break return result
def findUCRVariables(filterName=None, userRule=False): '''Returns a dict of all UCR variables or all variables matching the specified rule name.''' # refresh internal UCR cache ucr.load() # iterate over all UCR variables vars = {} for k, v in ucr.items(): imatch = _regFilterNames.match(k) if imatch: # we found a filter variable iname = imatch.group('name') if not iname or (filterName is not None and filterName != iname): # empty name or name does not match the specified filter continue # see whether this is a user specific rule or a general rule if userRule != bool(imatch.group('userPrefix')): continue # bingo, we got a match :) vars[k] = v # return all matched variables return vars
def enable_quota_in_kernel(activate): ucr.load() grub_append = ucr.get('grub/append', '') flags = [] option = 'usrquota' match = re.match(r'rootflags=([^\s]*)', grub_append) if match: flags = match.group(1).split(',') if activate and option not in flags: flags.append(option) elif not activate and option in flags: flags.remove(option) flags = ','.join(flags) if flags: flags = 'rootflags=%s' % (flags, ) new_grub_append = grub_append if 'rootflags=' not in grub_append: if flags: new_grub_append = '%s %s' % (grub_append, flags) else: new_grub_append = re.sub(r'rootflags=[^\s]*', flags, grub_append) if new_grub_append != grub_append: MODULE.info('Replacing grub/append from %s to %s' % (grub_append, new_grub_append)) handler_set(['grub/append=%s' % (new_grub_append, )]) status = _('enable') if activate else _('disable') raise QuotaActivationError( _('To %s quota support for the root filesystem the system has to be rebooted.' ) % (status, ))
def settings_get(self): """Return the current settings for a room""" if not self._italc.school or not self._italc.room: raise UMC_Error('no room selected') ucr.load() rule = ucr.get('proxy/filter/room/%s/rule' % self._italc.room, 'none') if rule == self._username: rule = 'custom' shareMode = ucr.get('samba/sharemode/room/%s' % self._italc.room, 'all') # load custom rule: key_prefix = 'proxy/filter/setting-user/%s/domain/whitelisted/' % self._username custom_rules = [] for key in ucr: if key.startswith(key_prefix): custom_rules.append(ucr[key]) printMode = ucr.get('samba/printmode/room/%s' % self._italc.room, 'default') # find AT jobs for the room and execute it to remove current settings jobs = atjobs.list(extended=True) for job in jobs: if job.comments.get(Instance.ATJOB_KEY, False) == self._italc.room: if job.execTime >= datetime.datetime.now(): self._ruleEndAt = job.execTime break else: self._ruleEndAt = None if rule == 'none' and shareMode == 'all' and printMode == 'default': self._ruleEndAt = None # find end of lesson period = self._lessons.current if period is None: if self._lessons.next: # between two lessons period = self._lessons.next.end else: # school is out ... 1 hour should be good (FIXME: configurable?) period = datetime.datetime.now() + datetime.timedelta(hours=1) period = period.time() else: period = period.end if self._ruleEndAt: time = self._ruleEndAt.time() for lesson in self._lessons.lessons: if time == lesson.begin: period = lesson break return { 'internetRule': rule, 'customRule': '\n'.join(custom_rules), 'shareMode': shareMode, 'printMode': printMode, 'period': str(period), }
def add(self, request): # does the same as put ucr.load() already_set = set(ucr.keys()) & set(v['object']['key'] for v in request.options) if already_set: raise UMC_Error(_('The UCR variable %s is already set.') % ('", "'.join(already_set))) self.put(request)
def __update_status(self): ucr.load() fn = ucr.get('connector/ad/ldap/certificate') self.status_ssl = ucr.is_true('connector/ad/ldap/ssl') self.status_password_sync = ucr.is_true('connector/ad/mapping/user/password/kinit') self.status_certificate = bool(fn and os.path.exists(fn)) self.status_running = self.__is_process_running('*python*univention/connector/ad/main.py*') self.status_mode_admember = admember.is_localhost_in_admember_mode(ucr) self.status_mode_adconnector = admember.is_localhost_in_adconnector_mode(ucr)
def ucr_rollback(ucr, variables): ucr.load() old = {} for variable in variables: old[variable] = ucr.get(variable) try: yield except BaseException: univention.config_registry.frontend.ucr_update(ucr, old) raise
def _thread(request): ucr.load() module = self._get_module_by_request(request) superordinate = request.options.get('superordinate') if superordinate == 'None': superordinate = None elif superordinate is not None: MODULE.info('Query defines a superordinate %s' % superordinate) mod = get_module(request.flavor, superordinate) if mod is not None: MODULE.info('Found UDM module %r for superordinate %s' % (mod.name, superordinate)) superordinate = mod.get(superordinate) if not request.options.get('container'): request.options['container'] = superordinate.dn else: raise SuperordinateDoesNotExist(superordinate) container = request.options.get('container') objectProperty = request.options['objectProperty'] objectPropertyValue = request.options['objectPropertyValue'] scope = request.options.get('scope', 'sub') hidden = request.options.get('hidden') fields = (set(request.options.get('fields', []) or []) | set([objectProperty])) - set(['name', 'None']) result = module.search(container, objectProperty, objectPropertyValue, superordinate, scope=scope, hidden=hidden) if result is None: return [] entries = [] object_type = request.options.get('objectType', request.flavor) for obj in result: if obj is None: continue module = get_module(object_type, obj.dn) if module is None: # This happens when concurrent a object is removed between the module.search() and get_module() call MODULE.warn('LDAP object does not exists %s (flavor: %s). The object is ignored.' % (obj.dn, request.flavor)) continue entry = { '$dn$': obj.dn, '$childs$': module.childs, '$flags$': obj.oldattr.get('univentionObjectFlag', []), '$operations$': module.operations, 'objectType': module.name, 'labelObjectType': module.subtitle, 'name': module.obj_description(obj), 'path': ldap_dn2path(obj.dn, include_rdn=False) } if '$value$' in fields: entry['$value$'] = [module.property_description(obj, column['name']) for column in module.columns] for field in fields - set(module.password_properties) - set(entry.keys()): entry[field] = module.property_description(obj, field) entries.append(entry) return entries
def run(_umc_instance): ucr.load() gateway = ucr.get('gateway') if not gateway: raise Critical(_('There is no gateway configured.')) process = Popen(['/bin/ping', '-c3', '-w4', '-W4', gateway], stdout=PIPE, stderr=STDOUT) stdout, stderr = process.communicate() if process.returncode: raise Critical('\n'.join([description % (gateway, ), '', stdout]))
def getGroupRuleName(groupNames): '''Return the name of the filter rule for the specified group name. Usage: getGroupRuleName([<groupName>, ...]) -> { <groupName>:<ruleName>, ... } or getGroupRuleName(<groupName) -> <ruleName>''' ucr.load() if not isinstance(groupNames, type([])): return ucr.get('proxy/filter/groupdefault/%s' % groupNames) return dict([(iname, ucr.get('proxy/filter/groupdefault/%s' % iname)) for iname in groupNames])
def query(self, **kwargs): """Returns a dictionary of initial values for the form.""" ucr.load() return { 'server_role': ucr.get('server/role'), 'joined': os.path.exists('/var/univention-join/joined'), 'samba': self.get_samba_version(), 'school_environment': self.get_school_environment(), 'guessed_master': get_master_dns_lookup(), 'hostname': ucr.get('hostname'), }
def deregister_account(self, username, password): MODULE.info("deregister_account(): username: {} password: *****".format(username)) ucr.load() if ucr.is_false('umc/self-service/account-deregistration/enabled', True): msg = _('The account deregistration was disabled via the Univention Configuration Registry.') MODULE.error('deregister_account(): {}'.format(msg)) raise UMC_Error(msg) dn, username = self.auth(username, password) if self.is_blacklisted(username, 'account-deregistration'): raise ServiceForbidden() try: return self._deregister_account(username) except Exception: raise UMC_Error(_('Account could not be deleted'), status=500)
def adconnector_save(self, request): """Saves the Active Directory connection configuration options: Host_IP: IP address of the AD server LDAP_Host: hostname of the AD server LDAP_Base: LDAP base of the AD server LDAP_BindDN: LDAP DN to use for authentication KerberosDomain: kerberos domain PollSleep: time in seconds between polls RetryRejected: how many time to retry a synchronisation MappingSyncMode: synchronisation mode MappingGroupLanguage: language of the AD server return: { 'success' : (True|False), 'message' : <details> } """ self.required_options(request, 'Host_IP') self.required_options(request, *[x[0] for x in Instance.OPTION_MAPPING if x[2] == '']) for umckey, ucrkey, default in Instance.OPTION_MAPPING: val = request.options.get(umckey, default) if val: if isinstance(val, bool): val = val and 'yes' or 'no' MODULE.info('Setting %s=%s' % (ucrkey, val)) univention.config_registry.handler_set([u'%s=%s' % (ucrkey, val)]) ucr.load() if ucr.get('connector/ad/ldap/ldaps'): MODULE.info('Unsetting connector/ad/ldap/ldaps') univention.config_registry.handler_unset([u'connector/ad/ldap/ldaps']) if ucr.get('connector/ad/ldap/port') == '636': MODULE.info('Setting ldap port to 389') univention.config_registry.handler_set([u'connector/ad/ldap/port=389']) if not request.options.get('LDAP_Password') in (None, '', DO_NOT_CHANGE_PWD): fn = ucr.get('connector/ad/ldap/bindpw', FN_BINDPW) try: fd = open(fn, 'w') fd.write(request.options.get('LDAP_Password')) fd.close() os.chmod(fn, 0600) os.chown(fn, 0, 0) univention.config_registry.handler_set([u'connector/ad/ldap/bindpw=%s' % fn]) except Exception, e: MODULE.info('Saving bind password failed (filename=%(fn)s ; exception=%(exception)s)' % {'fn': fn, 'exception': str(e.__class__)}) self.finished(request.id, {'success': False, 'message': _('Saving bind password failed (filename=%(fn)s ; exception=%(exception)s)') % {'fn': fn, 'exception': str(e.__class__)}}) return
def run(_umc_instance): MODULE.info('Checking samba logfiles for "Too many open files" messages') counter = 0 try: with open('/var/log/samba/log.smbd', 'rb') as fd: for line in fd: counter += len(re.findall('Too many open files', line)) except (OSError, IOError): return # logfile does not exists ucr.load() try: max_open_files = int(ucr.get('samba/max_open_files', 32808)) except ValueError: max_open_files = 0 if counter and max_open_files < suggested_max_open_files: raise Critical(umc_modules=[{'module': 'ucr'}])
def list_users(self): """ convenience function for the username entry. Lists all user names. We don't return this as an array of {id, label} tuples because: (1) id and label are always the same here (2) at the frontend, we must do some postprocessing, and an array is easier to handle. (3) the ComboBox is able to handle a plain array. """ ucr = ConfigRegistry() ucr.load() identity = ucr.get('ldap/hostdn') password = open('/etc/machine.secret').read().rstrip('\n') server = ucr.get('ldap/server/name') udm = UDM.credentials(identity, password, server=server).version(1) users = udm.get('users/user').search() return [user.props.username for user in users]
def updates_available(self): """ Asks if there are package updates available. (don't get confused by the name of the UniventionUpdater function that is called here.) This is a seperate call since it can take an amount of time, thus being invoked by a seperate button (and not in the background) """ ucr.load() try: # be as current as possible. what = 'reinitializing UniventionUpdater' self.uu.ucr_reinit() what = 'checking update availability' return self.uu.component_update_available() except Exception as ex: typ = str(type(ex)).strip('<>') msg = '[while %s] [%s] %s' % (what, typ, str(ex)) MODULE.error(msg) return False
def verify_contact(self, token, username, method): MODULE.info('verify_contact(): token: {} username: {} method: {}'.format(token, username, method)) ucr.load() if ucr.is_false('umc/self-service/account-verification/backend/enabled', True): msg = _('The account verification was disabled via the Univention Configuration Registry.') MODULE.error('verify_contact(): {}'.format(msg)) raise UMC_Error(msg) users_mod = UDM.admin().version(1).get('users/user') try: user = users_mod.get_by_id(username) except NoObject: return { 'success': False, 'failType': 'INVALID_INFORMATION', } next_steps = ucr.get('umc/self-service/account-verification/next-steps/%s' % self.locale.language, '') if not next_steps: next_steps = ucr.get('umc/self-service/account-verification/next-steps', '') plugin = self._get_send_plugin(method) if getattr(user.props, plugin.udm_property) == 'TRUE': # cleanup. map property to actual boolean? return { 'success': True, 'successType': 'ALREADY_VERIFIED', 'data': { 'username': username, 'nextSteps': next_steps, } } self._check_token(username, token, token_application=plugin.message_application()) setattr(user.props, plugin.udm_property, 'TRUE') user.save() self.db.delete_tokens(token=token, username=username) return { 'success': True, 'successType': 'VERIFIED', 'data': { 'username': username, 'nextSteps': next_steps, } }
def run(_umc_instance): ucr.load() failed = [] hostnames = { 'www.univention.de': ('dns/forwarder1', 'dns/forwarder2', 'dns/forwarder3'), ucr.get('hostname', ''): ('nameserver1', 'nameserver2', 'nameserver3') } for hostname, nameservers in hostnames.iteritems(): for nameserver in nameservers: if not ucr.get(nameserver): continue try: query_dns_server(ucr[nameserver], hostname) except DNSException as exc: msgs = [ '\n', _('The nameserver %(nameserver)s (UCR variable %(var)r) is not responsive:' ) % { 'nameserver': ucr[nameserver], 'var': nameserver } ] if isinstance(exc, Timeout): msgs.append( _('A timeout occurred while reaching the nameserver (is it online?).' )) else: msgs.append('%s' % (exc, )) failed.append('\n'.join(msgs)) if failed: raise Warning('%s%s' % (description % (len(failed), ), '\n'.join(failed)))
def _notify_about_account_deregistration(self, username, mail): if not mail: return ucr.load() path_ucr = ucr.get("umc/self-service/account-deregistration/email/text_file") if path_ucr and os.path.exists(path_ucr): path = path_ucr else: path = "/usr/share/univention-self-service/email_bodies/deregistration_notification_email_body.txt" with open(path, "r") as fp: txt = fp.read() txt = txt.format(username=username) msg = MIMENonMultipart('text', 'plain', charset='utf-8') msg["Subject"] = "Account deletion" msg["Date"] = formatdate(localtime=True) msg["From"] = ucr.get("umc/self-service/account-deregistration/email/sender_address", "Password Reset Service <noreply@{}>".format(".".join([ucr["hostname"], ucr["domainname"]]))) msg["To"] = mail cs = email.charset.Charset("utf-8") cs.body_encoding = email.charset.QP msg.set_payload(txt, charset=cs) smtp = smtplib.SMTP(ucr.get("umc/self-service/account-deregistration/email/server", "localhost")) smtp.sendmail(msg["From"], msg["To"], msg.as_string()) smtp.quit()
def _maintenance_information(self) -> Dict[str, Any]: default = {'show_warning': False} if not self.uu: return default ucr.load() if ucr.is_true('license/extended_maintenance/disable_warning'): return default version = self.uu.current_version for _ver, data in self.uu.get_releases(version, version): status = data.get('status', 'unmaintained') maintenance_extended = status == 'extended' show_warning = maintenance_extended or status != 'maintained' return { 'ucs_version': str(version), 'show_warning': show_warning, 'maintenance_extended': maintenance_extended, 'base_dn': ucr.get('license/base'), } return default
def adconnector_save(self, request): """Saves the Active Directory connection configuration options: Host_IP: IP address of the AD server LDAP_Host: hostname of the AD server LDAP_Base: LDAP base of the AD server LDAP_BindDN: LDAP DN to use for authentication KerberosDomain: kerberos domain PollSleep: time in seconds between polls RetryRejected: how many time to retry a synchronisation MappingSyncMode: synchronisation mode MappingGroupLanguage: language of the AD server return: { 'success' : (True|False), 'message' : <details> } """ for umckey, ucrkey, default in Instance.OPTION_MAPPING: val = request.options.get(umckey, default) if val: if isinstance(val, bool): val = 'yes' if val else 'no' MODULE.info('Setting %s=%s' % (ucrkey, val)) univention.config_registry.handler_set([u'%s=%s' % (ucrkey, val)]) ucr.load() if ucr.get('connector/ad/ldap/ldaps'): MODULE.info('Unsetting connector/ad/ldap/ldaps') univention.config_registry.handler_unset([u'connector/ad/ldap/ldaps']) if ucr.get('connector/ad/ldap/port') == '636': MODULE.info('Setting ldap port to 389') univention.config_registry.handler_set([u'connector/ad/ldap/port=389']) if not request.options.get('LDAP_Password') in (None, '', DO_NOT_CHANGE_PWD): fn = ucr.get('connector/ad/ldap/bindpw', FN_BINDPW) try: with open(fn, 'w') as fd: fd.write(request.options.get('LDAP_Password')) os.chmod(fn, 0o600) os.chown(fn, 0, 0) univention.config_registry.handler_set([u'connector/ad/ldap/bindpw=%s' % fn]) except Exception as e: MODULE.info('Saving bind password failed (filename=%(fn)s ; exception=%(exception)s)' % {'fn': fn, 'exception': str(e.__class__)}) self.finished(request.id, {'success': False, 'message': _('Saving bind password failed (filename=%(fn)s ; exception=%(exception)s)') % {'fn': fn, 'exception': str(e.__class__)}}) return ssldir = '/etc/univention/ssl/%s' % request.options.get('LDAP_Host') if not os.path.exists(ssldir): self._create_certificate(request) return # enter a static host entry such that the AD server's FQDN can be resolved univention.config_registry.handler_set([u'hosts/static/%(Host_IP)s=%(LDAP_Host)s' % request.options]) # check for SSL support on AD side if admember.server_supports_ssl(server=request.options.get('LDAP_Host')): MODULE.process('Enabling SSL...') admember.enable_ssl() else: MODULE.warn('SSL is not supported') admember.disable_ssl() # UCR variables are set, and now we can try to guess the language of # the AD domain ad_lang = guess_ad_domain_language() univention.config_registry.handler_set([u'connector/ad/mapping/group/language=%s' % ad_lang]) self.finished(request.id, {'success': True, 'message': _('Active Directory connection settings have been saved.')})
def change(self, role, ip, netmask, oldip=None): '''Return a dict with all necessary values for ipchange read from the current status of the system.''' # ignore link local addresses (no DHCP address received) network = ipaddress.IPv4Network(u'%s/%s' % (ip, netmask), False) if network.is_link_local: MODULE.error('Ignore link local address change.') return lo, position = univention.admin.uldap.getAdminConnection() hmodule = univention.admin.modules.get('dns/host_record') cmodule = univention.admin.modules.get('computers/%s' % (role,)) # check if already used res = univention.admin.modules.lookup(hmodule, None, lo, scope='sub', filter=filter_format('aRecord=%s', (ip,))) if res: used_by = [] for i in res: if 'name' in i: used_by.append(i['name']) raise BadRequest('The IP address is already in used by host record(s) for: %s' % ', '.join(used_by)) # do we have a forward zone for this IP address? if oldip and oldip != ip: fmodule = univention.admin.modules.get('dns/forward_zone') for forwardobject in univention.admin.modules.lookup(fmodule, None, lo, scope='sub', superordinate=None, filter=filter_format('(aRecord=%s)', (oldip,))): forwardobject.open() forwardobject['a'].remove(oldip) forwardobject['a'].append(ip) forwardobject.modify() # remove old DNS reverse entries with old IP server = cmodule.object(None, lo, position, self.user_dn) server.open() current_ips = server['ip'] for e in server['dnsEntryZoneReverse']: if e[1] in current_ips: server['dnsEntryZoneReverse'].remove(e) # change IP server['ip'] = ip MODULE.info('Change IP to %s' % (ip,)) server.modify() # do we have a new reverse zone for this IP address? rmodule = univention.admin.modules.get('dns/reverse_zone') parts = network.network_address.exploded.split('.') while parts[-1] == '0': parts.pop() while parts: subnet = '.'.join(parts) parts.pop() filter = filter_format('(subnet=%s)', (subnet,)) reverseobject = univention.admin.modules.lookup(rmodule, None, lo, scope='sub', superordinate=None, filter=filter) if reverseobject: server = cmodule.object(None, lo, position, self.user_dn) server.open() server['dnsEntryZoneReverse'].append([reverseobject[0].dn, ip]) server.modify() break # Change ucs-sso entry # FIXME: this should be done for UCS-in-AD domains as well! ucr.load() sso_fqdn = ucr.get('ucs/server/sso/fqdn') if ucr.is_true('ucs/server/sso/autoregistraton', True): fmodule = univention.admin.modules.get('dns/forward_zone') forwardobjects = univention.admin.modules.lookup(fmodule, None, lo, scope='sub', superordinate=None, filter=None) for forwardobject in forwardobjects: zone = forwardobject.get('zone') if not sso_fqdn.endswith(zone): continue sso_name = sso_fqdn[:-(len(zone) + 1)] for current_ip in current_ips: records = univention.admin.modules.lookup(hmodule, None, lo, scope='sub', superordinate=forwardobject, filter=filter_format('(&(relativeDomainName=%s)(aRecord=%s))', (sso_name, current_ip))) for record in records: record.open() if oldip in record['a']: record['a'].remove(oldip) record['a'].append(ip) record.modify()
def __update_status( self ): ucr.load() self.status_configured = bool( ucr.get( 'connector/ad/ldap/host' ) and ucr.get( 'connector/ad/ldap/base' ) and ucr.get( 'connector/ad/ldap/binddn' ) and ucr.get( 'connector/ad/ldap/bindpw' ) ) fn = ucr.get( 'connector/ad/ldap/certificate' ) self.status_certificate = bool( fn and os.path.exists( fn ) ) self.status_running = self.__is_process_running( '*python*univention/connector/ad/main.py*' )