Example #1
0
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)))
Example #2
0
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.'
                      ))
Example #3
0
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 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)
Example #5
0
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
Example #6
0
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', ))
Example #7
0
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))
Example #9
0
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_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 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 change_server_password(configRegistry):
	interval = configRegistry.get('server/password/interval', '21')
	ucr_set('server/password/interval=-1')
	try:
		cmd = ['/usr/lib/univention-server/server_password_change']
		output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
		MODULE.process('Output of server_password_change:\n%s' % (output,))
	except subprocess.CalledProcessError:
		MODULE.error('Error running server_password_change')
		MODULE.error('Output:\n%s' % (output,))
		error_descriptions = [
			_('Calling /usr/lib/univention-server/server_password_change failed.'),
			_('Please see {sdb} for more information.'),
		]
		MODULE.error(' '.join(error_descriptions))
		raise Critical(description=' '.join(error_descriptions))
	finally:
		ucr_set('server/password/interval={}'.format(interval))
Example #13
0
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
	MODULE.process("open files: %s , max open files: %s" % (counter, max_open_files))
	if counter and max_open_files < suggested_max_open_files:
		raise Critical(umc_modules=[{'module': 'ucr'}])
def probe_kdc(kdc, port, protocol, target_realm, user_name):
    request = build_kerberos_request(target_realm, user_name)
    if protocol == 'udp':
        MODULE.process(
            "Trying to contact KDC %s on udp port %d Similar to running: nmap %s -sU -p %d"
            % (kdc, port, kdc, port))
    else:
        MODULE.process(
            "Trying to contact KDC %s on tcp port %d Similar to running: nmap %s -sT -p %d"
            % (kdc, port, kdc, port))
    try:
        received = send_and_receive(kdc, port, protocol, request)
    except KerberosException:
        return False

    if target_realm in received:
        return True

    return False

    # this no longer works with >= 4.3, ??
    # I think the new pyasn1 version might need the full asn1Spec to work?:
    # http://snmplabs.com/pyasn1/changelog.html
    # Keyword: require strict two-zeros sentinel encoding
    try:
        (error, _sub) = pyasn1.codec.der.decoder.decode(received,
                                                        asn1Spec=KrbError())
    except pyasn1.error.PyAsn1Error:
        pass
    else:
        return True

    try:
        (rep, _sub) = pyasn1.codec.der.decoder.decode(received,
                                                      asn1Spec=AsRep())
    except pyasn1.error.PyAsn1Error:
        return False

    return True
Example #15
0
def test_identity_provider_certificate():
    # download from all ip addresses of ucs-sso. the IDP certificate (/etc/simplesamlphp/*-idp-certificate.crt)
    # compare this with /usr/share/univention-management-console/saml/idp/*.xml
    # If it fails: univention-run-joinscripts --force --run-scripts 92univention-management-console-web-server

    sso_fqdn = ucr.get('ucs/server/sso/fqdn')
    MODULE.process(
        "Checks ucs-sso by comparing 'ucr get ucs/server/sso/fqdn' with the Location field in /usr/share/univention-management-console/saml/idp/*.xml"
    )
    if not sso_fqdn:
        return
    for host in socket.gethostbyname_ex(sso_fqdn)[2]:
        try:
            with download_tempfile(
                    'https://%s/simplesamlphp/saml2/idp/certificate' %
                (host, ), {'host': sso_fqdn}) as certificate:
                certificate = certificate.read()
                for idp in glob.glob(
                        '/usr/share/univention-management-console/saml/idp/*.xml'
                ):
                    with open(idp) as fd:
                        cert = find_node(
                            fromstring(fd.read()),
                            '{http://www.w3.org/2000/09/xmldsig#}X509Certificate'
                        )
                        if cert.text.strip() not in certificate:
                            MODULE.error(
                                'The certificate of the SAML identity provider does not match.'
                            )
                            raise Critical(
                                _('The certificate of the SAML identity provider does not match.'
                                  ))

        except requests.exceptions.ConnectionError:
            print('error, connecting')
            pass
