예제 #1
0
def test_compact_db_task(topo):
    """Test creation of dbcompact task is successful

    :id: 1b3222ef-a336-4259-be21-6a52f76e1859
    :customerscenario: True
    :setup: Standalone Instance
    :steps:
        1. Create task
        2. Check task was successful
        3. Check errors log to show task was run
        4. Create task just for changelog
    :expectedresults:
        1. Success
        2. Success
        3. Success
        4. Success
    """
    inst = topo.ms["supplier1"]

    task = DBCompactTask(inst)
    task.create()
    task.wait()
    assert task.get_exit_code() == 0

    # Check errors log to make sure task actually compacted db
    assert inst.searchErrorsLog("Compacting databases")
    inst.deleteErrorLogs()

    # Create new task that only compacts changelog
    task = DBCompactTask(inst)
    task_properties = {'justChangelog': 'yes'}
    task.create(properties=task_properties)
    task.wait()
    assert task.get_exit_code() == 0

    # On bdb, check errors log to make sure task only performed changelog compaction
    # Note: as mdb contains a single map file (the justChangelog flags has
    #       no impact (and whole db is compacted))
    if get_default_db_lib() == "bdb":
        assert inst.searchErrorsLog("Compacting DB") == False
        assert inst.searchErrorsLog("Compacting Replication Changelog")
    inst.deleteErrorLogs(restart=False)
