def _wait_for_drs_replication(ldap_filter, attrs=None, base=None, scope=ldb.SCOPE_SUBTREE, lp=None, timeout=360, delta_t=1, verbose=True, should_exist=True, controls=None):
	# type: (str, Union[List[str], None, str], Optional[str], int, Optional[LoadParm], int, int, bool, bool, Optional[List[str]]) -> None
	if not package_installed('univention-samba4'):
		if package_installed('univention-samba'):
			time.sleep(15)
			print('Sleeping 15 seconds as a workaround for http://forge.univention.org/bugzilla/show_bug.cgi?id=52145')
		elif verbose:
			print('wait_for_drs_replication(): skip, univention-samba4 not installed.')
		return
	if not attrs:
		attrs = ['dn']
	elif not isinstance(attrs, list):
		attrs = [attrs]

	if not lp:
		lp = LoadParm()
		lp.load('/etc/samba/smb.conf')
	samdb = SamDB("tdb://%s" % lp.private_path("sam.ldb"), session_info=system_session(lp), lp=lp)
	if not controls:
		controls = ["domain_scope:0"]
	if base is None:
		ucr = config_registry.ConfigRegistry()
		ucr.load()
		base = ucr['samba4/ldap/base']
	else:
		if len(ldap.dn.str2dn(base)[0]) > 1:
			if verbose:
				print('wait_for_drs_replication(): skip, multiple RDNs are not supported')
			return
	if not base:
		if verbose:
			print('wait_for_drs_replication(): skip, no samba domain found')
		return

	if verbose:
		print("Waiting for DRS replication, filter: %r, base: %r, scope: %r, should_exist: %r" % (ldap_filter, base, scope, should_exist), end=' ')
	t = t0 = time.time()
	while t < t0 + timeout:
		try:
			res = samdb.search(base=base, scope=scope, expression=ldap_filter, attrs=attrs, controls=controls)
			if bool(res) is bool(should_exist):
				if verbose:
					print("\nDRS replication took %d seconds" % (t - t0, ))
				return  # res
		except ldb.LdbError as exc:
			(_num, msg) = exc.args
			if _num == ldb.ERR_INVALID_DN_SYNTAX:
				raise
			if _num == ldb.ERR_NO_SUCH_OBJECT and not should_exist:
				if verbose:
					print("\nDRS replication took %d seconds" % (t - t0, ))
				return
			print("Error during samdb.search: %s" % (msg, ))

		print('.', end=' ')
		time.sleep(delta_t)
		t = time.time()
	raise DRSReplicationFailed("DRS replication for filter: %r failed due to timeout after %d sec." % (ldap_filter, t - t0))
def force_drs_replication(source_dc=None,
                          destination_dc=None,
                          partition_dn=None,
                          direction="in"):
    if not package_installed('univention-samba4'):
        print(
            'force_drs_replication(): skip, univention-samba4 not installed.')
        return
    if not source_dc:
        source_dc = get_available_s4connector_dc()
        if not source_dc:
            return 1

    if not destination_dc:
        destination_dc = socket.gethostname()

    if destination_dc == source_dc:
        return

    if not partition_dn:
        lp = LoadParm()
        lp.load('/etc/samba/smb.conf')
        samdb = SamDB("tdb://%s" % lp.private_path("sam.ldb"),
                      session_info=system_session(lp),
                      lp=lp)
        partition_dn = str(samdb.domain_dn())
        print("USING partition_dn:", partition_dn)

    if direction == "in":
        cmd = ("/usr/bin/samba-tool", "drs", "replicate", destination_dc,
               source_dc, partition_dn)
    else:
        cmd = ("/usr/bin/samba-tool", "drs", "replicate", source_dc,
               destination_dc, partition_dn)
    return subprocess.call(cmd)
