ticket47536_test.py 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522
  1. # --- BEGIN COPYRIGHT BLOCK ---
  2. # Copyright (C) 2016 Red Hat, Inc.
  3. # All rights reserved.
  4. #
  5. # License: GPL (version 3 or any later version).
  6. # See LICENSE for details.
  7. # --- END COPYRIGHT BLOCK ---
  8. #
  9. import os
  10. import sys
  11. import time
  12. import shlex
  13. import subprocess
  14. import ldap
  15. import logging
  16. import pytest
  17. import base64
  18. from lib389 import DirSrv, Entry, tools, tasks
  19. from lib389.tools import DirSrvTools
  20. from lib389._constants import *
  21. from lib389.properties import *
  22. from lib389.tasks import *
  23. from lib389.utils import *
  24. logging.getLogger(__name__).setLevel(logging.DEBUG)
  25. log = logging.getLogger(__name__)
  26. CONFIG_DN = 'cn=config'
  27. ENCRYPTION_DN = 'cn=encryption,%s' % CONFIG_DN
  28. RSA = 'RSA'
  29. RSA_DN = 'cn=%s,%s' % (RSA, ENCRYPTION_DN)
  30. ISSUER = 'cn=CAcert'
  31. CACERT = 'CAcertificate'
  32. M1SERVERCERT = 'Server-Cert1'
  33. M2SERVERCERT = 'Server-Cert2'
  34. M1LDAPSPORT = '41636'
  35. M2LDAPSPORT = '42636'
  36. class TopologyReplication(object):
  37. def __init__(self, master1, master2):
  38. master1.open()
  39. self.master1 = master1
  40. master2.open()
  41. self.master2 = master2
  42. @pytest.fixture(scope="module")
  43. def topology(request):
  44. # Creating master 1...
  45. master1 = DirSrv(verbose=False)
  46. args_instance[SER_HOST] = HOST_MASTER_1
  47. args_instance[SER_PORT] = PORT_MASTER_1
  48. args_instance[SER_SERVERID_PROP] = SERVERID_MASTER_1
  49. args_instance[SER_CREATION_SUFFIX] = DEFAULT_SUFFIX
  50. args_master = args_instance.copy()
  51. master1.allocate(args_master)
  52. instance_master1 = master1.exists()
  53. if instance_master1:
  54. master1.delete()
  55. master1.create()
  56. master1.open()
  57. master1.replica.enableReplication(suffix=SUFFIX, role=REPLICAROLE_MASTER, replicaId=REPLICAID_MASTER_1)
  58. # Creating master 2...
  59. master2 = DirSrv(verbose=False)
  60. args_instance[SER_HOST] = HOST_MASTER_2
  61. args_instance[SER_PORT] = PORT_MASTER_2
  62. args_instance[SER_SERVERID_PROP] = SERVERID_MASTER_2
  63. args_instance[SER_CREATION_SUFFIX] = DEFAULT_SUFFIX
  64. args_master = args_instance.copy()
  65. master2.allocate(args_master)
  66. instance_master2 = master2.exists()
  67. if instance_master2:
  68. master2.delete()
  69. master2.create()
  70. master2.open()
  71. master2.replica.enableReplication(suffix=SUFFIX, role=REPLICAROLE_MASTER, replicaId=REPLICAID_MASTER_2)
  72. # Delete each instance in the end
  73. def fin():
  74. master1.delete()
  75. master2.delete()
  76. request.addfinalizer(fin)
  77. #
  78. # Create all the agreements
  79. #
  80. # Creating agreement from master 1 to master 2
  81. properties = {RA_NAME: r'meTo_%s:%s' % (master2.host, master2.port),
  82. RA_BINDDN: defaultProperties[REPLICATION_BIND_DN],
  83. RA_BINDPW: defaultProperties[REPLICATION_BIND_PW],
  84. RA_METHOD: defaultProperties[REPLICATION_BIND_METHOD],
  85. RA_TRANSPORT_PROT: defaultProperties[REPLICATION_TRANSPORT]}
  86. global m1_m2_agmt
  87. m1_m2_agmt = master1.agreement.create(suffix=SUFFIX, host=master2.host, port=master2.port, properties=properties)
  88. if not m1_m2_agmt:
  89. log.fatal("Fail to create a master -> master replica agreement")
  90. sys.exit(1)
  91. log.debug("%s created" % m1_m2_agmt)
  92. # Creating agreement from master 2 to master 1
  93. properties = {RA_NAME: r'meTo_%s:%s' % (master1.host, master1.port),
  94. RA_BINDDN: defaultProperties[REPLICATION_BIND_DN],
  95. RA_BINDPW: defaultProperties[REPLICATION_BIND_PW],
  96. RA_METHOD: defaultProperties[REPLICATION_BIND_METHOD],
  97. RA_TRANSPORT_PROT: defaultProperties[REPLICATION_TRANSPORT]}
  98. global m2_m1_agmt
  99. m2_m1_agmt = master2.agreement.create(suffix=SUFFIX, host=master1.host, port=master1.port, properties=properties)
  100. if not m2_m1_agmt:
  101. log.fatal("Fail to create a master -> master replica agreement")
  102. sys.exit(1)
  103. log.debug("%s created" % m2_m1_agmt)
  104. # Allow the replicas to get situated with the new agreements...
  105. time.sleep(2)
  106. global M1SUBJECT
  107. M1SUBJECT = 'CN=%s,OU=389 Directory Server' % (master1.host)
  108. global M2SUBJECT
  109. M2SUBJECT = 'CN=%s,OU=390 Directory Server' % (master2.host)
  110. #
  111. # Initialize all the agreements
  112. #
  113. master1.agreement.init(SUFFIX, HOST_MASTER_2, PORT_MASTER_2)
  114. master1.waitForReplInit(m1_m2_agmt)
  115. # Check replication is working...
  116. if master1.testReplication(DEFAULT_SUFFIX, master2):
  117. log.info('Replication is working.')
  118. else:
  119. log.fatal('Replication is not working.')
  120. assert False
  121. return TopologyReplication(master1, master2)
  122. @pytest.fixture(scope="module")
  123. def add_entry(server, name, rdntmpl, start, num):
  124. log.info("\n######################### Adding %d entries to %s ######################\n" % (num, name))
  125. for i in range(num):
  126. ii = start + i
  127. dn = '%s%d,%s' % (rdntmpl, ii, DEFAULT_SUFFIX)
  128. server.add_s(Entry((dn, {'objectclass': 'top person extensibleObject'.split(),
  129. 'uid': '%s%d' % (rdntmpl, ii),
  130. 'cn': '%s user%d' % (name, ii),
  131. 'sn': 'user%d' % (ii)})))
  132. def enable_ssl(server, ldapsport, mycert):
  133. log.info("\n######################### Enabling SSL LDAPSPORT %s ######################\n" % ldapsport)
  134. server.simple_bind_s(DN_DM, PASSWORD)
  135. server.modify_s(ENCRYPTION_DN, [(ldap.MOD_REPLACE, 'nsSSL3', 'off'),
  136. (ldap.MOD_REPLACE, 'nsTLS1', 'on'),
  137. (ldap.MOD_REPLACE, 'nsSSLClientAuth', 'allowed'),
  138. (ldap.MOD_REPLACE, 'nsSSL3Ciphers', '+all')])
  139. server.modify_s(CONFIG_DN, [(ldap.MOD_REPLACE, 'nsslapd-security', 'on'),
  140. (ldap.MOD_REPLACE, 'nsslapd-ssl-check-hostname', 'off'),
  141. (ldap.MOD_REPLACE, 'nsslapd-secureport', ldapsport)])
  142. server.add_s(Entry((RSA_DN, {'objectclass': "top nsEncryptionModule".split(),
  143. 'cn': RSA,
  144. 'nsSSLPersonalitySSL': mycert,
  145. 'nsSSLToken': 'internal (software)',
  146. 'nsSSLActivation': 'on'})))
  147. def check_pems(confdir, mycacert, myservercert, myserverkey, notexist):
  148. log.info("\n######################### Check PEM files (%s, %s, %s)%s in %s ######################\n"
  149. % (mycacert, myservercert, myserverkey, notexist, confdir))
  150. global cacert
  151. cacert = '%s/%s.pem' % (confdir, mycacert)
  152. if os.path.isfile(cacert):
  153. if notexist == "":
  154. log.info('%s is successfully generated.' % cacert)
  155. else:
  156. log.info('%s is incorrecly generated.' % cacert)
  157. assert False
  158. else:
  159. if notexist == "":
  160. log.fatal('%s is not generated.' % cacert)
  161. assert False
  162. else:
  163. log.info('%s is correctly not generated.' % cacert)
  164. servercert = '%s/%s.pem' % (confdir, myservercert)
  165. if os.path.isfile(servercert):
  166. if notexist == "":
  167. log.info('%s is successfully generated.' % servercert)
  168. else:
  169. log.info('%s is incorrecly generated.' % servercert)
  170. assert False
  171. else:
  172. if notexist == "":
  173. log.fatal('%s was not generated.' % servercert)
  174. assert False
  175. else:
  176. log.info('%s is correctly not generated.' % servercert)
  177. serverkey = '%s/%s.pem' % (confdir, myserverkey)
  178. if os.path.isfile(serverkey):
  179. if notexist == "":
  180. log.info('%s is successfully generated.' % serverkey)
  181. else:
  182. log.info('%s is incorrectly generated.' % serverkey)
  183. assert False
  184. else:
  185. if notexist == "":
  186. log.fatal('%s was not generated.' % serverkey)
  187. assert False
  188. else:
  189. log.info('%s is correctly not generated.' % serverkey)
  190. def doAndPrintIt(cmdline):
  191. proc = subprocess.Popen(cmdline, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  192. log.info(" OUT:")
  193. while True:
  194. l = proc.stdout.readline()
  195. if l == "":
  196. break
  197. log.info(" %s" % l)
  198. log.info(" ERR:")
  199. while True:
  200. l = proc.stderr.readline()
  201. if l == "" or l == "\n":
  202. break
  203. log.info(" <%s>" % l)
  204. assert False
  205. def create_keys_certs(topology):
  206. log.info("\n######################### Creating SSL Keys and Certs ######################\n")
  207. global m1confdir
  208. m1confdir = topology.master1.confdir
  209. global m2confdir
  210. m2confdir = topology.master2.confdir
  211. log.info("##### shutdown master1")
  212. topology.master1.stop(timeout=10)
  213. log.info("##### Creating a password file")
  214. pwdfile = '%s/pwdfile.txt' % (m1confdir)
  215. os.system('rm -f %s' % pwdfile)
  216. opasswd = os.popen("(ps -ef ; w ) | sha1sum | awk '{print $1}'", "r")
  217. passwd = opasswd.readline()
  218. pwdfd = open(pwdfile, "w")
  219. pwdfd.write(passwd)
  220. pwdfd.close()
  221. log.info("##### create the pin file")
  222. m1pinfile = '%s/pin.txt' % (m1confdir)
  223. m2pinfile = '%s/pin.txt' % (m2confdir)
  224. os.system('rm -f %s' % m1pinfile)
  225. os.system('rm -f %s' % m2pinfile)
  226. pintxt = 'Internal (Software) Token:%s' % passwd
  227. pinfd = open(m1pinfile, "w")
  228. pinfd.write(pintxt)
  229. pinfd.close()
  230. os.system('chmod 400 %s' % m1pinfile)
  231. log.info("##### Creating a noise file")
  232. noisefile = '%s/noise.txt' % (m1confdir)
  233. noise = os.popen("(w ; ps -ef ; date ) | sha1sum | awk '{print $1}'", "r")
  234. noisewdfd = open(noisefile, "w")
  235. noisewdfd.write(noise.readline())
  236. noisewdfd.close()
  237. cmdline = ['certutil', '-N', '-d', m1confdir, '-f', pwdfile]
  238. log.info("##### Create key3.db and cert8.db database (master1): %s" % cmdline)
  239. doAndPrintIt(cmdline)
  240. cmdline = ['certutil', '-G', '-d', m1confdir, '-z', noisefile, '-f', pwdfile]
  241. log.info("##### Creating encryption key for CA (master1): %s" % cmdline)
  242. #os.system('certutil -G -d %s -z %s -f %s' % (m1confdir, noisefile, pwdfile))
  243. doAndPrintIt(cmdline)
  244. time.sleep(2)
  245. log.info("##### Creating self-signed CA certificate (master1) -- nickname %s" % CACERT)
  246. 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))
  247. global M1SUBJECT
  248. cmdline = ['certutil', '-S', '-n', M1SERVERCERT, '-s', M1SUBJECT, '-c', CACERT, '-t', ',,', '-m', '1001', '-v', '120', '-d', m1confdir, '-z', noisefile, '-f', pwdfile]
  249. log.info("##### Creating Server certificate -- nickname %s: %s" % (M1SERVERCERT, cmdline))
  250. doAndPrintIt(cmdline)
  251. time.sleep(2)
  252. global M2SUBJECT
  253. cmdline = ['certutil', '-S', '-n', M2SERVERCERT, '-s', M2SUBJECT, '-c', CACERT, '-t', ',,', '-m', '1002', '-v', '120', '-d', m1confdir, '-z', noisefile, '-f', pwdfile]
  254. log.info("##### Creating Server certificate -- nickname %s: %s" % (M2SERVERCERT, cmdline))
  255. doAndPrintIt(cmdline)
  256. time.sleep(2)
  257. log.info("##### start master1")
  258. topology.master1.start(timeout=10)
  259. log.info("##### enable SSL in master1 with all ciphers")
  260. enable_ssl(topology.master1, M1LDAPSPORT, M1SERVERCERT)
  261. cmdline = ['certutil', '-L', '-d', m1confdir]
  262. log.info("##### Check the cert db: %s" % cmdline)
  263. doAndPrintIt(cmdline)
  264. log.info("##### restart master1")
  265. topology.master1.restart(timeout=10)
  266. log.info("##### Check PEM files of master1 (before setting nsslapd-extract-pemfiles")
  267. check_pems(m1confdir, CACERT, M1SERVERCERT, M1SERVERCERT + '-Key', " not")
  268. log.info("##### Set on to nsslapd-extract-pemfiles")
  269. topology.master1.modify_s(CONFIG_DN, [(ldap.MOD_REPLACE, 'nsslapd-extract-pemfiles', 'on')])
  270. log.info("##### restart master1")
  271. topology.master1.restart(timeout=10)
  272. log.info("##### Check PEM files of master1 (after setting nsslapd-extract-pemfiles")
  273. check_pems(m1confdir, CACERT, M1SERVERCERT, M1SERVERCERT + '-Key', "")
  274. global mytmp
  275. mytmp = '/tmp'
  276. m2pk12file = '%s/%s.pk12' % (mytmp, M2SERVERCERT)
  277. cmd = 'pk12util -o %s -n "%s" -d %s -w %s -k %s' % (m2pk12file, M2SERVERCERT, m1confdir, pwdfile, pwdfile)
  278. log.info("##### Extract PK12 file for master2: %s" % cmd)
  279. os.system(cmd)
  280. log.info("##### Check PK12 files")
  281. if os.path.isfile(m2pk12file):
  282. log.info('%s is successfully extracted.' % m2pk12file)
  283. else:
  284. log.fatal('%s was not extracted.' % m2pk12file)
  285. assert False
  286. log.info("##### stop master2")
  287. topology.master2.stop(timeout=10)
  288. log.info("##### Initialize Cert DB for master2")
  289. cmdline = ['certutil', '-N', '-d', m2confdir, '-f', pwdfile]
  290. log.info("##### Create key3.db and cert8.db database (master2): %s" % cmdline)
  291. doAndPrintIt(cmdline)
  292. log.info("##### Import certs to master2")
  293. log.info('Importing %s' % CACERT)
  294. global cacert
  295. os.system('certutil -A -n "%s" -t "CT,," -f %s -d %s -a -i %s' % (CACERT, pwdfile, m2confdir, cacert))
  296. cmd = 'pk12util -i %s -n "%s" -d %s -w %s -k %s' % (m2pk12file, M2SERVERCERT, m2confdir, pwdfile, pwdfile)
  297. log.info('##### Importing %s to master2: %s' % (M2SERVERCERT, cmd))
  298. os.system(cmd)
  299. log.info('copy %s to %s' % (m1pinfile, m2pinfile))
  300. os.system('cp %s %s' % (m1pinfile, m2pinfile))
  301. os.system('chmod 400 %s' % m2pinfile)
  302. log.info("##### start master2")
  303. topology.master2.start(timeout=10)
  304. log.info("##### enable SSL in master2 with all ciphers")
  305. enable_ssl(topology.master2, M2LDAPSPORT, M2SERVERCERT)
  306. log.info("##### restart master2")
  307. topology.master2.restart(timeout=10)
  308. log.info("##### Check PEM files of master2 (before setting nsslapd-extract-pemfiles")
  309. check_pems(m2confdir, CACERT, M2SERVERCERT, M2SERVERCERT + '-Key', " not")
  310. log.info("##### Set on to nsslapd-extract-pemfiles")
  311. topology.master2.modify_s(CONFIG_DN, [(ldap.MOD_REPLACE, 'nsslapd-extract-pemfiles', 'on')])
  312. log.info("##### restart master2")
  313. topology.master2.restart(timeout=10)
  314. log.info("##### Check PEM files of master2 (after setting nsslapd-extract-pemfiles")
  315. check_pems(m2confdir, CACERT, M2SERVERCERT, M2SERVERCERT + '-Key', "")
  316. log.info("##### restart master1")
  317. topology.master1.restart(timeout=10)
  318. log.info("\n######################### Creating SSL Keys and Certs Done ######################\n")
  319. def config_tls_agreements(topology):
  320. log.info("######################### Configure SSL/TLS agreements ######################")
  321. log.info("######################## master1 -- startTLS -> master2 #####################")
  322. log.info("##################### master1 <- tls_clientAuth -- master2 ##################")
  323. log.info("##### Update the agreement of master1")
  324. global m1_m2_agmt
  325. topology.master1.modify_s(m1_m2_agmt, [(ldap.MOD_REPLACE, 'nsDS5ReplicaTransportInfo', 'TLS')])
  326. log.info("##### Add the cert to the repl manager on master1")
  327. global mytmp
  328. global m2confdir
  329. m2servercert = '%s/%s.pem' % (m2confdir, M2SERVERCERT)
  330. m2sc = open(m2servercert, "r")
  331. m2servercertstr = ''
  332. for l in m2sc.readlines():
  333. if ((l == "") or l.startswith('This file is auto-generated') or
  334. l.startswith('Do not edit') or l.startswith('Issuer:') or
  335. l.startswith('Subject:') or l.startswith('-----')):
  336. continue
  337. m2servercertstr = "%s%s" % (m2servercertstr, l.rstrip())
  338. m2sc.close()
  339. log.info('##### master2 Server Cert in base64 format: %s' % m2servercertstr)
  340. replmgr = defaultProperties[REPLICATION_BIND_DN]
  341. rentry = topology.master1.search_s(replmgr, ldap.SCOPE_BASE, 'objectclass=*')
  342. log.info('##### Replication manager on master1: %s' % replmgr)
  343. oc = 'ObjectClass'
  344. log.info(' %s:' % oc)
  345. if rentry:
  346. for val in rentry[0].getValues(oc):
  347. log.info(' : %s' % val)
  348. topology.master1.modify_s(replmgr, [(ldap.MOD_ADD, oc, 'extensibleObject')])
  349. global M2SUBJECT
  350. topology.master1.modify_s(replmgr, [(ldap.MOD_ADD, 'userCertificate;binary', base64.b64decode(m2servercertstr)),
  351. (ldap.MOD_ADD, 'description', M2SUBJECT)])
  352. log.info("##### Modify the certmap.conf on master1")
  353. m1certmap = '%s/certmap.conf' % (m1confdir)
  354. os.system('chmod 660 %s' % m1certmap)
  355. m1cm = open(m1certmap, "w")
  356. m1cm.write('certmap Example %s\n' % ISSUER)
  357. m1cm.write('Example:DNComps cn\n')
  358. m1cm.write('Example:FilterComps\n')
  359. m1cm.write('Example:verifycert on\n')
  360. m1cm.write('Example:CmapLdapAttr description')
  361. m1cm.close()
  362. os.system('chmod 440 %s' % m1certmap)
  363. log.info("##### Update the agreement of master2")
  364. global m2_m1_agmt
  365. topology.master2.modify_s(m2_m1_agmt, [(ldap.MOD_REPLACE, 'nsDS5ReplicaTransportInfo', 'TLS'),
  366. (ldap.MOD_REPLACE, 'nsDS5ReplicaBindMethod', 'SSLCLIENTAUTH')])
  367. topology.master1.stop(10)
  368. topology.master2.stop(10)
  369. topology.master1.start(10)
  370. topology.master2.start(10)
  371. log.info("\n######################### Configure SSL/TLS agreements Done ######################\n")
  372. def relocate_pem_files(topology):
  373. log.info("######################### Relocate PEM files on master1 ######################")
  374. mycacert = 'MyCA'
  375. topology.master1.modify_s(ENCRYPTION_DN, [(ldap.MOD_REPLACE, 'CACertExtractFile', mycacert)])
  376. myservercert = 'MyServerCert1'
  377. myserverkey = 'MyServerKey1'
  378. topology.master1.modify_s(RSA_DN, [(ldap.MOD_REPLACE, 'ServerCertExtractFile', myservercert),
  379. (ldap.MOD_REPLACE, 'ServerKeyExtractFile', myserverkey)])
  380. log.info("##### restart master1")
  381. topology.master1.restart(timeout=10)
  382. check_pems(m1confdir, mycacert, myservercert, myserverkey, "")
  383. def test_ticket47536(topology):
  384. """
  385. Set up 2way MMR:
  386. master_1 ----- startTLS -----> master_2
  387. master_1 <-- TLS_clientAuth -- master_2
  388. Check CA cert, Server-Cert and Key are retrieved as PEM from cert db
  389. when the server is started. First, the file names are not specified
  390. and the default names derived from the cert nicknames. Next, the
  391. file names are specified in the encryption config entries.
  392. Each time add 5 entries to master 1 and 2 and check they are replicated.
  393. """
  394. log.info("Ticket 47536 - Allow usage of OpenLDAP libraries that don't use NSS for crypto")
  395. create_keys_certs(topology)
  396. config_tls_agreements(topology)
  397. add_entry(topology.master1, 'master1', 'uid=m1user', 0, 5)
  398. add_entry(topology.master2, 'master2', 'uid=m2user', 0, 5)
  399. time.sleep(1)
  400. log.info('##### Searching for entries on master1...')
  401. entries = topology.master1.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(uid=*)')
  402. assert 10 == len(entries)
  403. log.info('##### Searching for entries on master2...')
  404. entries = topology.master2.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(uid=*)')
  405. assert 10 == len(entries)
  406. relocate_pem_files(topology)
  407. add_entry(topology.master1, 'master1', 'uid=m1user', 10, 5)
  408. add_entry(topology.master2, 'master2', 'uid=m2user', 10, 5)
  409. time.sleep(10)
  410. log.info('##### Searching for entries on master1...')
  411. entries = topology.master1.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(uid=*)')
  412. assert 20 == len(entries)
  413. log.info('##### Searching for entries on master2...')
  414. entries = topology.master2.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(uid=*)')
  415. assert 20 == len(entries)
  416. db2ldifpl = '%s/sbin/db2ldif.pl' % topology.master1.prefix
  417. cmdline = [db2ldifpl, '-n', 'userRoot', '-Z', SERVERID_MASTER_1, '-D', DN_DM, '-w', PASSWORD]
  418. log.info("##### db2ldif.pl -- %s" % (cmdline))
  419. doAndPrintIt(cmdline)
  420. log.info("Ticket 47536 - PASSED")
  421. if __name__ == '__main__':
  422. # Run isolated
  423. # -s for DEBUG mode
  424. CURRENT_FILE = os.path.realpath(__file__)
  425. pytest.main("-s %s" % CURRENT_FILE)