예제 #2
0
    def create_from_cli(self):
        # Ask questions to generate general, slapd, and backends
        print('Install Directory Server (interactive mode)')
        print('===========================================')

        # Set the defaults
        general = {
            'config_version': 2,
            'full_machine_name': socket.getfqdn(),
            'strict_host_checking': False,
            'selinux': True,
            'systemd': ds_paths.with_systemd,
            'defaults': '999999999',
            'start': True
        }

        slapd = {
            'self_sign_cert_valid_months': 24,
            'group': ds_paths.group,
            'root_dn': ds_paths.root_dn,
            'initconfig_dir': ds_paths.initconfig_dir,
            'self_sign_cert': True,
            'root_password': '',
            'port': 389,
            'instance_name': 'localhost',
            'user': ds_paths.user,
            'secure_port': 636,
            'prefix': ds_paths.prefix,
            'bin_dir': ds_paths.bin_dir,
            'sbin_dir': ds_paths.sbin_dir,
            'sysconf_dir': ds_paths.sysconf_dir,
            'data_dir': ds_paths.data_dir,
            'local_state_dir': ds_paths.local_state_dir,
            'ldapi': ds_paths.ldapi,
            'lib_dir': ds_paths.lib_dir,
            'run_dir': ds_paths.run_dir,
            'tmp_dir': ds_paths.tmp_dir,
            'cert_dir': ds_paths.cert_dir,
            'config_dir': ds_paths.config_dir,
            'inst_dir': ds_paths.inst_dir,
            'backup_dir': ds_paths.backup_dir,
            'db_dir': ds_paths.db_dir,
            'db_home_dir': ds_paths.db_home_dir,
            'db_lib': get_default_db_lib(),
            'ldif_dir': ds_paths.ldif_dir,
            'lock_dir': ds_paths.lock_dir,
            'log_dir': ds_paths.log_dir,
            'schema_dir': ds_paths.schema_dir
        }

        # Let them know about the selinux status
        if not selinux_present():
            val = input(
                '\nSelinux support will be disabled, continue? [yes]: ')
            if val.strip().lower().startswith('n'):
                return

        # Start asking questions, beginning with the hostname...
        val = input('\nEnter system\'s hostname [{}]: '.format(
            general['full_machine_name'])).rstrip()
        if val != "":
            general['full_machine_name'] = val

        # Instance name - adjust defaults once set
        while 1:
            slapd['instance_name'] = general['full_machine_name'].split(
                '.', 1)[0]

            # Check if default server id is taken
            if self._server_id_taken(slapd['instance_name'],
                                     prefix=slapd['prefix']):
                slapd['instance_name'] = ""

            val = input('\nEnter the instance name [{}]: '.format(
                slapd['instance_name'])).rstrip()
            if val != "":
                if len(val) > 80:
                    print(
                        "Server identifier should not be longer than 80 symbols"
                    )
                    continue
                if not all(ord(c) < 128 for c in val):
                    print(
                        "Server identifier can not contain non ascii characters"
                    )
                    continue
                if ' ' in val:
                    print("Server identifier can not contain a space")
                    continue
                if val == 'admin':
                    print(
                        "Server identifier \"admin\" is reserved, please choose a different identifier"
                    )
                    continue

                # Check that valid characters are used
                safe = re.compile(r'^[#%:\w@_-]+$').search
                if not bool(safe(val)):
                    print(
                        "Server identifier has invalid characters, please choose a different value"
                    )
                    continue

                # Check if server id is taken
                if self._server_id_taken(val, prefix=slapd['prefix']):
                    print(
                        "Server identifier \"{}\" is already taken, please choose a new name"
                        .format(val))
                    continue

                # instance name is good
                slapd['instance_name'] = val
                break
            elif slapd['instance_name'] == "":
                continue
            else:
                # Check if default server id is taken
                if self._server_id_taken(slapd['instance_name'],
                                         prefix=slapd['prefix']):
                    print(
                        "Server identifier \"{}\" is already taken, please choose a new name"
                        .format(slapd['instance_name']))
                    continue
                break

        # Finally have a good server id, adjust the default paths
        for key, value in slapd.items():
            if isinstance(value, str):
                slapd[key] = value.format(instance_name=slapd['instance_name'])

        # Non-Secure Port
        if not socket_check_open('::1', slapd['port']):
            port = get_port(slapd['port'], slapd['port'])
        else:
            # Port 389 is already taken, pick another port
            port = get_port(slapd['port'], "")
        slapd['port'] = port

        # Self-Signed Cert DB
        while 1:
            val = input('\nCreate self-signed certificate database [yes]: '
                        ).rstrip().lower()
            if val != "":
                if val == 'no' or val == "n":
                    slapd['self_sign_cert'] = False
                    break
                elif val == "yes" or val == "y":
                    # Default value is already yes
                    break
                else:
                    print('Invalid value "{}", please use "yes" or "no"')
                    continue
            else:
                # use default
                break

        # Secure Port (only if using self signed cert)
        if slapd['self_sign_cert']:
            if not socket_check_open('::1', slapd['secure_port']):
                port = get_port(slapd['secure_port'],
                                slapd['secure_port'],
                                secure=True)
            else:
                # Port 636 is already taken, pick another port
                port = get_port(slapd['secure_port'], "", secure=True)
            slapd['secure_port'] = port
        else:
            slapd['secure_port'] = False

        # Root DN
        while 1:
            val = input('\nEnter Directory Manager DN [{}]: '.format(
                slapd['root_dn'])).rstrip()
            if val != '':
                # Validate value is a DN
                if is_a_dn(val, allow_anon=False):
                    slapd['root_dn'] = val
                    break
                else:
                    print('The value "{}" is not a valid DN'.format(val))
                    continue
            else:
                # use default
                break

        # Root DN Password
        while 1:
            rootpw1 = getpass.getpass(
                '\nEnter the Directory Manager password: '******'':
                print('Password can not be empty')
                continue

            if len(rootpw1) < 8:
                print('Password must be at least 8 characters long')
                continue

            rootpw2 = getpass.getpass(
                'Confirm the Directory Manager Password: '******'Passwords do not match')
                continue

            # Passwords match, set it
            slapd['root_password'] = rootpw1
            break

        # Backend   [{'name': 'userroot', 'suffix': 'dc=example,dc=com'}]
        backend = {'name': 'userroot', 'suffix': ''}
        backends = [backend]
        suffix = ''
        domain_comps = general['full_machine_name'].split('.')
        for comp in domain_comps:
            if suffix == '':
                suffix = "dc=" + comp
            else:
                suffix += ",dc=" + comp

        while 1:
            val = input(
                "\nEnter the database suffix (or enter \"none\" to skip) [{}]: "
                .format(suffix)).rstrip()
            if val != '':
                if val.lower() == "none":
                    # No database, no problem
                    backends = []
                    break
                if is_a_dn(val, allow_anon=False):
                    backend['suffix'] = val
                    break
                else:
                    print("The suffix \"{}\" is not a valid DN".format(val))
                    continue
            else:
                backend['suffix'] = suffix
                break

        # Add sample entries or root suffix entry?
        if len(backends) > 0:
            while 1:
                val = input("\nCreate sample entries in the suffix [no]: "
                            ).rstrip().lower()
                if val != "":
                    if val == "no" or val == "n":
                        break
                    if val == "yes" or val == "y":
                        backend['sample_entries'] = INSTALL_LATEST_CONFIG
                        break

                    # Unknown value
                    print(
                        "Value \"{}\" is invalid, please use \"yes\" or \"no\""
                        .format(val))
                    continue
                else:
                    break

            if 'sample_entries' not in backend:
                # Check if they want to create the root node entry instead
                while 1:
                    val = input("\nCreate just the top suffix entry [no]: "
                                ).rstrip().lower()
                    if val != "":
                        if val == "no" or val == "n":
                            break
                        if val == "yes" or val == "y":
                            backend['create_suffix_entry'] = True
                            break

                        # Unknown value
                        print(
                            "Value \"{}\" is invalid, please use \"yes\" or \"no\""
                            .format(val))
                        continue
                    else:
                        break

        # Start the instance?
        while 1:
            val = input(
                '\nDo you want to start the instance after the installation? [yes]: '
            ).rstrip().lower()
            if val == '' or val == 'yes' or val == 'y':
                # Default behaviour
                break
            elif val == "no" or val == 'n':
                general['start'] = False
                break
            else:
                print('Invalid value, please use \"yes\" or \"no\"')
                continue

        # Are you ready?
        while 1:
            val = input('\nAre you ready to install? [no]: ').rstrip().lower()
            if val == '' or val == "no" or val == 'n':
                print('Aborting installation...')
                sys.exit(0)
            elif val == 'yes' or val == 'y':
                # lets do it!
                break
            else:
                print('Invalid value, please use \"yes\" or \"no\"')
                continue

        self.create_from_args(general, slapd, backends, self.extra)

        return True
예제 #3
0
    task = DBCompactTask(inst)
    task_properties = {'justChangelog': 'yes'}
    task.create(properties=task_properties)
    task.wait()
    assert task.get_exit_code() == 0

    # On bdb, check errors log to make sure task only performed changelog compaction
    # Note: as mdb contains a single map file (the justChangelog flags has
    #       no impact (and whole db is compacted))
    if get_default_db_lib() == "bdb":
        assert inst.searchErrorsLog("Compacting DB") == False
        assert inst.searchErrorsLog("Compacting Replication Changelog")
    inst.deleteErrorLogs(restart=False)


@pytest.mark.skipif(get_default_db_lib() == "mdb",
                    reason="Not supported over mdb")
def test_compaction_interval_and_time(topo):
    """Test dbcompact is successful when nsslapd-db-compactdb-interval and nsslapd-db-compactdb-time is set

    :id: f361bee9-d7e7-4569-9255-d7b60dd9d92e
    :customerscenario: True
    :setup: Supplier Instance
    :steps:
        1. Configure compact interval and time
        2. Check compaction occurs as expected
    :expectedresults:
        1. Success
        2. Success
    """
예제 #4
0
def test_huge_index_key(topo, add_users):
    """
    Test very long indexed attribute values (that should be hashed on mdb)

    :id: 4bbd0ee2-0108-11ec-a5ce-482ae39447e5
    :customerscenario: False
    :setup: Standalone instance
    :steps:
        1. Add users
        2. Change nsslapd-idlistscanlimit to a smaller value to accelerate the reproducer
        3. Replace sn with a 600 bytes value
        4. equality search for the sn
        5. Range search including the sn
        6. Replace sn back with small value
        7. equality search for the sn
        8. Range search including the sn
    :expectedresults:
        1. Should succeed
        2. Should succeed
        3. Should succeed
        4. Should succeed and have exactly 1 result
           search should be indexed.
        5. Should succeed and have exactly 3 results
           on bdb: search should be indexed.
           on mdb: search should be unindexed.
        6. Should succeed
        7. Should succeed and have exactly 1 result
           search should be indexed.
        8. Should succeed and have exactly 3 results
           search should be indexed.
    """
    inst = topo.standalone
    ldc = super(DirSrv, inst)
    # ldap connection to be able to use
    #  the SimpleLDAPObject methods
    shortsn = 'test_020'
    test_user = users_list[20]
    log.debug(
        f'Check user {test_user} sn: {test_user.get_attr_val_utf8("sn")}')
    assert (test_user)

    users = UserAccounts(topo.standalone, DEFAULT_SUFFIX, rdn=None)
    log.debug(f'Check users {users.list()}')

    sn600b = shortsn + \
             "0001abcdefghijklmnopqrstuvwxyz0001abcdefghijklmnopqrstuvwxyz" + \
             "0002abcdefghijklmnopqrstuvwxyz0001abcdefghijklmnopqrstuvwxyz" + \
             "0003abcdefghijklmnopqrstuvwxyz0001abcdefghijklmnopqrstuvwxyz" + \
             "0004abcdefghijklmnopqrstuvwxyz0001abcdefghijklmnopqrstuvwxyz" + \
             "0005abcdefghijklmnopqrstuvwxyz0001abcdefghijklmnopqrstuvwxyz" + \
             "0006abcdefghijklmnopqrstuvwxyz0001abcdefghijklmnopqrstuvwxyz" + \
             "0007abcdefghijklmnopqrstuvwxyz0001abcdefghijklmnopqrstuvwxyz" + \
             "0008abcdefghijklmnopqrstuvwxyz0001abcdefghijklmnopqrstuvwxyz" + \
             "0009abcdefghijklmnopqrstuvwxyz0001abcdefghijklmnopqrstuvwxyz" + \
             "0010abcdefghijklmnopqrstuvwxyz0001abcdefghijklmnopqrstuvwxyz"

    test_user.replace('sn', sn600b)
    result = ldc.search_s(base=DEFAULT_SUFFIX,
                          scope=ldap.SCOPE_SUBTREE,
                          filterstr=f'(sn={sn600b})')
    assert (len(result) == 1)
    assert (not inst.searchAccessLog("notes=U"))
    result = ldc.search_s(base=DEFAULT_SUFFIX,
                          scope=ldap.SCOPE_SUBTREE,
                          filterstr=f'(&(sn>=test_019)(sn<=test_021))')
    #with pytest.raises(ldap.INVALID_SYNTAX):
    assert (len(result) == 3)
    if (get_default_db_lib() == "bdb"):
        assert (not inst.searchAccessLog("notes=U"))
    else:
        assert (inst.searchAccessLog("notes=U"))
    inst.deleteLog(inst.accesslog)
    test_user.replace('sn', shortsn)
    result = ldc.search_s(base=DEFAULT_SUFFIX,
                          scope=ldap.SCOPE_SUBTREE,
                          filterstr=f'(sn={shortsn})')
    assert (len(result) == 1)
    assert (not inst.searchAccessLog("notes=U"))
    result = ldc.search_s(base=DEFAULT_SUFFIX,
                          scope=ldap.SCOPE_SUBTREE,
                          filterstr=f'(&(sn>=test_019)(sn<=test_021))')
    assert (len(result) == 3)
    assert (not inst.searchAccessLog("notes=U"))
예제 #5
0
if DEBUGGING:
    logging.getLogger(__name__).setLevel(logging.DEBUG)
else:
    logging.getLogger(__name__).setLevel(logging.INFO)
log = logging.getLogger(__name__)

bdb_values = {
  'wait30' : 30
}

# Note: I still sometime get failure with a 60s timeout so lets use 90s
mdb_values = {
  'wait30' : 90
}

if get_default_db_lib() is 'bdb':
    values = bdb_values
else:
    values = mdb_values


def _generate_ldif(topo, no_no):
    """
    Will generate the ldifs
    """
    ldif_dir = topo.standalone.get_ldif_dir()
    import_ldif = ldif_dir + '/basic_import.ldif'
    if os.path.isfile(import_ldif):
        pass
    else:
        dbgen_users(topo.standalone, no_no, import_ldif, DEFAULT_SUFFIX)
예제 #6
0
                               REPLICATION_TRANSPORT, DEFAULT_BACKUPDIR,
                               RA_NAME, RA_BINDDN, RA_BINDPW, RA_METHOD,
                               RA_TRANSPORT_PROT, defaultProperties)