def password_policy(complexity=False,
                    minimum_password_age=0,
                    maximum_password_age=3):
    if not package_installed('univention-samba4'):
        print('skipping samba password policy adjustment')
        yield
        return
    complexity = 'on' if complexity else 'off'
    minimum_password_age = str(minimum_password_age)
    maximum_password_age = str(maximum_password_age)
    min_pwd_age = subprocess.check_output(
        'samba-tool domain passwordsettings show | grep "Minimum password age" | sed s/[^0-9]*/""/',
        shell=True).strip()
    max_pwd_age = subprocess.check_output(
        'samba-tool domain passwordsettings show | grep "Maximum password age" | sed s/[^0-9]*/""/',
        shell=True).strip()
    pwd_complexity = subprocess.check_output(
        'samba-tool domain passwordsettings show | grep complexity | sed "s/Password complexity: //"',
        shell=True).strip()
    if complexity != pwd_complexity or minimum_password_age != min_pwd_age or maximum_password_age != max_pwd_age:
        subprocess.call([
            'samba-tool', 'domain', 'passwordsettings', 'set', '--min-pwd-age',
            minimum_password_age, '--max-pwd-age', maximum_password_age,
            '--complexity', complexity
        ])
    yield
    if complexity != pwd_complexity or minimum_password_age != min_pwd_age:
        subprocess.call([
            'samba-tool', 'domain', 'passwordsettings', 'set', '--min-pwd-age',
            min_pwd_age, '--max-pwd-age', max_pwd_age, '--complexity',
            pwd_complexity
        ])
Beispiel #4
0
    def move_object(self, modulename, wait_for_replication=True, check_for_drs_replication=False, **kwargs):
        if not modulename:
            raise UCSTestUDM_MissingModulename()
        dn = kwargs.get('dn')
        if not dn:
            raise UCSTestUDM_MissingDn()
        if dn not in self._cleanup.get(modulename, set()):
            raise UCSTestUDM_CannotModifyExistingObject(dn)

        cmd = self._build_udm_cmdline(modulename, 'move', kwargs)
        print('Moving %s object %s' % (modulename, _prettify_cmd(cmd)))
        child = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False)
        (stdout, stderr) = child.communicate()

        if child.returncode:
            raise UCSTestUDM_MoveUDMObjectFailed({'module': modulename, 'kwargs': kwargs, 'returncode': child.returncode, 'stdout': stdout, 'stderr': stderr})

        for line in stdout.splitlines():  # :pylint: disable-msg=E1103
            if line.startswith('Object modified: '):
                self._cleanup.get(modulename, []).remove(dn)

                new_dn = ldap.dn.dn2str(ldap.dn.str2dn(dn)[0:1] + ldap.dn.str2dn(kwargs.get('position', '')))
                self._cleanup.setdefault(modulename, []).append(new_dn)
                break
        else:
            raise UCSTestUDM_ModifyUDMUnknownDN({'module': modulename, 'kwargs': kwargs, 'stdout': stdout, 'stderr': stderr})

        if wait_for_replication:
            utils.wait_for_replication(verbose=False)
            if check_for_drs_replication:
                if utils.package_installed('univention-samba4'):
                    wait_for_drs_replication(ldap.filter.filter_format('cn=%s', (ldap.dn.str2dn(dn)[0][0][1],)))
        return new_dn
