浏览代码

Ticket #47536 - CI test: added test cases for ticket 47536

Description: Allow usage of OpenLDAP libraries that don't use NSS for crypto

OpenLDAP has an ability to tell the application which crypto library is
linked with.  The DS supports the both cases (OpenLDAP+NSS and OpenLDAP+
OpenSSL) by switching the behaviour based upon the info.  This test also
works for both.

This test also covers:
    Ticket #48756 - if startTLS is enabled, perl utilities fail to start.
    Config param nsslapd-extract-pemfiles

https://fedorahosted.org/389/ticket/48536

Reviewed by [email protected] (Thank you, William!!!)
Noriko Hosoi 9 年之前
父节点
当前提交
e3c533534a
共有 1 个文件被更改,包括 528 次插入0 次删除
  1. 528 0
      dirsrvtests/tests/tickets/ticket47536_test.py

+ 528 - 0
dirsrvtests/tests/tickets/ticket47536_test.py

@@ -0,0 +1,528 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2016 Red Hat, Inc.
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+#
+import os
+import sys
+import time
+import shlex
+import subprocess
+import ldap
+import logging
+import pytest
+import base64
+from lib389 import DirSrv, Entry, tools, tasks
+from lib389.tools import DirSrvTools
+from lib389._constants import *
+from lib389.properties import *
+from lib389.tasks import *
+from lib389.utils import *
+
+logging.getLogger(__name__).setLevel(logging.DEBUG)
+log = logging.getLogger(__name__)
+
+installation1_prefix = None
+
+CONFIG_DN = 'cn=config'
+ENCRYPTION_DN = 'cn=encryption,%s' % CONFIG_DN
+RSA = 'RSA'
+RSA_DN = 'cn=%s,%s' % (RSA, ENCRYPTION_DN)
+ISSUER = 'cn=CAcert'
+CACERT = 'CAcertificate'
+M1SERVERCERT = 'Server-Cert1'
+M2SERVERCERT = 'Server-Cert2'
+M1LDAPSPORT = '41636'
+M2LDAPSPORT = '42636'
+
+class TopologyReplication(object):
+    def __init__(self, master1, master2):
+        master1.open()
+        self.master1 = master1
+        master2.open()
+        self.master2 = master2
+
+
[email protected](scope="module")
+def topology(request):
+    global installation1_prefix
+    if installation1_prefix:
+        args_instance[SER_DEPLOYED_DIR] = installation1_prefix
+
+    # Creating master 1...
+    master1 = DirSrv(verbose=False)
+    if installation1_prefix:
+        args_instance[SER_DEPLOYED_DIR] = installation1_prefix
+    args_instance[SER_HOST] = HOST_MASTER_1
+    args_instance[SER_PORT] = PORT_MASTER_1
+    args_instance[SER_SERVERID_PROP] = SERVERID_MASTER_1
+    args_instance[SER_CREATION_SUFFIX] = DEFAULT_SUFFIX
+    args_master = args_instance.copy()
+    master1.allocate(args_master)
+    instance_master1 = master1.exists()
+    if instance_master1:
+        master1.delete()
+    master1.create()
+    master1.open()
+    master1.replica.enableReplication(suffix=SUFFIX, role=REPLICAROLE_MASTER, replicaId=REPLICAID_MASTER_1)
+
+    # Creating master 2...
+    master2 = DirSrv(verbose=True)
+    if installation1_prefix:
+        args_instance[SER_DEPLOYED_DIR] = installation1_prefix
+    args_instance[SER_HOST] = HOST_MASTER_2
+    args_instance[SER_PORT] = PORT_MASTER_2
+    args_instance[SER_SERVERID_PROP] = SERVERID_MASTER_2
+    args_instance[SER_CREATION_SUFFIX] = DEFAULT_SUFFIX
+    args_master = args_instance.copy()
+    master2.allocate(args_master)
+    instance_master2 = master2.exists()
+    if instance_master2:
+        master2.delete()
+    master2.create()
+    master2.open()
+    master2.replica.enableReplication(suffix=SUFFIX, role=REPLICAROLE_MASTER, replicaId=REPLICAID_MASTER_2)
+
+    #
+    # Create all the agreements
+    #
+    # Creating agreement from master 1 to master 2
+    properties = {RA_NAME:      r'meTo_%s:%s' % (master2.host, master2.port),
+                  RA_BINDDN:    defaultProperties[REPLICATION_BIND_DN],
+                  RA_BINDPW:    defaultProperties[REPLICATION_BIND_PW],
+                  RA_METHOD:    defaultProperties[REPLICATION_BIND_METHOD],
+                  RA_TRANSPORT_PROT: defaultProperties[REPLICATION_TRANSPORT]}
+    global m1_m2_agmt
+    m1_m2_agmt = master1.agreement.create(suffix=SUFFIX, host=master2.host, port=master2.port, properties=properties)
+    if not m1_m2_agmt:
+        log.fatal("Fail to create a master -> master replica agreement")
+        sys.exit(1)
+    log.debug("%s created" % m1_m2_agmt)
+
+    # Creating agreement from master 2 to master 1
+    properties = {RA_NAME:      r'meTo_%s:%s' % (master1.host, master1.port),
+                  RA_BINDDN:    defaultProperties[REPLICATION_BIND_DN],
+                  RA_BINDPW:    defaultProperties[REPLICATION_BIND_PW],
+                  RA_METHOD:    defaultProperties[REPLICATION_BIND_METHOD],
+                  RA_TRANSPORT_PROT: defaultProperties[REPLICATION_TRANSPORT]}
+    global m2_m1_agmt
+    m2_m1_agmt = master2.agreement.create(suffix=SUFFIX, host=master1.host, port=master1.port, properties=properties)
+    if not m2_m1_agmt:
+        log.fatal("Fail to create a master -> master replica agreement")
+        sys.exit(1)
+    log.debug("%s created" % m2_m1_agmt)
+
+    # Allow the replicas to get situated with the new agreements...
+    time.sleep(2)
+
+    global M1SUBJECT
+    M1SUBJECT = 'CN=%s,OU=389 Directory Server' % (master1.host)
+    global M2SUBJECT
+    M2SUBJECT = 'CN=%s,OU=390 Directory Server' % (master2.host)
+
+    #
+    # Initialize all the agreements
+    #
+    master1.agreement.init(SUFFIX, HOST_MASTER_2, PORT_MASTER_2)
+    master1.waitForReplInit(m1_m2_agmt)
+
+    # Check replication is working...
+    if master1.testReplication(DEFAULT_SUFFIX, master2):
+        log.info('Replication is working.')
+    else:
+        log.fatal('Replication is not working.')
+        assert False
+
+    # Delete each instance in the end
+    def fin():
+       master1.delete()
+       master2.delete()
+    request.addfinalizer(fin)
+
+    # Clear out the tmp dir
+    master1.clearTmpDir(__file__)
+
+    return TopologyReplication(master1, master2)
+
+
[email protected](scope="module")
+
+
+def add_entry(server, name, rdntmpl, start, num):
+    log.info("\n######################### Adding %d entries to %s ######################\n" % (num, name))
+
+    for i in range(num):
+        ii = start + i
+        dn = '%s%d,%s' % (rdntmpl, ii, DEFAULT_SUFFIX)
+        server.add_s(Entry((dn, {'objectclass': 'top person extensibleObject'.split(),
+                                 'uid': '%s%d' % (rdntmpl, ii),
+                                 'cn': '%s user%d' % (name, ii),
+                                 'sn': 'user%d' % (ii)})))
+
+def enable_ssl(server, ldapsport, mycert):
+    log.info("\n######################### Enabling SSL LDAPSPORT %s ######################\n" % ldapsport)
+    server.simple_bind_s(DN_DM, PASSWORD)
+    server.modify_s(ENCRYPTION_DN, [(ldap.MOD_REPLACE, 'nsSSL3', 'off'),
+                                    (ldap.MOD_REPLACE, 'nsTLS1', 'on'),
+                                    (ldap.MOD_REPLACE, 'nsSSLClientAuth', 'allowed'),
+                                    (ldap.MOD_REPLACE, 'nsSSL3Ciphers', '+all')])
+
+    server.modify_s(CONFIG_DN, [(ldap.MOD_REPLACE, 'nsslapd-security', 'on'),
+                                (ldap.MOD_REPLACE, 'nsslapd-ssl-check-hostname', 'off'),
+                                (ldap.MOD_REPLACE, 'nsslapd-secureport', ldapsport)])
+
+    server.add_s(Entry((RSA_DN, {'objectclass': "top nsEncryptionModule".split(),
+                                 'cn': RSA,
+                                 'nsSSLPersonalitySSL': mycert,
+                                 'nsSSLToken': 'internal (software)',
+                                 'nsSSLActivation': 'on'})))
+
+def check_pems(confdir, mycacert, myservercert, myserverkey, notexist):
+    log.info("\n######################### Check PEM files (%s, %s, %s)%s in %s ######################\n"
+             % (mycacert, myservercert, myserverkey, notexist, confdir))
+    global cacert
+    cacert = '%s/%s.pem' % (confdir, mycacert)
+    if os.path.isfile(cacert):
+        if notexist == "":
+            log.info('%s is successfully generated.' % cacert)
+        else:
+            log.info('%s is incorrecly generated.' % cacert)
+            assert False
+    else:
+        if notexist == "":
+            log.fatal('%s is not generated.' % cacert)
+            assert False
+        else:
+            log.info('%s is correctly not generated.' % cacert)
+    servercert = '%s/%s.pem' % (confdir, myservercert)
+    if os.path.isfile(servercert):
+        if notexist == "":
+            log.info('%s is successfully generated.' % servercert)
+        else:
+            log.info('%s is incorrecly generated.' % servercert)
+            assert False
+    else:
+        if notexist == "":
+            log.fatal('%s was not generated.' % servercert)
+            assert False
+        else:
+            log.info('%s is correctly not generated.' % servercert)
+    serverkey = '%s/%s.pem' % (confdir, myserverkey)
+    if os.path.isfile(serverkey):
+        if notexist == "":
+            log.info('%s is successfully generated.' % serverkey)
+        else:
+            log.info('%s is incorrectly generated.' % serverkey)
+            assert False
+    else:
+        if notexist == "":
+            log.fatal('%s was not generated.' % serverkey)
+            assert False
+        else:
+            log.info('%s is correctly not generated.' % serverkey)
+
+def doAndPrintIt(cmdline):
+    proc = subprocess.Popen(cmdline, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+    log.info("      OUT:")
+    while True:
+        l = proc.stdout.readline()
+        if l == "":
+            break
+        log.info("      %s" % l)
+    log.info("      ERR:")
+    while True:
+        l = proc.stderr.readline()
+        if l == "" or l == "\n":
+            break
+        log.info("      <%s>" % l)
+        assert False
+
+def create_keys_certs(topology):
+    log.info("\n######################### Creating SSL Keys and Certs ######################\n")
+
+    global m1confdir
+    m1confdir = topology.master1.confdir
+    global m2confdir
+    m2confdir = topology.master2.confdir
+
+    log.info("##### shutdown master1")
+    topology.master1.stop(timeout=10)
+
+    log.info("##### Creating a password file")
+    pwdfile = '%s/pwdfile.txt' % (m1confdir)
+    os.system('rm -f %s' % pwdfile)
+    opasswd = os.popen("(ps -ef ; w ) | sha1sum | awk '{print $1}'", "r")
+    passwd = opasswd.readline()
+    pwdfd = open(pwdfile, "w")
+    pwdfd.write(passwd)
+    pwdfd.close()
+
+    log.info("##### create the pin file")
+    m1pinfile = '%s/pin.txt' % (m1confdir)
+    m2pinfile = '%s/pin.txt' % (m2confdir)
+    os.system('rm -f %s' % m1pinfile)
+    os.system('rm -f %s' % m2pinfile)
+    pintxt = 'Internal (Software) Token:%s' % passwd
+    pinfd = open(m1pinfile, "w")
+    pinfd.write(pintxt)
+    pinfd.close()
+    os.system('chmod 400 %s' % m1pinfile)
+
+    log.info("##### Creating a noise file")
+    noisefile = '%s/noise.txt' % (m1confdir)
+    noise = os.popen("(w ; ps -ef ; date ) | sha1sum | awk '{print $1}'", "r")
+    noisewdfd = open(noisefile, "w")
+    noisewdfd.write(noise.readline())
+    noisewdfd.close()
+
+    cmdline = ['certutil', '-N', '-d', m1confdir, '-f', pwdfile]
+    log.info("##### Create key3.db and cert8.db database (master1): %s" % cmdline)
+    doAndPrintIt(cmdline)
+
+    cmdline = ['certutil', '-G', '-d', m1confdir, '-z',  noisefile, '-f', pwdfile]
+    log.info("##### Creating encryption key for CA (master1): %s" % cmdline)
+    #os.system('certutil -G -d %s -z %s -f %s' % (m1confdir, noisefile, pwdfile))
+    doAndPrintIt(cmdline)
+
+    time.sleep(2)
+
+    log.info("##### Creating self-signed CA certificate (master1) -- nickname %s" % CACERT)
+    os.system('( echo y ; echo ; echo y ) | certutil -S -n "%s" -s "%s" -x -t "CT,," -m 1000 -v 120 -d %s -z %s -f %s -2' % (CACERT, ISSUER, m1confdir, noisefile, pwdfile))
+
+    global M1SUBJECT
+    cmdline = ['certutil', '-S', '-n', M1SERVERCERT, '-s', M1SUBJECT, '-c', CACERT, '-t', ',,', '-m', '1001', '-v', '120', '-d', m1confdir, '-z', noisefile, '-f', pwdfile]
+    log.info("##### Creating Server certificate -- nickname %s: %s" % (M1SERVERCERT, cmdline))
+    doAndPrintIt(cmdline)
+
+    time.sleep(2)
+
+    global M2SUBJECT
+    cmdline = ['certutil', '-S', '-n', M2SERVERCERT, '-s', M2SUBJECT, '-c', CACERT, '-t', ',,', '-m', '1002', '-v', '120', '-d', m1confdir, '-z', noisefile, '-f', pwdfile]
+    log.info("##### Creating Server certificate -- nickname %s: %s" % (M2SERVERCERT, cmdline))
+    doAndPrintIt(cmdline)
+
+    time.sleep(2)
+
+    log.info("##### start master1")
+    topology.master1.start(timeout=10)
+
+    log.info("##### enable SSL in master1 with all ciphers")
+    enable_ssl(topology.master1, M1LDAPSPORT, M1SERVERCERT)
+
+    cmdline = ['certutil', '-L', '-d', m1confdir]
+    log.info("##### Check the cert db: %s" % cmdline)
+    doAndPrintIt(cmdline)
+
+    log.info("##### restart master1")
+    topology.master1.restart(timeout=10)
+
+    log.info("##### Check PEM files of master1 (before setting nsslapd-extract-pemfiles")
+    check_pems(m1confdir, CACERT, M1SERVERCERT, M1SERVERCERT + '-Key', " not")
+
+    log.info("##### Set on to nsslapd-extract-pemfiles")
+    topology.master1.modify_s(CONFIG_DN, [(ldap.MOD_REPLACE, 'nsslapd-extract-pemfiles', 'on')])
+
+    log.info("##### restart master1")
+    topology.master1.restart(timeout=10)
+
+    log.info("##### Check PEM files of master1 (after setting nsslapd-extract-pemfiles")
+    check_pems(m1confdir, CACERT, M1SERVERCERT, M1SERVERCERT + '-Key', "")
+
+    global mytmp
+    mytmp = topology.master1.getDir(__file__, TMP_DIR)
+    m2pk12file = '%s/%s.pk12' % (mytmp, M2SERVERCERT)
+    cmd = 'pk12util -o %s -n "%s" -d %s -w %s -k %s' % (m2pk12file, M2SERVERCERT, m1confdir, pwdfile, pwdfile)
+    log.info("##### Extract PK12 file for master2: %s" % cmd)
+    os.system(cmd)
+
+    log.info("##### Check PK12 files")
+    if os.path.isfile(m2pk12file):
+        log.info('%s is successfully extracted.' % m2pk12file)
+    else:
+        log.fatal('%s was not extracted.' % m2pk12file)
+        assert False
+
+    log.info("##### stop master2")
+    topology.master2.stop(timeout=10)
+
+    log.info("##### Initialize Cert DB for master2")
+    cmdline = ['certutil', '-N', '-d', m2confdir, '-f', pwdfile]
+    log.info("##### Create key3.db and cert8.db database (master2): %s" % cmdline)
+    doAndPrintIt(cmdline)
+
+    log.info("##### Import certs to master2")
+    log.info('Importing %s' % CACERT)
+    global cacert
+    os.system('certutil -A -n "%s" -t "CT,," -f %s -d %s -a -i %s' % (CACERT, pwdfile, m2confdir, cacert))
+    cmd = 'pk12util -i %s -n "%s" -d %s -w %s -k %s' % (m2pk12file, M2SERVERCERT, m2confdir, pwdfile, pwdfile)
+    log.info('##### Importing %s to master2: %s' % (M2SERVERCERT, cmd))
+    os.system(cmd)
+    log.info('copy %s to %s' % (m1pinfile, m2pinfile))
+    os.system('cp %s %s' % (m1pinfile, m2pinfile))
+    os.system('chmod 400 %s' % m2pinfile)
+
+    log.info("##### start master2")
+    topology.master2.start(timeout=10)
+
+    log.info("##### enable SSL in master2 with all ciphers")
+    enable_ssl(topology.master2, M2LDAPSPORT, M2SERVERCERT)
+
+    log.info("##### restart master2")
+    topology.master2.restart(timeout=10)
+
+    log.info("##### Check PEM files of master2 (before setting nsslapd-extract-pemfiles")
+    check_pems(m2confdir, CACERT, M2SERVERCERT, M2SERVERCERT + '-Key', " not")
+
+    log.info("##### Set on to nsslapd-extract-pemfiles")
+    topology.master2.modify_s(CONFIG_DN, [(ldap.MOD_REPLACE, 'nsslapd-extract-pemfiles', 'on')])
+
+    log.info("##### restart master2")
+    topology.master2.restart(timeout=10)
+
+    log.info("##### Check PEM files of master2 (after setting nsslapd-extract-pemfiles")
+    check_pems(m2confdir, CACERT, M2SERVERCERT, M2SERVERCERT + '-Key', "")
+
+    log.info("##### restart master1")
+    topology.master1.restart(timeout=10)
+
+
+    log.info("\n######################### Creating SSL Keys and Certs Done ######################\n")
+
+def config_tls_agreements(topology):
+    log.info("######################### Configure SSL/TLS agreements ######################")
+    log.info("######################## master1 -- startTLS -> master2 #####################")
+    log.info("##################### master1 <- tls_clientAuth -- master2 ##################")
+
+    log.info("##### Update the agreement of master1")
+    global m1_m2_agmt
+    topology.master1.modify_s(m1_m2_agmt, [(ldap.MOD_REPLACE, 'nsDS5ReplicaTransportInfo', 'TLS')])
+
+    log.info("##### Add the cert to the repl manager on master1")
+    global mytmp
+    global m2confdir
+    m2servercert = '%s/%s.pem' % (m2confdir, M2SERVERCERT)
+    m2sc = open(m2servercert, "r")
+    m2servercertstr = ''
+    for l in m2sc.readlines():
+        if ((l == "") or l.startswith('This file is auto-generated') or
+            l.startswith('Do not edit') or l.startswith('Issuer:') or
+            l.startswith('Subject:') or l.startswith('-----')):
+            continue
+        m2servercertstr = "%s%s" % (m2servercertstr, l.rstrip())
+    m2sc.close()
+
+    log.info('##### master2 Server Cert in base64 format: %s' % m2servercertstr)
+
+    replmgr = defaultProperties[REPLICATION_BIND_DN]
+    rentry = topology.master1.search_s(replmgr, ldap.SCOPE_BASE, 'objectclass=*')
+    log.info('##### Replication manager on master1: %s' % replmgr)
+    oc = 'ObjectClass'
+    log.info('      %s:' % oc)
+    if rentry:
+        for val in rentry[0].getValues(oc):
+            log.info('                 : %s' % val)
+    topology.master1.modify_s(replmgr, [(ldap.MOD_ADD, oc, 'extensibleObject')])
+
+    global M2SUBJECT
+    topology.master1.modify_s(replmgr, [(ldap.MOD_ADD, 'userCertificate;binary', base64.b64decode(m2servercertstr)),
+                                        (ldap.MOD_ADD, 'description', M2SUBJECT)])
+
+    log.info("##### Modify the certmap.conf on master1")
+    m1certmap = '%s/certmap.conf' % (m1confdir)
+    os.system('chmod 660 %s' % m1certmap)
+    m1cm = open(m1certmap, "w")
+    m1cm.write('certmap Example	%s\n' % ISSUER)
+    m1cm.write('Example:DNComps	cn\n')
+    m1cm.write('Example:FilterComps\n')
+    m1cm.write('Example:verifycert	on\n')
+    m1cm.write('Example:CmapLdapAttr	description')
+    m1cm.close()
+    os.system('chmod 440 %s' % m1certmap)
+
+    log.info("##### Update the agreement of master2")
+    global m2_m1_agmt
+    topology.master2.modify_s(m2_m1_agmt, [(ldap.MOD_REPLACE, 'nsDS5ReplicaTransportInfo', 'TLS'),
+                                           (ldap.MOD_REPLACE, 'nsDS5ReplicaBindMethod', 'SSLCLIENTAUTH')])
+
+    topology.master1.stop(10)
+    topology.master2.stop(10)
+    topology.master1.start(10)
+    topology.master2.start(10)
+
+    log.info("\n######################### Configure SSL/TLS agreements Done ######################\n")
+
+
+def relocate_pem_files(topology):
+    log.info("######################### Relocate PEM files on master1 ######################")
+    mycacert = 'MyCA'
+    topology.master1.modify_s(ENCRYPTION_DN, [(ldap.MOD_REPLACE, 'CACertExtractFile', mycacert)])
+    myservercert = 'MyServerCert1'
+    myserverkey = 'MyServerKey1'
+    topology.master1.modify_s(RSA_DN, [(ldap.MOD_REPLACE, 'ServerCertExtractFile', myservercert),
+                                       (ldap.MOD_REPLACE, 'ServerKeyExtractFile', myserverkey)])
+    log.info("##### restart master1")
+    topology.master1.restart(timeout=10)
+    check_pems(m1confdir, mycacert, myservercert, myserverkey, "")
+
+def test_ticket47536(topology):
+    """
+    Set up 2way MMR:
+        master_1 ----- startTLS -----> master_2
+        master_1 <-- TLS_clientAuth -- master_2
+
+    Check CA cert, Server-Cert and Key are retrieved as PEM from cert db
+    when the server is started.  First, the file names are not specified
+    and the default names derived from the cert nicknames.  Next, the
+    file names are specified in the encryption config entries.
+
+    Each time add 5 entries to master 1 and 2 and check they are replicated.
+    """
+    log.info("Ticket 47536 - Allow usage of OpenLDAP libraries that don't use NSS for crypto")
+
+    create_keys_certs(topology)
+    config_tls_agreements(topology)
+
+    add_entry(topology.master1, 'master1', 'uid=m1user', 0, 5)
+    add_entry(topology.master2, 'master2', 'uid=m2user', 0, 5)
+
+    time.sleep(1)
+   
+    log.info('##### Searching for entries on master1...')
+    entries = topology.master1.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(uid=*)')
+    assert 10 == len(entries)
+
+    log.info('##### Searching for entries on master2...')
+    entries = topology.master2.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(uid=*)')
+    assert 10 == len(entries)
+
+    relocate_pem_files(topology)
+
+    add_entry(topology.master1, 'master1', 'uid=m1user', 10, 5)
+    add_entry(topology.master2, 'master2', 'uid=m2user', 10, 5)
+
+    time.sleep(10)
+
+    log.info('##### Searching for entries on master1...')
+    entries = topology.master1.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(uid=*)')
+    assert 20 == len(entries)
+
+    log.info('##### Searching for entries on master2...')
+    entries = topology.master2.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(uid=*)')
+    assert 20 == len(entries)
+
+    db2ldifpl = '%s/sbin/db2ldif.pl' % os.getenv('PREFIX')
+    cmdline = [db2ldifpl, '-n', 'userRoot', '-Z', SERVERID_MASTER_1, '-D', DN_DM, '-w', PASSWORD]
+    log.info("##### db2ldif.pl -- %s" % (cmdline))
+    doAndPrintIt(cmdline)
+
+    log.info("Ticket 47536 - PASSED")
+
+if __name__ == '__main__':
+    # Run isolated
+    # -s for DEBUG mode
+
+    CURRENT_FILE = os.path.realpath(__file__)
+    pytest.main("-s %s" % CURRENT_FILE)