import json

pytestmark = pytest.mark.tier1

DEBUGGING = os.getenv("DEBUGGING", default=False)
if DEBUGGING:
    logging.getLogger(__name__).setLevel(logging.DEBUG)
else:
    logging.getLogger(__name__).setLevel(logging.INFO)
log = logging.getLogger(__name__)


@pytest.mark.skipif(get_default_db_lib() != "bdb",
                    reason="Test requires bdb files")
def test_mail_attr_repl(topo_r):
    """Check that no crash happens during mail attribute replication

    :id: 959edc84-05be-4bf9-a541-53afae482052
    :customerscenario: True
    :setup: Replication setup with supplier and consumer instances,
            test user on supplier
    :steps:
        1. Check that user was replicated to consumer
        2. Back up mail database file
        3. Remove mail attribute from the user entry
        4. Restore mail database
        5. Search for the entry with a substring 'mail=user*'
        6. Search for the entry once again to make sure that server is alive
예제 #7
0
    def __init__(self, log):
        super(Slapd2Base, self).__init__(log)
        self._section = 'slapd'

        self._options['instance_name'] = 'localhost'
        self._type['instance_name'] = str
        self._helptext['instance_name'] = "Sets the name of the instance. You can refer to this value in other parameters of this INF file using the \"{instance_name}\" variable. Note that this name cannot be changed after the installation!"

        self._options['user'] = ds_paths.user
        self._type['user'] = str
        self._helptext['user'] = "******"
        self._advanced['user'] = True

        self._options['group'] = ds_paths.group
        self._type['group'] = str
        self._helptext['group'] = "Sets the group name the ns-slapd process will use after the service started."
        self._advanced['group'] = True

        self._options['root_dn'] = ds_paths.root_dn
        self._type['root_dn'] = str
        self._helptext['root_dn'] = "Sets the Distinquished Name (DN) of the administrator account for this instance. It is recommended that you do not change this value from the default \"cn=Directory Manager\""
        self._advanced['root_dn'] = True

        self._options['root_password'] = '******'
        self._type['root_password'] = str
        self._helptext['root_password'] = ("Sets the password of the \"cn=Directory Manager\" account (\"root_dn\" parameter)." +
                                           "You can either set this parameter to a plain text password dscreate hashes " +
                                           "during the installation or to a \"{algorithm}hash\" string generated by the " +
                                           "pwdhash utility. The password must be at least 8 characters long.  Note " +
                                           "that setting a plain text password can be a security risk if unprivileged " +
                                           "users can read this INF file!")

        self._options['prefix'] = ds_paths.prefix
        self._type['prefix'] = str
        self._helptext['prefix'] = "Sets the file system prefix for all other directories. You can refer to this value in other fields using the {prefix} variable or the $PREFIX environment variable. Only set this parameter in a development environment."
        self._advanced['prefix'] = True

        self._options['port'] = 389
        self._type['port'] = int
        self._helptext['port'] = "Sets the TCP port the instance uses for LDAP connections."

        self._options['secure_port'] = 636
        self._type['secure_port'] = int
        self._helptext['secure_port'] = "Sets the TCP port the instance uses for TLS-secured LDAP connections (LDAPS)."

        self._options['self_sign_cert'] = True
        self._type['self_sign_cert'] = bool
        self._helptext['self_sign_cert'] = "Sets whether the setup creates a self-signed certificate and enables TLS encryption during the installation. The certificate is not suitable for production, but it enables administrators to use TLS right after the installation. You can replace the self-signed certificate with a certificate issued by a Certificate Authority. If set to False, you can enable TLS later by importing a CA/Certificate and enabling 'dsconf <instance_name> config replace nsslapd-security=on'"

        self._options['self_sign_cert_valid_months'] = 24
        self._type['self_sign_cert_valid_months'] = int
        self._helptext['self_sign_cert_valid_months'] = "Set the number of months the issued self-signed certificate will be valid."

        # In the future, make bin and sbin /usr/[s]bin, but we may need autotools assistance from Ds
        self._options['bin_dir'] = ds_paths.bin_dir
        self._type['bin_dir'] = str
        self._helptext['bin_dir'] = "Sets the location where the Directory Server binaries are stored. Only set this parameter in a development environment."
        self._advanced['bin_dir'] = True

        self._options['sbin_dir'] = ds_paths.sbin_dir
        self._type['sbin_dir'] = str
        self._helptext['sbin_dir'] = "Sets the location where the Directory Server administration binaries are stored. Only set this parameter in a development environment."
        self._advanced['sbin_dir'] = True

        self._options['sysconf_dir'] = ds_paths.sysconf_dir
        self._type['sysconf_dir'] = str
        self._helptext['sysconf_dir'] = "Sets the location of the system's configuration directory. Only set this parameter in a development environment."
        self._advanced['sysconf_dir'] = True

        self._options['initconfig_dir'] = ds_paths.initconfig_dir
        self._type['initconfig_dir'] = str
        self._helptext['initconfig_dir'] = "Sets the directory of the operating system's rc configuration directory. Only set this parameter in a development environment."
        self._advanced['initconfig_dir'] = True

        # In the future, make bin and sbin /usr/[s]bin, but we may need autotools assistance from Ds
        self._options['data_dir'] = ds_paths.data_dir
        self._type['data_dir'] = str
        self._helptext['data_dir'] = "Sets the location of Directory Server shared static data. Only set this parameter in a development environment."
        self._advanced['data_dir'] = True

        self._options['local_state_dir'] = ds_paths.local_state_dir
        self._type['local_state_dir'] = str
        self._helptext['local_state_dir'] = "Sets the location of Directory Server variable data. Only set this parameter in a development environment."
        self._advanced['local_state_dir'] = True

        self._options['ldapi'] = ds_paths.ldapi
        self._type['ldapi'] = str
        self._helptext['ldapi'] = "Sets the location of socket interface of the Directory Server."

        self._options['lib_dir'] = ds_paths.lib_dir
        self._type['lib_dir'] = str
        self._helptext['lib_dir'] = "Sets the location of Directory Server shared libraries. Only set this parameter in a development environment."
        self._advanced['lib_dir'] = True

        self._options['cert_dir'] = ds_paths.cert_dir
        self._type['cert_dir'] = str
        self._helptext['cert_dir'] = "Sets the directory of the instance's Network Security Services (NSS) database."
        self._advanced['cert_dir'] = True

        self._options['config_dir'] = ds_paths.config_dir
        self._type['config_dir'] = str
        self._helptext['config_dir'] = "Sets the configuration directory of the instance."
        self._advanced['config_dir'] = True

        self._options['inst_dir'] = ds_paths.inst_dir
        self._type['inst_dir'] = str
        self._helptext['inst_dir'] = "Sets the directory of instance-specific scripts."
        self._advanced['inst_dir'] = True

        self._options['backup_dir'] = ds_paths.backup_dir
        self._type['backup_dir'] = str
        self._helptext['backup_dir'] = "Set the backup directory of the instance."
        self._advanced['backup_dir'] = True

        self._options['db_dir'] = ds_paths.db_dir
        self._type['db_dir'] = str
        self._helptext['db_dir'] = "Sets the database directory of the instance."
        self._advanced['db_dir'] = True

        self._options['db_home_dir'] = ds_paths.db_home_dir
        self._type['db_home_dir'] = str
        self._helptext['db_home_dir'] = "Sets the memory-mapped database files location of the instance."
        self._advanced['db_home_dir'] = True

        self._options['db_lib'] = get_default_db_lib()
        self._type['db_lib'] = str
        self._helptext['db_lib'] = "Select the database implementation library (bdb or mdb)."
        self._advanced['db_lib'] = True

        self._options['ldif_dir'] = ds_paths.ldif_dir
        self._type['ldif_dir'] = str
        self._helptext['ldif_dir'] = "Sets the LDIF export and import directory of the instance."
        self._advanced['ldif_dir'] = True

        self._options['lock_dir'] = ds_paths.lock_dir
        self._type['lock_dir'] = str
        self._helptext['lock_dir'] = "Sets the lock directory of the instance."
        self._advanced['lock_dir'] = True

        self._options['log_dir'] = ds_paths.log_dir
        self._type['log_dir'] = str
        self._helptext['log_dir'] = "Sets the log directory of the instance."
        self._advanced['log_dir'] = True

        self._options['run_dir'] = ds_paths.run_dir
        self._type['run_dir'] = str
        self._helptext['run_dir'] = "Sets PID directory of the instance."
        self._advanced['run_dir'] = True

        self._options['schema_dir'] = ds_paths.schema_dir
        self._type['schema_dir'] = str
        self._helptext['schema_dir'] = "Sets schema directory of the instance."
        self._advanced['schema_dir'] = True

        self._options['tmp_dir'] = ds_paths.tmp_dir
        self._type['tmp_dir'] = str
        self._helptext['tmp_dir'] = "Sets the temporary directory of the instance."
        self._advanced['tmp_dir'] = True
예제 #8
0
    def initInstance(self):
        if (self._instance):
            return self._instance
        uidpath = self.getFilePath("uids")
        nb_uids = 0
        try:
            with open(uidpath, 'r') as f:
                while f.readline():
                    nb_uids += 1
        except FileNotFoundError:
            pass
        nb_users = self._options['nbUsers']
        need_rebuild = True
        if (nb_uids == nb_users):
            # Lets try to reuse existing instance
            try:
                self._instance = DirSrv(verbose=True)
                self._instance.local_simple_allocate(serverid="standalone1",
                                                     password=PW_DM)
                self._instance.open()
                if (self._instance.exists()):
                    if (self._instance.get_db_lib() == get_default_db_lib()):
                        need_rebuild = False
                    else:
                        print(
                            f"db is {self._instance.get_db_lib()} instead of {get_default_db_lib()} ==> instance must be rebuild"
                        )
                else:
                    print(f"missing instance ==> instance must be rebuild")
            except Exception:
                pass
        else:
            print(
                f"Instance has {nb_uids} users instead of {nb_users} ==> instance must be rebuild"
            )
        if (need_rebuild):
            print("Rebuilding standalone1 instance")
            # Should rebuild the instance from scratch
            topology = create_topology({ReplicaRole.STANDALONE: 1})
            self._instance = topology.standalone
            #  Adjust db size if needed (i.e about 670 K users)
            defaultDBsize = 1073741824
            entrySize = 1600  # Real size is around 1525
            if (self._instance.get_db_lib() == "mdb"
                    and nb_users * entrySize > defaultDBsize):
                mdb_config = LMDB_LDBMConfig(self._instance)
                mdb_config.replace("nsslapd-mdb-max-size",
                                   str(nb_users * entrySize))
                self._instance.restart()
            # Then populate the users
            useraccounts = UserAccounts(self._instance,
                                        self._options['suffix'])
            with open(uidpath, 'w') as f:
                uidgen = IdGeneratorWithNumbers(nb_users)
                cnGen = IdGeneratorWithNames(100)
                snGen = IdGeneratorWithNames(100)

                for uid in uidgen:
                    cn = cnGen.random()
                    sn = snGen.random()
                    rdn = f"uid={uid}"
                    osuid = uidgen.getIdx() + 1000
                    osgid = int(osuid % 100) + 1000
                    properties = {
                        'uid': uid,
                        'cn': cn,
                        'sn': sn,
                        'uidNumber': str(osuid),
                        'gidNumber': str(osgid),
                        'homeDirectory': f'/home/{uid}'
                    }
                    super(UserAccounts, useraccounts).create(rdn, properties)
                    f.write(f'{uid}\n')
        return self._instance