def wait_for_drs_replication(ldap_filter, attrs=None, base=None, scope=ldb.SCOPE_SUBTREE, lp=None, timeout=360, delta_t=1, verbose=True, should_exist=True, controls=None):
	if not package_installed('univention-samba4'):
		if verbose:
			print('wait_for_drs_replication(): skip, univention-samba4 not installed.')
		return
	if not lp:
		lp = LoadParm()
		lp.load('/etc/samba/smb.conf')
	if not attrs:
		attrs = ['dn']
	elif not isinstance(attrs, list):
		attrs = [attrs]

	samdb = SamDB("tdb://%s" % lp.private_path("sam.ldb"), session_info=system_session(lp), lp=lp)
	if not controls:
		controls = ["domain_scope:0"]
	if base is None:
		base = samdb.domain_dn()
	else:
		if len(ldap.dn.str2dn(base)[0]) > 1:
			if verbose:
				print('wait_for_drs_replication(): skip, multiple RDNs are not supported')
			return
	if not base or base == 'None':
		if verbose:
			print('wait_for_drs_replication(): skip, no samba domain found')
		return

	if verbose:
		print("Waiting for DRS replication, filter: %r, base: %r, scope: %r, should_exist: %r" % (ldap_filter, base, scope, should_exist), end=' ')
	t = t0 = time.time()
	while t < t0 + timeout:
		try:
			res = samdb.search(base=base, scope=scope, expression=ldap_filter, attrs=attrs, controls=controls)
			if res and should_exist:
				if verbose:
					print("\nDRS replication took %d seconds" % (t - t0, ))
				return res
			if not res and not should_exist:
				if verbose:
					print("\nDRS replication took %d seconds" % (t - t0, ))
				return res
		except ldb.LdbError as exc:
			(_num, msg) = exc.args
			if _num == ldb.ERR_INVALID_DN_SYNTAX:
				raise
			if _num == ldb.ERR_NO_SUCH_OBJECT and not should_exist:
				if verbose:
					print("\nDRS replication took %d seconds" % (t - t0, ))
				return
			print("Error during samdb.search: %s" % (msg, ))

		print('.', end=' ')
		time.sleep(delta_t)
		t = time.time()
	raise DRSReplicationFailed("DRS replication for filter: %r failed due to timeout after %d sec." % (ldap_filter, t - t0))
Beispiel #6
0
def wait_for_drs_replication(ldap_filter,
                             attrs=None,
                             base=None,
                             scope=ldb.SCOPE_SUBTREE,
                             lp=None,
                             timeout=360,
                             delta_t=1,
                             verbose=True):
    if not package_installed('univention-samba4'):
        if verbose:
            print 'wait_for_drs_replication(): skip, univention-samba4 not installed.'
        return
    if not lp:
        lp = LoadParm()
        lp.load('/etc/samba/smb.conf')
    if not attrs:
        attrs = ['dn']
    elif not isinstance(attrs, list):
        attrs = [attrs]

    samdb = SamDB("tdb://%s" % lp.private_path("sam.ldb"),
                  session_info=system_session(lp),
                  lp=lp)
    controls = ["domain_scope:0"]
    if base is None:
        base = samdb.domain_dn()
    if not base or base == 'None':
        if verbose:
            print 'wait_for_drs_replication(): skip, no samba domain found'
        return

    if verbose:
        print "Waiting for DRS replication, filter: '%s'" % (ldap_filter, ),
    t = t0 = time.time()
    while t < t0 + timeout:
        try:
            res = samdb.search(base=base,
                               scope=scope,
                               expression=ldap_filter,
                               attrs=attrs,
                               controls=controls)
            if res:
                if verbose:
                    print "\nDRS replication took %d seconds" % (t - t0, )
                return res
        except ldb.LdbError as (_num, msg):
            print "Error during samdb.search: %s" % (msg, )

        print '.',
        time.sleep(delta_t)
        t = time.time()
Beispiel #7
0
    def modify_object(self, modulename, wait_for_replication=True, check_for_drs_replication=False, **kwargs):
        """
        Modifies a LDAP object via UDM. Values for UDM properties can be passed via keyword arguments
        only and have to exactly match UDM property names (case-sensitive!).
        Please note: the object has to be created by create_object otherwise this call will raise an exception!

        :param str modulename: name of UDM module (e.g. 'users/user')
        """
        if not modulename:
            raise UCSTestUDM_MissingModulename()
        dn = kwargs.get('dn')
        if not dn:
            raise UCSTestUDM_MissingDn()
        if dn not in self._cleanup.get(modulename, set()):
            raise UCSTestUDM_CannotModifyExistingObject(dn)

        cmd = self._build_udm_cmdline(modulename, 'modify', kwargs)
        print('Modifying %s object with %s' % (modulename, _prettify_cmd(cmd)))
        child = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False)
        (stdout, stderr) = child.communicate()

        if child.returncode:
            raise UCSTestUDM_ModifyUDMObjectFailed({'module': modulename, 'kwargs': kwargs, 'returncode': child.returncode, 'stdout': stdout, 'stderr': stderr})

        for line in stdout.splitlines():  # :pylint: disable-msg=E1103
            if line.startswith('Object modified: '):
                dn = line.split('Object modified: ', 1)[-1]
                if dn != kwargs.get('dn'):
                    print('modrdn detected: %r ==> %r' % (kwargs.get('dn'), dn))
                    if kwargs.get('dn') in self._cleanup.get(modulename, []):
                        self._cleanup.setdefault(modulename, []).append(dn)
                        self._cleanup[modulename].remove(kwargs.get('dn'))
                break
            elif line.startswith('No modification: '):
                raise UCSTestUDM_NoModification({'module': modulename, 'kwargs': kwargs, 'stdout': stdout, 'stderr': stderr})
        else:
            raise UCSTestUDM_ModifyUDMUnknownDN({'module': modulename, 'kwargs': kwargs, 'stdout': stdout, 'stderr': stderr})

        if wait_for_replication:
            utils.wait_for_replication(verbose=False)
            if check_for_drs_replication:
                if utils.package_installed('univention-samba4'):
                    wait_for_drs_replication(ldap.filter.filter_format('cn=%s', (ldap.dn.str2dn(dn)[0][0][1],)))
        return dn
