def remove_ldif_files_from_changelogdir(topo, extension): """ Remove existing ldif files from changelog dir """ if ds_supports_new_changelog(): changelog_dir = topo.ms['master1'].get_ldif_dir() else: changelog_dir = topo.ms['master1'].get_changelog_dir() log.info('Remove %s files, if present in: %s' % (extension, changelog_dir)) for files in os.listdir(changelog_dir): if files.endswith(extension): changelog_file = os.path.join(changelog_dir, files) try: os.remove(changelog_file) except OSError as e: log.fatal('Failed to remove %s file: %s' % (extension,changelog_file)) raise e else: log.info('Existing changelog %s file: %s removed' % (extension,changelog_file))
def _check_unhashed_userpw(inst, user_dn, is_present=False): """Check if unhashed#user#password attribute is present or not in the changelog""" unhashed_pwd_attribute = 'unhashed#user#password' if ds_supports_new_changelog(): dbscanOut = inst.dbscan(DEFAULT_BENAME, 'replication_changelog') else: changelog_dbdir = os.path.join(os.path.dirname(inst.dbdir), DEFAULT_CHANGELOG_DB) for changelog_dbfile in glob.glob(f'{changelog_dbdir}*/*.db*'): log.info( 'Changelog dbfile file exist: {}'.format(changelog_dbfile)) dbscanOut = inst.dbscan(DEFAULT_CHANGELOG_DB, changelog_dbfile) for entry in dbscanOut.split(b'dbid: '): if ensure_bytes('operation: modify') in entry and ensure_bytes( user_dn) in entry and ensure_bytes('userPassword') in entry: if is_present: assert ensure_bytes(unhashed_pwd_attribute) in entry else: assert ensure_bytes(unhashed_pwd_attribute) not in entry
def _create_changelog_dump(topo): """Dump changelog using nss5task and check if ldap operations are logged""" log.info('Dump changelog using nss5task and check if ldap operations are logged') if ds_supports_new_changelog(): changelog_dir = topo.ms['master1'].get_ldif_dir() changelog_end = '_cl.ldif' else: changelog_dir = topo.ms['master1'].get_changelog_dir() changelog_end = '.ldif' replicas = Replicas(topo.ms["master1"]) replica = replicas.get(DEFAULT_SUFFIX) log.info('Remove ldif files, if present in: {}'.format(changelog_dir)) for files in os.listdir(changelog_dir): if files.endswith(changelog_end): changelog_file = os.path.join(changelog_dir, files) try: os.remove(changelog_file) except OSError as e: log.fatal('Failed to remove ldif file: {}'.format(changelog_file)) raise e log.info('Existing changelog ldif file: {} removed'.format(changelog_file)) else: log.info('No existing changelog ldif files present') log.info('Running nsds5task to dump changelog database to a file') replica.begin_task_cl2ldif() log.info('Check if changelog ldif file exist in: {}'.format(changelog_dir)) for files in os.listdir(changelog_dir): if files.endswith(changelog_end): changelog_ldif = os.path.join(changelog_dir, files) log.info('Changelog ldif file exist: {}'.format(changelog_ldif)) return changelog_ldif else: log.fatal('Changelog ldif file does not exist in: {}'.format(changelog_dir)) assert False
def _check_unhashed_userpw_encrypted(inst, change_type, user_dn, user_pw, is_encrypted): """Check if unhashed#user#password attribute value is encrypted or not""" if ds_supports_new_changelog(): log.info('Running dbscan -f to check {} attr'.format(ATTRIBUTE)) dbscanOut = inst.dbscan(DEFAULT_BENAME, 'replication_changelog') else: changelog_dbdir = os.path.join(os.path.dirname(inst.dbdir), DEFAULT_CHANGELOG_DB) for changelog_dbfile in glob.glob(f'{changelog_dbdir}*/*.db*'): log.info('Changelog dbfile file exist: {}'.format(changelog_dbfile)) log.info('Running dbscan -f to check {} attr'.format(ATTRIBUTE)) dbscanOut = inst.dbscan(DEFAULT_CHANGELOG_DB, changelog_dbfile) count = 0 for entry in dbscanOut.split(b'dbid: '): if ensure_bytes('operation: {}'.format(change_type)) in entry and\ ensure_bytes(ATTRIBUTE) in entry and ensure_bytes(user_dn.lower()) in entry.lower(): count += 1 user_pw_attr = ensure_bytes('{}: {}'.format(ATTRIBUTE, user_pw)) if is_encrypted: assert user_pw_attr not in entry, 'Changelog entry contains clear text password' else: assert user_pw_attr in entry, 'Changelog entry does not contain clear text password' assert count, 'Operation type and DN of the entry not matched in changelog'
def test_dsconf_dump_changelog_files_removed(topo): """Verify that the python counterpart of cl-dump (using dsconf) has a correct management of generated files :id: e41dcf90-098a-4386-acb5-789384579bf7 :setup: Replication with two supplier, nsslapd-changelogdir is '/var/lib/dirsrv/slapd-supplier1/changelog' retrochangelog plugin disabled :steps: 1. Clean the changelog directory, removing .ldif files present, if any 2. Clean the changelog directory, removing .ldif.done files present, if any 3. Perform ldap operations to record replication changes 4. Try a dsconf call with invalid arguments to secure the next steps 5. Launch dsconf export-changelog cli without -l option 6. Wait so that all dsconf tasks be finished 7. Check that all .ldif.done generated files have been removed from the changelog dir 8. Launch dsconf export-changelog cli with -l option 9. Wait so that all dsconf tasks be finished 10. Check that the generated .ldif.done files are present in the changelog dir :expectedresults: 1. No remaining .ldif file in the changelog directory 2. No remaining .ldif.done file in the changelog directory 3. ldap operations are replicated and recorded in changelog 4. A result code different from 0 is raised 5. dsconf export-changelog is successfully executed 6. dsconf process has finished 7. No .ldif.done files in the changelog dir 8. dsconf export-changelog is successfully executed 9. dsconf process has finished 10. .ldif.done generated files are present in the changelog dir """ if ds_supports_new_changelog(): changelog_dir = topo.ms['supplier1'].get_ldif_dir() else: changelog_dir = topo.ms['supplier1'].get_changelog_dir() instance = topo.ms['supplier1'] instance_url = 'ldap://%s:%s' % (HOST_SUPPLIER_1, PORT_SUPPLIER_1) # Remove existing .ldif files in changelog dir remove_ldif_files_from_changelogdir(topo, '.ldif') # Remove existing .ldif.done files from changelog dir remove_ldif_files_from_changelogdir(topo, '.done') _perform_ldap_operations(topo) # This part to make sure that an error in the python dsconf export-changelog execution will be detected, # primary condition before executing the core goal of this case : management of generated files. log.info("Use dsconf export-changelog with invalid parameters") cmdline = [ '/usr/sbin/dsconf', instance_url, '-D', DN_DM, '-w', 'badpasswd', 'replication', 'export-changelog' ] log.info('Command used : %s' % cmdline) proc = subprocess.Popen(cmdline, stdout=subprocess.PIPE) msg = proc.communicate() log.info('output message : %s' % msg[0]) assert proc.returncode != 0 # Now the core goal of the test case # Using dsconf replication changelog without -l option log.info( 'Use dsconf replication changelog without -l option: no generated ldif files should be present in %s ' % changelog_dir) cmdline = [ '/usr/sbin/dsconf', instance_url, '-D', DN_DM, '-w', PASSWORD, 'replication', 'export-changelog', 'default', '-r', DEFAULT_SUFFIX ] log.info('Command used : %s' % cmdline) proc = subprocess.Popen(cmdline, stdout=subprocess.PIPE) proc.communicate() assert proc.returncode == 0 log.info('Wait for all dsconf export-changelog files to be generated') time.sleep(1) log.info( 'Check if dsconf export-changelog generated .ldif.done files are present - should not' ) for files in os.listdir(changelog_dir): if files.endswith('.done'): log.fatal( 'export-changelog generated .ldif.done files are present in %s - they should not' % changelog_dir) assert False else: log.info( 'All dsconf export-changelog generated .ldif files have been successfully removed from %s ' % changelog_dir) # Using dsconf replication changelog without -l option log.info( 'Use dsconf replication changelog with -l option: generated ldif files should be kept in %s ' % changelog_dir) cmdline = [ '/usr/sbin/dsconf', instance_url, '-D', DN_DM, '-w', PASSWORD, 'replication', 'export-changelog', 'to-ldif', '-o', changelog_dir + '/test.ldif', '-r', DEFAULT_SUFFIX, '-l' ] log.info('Command used : %s' % cmdline) proc = subprocess.Popen(cmdline, stdout=subprocess.PIPE) proc.communicate() assert proc.returncode == 0 log.info('Wait for all dsconf export-changelog files to be generated') time.sleep(1) log.info( 'Check if dsconf export-changelog generated .ldif.done files are present - should be' ) for files in os.listdir(changelog_dir): if files.endswith('.done'): cldump_file = os.path.join(changelog_dir, files) log.info('Success : ldif file %s is present' % cldump_file) break else: log.fatal('.ldif.done files are not present in %s - they should be' % changelog_dir) assert False
from lib389.properties import TASK_WAIT from lib389.replica import Replicas from lib389.idm.user import UserAccounts from lib389.topologies import topology_m2 as topo from lib389._constants import * from lib389.plugins import RetroChangelogPlugin from lib389.dseldif import DSEldif from lib389.tasks import * from lib389.utils import * from lib389.utils import ensure_bytes, ds_supports_new_changelog pytestmark = pytest.mark.tier1 TEST_ENTRY_NAME = 'replusr' NEW_RDN_NAME = 'cl5usr' if ds_supports_new_changelog(): CHANGELOG = 'cn=changelog,{}'.format(DN_USERROOT_LDBM) else: CHANGELOG = 'cn=changelog5,cn=config' RETROCHANGELOG = 'cn=Retro Changelog Plugin,cn=plugins,cn=config' MAXAGE = 'nsslapd-changelogmaxage' TRIMINTERVAL = 'nsslapd-changelogtrim-interval' COMPACTDBINTERVAL = 'nsslapd-changelogcompactdb-interval' FILTER = '(cn=*)' 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__)
from lib389.properties import TASK_WAIT from lib389.replica import Replicas from lib389.idm.user import UserAccounts from lib389.topologies import topology_m2 as topo from lib389._constants import * from lib389.plugins import RetroChangelogPlugin from lib389.dseldif import DSEldif from lib389.tasks import * from lib389.utils import * from lib389.utils import ensure_bytes, ds_supports_new_changelog pytestmark = pytest.mark.tier1 TEST_ENTRY_NAME = 'replusr' NEW_RDN_NAME = 'cl5usr' if ds_supports_new_changelog(): CHANGELOG = 'cn=changelog,{}'.format(DN_USERROOT_LDBM) else: CHANGELOG = 'cn=changelog5,cn=config' RETROCHANGELOG = 'cn=Retro Changelog Plugin,cn=plugins,cn=config' MAXAGE = 'nsslapd-changelogmaxage' TRIMINTERVAL = 'nsslapd-changelogtrim-interval' COMPACTDBINTERVAL = 'nsslapd-changelogcompactdb-interval' FILTER = '(cn=*)' 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__)