def reset_kerberos_kdc(umc_instance):
    MODULE.process('Resetting kerberos/kdc=127.0.0.1')
    ucr_set(['kerberos/kdc=127.0.0.1'])
    return run(umc_instance, retest=True)
def reset_password_change(umc_instance):
    MODULE.process('Unsetting server/password/change')
    ucr_unset(['server/password/change'])
    return run(umc_instance, retest=True)
def run(_umc_instance,
        url='http://www.univention.de/',
        connecttimeout=30,
        timeout=30):
    ucr.load()

    proxy = ucr.get('proxy/http')
    if not proxy:
        return

    proxy = urlparse(proxy)
    MODULE.info('The proxy is configured, using host=%r, port=%r' %
                (proxy.hostname, proxy.port))
    curl = pycurl.Curl()
    curl.setopt(pycurl.PROXYTYPE, pycurl.PROXYTYPE_HTTP)
    if proxy.hostname:
        curl.setopt(pycurl.PROXY, proxy.hostname)
    if proxy.port:
        curl.setopt(pycurl.PROXYPORT, proxy.port)
    curl.setopt(pycurl.FOLLOWLOCATION, True)
    curl.setopt(pycurl.MAXREDIRS, 5)
    curl.setopt(pycurl.CONNECTTIMEOUT, connecttimeout)
    curl.setopt(pycurl.TIMEOUT, 30)
    if proxy.username:
        curl.setopt(pycurl.PROXYAUTH, pycurl.HTTPAUTH_ANY)
        credentials = '%s' % (proxy.username, )
        if proxy.password:
            credentials = '%s:%s' % (proxy.username, proxy.password)
        curl.setopt(pycurl.PROXYUSERPWD, credentials)

    curl.setopt(pycurl.URL, url)
    # curl.setopt(pycurl.VERBOSE, bVerbose)

    buf = io.StringIO()
    curl.setopt(pycurl.WRITEFUNCTION, buf.write)
    MODULE.process(''.join("Trying to connect to %s via HTTP proxy %s" %
                           (url, proxy)))

    try:
        curl.perform()
    except pycurl.error as exc:
        try:
            code, msg = exc.args
            msg = '%s (code=%s)' % (msg, code)
            MODULE.info(msg)
        except ValueError:
            MODULE.error(traceback.format_exc())
            code = 0
            msg = str(exc)
        if code == pycurl.E_COULDNT_CONNECT:
            msg = _(
                'The proxy host could not be reached. Make sure that hostname (%(hostname)r) and port (%(port)r) are correctly set up.'
            ) % {
                'hostname': proxy.hostname,
                'port': proxy.port
            }
        elif code == pycurl.E_COULDNT_RESOLVE_PROXY:
            msg = _(
                'The hostname of the proxy could not be resolved. May check your DNS configuration.'
            )
        elif code == pycurl.E_OPERATION_TIMEOUTED:
            msg = _(
                'The server did not respond within %d seconds. Please check your network configuration.'
            ) % (timeout, )
        elif code == 0:
            MODULE.error(traceback.format_exc())

        MODULE.error('\n'.join([description, msg]))
        raise Critical('\n'.join([description, msg]))
    else:
        # page = buf.getvalue()
        # MODULE.info(page[:100])
        buf.close()
        http_status = curl.getinfo(pycurl.HTTP_CODE)
        if http_status >= 400:
            warning = '\n'.join([
                description,
                _('The proxy server is reachable but the HTTP response status code (%d) does not indicate success.'
                  ) % (http_status, ),
                _('This warning might be harmless. Nevertheless make sure the authentication credentials (if any) are correct and the proxy server ACLs do not forbid requests to %s.'
                  ) % (url, )
            ])
            MODULE.warn(warning)
            raise Warning(warning)
    finally:
        curl.close()
def reset_password_interval(umc_instance):
    MODULE.process('Resetting server/password/interval=21')
    ucr_set(['server/password/interval=21'])
    return run(umc_instance, retest=True)
def adjust(_umc_instance):
    MODULE.process('Setting samba/max_open_files')
    handler_set(['samba/max_open_files=%d' % (suggested_max_open_files, )])
    raise ProblemFixed(
        _('The limits have been adjusted to the suggested value.'), buttons=[])