def force_drs_replication(source_dc=None, destination_dc=None, partition_dn=None, direction="in"):
	# type: (Optional[str], Optional[str], Optional[str], str) -> int
	if not package_installed('univention-samba4'):
		print('force_drs_replication(): skip, univention-samba4 not installed.')
		return 0

	src = source_dc or get_available_s4connector_dc()
	if not src:
		return 1

	dst = destination_dc or socket.gethostname()
	if src == dst:
		return 0

	if not partition_dn:
		ucr = config_registry.ConfigRegistry()
		ucr.load()
		partition_dn = str(ucr.get('samba4/ldap/base'))
		print("USING partition_dn:", partition_dn)

	cmd = ("/usr/bin/samba-tool", "drs", "replicate", dst, src, partition_dn)
	return subprocess.call(cmd)
Beispiel #9
0
    def create_object(self, modulename, wait_for_replication=True, check_for_drs_replication=False, **kwargs):
        r"""
        Creates a LDAP object via UDM. Values for UDM properties can be passed via keyword arguments
        only and have to exactly match UDM property names (case-sensitive!).

        :param str modulename: name of UDM module (e.g. 'users/user')
        :param bool wait_for_replication: delay return until Listener has settled.
        :param bool check_for_drs_replication: delay return until Samab4 has settled.
        :param \*\*kwargs:
        """
        if not modulename:
            raise UCSTestUDM_MissingModulename()

        dn = None
        cmd = self._build_udm_cmdline(modulename, 'create', kwargs)
        print('Creating %s object with %s' % (modulename, _prettify_cmd(cmd)))
        child = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False)
        (stdout, stderr) = child.communicate()

        if child.returncode:
            raise UCSTestUDM_CreateUDMObjectFailed({'module': modulename, 'kwargs': kwargs, 'returncode': child.returncode, 'stdout': stdout, 'stderr': stderr})

        # find DN of freshly created object and add it to cleanup list
        for line in stdout.splitlines():  # :pylint: disable-msg=E1103
            if line.startswith('Object created: ') or line.startswith('Object exists: '):
                dn = line.split(': ', 1)[-1]
                if not line.startswith('Object exists: '):
                    self._cleanup.setdefault(modulename, []).append(dn)
                break
        else:
            raise UCSTestUDM_CreateUDMUnknownDN({'module': modulename, 'kwargs': kwargs, 'stdout': stdout, 'stderr': stderr})

        if wait_for_replication:
            utils.wait_for_replication(verbose=False)
            if check_for_drs_replication:
                if utils.package_installed('univention-samba4'):
                    if "options" not in kwargs or "kerberos" in kwargs["options"]:
                        wait_for_drs_replication(ldap.filter.filter_format('cn=%s', (ldap.dn.str2dn(dn)[0][0][1],)))
        return dn
def append_dot(verify_list):
    """The S4-Connector appends dots to various dns records. Helper function to adjust a list."""
    if not package_installed('univention-s4-connector'):
        return verify_list
    return ['%s.' % (x, ) for x in verify_list]
