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 run(_umc_instance): configRegistry = univention.config_registry.ConfigRegistry() configRegistry.load() all_certificates = certificates(configRegistry) is_local_check = configRegistry.get('server/role') in \ ('domaincontroller_master', 'domaincontroller_backup') if is_local_check: cert_verify = list(verify_local(all_certificates)) else: cert_verify = list( verify_from_master(configRegistry.get('ldap/master'), all_certificates)) error_descriptions = [ str(error) for error in cert_verify if isinstance(error, CertificateWarning) ] if error_descriptions: error_descriptions.append( _('Please see {sdb} on how to renew certificates.')) if any(isinstance(error, CertificateError) for error in cert_verify): raise Critical(description='\n'.join(error_descriptions)) MODULE.error('\n'.join(error_descriptions)) raise Warning(description='\n'.join(error_descriptions))
def run(_umc_instance, rerun=False, fix_log=''): if not util.is_service_active('Samba 4'): return error_descriptions = list() if rerun and fix_log: error_descriptions.append(fix_log) buttons = [{ 'action': 'run_samba_tool_dbcheck_fix', 'label': _('Run `samba-tool dbcheck --fix --cross-ncs --yes`'), }] cmd = ['samba-tool', 'dbcheck'] (success, output) = util.run_with_output(cmd) if [x for x in output.split('\n') if x.startswith("ERROR:")]: error = _( '`samba-tool dbcheck` found an error in the local AD database.') error_descriptions.append(error) error_descriptions.append(output) if not rerun: fix = _('You can run `samba-tool dbcheck --fix` to fix the issue.') error_descriptions.append(fix) raise Critical(description='\n'.join(error_descriptions), buttons=buttons) if rerun: fixed = _( '`samba-tool dbcheck` found no errors in the local AD database.') error_descriptions.append(fixed) MODULE.error('\n'.join(error_descriptions)) raise ProblemFixed(description='\n'.join(error_descriptions))
def get_s4_connector(configbasename='connector'): configRegistry = univention.config_registry.ConfigRegistry() configRegistry.load() if '%s/s4/ldap/certificate' % configbasename not in configRegistry or True: if configRegistry.is_true('%s/s4/ldap/ssl' % configbasename): MODULE.error('Missing Configuration Key %s/s4/ldap/certificate' % configbasename) raise MissingConfigurationKey('%s/s4/ldap/certificate' % configbasename) if configRegistry.get('%s/s4/ldap/bindpw' % configbasename): with open(configRegistry['%s/s4/ldap/bindpw' % configbasename]) as fob: s4_ldap_bindpw = fob.read().rstrip('\n') else: s4_ldap_bindpw = None try: s4 = univention.s4connector.s4.s4( configbasename, load_mapping(configbasename), configRegistry, configRegistry['%s/s4/ldap/host' % configbasename], configRegistry['%s/s4/ldap/port' % configbasename], configRegistry['%s/s4/ldap/base' % configbasename], configRegistry.get('%s/s4/ldap/binddn' % configbasename), s4_ldap_bindpw, configRegistry['%s/s4/ldap/certificate' % configbasename], configRegistry['%s/s4/listener/dir' % configbasename], False) except KeyError as error: MODULE.error('Missing Configuration key %s' % error.message) raise MissingConfigurationKey(error.message) else: return s4
def run(_umc_instance): if not util.is_service_active('IMAP'): return configRegistry = univention.config_registry.ConfigRegistry() configRegistry.load() if configRegistry.is_true('mail/dovecot'): acl_class = DovecotACL else: return differences = list(all_differences(acl_class)) ed = [ _('Found differences in the ACLs for IMAP shared folders between UDM and IMAP.' ) + ' ' + _('This is not necessarily a problem, if the the ACL got changed via IMAP.' ) ] modules = list() for (folder, group) in it.groupby(differences, lambda x: x[0]): name = folder.common_name ed.append('') ed.append( _('In mail folder {name} (see {{udm:mail/mail}}):').format( name=name)) ed.extend(str(error) for (_, error) in group) modules.append(udm_mail_link(folder)) if modules: MODULE.error('\n'.join(ed)) raise Warning(description='\n'.join(ed), umc_modules=modules)
def run(_umc_instance): high = high_disk_usage() tmpl = _('- Disk for mountpoint %(mp)s is %(pc)s%% full.') disk_errors = [tmpl % {'mp': mp, 'pc': pc} for (mp, pc) in high.items()] problem_on_root = '/' in high problem_on_varlog = '/var/log' in high or '/var' in high or \ (problem_on_root and not is_varlog_own_partition()) if disk_errors: umc_modules = [{'module': 'appcenter', 'flavor': 'appcenter'}] error_descriptions = [_('Some disks are nearly full:')] error_descriptions.extend(disk_errors) if problem_on_root: error_descriptions.append('\n'.join(solutions())) if problem_on_varlog and high_log_levels(): lvl_errors = (_('You have configured some high log levels.'), _('You may want to reset them via {ucr}.')) umc_modules.append({'module': 'ucr'}) error_descriptions.append(' '.join(lvl_errors)) if problem_on_root: MODULE.error('\n'.join(error_descriptions)) raise Critical('\n'.join(error_descriptions), umc_modules=umc_modules) raise Warning('\n'.join(error_descriptions), umc_modules=umc_modules)
def test_service_provider_certificate(): # compare /etc/univention/ssl/$(hostname -f)/cert.pem with # univention-ldapsearch -LLL "(&(serviceProviderMetadata=*)(univentionObjectType=saml/serviceprovider)(SAMLServiceProviderIdentifier=https://$(hostname -f)/univention/saml/metadata))" serviceProviderMetadata | ldapsearch-wrapper | ldapsearch-decode64 # If it fails: /usr/share/univention-management-console/saml/update_metadata # # fails because https://help.univention.com/t/renewing-the-ssl-certificates/37 was not used. https://help.univention.com/t/renewing-the-complete-ssl-certificate-chain/36 lo = univention.uldap.getMachineConnection() certs = lo.search(filter_format( '(&(serviceProviderMetadata=*)(univentionObjectType=saml/serviceprovider)(SAMLServiceProviderIdentifier=https://%s/univention/saml/metadata))', ['%s.%s' % (ucr.get('hostname'), ucr.get('domainname'))]), attr=['serviceProviderMetadata']) MODULE.process( "Checking certificates of /etc/univention/ssl/%s.%s/cert.pem" % (ucr.get('hostname'), ucr.get('domainname'))) with open('/etc/univention/ssl/%s.%s/cert.pem' % (ucr.get('hostname'), ucr.get('domainname'))) as fd: for cert in certs: cert = find_node( fromstring( cert[1]['serviceProviderMetadata'][0].decode('UTF-8')), '{http://www.w3.org/2000/09/xmldsig#}X509Certificate') if cert.text.strip() not in fd.read(): MODULE.error( 'The certificate of the SAML service provider does not match.' ) raise Critical( _('The certificate of the SAML service provider does not match.' ))
def run(_umc_instance): if not util.is_service_active('S4 Connector'): return check_errors = list(check_existence_and_consistency()) if check_errors: MODULE.error('\n'.join(str(x) for x in check_errors)) raise Warning(description='\n'.join(str(x) for x in check_errors))
def run(_umc_instance): error_descriptions = [_('The following FQDNs were not resolvable:')] unresolvable = list(unresolvable_repositories()) if unresolvable: error_descriptions.extend(unresolvable) error_descriptions.append(_('Please see {sdb} for troubleshooting DNS problems.')) MODULE.error('\n'.join(error_descriptions)) raise Warning(description='\n'.join(error_descriptions))
def run(_umc_instance, retest=False): configRegistry = univention.config_registry.ConfigRegistry() configRegistry.load() error_descriptions = list() buttons = [{ 'action': 'fix_machine_password', 'label': _('Fix machine password'), }] is_master = configRegistry.get('server/role') == 'domaincontroller_master' if not is_master and not check_machine_password(master=False): error = _( 'Authentication against the local LDAP failed with the machine password.' ) error_descriptions.append(error) if not check_machine_password(master=True): error = _( 'Authentication against the master LDAP failed with the machine password.' ) error_descriptions.append(error) password_change = configRegistry.is_true('server/password/change', True) try: change_interval = int( configRegistry.get('server/password/interval', '21')) except TypeError: change_interval = 21 error_change = _( 'Note that password rotation is disabled via the UCR variable server/password/change.' ) error_interval = _('Note that server/password/interval is set to {}.') if error_descriptions: note_sdb = _( 'See {sdb} for information on manual server password change.') error_descriptions.append(note_sdb) if not password_change: error_descriptions.append(error_change) buttons.append({ 'action': 'reset_password_change', 'label': _('Set server/password/change=True'), }) if change_interval < 1: error_descriptions.append(error_interval.format(change_interval)) buttons.append({ 'action': 'reset_password_interval', 'label': _('Set server/password/interval=21'), }) MODULE.error('\n'.join(error_descriptions)) raise Critical(description=' '.join(error_descriptions), buttons=buttons) if retest: raise ProblemFixed(buttons=[])
def add_lo_to_samba_interfaces(umc_instance): configRegistry = univention.config_registry.ConfigRegistry() configRegistry.load() interfaces = configRegistry.get('samba/interfaces', '').split() interfaces.append('lo') MODULE.process('Setting samba/interfaces') ucr_set(['samba/interfaces={}'.format(' '.join(interfaces))]) return run(umc_instance, retest=True)
def migrate_users(_umc_instance): process = Popen(['/usr/share/univention-directory-manager-tools/univention-migrate-users-to-ucs4.3'], stderr=STDOUT, stdout=PIPE) stdout, stderr = process.communicate() if process.returncode: MODULE.error('Error running univention-migrate-users-to-ucs4.3:\n%s' % (stdout,)) raise Critical(_('The migration failed: %s') % (stdout,)) else: MODULE.process('Output of univention-migrate-users-to-ucs4.3:\n%s' % (stdout,)) raise ProblemFixed(buttons=[])
def run(_umc_instance): hostnames = list(non_compliant_hostnames()) if hostnames: invalid = _('The following non-compliant hostnames have been found: {hostnames}.') problem = _('This may lead to DNS problems.') specification = _('Please refer to {rfc1123} for the syntax of host names.') description = [invalid.format(hostnames=', '.join(hostnames)), problem, specification] MODULE.error('\n'.join(description)) raise Warning(description='\n'.join(description))
def test_resolve(url): parsed = urlparse.urlsplit(url if '//' in url else '//' + url) MODULE.process("Trying to resolve address of repository server %s" % (parsed.hostname)) MODULE.process("Similar to running: host %s" % (parsed.hostname)) try: socket.getaddrinfo(parsed.hostname, parsed.scheme) except socket.gaierror: return False return True
def run(_umc_instance): ucr.load() gateway = ucr.get('gateway') if not gateway: MODULE.error('There is no gateway configured.') 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: MODULE.error('\n'.join(description)) raise Critical('\n'.join([description % (gateway,), '', stdout]))
def kinit(principal, keytab=None, password_file=None): auth = '--keytab={tab}' if keytab else '--password-file={file}' cmd = ('kinit', auth.format(tab=keytab, file=password_file), principal) MODULE.process('Running: %s' % (' '.join(cmd))) try: subprocess.check_call(cmd) except subprocess.CalledProcessError: raise KinitError(principal, keytab, password_file) else: yield subprocess.call(('kdestroy', ))
def get_s4_connector(configbasename='connector'): configRegistry = univention.config_registry.ConfigRegistry() configRegistry.load() try: s4 = univention.s4connector.s4.s4.main(configRegistry, configbasename) except SystemExit as error: MODULE.error('Missing Configuration key %s' % (error, )) raise MissingConfigurationKey(error.code) else: s4.init_ldap_connections() return s4
def run(_umc_instance): process = Popen(['univention-check-join-status'], stdout=PIPE, stderr=STDOUT) (stdout, stderr) = process.communicate() if process.returncode != 0: errors = [_('"univention-check-join-status" returned a problem with the domain join.')] if stdout: errors.append("\nSTDOUT:\n{}".format(stdout.decode('UTF-8', 'replace'))) if stderr: errors.append("\nSTDERR:\n{}".format(stderr.decode('UTF-8', 'replace'))) errors.append(_('See {erroranalysis} or run the join-scripts via {join}.')) MODULE.error('\n'.join(errors)) raise Critical(description='\n'.join(errors))
def migrate_users(_umc_instance): process = Popen([SCRIPT], stderr=STDOUT, stdout=PIPE) stdout, stderr = process.communicate() stdout = stdout.decode('UTF-8', 'replace') if process.returncode: MODULE.error('Error running univention-migrate-users-to-ucs4.3:\n%s' % (stdout, )) raise Critical(_('The migration failed: %s') % (stdout, )) else: MODULE.process('Output of univention-migrate-users-to-ucs4.3:\n%s' % (stdout, )) raise ProblemFixed(buttons=[])
def run_samba_tool_dbcheck_fix(umc_instance): if not util.is_service_active('Samba 4'): return cmd = ['samba-tool', 'dbcheck', '--fix', '--cross-ncs', '--yes'] (success, output) = util.run_with_output(cmd) cmd_string = ' '.join(cmd) MODULE.process('Output of %s:\n%s' % (cmd_string, output)) fix_log = [_('Output of `{cmd}`:').format(cmd=cmd_string)] fix_log.append(output.decode('utf-8', 'replace')) run(umc_instance, rerun=True, fix_log='\n'.join(fix_log))
def nsupdate(server, domainname): process = subprocess.Popen(('nsupdate', '-g', '-t', '15'), stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) cmd_template = 'server {server}\nprereq yxdomain {domain}\nsend\nquit\n' cmd = cmd_template.format(server=server, domain=domainname) MODULE.process("Running: 'echo %s | nsupdate -g -t 15'" % (cmd, )) process.communicate(cmd) if process.poll() != 0: MODULE.error('NS Update Error at %s %s' % (server, domainname)) raise NSUpdateError(server, domainname)
def run(_umc_instance): if ucr.get('server/role') != 'domaincontroller_master': return process = Popen([SCRIPT, '--check'], stderr=STDOUT, stdout=PIPE) stdout, stderr = process.communicate() stdout = stdout.decode('UTF-8', 'replace') if process.returncode: MODULE.error(description + stdout) raise Critical(description + stdout, buttons=[{ 'action': 'migrate_users', 'label': _('Migrate user objects'), }])
def run(_umc_instance): cmd = ['univention-check-templates'] try: subprocess.check_output(cmd) except subprocess.CalledProcessError as error: error_description = [ _('Errors found by `univention-check-templates`.'), _('The following UCR files are modified locally.'), _('Updated versions will be named FILENAME.dpkg-*.'), _('The files should be checked for differences.'), ] if error.output: MODULE.error('\n'.join(error_description)) error_description.extend(('\n\n', error.output)) raise Warning(' '.join(error_description))
def run(_umc_instance): if not util.is_service_active('S4 Connector'): return try: import univention.s4connector import univention.s4connector.s4 except ImportError: error_description = _('Univention S4 Connector is not installed.') raise Critical(description=error_description) try: s4 = get_s4_connector() except MissingConfigurationKey as error: error_description = _( 'The UCR variable {variable!r} is unset, but necessary for the S4 Connector.' ) MODULE.error(error_description.format(variable=error.message)) raise Critical(description=error_description.format( variable=error.message)) ucs_rejects = list(get_ucs_rejected(s4)) s4_rejects = list(get_s4_rejected(s4)) if ucs_rejects or s4_rejects: error_description = _( 'Found {ucs} UCS rejects and {s4} S4 rejects. See {{sdb}} for more information.' ) error_description = error_description.format(ucs=len(ucs_rejects), s4=len(s4_rejects)) error_descriptions = [error_description] if ucs_rejects: error_descriptions.append(_('UCS rejected:')) for (filename, ucs_dn, s4_dn) in ucs_rejects: s4_dn = s4_dn if s4_dn else _('not found') line = _('UCS DN: {ucs}, S4 DN: {s4}, Filename: {fn}') line = line.format(ucs=ucs_dn, s4=s4_dn, fn=filename) error_descriptions.append(line) if s4_rejects: error_descriptions.append(_('S4 rejected:')) for (_s4_id, s4_dn, ucs_dn) in s4_rejects: ucs_dn = ucs_dn if ucs_dn else _('not found') line = _('S4 DN: {s4}, UCS DN: {ucs}') line = line.format(s4=s4_dn, ucs=ucs_dn) error_descriptions.append(line) MODULE.error('\n'.join(error_descriptions)) raise Warning(description='\n'.join(error_descriptions))
def run(_umc_instance): if ucr.get('server/role') != 'domaincontroller_master': return unregistered = [] for fname in sorted(SCHEMA_FILES): if not os.path.exists(fname): continue if not udm_schema_obj_exists(fname): unregistered.append(fname) if unregistered: MODULE.error(description + repr(unregistered)) raise Warning(description + '\n' + _('The following files seem to be registered in the old way:') + '\n * ' + '\n * '.join(unregistered), buttons=[{ 'action': 'register_schema', 'label': _('Register Schema files'), }])
def run_samba_tool_ntacl_sysvolreset(umc_instance): if not util.is_service_active('Samba 4'): return cmd = ['samba-tool', 'ntacl', 'sysvolreset'] (success, output) = util.run_with_output(cmd) cmd_string = ' '.join(cmd) if success: fix_log = [_('`{cmd}` succeeded.').format(cmd=cmd_string)] MODULE.process('Output of %s:\n%s' % (cmd_string, output)) else: fix_log = [_('`{cmd}` failed.').format(cmd=cmd_string)] MODULE.error('Error running %s:\n%s' % (cmd_string, output)) fix_log.append(output.decode('utf-8', 'replace')) run(umc_instance, rerun=True, fix_log='\n'.join(fix_log))
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 run(_umc_instance): if ucr.get('server/role') != 'domaincontroller_master': return process = Popen([ '/usr/share/univention-directory-manager-tools/univention-migrate-users-to-ucs4.3', '--check' ], stderr=STDOUT, stdout=PIPE) stdout, stderr = process.communicate() if process.returncode: MODULE.error(description + stdout) raise Critical(description + stdout, buttons=[{ 'action': 'migrate_users', 'label': _('Migrate user objects'), }])
def restore_machine_password(role, ldap_connection): with open('/etc/machine.secret') as fob: password = fob.read().rstrip('\n') if not password: password = univention.lib.misc.createMachinePassword() with open('/etc/machine.secret', 'w') as fob: fob.write(password) computers = udm_modules.get('computers/{}'.format(role)) position = univention.admin.uldap.position(ldap_connection.base) udm_modules.init(ldap_connection, position, computers) filter_expr = ldap.filter.filter_format('(cn=%s)', (socket.gethostname(),)) for computer in computers.lookup(None, ldap_connection, filter_expr): MODULE.process('Restoring password of UDM computer object') computer.open() computer['password'] = password computer.modify()
def run(_umc_instance): error = _( 'This is a Samba 4 DC, but `samba-tool processes` reports no `kdc_server`.' ) heimdal_error = _('This may be, because Heimdal KDC seems to be running.') autostart_error = _( 'This may be, because `kerberos/autostart` is not disabled.') solution = _( 'You may want to stop Heimdal KDC and restart Samba via {services}') if util.is_service_active('Samba 4') and not samba_kdc_running(): error_descriptions = [error] if is_heimdal_kdc_running(): error_descriptions.append(heimdal_error) if not is_kerberos_autostart_disabled(): error_descriptions.append(autostart_error) error_descriptions.append(solution) MODULE.error('n'.join(error_descriptions)) raise Critical('\n'.join(error_descriptions))