def wait_for_s4connector(timeout=360, delta_t=1, s4cooldown_t=10):
    ucr = config_registry.ConfigRegistry()
    ucr.load()

    if not package_installed('univention-s4-connector'):
        print(
            'wait_for_s4connector(): skip, univention-s4-connector not installed.'
        )
        return
    if ucr.is_false('connector/s4/autostart'):
        print(
            'wait_for_s4connector(): skip, connector/s4/autostart is set to false.'
        )
        return
    conn = sqlite3.connect('/etc/univention/connector/s4internal.sqlite')
    c = conn.cursor()

    static_count = 0

    highestCommittedUSN = -1
    lastUSN = -1
    t = t0 = time.time()
    while t < t0 + timeout:
        time.sleep(delta_t)

        if not _ldap_replication_complete():
            continue

        previous_highestCommittedUSN = highestCommittedUSN

        highestCommittedUSN = -1
        ldbresult = subprocess.check_output([
            'ldbsearch',
            '--url',
            '/var/lib/samba/private/sam.ldb',
            '--scope',
            'base',
            '--basedn',
            '',
            'highestCommittedUSN',
        ])
        for line in ldbresult.split('\n'):
            line = line.strip()
            if line.startswith('highestCommittedUSN: '):
                highestCommittedUSN = line.replace('highestCommittedUSN: ', '')
                break
        else:
            raise KeyError('No highestCommittedUSN in ldbsearch')

        previous_lastUSN = lastUSN
        c.execute('select value from S4 where key=="lastUSN"')

        lastUSN = c.fetchone()[0]
        print('highestCommittedUSN: {}'.format(highestCommittedUSN))
        print('lastUSN: {}'.format(lastUSN))

        if not (lastUSN == highestCommittedUSN and lastUSN == previous_lastUSN
                and highestCommittedUSN == previous_highestCommittedUSN):
            static_count = 0
            print('Reset counter')
        else:
            static_count = static_count + 1
        print('Counter: %d' % static_count)
        if static_count * delta_t >= s4cooldown_t:
            return 0
        t = time.time()

    conn.close()
    raise WaitForS4ConnectorTimeout()
Beispiel #12
0
import random
import re
import subprocess
import time
import os
import sys
import shlex

import ldap.dn
import pytest

import univention.testing.strings as uts
import univention.testing.ucr
import univention.testing.utils as utils

printserver_installed = utils.package_installed('univention-printserver')
samba_common_bin_installed = utils.package_installed('samba-common-bin')

PRINTER_PROTOCOLS = ['usb://', 'ipp://', 'socket://', 'parallel://', 'http://']


def random_fqdn(
        ucr):  # type: (univention.testing.ucr.UCSTestConfigRegistry) -> str
    return '%s.%s' % (uts.random_name(), ucr.get('domainname'))


@pytest.mark.tags('udm')
@pytest.mark.roles('domaincontroller_master', 'domaincontroller_backup',
                   'domaincontroller_slave', 'memberserver')
@pytest.mark.exposure('careful')
def test_create_printer(ucr, udm):
Beispiel #13
0
def test_create_printer_and_check_printing_works(ucr, udm):
    """Create shares/printer and check if print access works"""
    ucr.load()
    admin_dn = ucr.get(
        'tests/domainadmin/account',
        'uid=Administrator,cn=users,%s' % (ucr.get('ldap/base'), ))
    admin_name = ldap.dn.str2dn(admin_dn)[0][0][1]
    password = ucr.get('tests/domainadmin/pwd', 'univention')

    spoolhost = '.'.join([ucr['hostname'], ucr['domainname']])
    acltype = random.choice(['allow all', 'allow'])

    properties = {
        'name': uts.random_name(),
        'location': uts.random_string(),
        'description': uts.random_name(),
        'spoolHost': spoolhost,
        'uri': '%s %s' % (
            random.choice(PRINTER_PROTOCOLS),
            uts.random_ip(),
        ),
        'model': 'hp-ppd/HP/HP_Business_Inkjet_2500C_Series.ppd',
        'producer':
        'cn=Generic,cn=cups,cn=univention,%s' % (ucr.get('ldap/base'), ),
        'sambaName': uts.random_name(),
        'ACLtype': acltype,
        'ACLUsers': admin_dn,
        'ACLGroups':
        'cn=Printer Admins,cn=groups,%s' % (ucr.get('ldap/base'), ),
    }

    print('*** Create shares/printer object')
    print_share_dn = udm.create_object('shares/printer',
                                       position='cn=printers,%s' %
                                       (ucr['ldap/base'], ),
                                       **properties)

    utils.verify_ldap_object(print_share_dn, {
        'cn': [properties['name']],
        'description': [properties['description']],
        'univentionObjectType': ['shares/printer'],
        'univentionPrinterACLGroups': [properties['ACLGroups']],
        'univentionPrinterACLUsers': [properties['ACLUsers']],
        'univentionPrinterACLtype': [properties['ACLtype']],
        'univentionPrinterLocation': [properties['location']],
        'univentionPrinterModel': [properties['model']],
        'univentionPrinterSambaName': [properties['sambaName']],
        'univentionPrinterSpoolHost': [properties['spoolHost']],
        'univentionPrinterURI': [properties['uri'].replace(' ', '')],
    },
                             delay=1)

    print('*** Modify shares/printer samba share name')
    properties['sambaName'] = uts.random_name()
    udm.modify_object('shares/printer',
                      dn=print_share_dn,
                      sambaName=properties['sambaName'])
    utils.verify_ldap_object(
        print_share_dn,
        {'univentionPrinterSambaName': [properties['sambaName']]},
        delay=1)

    delay = 15
    print('*** Wait %s seconds for listener postrun' % delay)
    time.sleep(delay)
    p = subprocess.Popen(['lpq', '-P', properties['name']], close_fds=True)
    p.wait()
    assert not p.returncode, "CUPS printer {} not created after {} seconds".format(
        properties['name'], delay)

    p = subprocess.Popen(
        ['su', admin_name, '-c',
         'lpr -P %s /etc/hosts' % properties['name']],
        close_fds=True)
    p.wait()
    assert not p.returncode, "Printing to CUPS printer {} as {} failed".format(
        properties['name'], admin_name)

    s4_dc_installed = utils.package_installed("univention-samba4")
    s3_file_and_print_server_installed = utils.package_installed(
        "univention-samba")
    smb_server = s3_file_and_print_server_installed or s4_dc_installed
    if smb_server:
        delay = 1
        time.sleep(delay)
        cmd = [
            'smbclient',
            '//localhost/%s' % properties['sambaName'], '-U',
            '%'.join([admin_name, password]), '-c', 'print /etc/hosts'
        ]
        print('\nRunning: %s' % ' '.join(cmd))
        p = subprocess.Popen(cmd, close_fds=True)
        p.wait()
        if p.returncode:
            share_definition = '/etc/samba/printers.conf.d/%s' % properties[
                'sambaName']
            with open(share_definition) as f:
                print('### Samba share file %s :' % share_definition)
                print(f.read())
            print('### testpam for that smb.conf section:')
            p = subprocess.Popen(
                ['testparm', '-s', '--section-name', properties['sambaName']],
                close_fds=True)
            p.wait()
            assert False, 'Samba printer share {} not accessible'.format(
                properties['sambaName'])

    p = subprocess.Popen(['lprm', '-P', properties['name'], '-'],
                         close_fds=True)
    p.wait()
#!/usr/share/ucs-test/runner /usr/bin/py.test -s
## desc: Test UMC authentication with expired accounts
## exposure: dangerous
## packages: [univention-management-console-server]
## roles: [domaincontroller_master, domaincontroller_backup]
## tags: [skip_admember]

import pytest
from univention.testing import utils
# TODO: test detection of expired password + account disabled + both
# TODO: test password history, complexity, length

samba4_installed = utils.package_installed('univention-samba4')


class TestPwdChangeNextLogin(object):
    """
	Ensure that the UMC PAM configuration for pam_unix.so + pam_krb5.so is correct.
	This is tested by UMC authenticating a user with pwdChangeNextLogin=1
	pam_ldap is therefore untested!
	"""

    PWD_CHANGE_NEXT_LOGIN_OPTIONS = [
        [],  # TODO: test without mail, person,
    ]

    @pytest.mark.parametrize('options', PWD_CHANGE_NEXT_LOGIN_OPTIONS)
    def test_expired_password_detection_create_pwdchangenextlogin(
            self, options, udm, Client, random_string, Unauthorized):
        print 'test_expired_password_detection_create_pwdchangenextlogin(%r)' % (
            options, )
    def test_container_cn_rename_uppercase_with_special_characters(
            self, udm, ucr):
        """Rename a container/cn with subobjects from lower to upper case"""
        if utils.package_installed('univention-s4-connector'):
            # this test is not stable with the s4-connector
            # somehow we end up with
            #
            # Creating container/cn object with /usr/sbin/udm-test container/cn create --position dc=four,dc=four --set 'name=ĝkn}_>ä%\6'
            # Waiting for connector replication
            # Modifying container/cn object with /usr/sbin/udm-test container/cn modify --dn 'cn=ĝkn}_\>ä%\\6,dc=four,dc=four' --set 'name=ĝKN}_>ä%\6'
            # modrdn detected: 'cn=\xc4\x9dkn}_\\>\xc3\xa4%\\\\6,dc=four,dc=four' ==> 'cn=\xc4\x9dKN}_\\>\xc3\xa4%\\\\6,dc=four,dc=four'
            # Waiting for connector replication
            # ### FAIL ###
            # #cn = ĝkn}_>ä%\6; expected: ĝKN}_>ä%\6
            pytest.skip('S4-Connector')

        def test_container(parent, add_user):
            if parent is None:
                parent = ucr.get('ldap/base')
            user_name = 'X' + uts.random_string(
            )  # test preserving name (case sensitivity)

            cn_name = uts.random_name_special_characters()
            cn_name_new = cn_name.upper()

            cn = udm.create_object('container/cn',
                                   position=parent,
                                   name=cn_name)
            if add_user:
                udm.create_user(position=cn, username=user_name)

            try:
                udm.modify_object('container/cn', dn=cn, name=cn_name_new)
            except AssertionError:
                pass
            lo = utils.get_ldap_connection()
            for dn, entry in lo.search(filter='ou=temporary_move_container_*'):
                to_be_removed = udm._cleanup.setdefault('container/ou', [])
                to_be_removed.append(dn)
                assert False, 'ou = %s remained' % dn

            new_cn = 'cn=%s,%s' % (ldap.dn.escape_dn_chars(cn_name_new),
                                   parent)
            new_user = '******' % (ldap.dn.escape_dn_chars(user_name),
                                      new_cn)

            utils.verify_ldap_object(new_cn, should_exist=True)
            if add_user:
                for dn, entry in lo.search(filter=ldap.filter.filter_format(
                        'uid=%s', [user_name])):
                    assert entry.get('uid')[0] == user_name.encode(
                        'UTF-8'
                    ), 'CASE SENSITIVITY: uid = %s; expected: %s' % (
                        entry.get('uid')[0], user_name)
                utils.verify_ldap_object(new_user, should_exist=True)

            for dn, entry in lo.search(
                    filter=ldap.filter.filter_format('cn=%s', [cn_name_new])):
                assert entry.get('cn')[0] == cn_name_new.encode(
                    'UTF-8'), 'cn = %s; expected: %s' % (entry.get('cn')[0],
                                                         cn_name_new)
            return new_cn

        # EMPTY
        # FIRST LEVEL
        first_level_container = test_container(parent=None, add_user=False)

        # SECOND LEVEL
        test_container(parent=first_level_container, add_user=False)

        # WITH USER
        # FIRST LEVEL
        first_level_container = test_container(parent=None, add_user=True)

        # SECOND LEVEL
        test_container(parent=first_level_container, add_user=True)
def wait_for_s4connector(timeout=360, delta_t=1, s4cooldown_t=5):
	# type: (int, int, int) -> int
	ucr = config_registry.ConfigRegistry()
	ucr.load()

	if not package_installed('univention-s4-connector'):
		print('wait_for_s4connector(): skip, univention-s4-connector not installed.')
		return 0
	if ucr.is_false('connector/s4/autostart'):
		print('wait_for_s4connector(): skip, connector/s4/autostart is set to false.')
		return 0
	conn = sqlite3.connect('/etc/univention/connector/s4internal.sqlite')
	c = conn.cursor()

	static_count = 0

	replication_complete = False
	highestCommittedUSN = -1
	lastUSN = -1
	t = t0 = time.time()
	while t < t0 + timeout:
		time.sleep(delta_t)

		if not _ldap_replication_complete(verbose=False):
			continue
		else:
			if not replication_complete:
				print('Start waiting for S4-Connector replication')
			replication_complete = True

		previous_highestCommittedUSN = highestCommittedUSN
		ldbresult = subprocess.Popen([
			'ldbsearch',
			'--url', '/var/lib/samba/private/sam.ldb',
			'--scope', 'base',
			'--basedn', '',
			'highestCommittedUSN',
		], stdout=subprocess.PIPE)
		assert ldbresult.stdout
		for chunk in ldbresult.stdout:
			line = chunk.decode('utf-8').strip()
			if line.startswith('highestCommittedUSN: '):
				highestCommittedUSN = int(line[len('highestCommittedUSN: '):])
				break
		else:
			raise KeyError('No highestCommittedUSN in ldbsearch')

		previous_lastUSN = lastUSN
		c.execute('select value from S4 where key=="lastUSN"')
		lastUSN = int(c.fetchone()[0])

		if not (lastUSN == highestCommittedUSN and lastUSN == previous_lastUSN and highestCommittedUSN == previous_highestCommittedUSN):
			static_count = 0
			print('Reset counter')
		else:
			static_count += 1

		print('Counter: {}; highestCommittedUSN: {!r}; lastUSN: {!r}'.format(static_count, highestCommittedUSN, lastUSN))

		if static_count * delta_t >= s4cooldown_t:
			return 0
		t = time.time()

	conn.close()
	raise WaitForS4ConnectorTimeout()
Beispiel #17
0
def wait_for_s4connector():
    ucr = config_registry.ConfigRegistry()
    ucr.load()

    if not package_installed('univention-s4-connector'):
        print 'wait_for_s4connector(): skip, univention-s4-connector not installed.'
        return
    if ucr.is_false('connector/s4/autostart'):
        print 'wait_for_s4connector(): skip, connector/s4/autostart is set to false.'
        return
    conn = sqlite3.connect('/etc/univention/connector/s4internal.sqlite')
    c = conn.cursor()

    static_count = 0

    highestCommittedUSN = -1
    lastUSN = -1
    while static_count < CONNECTOR_WAIT_INTERVAL:
        time.sleep(CONNECTOR_WAIT_SLEEP)

        if not _ldap_replication_complete():
            continue

        previous_highestCommittedUSN = highestCommittedUSN

        highestCommittedUSN = -1
        ldbsearch = subprocess.Popen(
            "ldbsearch -H /var/lib/samba/private/sam.ldb -s base -b '' highestCommittedUSN",
            shell=True,
            stdout=subprocess.PIPE)
        ldbresult = ldbsearch.communicate()
        for line in ldbresult[0].split('\n'):
            line = line.strip()
            if line.startswith('highestCommittedUSN: '):
                highestCommittedUSN = line.replace('highestCommittedUSN: ', '')
                break

        print highestCommittedUSN

        previous_lastUSN = lastUSN
        try:
            c.execute('select value from S4 where key=="lastUSN"')
        except sqlite3.OperationalError as e:
            static_count = 0
            print 'Reset counter: sqlite3.OperationalError: %s' % e
            print 'Counter: %d' % static_count
            continue

        conn.commit()
        lastUSN = c.fetchone()[0]

        if not (lastUSN == highestCommittedUSN and lastUSN == previous_lastUSN
                and highestCommittedUSN == previous_highestCommittedUSN):
            static_count = 0
            print 'Reset counter'
        else:
            static_count = static_count + 1
        print 'Counter: %d' % static_count

    conn.close()
    return 0