ticket47553_single_aci_test.py 47 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187
  1. '''
  2. Created on Nov 7, 2013
  3. @author: tbordaz
  4. '''
  5. import os
  6. import sys
  7. import time
  8. import ldap
  9. import logging
  10. import socket
  11. import time
  12. import logging
  13. import pytest
  14. import re
  15. from lib389 import DirSrv, Entry, tools
  16. from lib389.tools import DirSrvTools
  17. from lib389._constants import *
  18. from lib389.properties import *
  19. from constants import *
  20. from lib389._constants import REPLICAROLE_MASTER
  21. logging.getLogger(__name__).setLevel(logging.DEBUG)
  22. log = logging.getLogger(__name__)
  23. #
  24. # important part. We can deploy Master1 and Master2 on different versions
  25. #
  26. installation1_prefix = None
  27. installation2_prefix = None
  28. TEST_REPL_DN = "cn=test_repl, %s" % SUFFIX
  29. STAGING_CN = "staged user"
  30. PRODUCTION_CN = "accounts"
  31. EXCEPT_CN = "excepts"
  32. STAGING_DN = "cn=%s,%s" % (STAGING_CN, SUFFIX)
  33. PRODUCTION_DN = "cn=%s,%s" % (PRODUCTION_CN, SUFFIX)
  34. PROD_EXCEPT_DN = "cn=%s,%s" % (EXCEPT_CN, PRODUCTION_DN)
  35. STAGING_PATTERN = "cn=%s*,%s" % (STAGING_CN[:2], SUFFIX)
  36. PRODUCTION_PATTERN = "cn=%s*,%s" % (PRODUCTION_CN[:2], SUFFIX)
  37. BAD_STAGING_PATTERN = "cn=bad*,%s" % (SUFFIX)
  38. BAD_PRODUCTION_PATTERN = "cn=bad*,%s" % (SUFFIX)
  39. BIND_CN = "bind_entry"
  40. BIND_DN = "cn=%s,%s" % (BIND_CN, SUFFIX)
  41. BIND_PW = "password"
  42. NEW_ACCOUNT = "new_account"
  43. MAX_ACCOUNTS = 20
  44. CONFIG_MODDN_ACI_ATTR = "nsslapd-moddn-aci"
  45. class TopologyMaster1Master2(object):
  46. def __init__(self, master1, master2):
  47. master1.open()
  48. self.master1 = master1
  49. master2.open()
  50. self.master2 = master2
  51. #@pytest.fixture(scope="module")
  52. def topology(request):
  53. '''
  54. This fixture is used to create a replicated topology for the 'module'.
  55. The replicated topology is MASTER1 <-> Master2.
  56. At the beginning, It may exists a master2 instance and/or a master2 instance.
  57. It may also exists a backup for the master1 and/or the master2.
  58. Principle:
  59. If master1 instance exists:
  60. restart it
  61. If master2 instance exists:
  62. restart it
  63. If backup of master1 AND backup of master2 exists:
  64. create or rebind to master1
  65. create or rebind to master2
  66. restore master1 from backup
  67. restore master2 from backup
  68. else:
  69. Cleanup everything
  70. remove instances
  71. remove backups
  72. Create instances
  73. Initialize replication
  74. Create backups
  75. '''
  76. global installation1_prefix
  77. global installation2_prefix
  78. # allocate master1 on a given deployement
  79. master1 = DirSrv(verbose=False)
  80. if installation1_prefix:
  81. args_instance[SER_DEPLOYED_DIR] = installation1_prefix
  82. # Args for the master1 instance
  83. args_instance[SER_HOST] = HOST_MASTER_1
  84. args_instance[SER_PORT] = PORT_MASTER_1
  85. args_instance[SER_SERVERID_PROP] = SERVERID_MASTER_1
  86. args_master = args_instance.copy()
  87. master1.allocate(args_master)
  88. # allocate master1 on a given deployement
  89. master2 = DirSrv(verbose=False)
  90. if installation2_prefix:
  91. args_instance[SER_DEPLOYED_DIR] = installation2_prefix
  92. # Args for the consumer instance
  93. args_instance[SER_HOST] = HOST_MASTER_2
  94. args_instance[SER_PORT] = PORT_MASTER_2
  95. args_instance[SER_SERVERID_PROP] = SERVERID_MASTER_2
  96. args_master = args_instance.copy()
  97. master2.allocate(args_master)
  98. # Get the status of the backups
  99. backup_master1 = master1.checkBackupFS()
  100. backup_master2 = master2.checkBackupFS()
  101. # Get the status of the instance and restart it if it exists
  102. instance_master1 = master1.exists()
  103. if instance_master1:
  104. master1.stop(timeout=10)
  105. master1.start(timeout=10)
  106. instance_master2 = master2.exists()
  107. if instance_master2:
  108. master2.stop(timeout=10)
  109. master2.start(timeout=10)
  110. if backup_master1 and backup_master2:
  111. # The backups exist, assuming they are correct
  112. # we just re-init the instances with them
  113. if not instance_master1:
  114. master1.create()
  115. # Used to retrieve configuration information (dbdir, confdir...)
  116. master1.open()
  117. if not instance_master2:
  118. master2.create()
  119. # Used to retrieve configuration information (dbdir, confdir...)
  120. master2.open()
  121. # restore master1 from backup
  122. master1.stop(timeout=10)
  123. master1.restoreFS(backup_master1)
  124. master1.start(timeout=10)
  125. # restore master2 from backup
  126. master2.stop(timeout=10)
  127. master2.restoreFS(backup_master2)
  128. master2.start(timeout=10)
  129. else:
  130. # We should be here only in two conditions
  131. # - This is the first time a test involve master-consumer
  132. # so we need to create everything
  133. # - Something weird happened (instance/backup destroyed)
  134. # so we discard everything and recreate all
  135. # Remove all the backups. So even if we have a specific backup file
  136. # (e.g backup_master) we clear all backups that an instance my have created
  137. if backup_master1:
  138. master1.clearBackupFS()
  139. if backup_master2:
  140. master2.clearBackupFS()
  141. # Remove all the instances
  142. if instance_master1:
  143. master1.delete()
  144. if instance_master2:
  145. master2.delete()
  146. # Create the instances
  147. master1.create()
  148. master1.open()
  149. master2.create()
  150. master2.open()
  151. #
  152. # Now prepare the Master-Consumer topology
  153. #
  154. # First Enable replication
  155. master1.replica.enableReplication(suffix=SUFFIX, role=REPLICAROLE_MASTER, replicaId=REPLICAID_MASTER_1)
  156. master2.replica.enableReplication(suffix=SUFFIX, role=REPLICAROLE_MASTER, replicaId=REPLICAID_MASTER_2)
  157. # Initialize the supplier->consumer
  158. properties = {RA_NAME: r'meTo_$host:$port',
  159. RA_BINDDN: defaultProperties[REPLICATION_BIND_DN],
  160. RA_BINDPW: defaultProperties[REPLICATION_BIND_PW],
  161. RA_METHOD: defaultProperties[REPLICATION_BIND_METHOD],
  162. RA_TRANSPORT_PROT: defaultProperties[REPLICATION_TRANSPORT]}
  163. repl_agreement = master1.agreement.create(suffix=SUFFIX, host=master2.host, port=master2.port, properties=properties)
  164. if not repl_agreement:
  165. log.fatal("Fail to create a replica agreement")
  166. sys.exit(1)
  167. log.debug("%s created" % repl_agreement)
  168. properties = {RA_NAME: r'meTo_$host:$port',
  169. RA_BINDDN: defaultProperties[REPLICATION_BIND_DN],
  170. RA_BINDPW: defaultProperties[REPLICATION_BIND_PW],
  171. RA_METHOD: defaultProperties[REPLICATION_BIND_METHOD],
  172. RA_TRANSPORT_PROT: defaultProperties[REPLICATION_TRANSPORT]}
  173. master2.agreement.create(suffix=SUFFIX, host=master1.host, port=master1.port, properties=properties)
  174. master1.agreement.init(SUFFIX, HOST_MASTER_2, PORT_MASTER_2)
  175. master1.waitForReplInit(repl_agreement)
  176. # Check replication is working fine
  177. master1.add_s(Entry((TEST_REPL_DN, {
  178. 'objectclass': "top person".split(),
  179. 'sn': 'test_repl',
  180. 'cn': 'test_repl'})))
  181. loop = 0
  182. while loop <= 10:
  183. try:
  184. ent = master2.getEntry(TEST_REPL_DN, ldap.SCOPE_BASE, "(objectclass=*)")
  185. break
  186. except ldap.NO_SUCH_OBJECT:
  187. time.sleep(1)
  188. loop += 1
  189. # Time to create the backups
  190. master1.stop(timeout=10)
  191. master1.backupfile = master1.backupFS()
  192. master1.start(timeout=10)
  193. master2.stop(timeout=10)
  194. master2.backupfile = master2.backupFS()
  195. master2.start(timeout=10)
  196. #
  197. # Here we have two instances master and consumer
  198. # with replication working. Either coming from a backup recovery
  199. # or from a fresh (re)init
  200. # Time to return the topology
  201. return TopologyMaster1Master2(master1, master2)
  202. def _bind_manager(topology):
  203. topology.master1.log.info("Bind as %s " % DN_DM)
  204. topology.master1.simple_bind_s(DN_DM, PASSWORD)
  205. def _bind_normal(topology):
  206. # bind as bind_entry
  207. topology.master1.log.info("Bind as %s" % BIND_DN)
  208. topology.master1.simple_bind_s(BIND_DN, BIND_PW)
  209. def _moddn_aci_deny_tree(topology, mod_type=None, target_from=STAGING_DN, target_to=PROD_EXCEPT_DN):
  210. '''
  211. It denies the access moddn_to in cn=except,cn=accounts,SUFFIX
  212. '''
  213. assert mod_type != None
  214. ACI_TARGET_FROM = ""
  215. ACI_TARGET_TO = ""
  216. if target_from:
  217. ACI_TARGET_FROM = "(target_from = \"ldap:///%s\")" % (target_from)
  218. if target_to:
  219. ACI_TARGET_TO = "(target_to = \"ldap:///%s\")" % (target_to)
  220. ACI_ALLOW = "(version 3.0; acl \"Deny MODDN to prod_except\"; deny (moddn)"
  221. ACI_SUBJECT = " userdn = \"ldap:///%s\";)" % BIND_DN
  222. ACI_BODY = ACI_TARGET_TO + ACI_TARGET_FROM + ACI_ALLOW + ACI_SUBJECT
  223. mod = [(mod_type, 'aci', ACI_BODY)]
  224. #topology.master1.modify_s(SUFFIX, mod)
  225. topology.master1.log.info("Add a DENY aci under %s " % PROD_EXCEPT_DN)
  226. topology.master1.modify_s(PROD_EXCEPT_DN, mod)
  227. def _moddn_aci_staging_to_production(topology, mod_type=None, target_from=STAGING_DN, target_to=PRODUCTION_DN):
  228. assert mod_type != None
  229. ACI_TARGET_FROM = ""
  230. ACI_TARGET_TO = ""
  231. if target_from:
  232. ACI_TARGET_FROM = "(target_from = \"ldap:///%s\")" % (target_from)
  233. if target_to:
  234. ACI_TARGET_TO = "(target_to = \"ldap:///%s\")" % (target_to)
  235. ACI_ALLOW = "(version 3.0; acl \"MODDN from staging to production\"; allow (moddn)"
  236. ACI_SUBJECT = " userdn = \"ldap:///%s\";)" % BIND_DN
  237. ACI_BODY = ACI_TARGET_FROM + ACI_TARGET_TO + ACI_ALLOW + ACI_SUBJECT
  238. mod = [(mod_type, 'aci', ACI_BODY)]
  239. topology.master1.modify_s(SUFFIX, mod)
  240. def _moddn_aci_from_production_to_staging(topology, mod_type=None):
  241. assert mod_type != None
  242. ACI_TARGET = "(target_from = \"ldap:///%s\") (target_to = \"ldap:///%s\")" % (PRODUCTION_DN, STAGING_DN)
  243. ACI_ALLOW = "(version 3.0; acl \"MODDN from production to staging\"; allow (moddn)"
  244. ACI_SUBJECT = " userdn = \"ldap:///%s\";)" % BIND_DN
  245. ACI_BODY = ACI_TARGET + ACI_ALLOW + ACI_SUBJECT
  246. mod = [(mod_type, 'aci', ACI_BODY)]
  247. topology.master1.modify_s(SUFFIX, mod)
  248. def test_ticket47553_init(topology):
  249. """
  250. Creates
  251. - a staging DIT
  252. - a production DIT
  253. - add accounts in staging DIT
  254. - enable ACL logging (commented for performance reason)
  255. """
  256. topology.master1.log.info("\n\n######################### INITIALIZATION ######################\n")
  257. # entry used to bind with
  258. topology.master1.log.info("Add %s" % BIND_DN)
  259. topology.master1.add_s(Entry((BIND_DN, {
  260. 'objectclass': "top person".split(),
  261. 'sn': BIND_CN,
  262. 'cn': BIND_CN,
  263. 'userpassword': BIND_PW})))
  264. # DIT for staging
  265. topology.master1.log.info("Add %s" % STAGING_DN)
  266. topology.master1.add_s(Entry((STAGING_DN, {
  267. 'objectclass': "top organizationalRole".split(),
  268. 'cn': STAGING_CN,
  269. 'description': "staging DIT"})))
  270. # DIT for production
  271. topology.master1.log.info("Add %s" % PRODUCTION_DN)
  272. topology.master1.add_s(Entry((PRODUCTION_DN, {
  273. 'objectclass': "top organizationalRole".split(),
  274. 'cn': PRODUCTION_CN,
  275. 'description': "production DIT"})))
  276. # DIT for production/except
  277. topology.master1.log.info("Add %s" % PROD_EXCEPT_DN)
  278. topology.master1.add_s(Entry((PROD_EXCEPT_DN, {
  279. 'objectclass': "top organizationalRole".split(),
  280. 'cn': EXCEPT_CN,
  281. 'description': "production except DIT"})))
  282. # enable acl error logging
  283. #mod = [(ldap.MOD_REPLACE, 'nsslapd-errorlog-level', '128')]
  284. #topology.master1.modify_s(DN_CONFIG, mod)
  285. #topology.master2.modify_s(DN_CONFIG, mod)
  286. # add dummy entries in the staging DIT
  287. for cpt in range(MAX_ACCOUNTS):
  288. name = "%s%d" % (NEW_ACCOUNT, cpt)
  289. topology.master1.add_s(Entry(("cn=%s,%s" % (name, STAGING_DN), {
  290. 'objectclass': "top person".split(),
  291. 'sn': name,
  292. 'cn': name})))
  293. def test_ticket47553_add(topology):
  294. '''
  295. This test case checks that the ADD operation fails (no ADD aci on production)
  296. '''
  297. topology.master1.log.info("\n\n######################### ADD (should fail) ######################\n")
  298. _bind_normal(topology)
  299. #
  300. # First try to add an entry in production => INSUFFICIENT_ACCESS
  301. #
  302. try:
  303. topology.master1.log.info("Try to add %s" % PRODUCTION_DN)
  304. name = "%s%d" % (NEW_ACCOUNT, 0)
  305. topology.master1.add_s(Entry(("cn=%s,%s" % (name, PRODUCTION_DN), {
  306. 'objectclass': "top person".split(),
  307. 'sn': name,
  308. 'cn': name})))
  309. assert 0 # this is an error, we should not be allowed to add an entry in production
  310. except Exception as e:
  311. topology.master1.log.info("Exception (expected): %s" % type(e).__name__)
  312. assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
  313. def test_ticket47553_delete(topology):
  314. '''
  315. This test case checks that the DEL operation fails (no 'delete' aci on production)
  316. '''
  317. topology.master1.log.info("\n\n######################### DELETE (should fail) ######################\n")
  318. _bind_normal(topology)
  319. #
  320. # Second try to delete an entry in staging => INSUFFICIENT_ACCESS
  321. #
  322. try:
  323. topology.master1.log.info("Try to delete %s" % STAGING_DN)
  324. name = "%s%d" % (NEW_ACCOUNT, 0)
  325. topology.master1.delete_s("cn=%s,%s" % (name, STAGING_DN))
  326. assert 0 # this is an error, we should not be allowed to add an entry in production
  327. except Exception as e:
  328. topology.master1.log.info("Exception (expected): %s" % type(e).__name__)
  329. assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
  330. def test_ticket47553_moddn_staging_prod_0(topology):
  331. '''
  332. This test case MOVE entry NEW_ACCOUNT0 from staging to prod
  333. target_to/target_from: equality filter
  334. '''
  335. topology.master1.log.info("\n\n######################### MOVE staging -> Prod (0) ######################\n")
  336. _bind_normal(topology)
  337. old_rdn = "cn=%s0" % NEW_ACCOUNT
  338. old_dn = "%s,%s" % (old_rdn, STAGING_DN)
  339. new_rdn = old_rdn
  340. new_superior = PRODUCTION_DN
  341. #
  342. # Try to rename without the apropriate ACI => INSUFFICIENT_ACCESS
  343. #
  344. try:
  345. topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
  346. topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
  347. assert 0
  348. except AssertionError:
  349. topology.master1.log.info("Exception (not really expected exception but that is fine as it fails to rename)")
  350. except Exception as e:
  351. topology.master1.log.info("Exception (expected): %s" % type(e).__name__)
  352. assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
  353. # successfull MOD with the ACI
  354. topology.master1.log.info("\n\n######################### MOVE to and from equality filter ######################\n")
  355. _bind_manager(topology)
  356. _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_ADD, target_from=STAGING_DN, target_to=PRODUCTION_DN)
  357. _bind_normal(topology)
  358. topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
  359. topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
  360. # successfull MOD with the both ACI
  361. _bind_manager(topology)
  362. _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_DELETE, target_from=STAGING_DN, target_to=PRODUCTION_DN)
  363. _bind_normal(topology)
  364. def test_ticket47553_moddn_staging_prod_1(topology):
  365. '''
  366. This test case MOVE entry NEW_ACCOUNT1 from staging to prod
  367. target_to/target_from: substring/equality filter
  368. '''
  369. topology.master1.log.info("\n\n######################### MOVE staging -> Prod (1) ######################\n")
  370. _bind_normal(topology)
  371. old_rdn = "cn=%s1" % NEW_ACCOUNT
  372. old_dn = "%s,%s" % (old_rdn, STAGING_DN)
  373. new_rdn = old_rdn
  374. new_superior = PRODUCTION_DN
  375. #
  376. # Try to rename without the apropriate ACI => INSUFFICIENT_ACCESS
  377. #
  378. try:
  379. topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
  380. topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
  381. assert 0
  382. except AssertionError:
  383. topology.master1.log.info("Exception (not really expected exception but that is fine as it fails to rename)")
  384. except Exception as e:
  385. topology.master1.log.info("Exception (expected): %s" % type(e).__name__)
  386. assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
  387. # successfull MOD with the ACI
  388. topology.master1.log.info("\n\n######################### MOVE to substring/ from equality filter ######################\n")
  389. _bind_manager(topology)
  390. _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_ADD, target_from=STAGING_DN, target_to=PRODUCTION_PATTERN)
  391. _bind_normal(topology)
  392. topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
  393. topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
  394. # successfull MOD with the both ACI
  395. _bind_manager(topology)
  396. _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_DELETE, target_from=STAGING_DN, target_to=PRODUCTION_PATTERN)
  397. _bind_normal(topology)
  398. def test_ticket47553_moddn_staging_prod_2(topology):
  399. '''
  400. This test case fails to MOVE entry NEW_ACCOUNT2 from staging to prod
  401. because of bad pattern
  402. '''
  403. topology.master1.log.info("\n\n######################### MOVE staging -> Prod (2) ######################\n")
  404. _bind_normal(topology)
  405. old_rdn = "cn=%s2" % NEW_ACCOUNT
  406. old_dn = "%s,%s" % (old_rdn, STAGING_DN)
  407. new_rdn = old_rdn
  408. new_superior = PRODUCTION_DN
  409. #
  410. # Try to rename without the apropriate ACI => INSUFFICIENT_ACCESS
  411. #
  412. try:
  413. topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
  414. topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
  415. assert 0
  416. except AssertionError:
  417. topology.master1.log.info("Exception (not really expected exception but that is fine as it fails to rename)")
  418. except Exception as e:
  419. topology.master1.log.info("Exception (expected): %s" % type(e).__name__)
  420. assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
  421. # successfull MOD with the ACI
  422. topology.master1.log.info("\n\n######################### MOVE to substring (BAD)/ from equality filter ######################\n")
  423. _bind_manager(topology)
  424. _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_ADD, target_from=STAGING_DN, target_to=BAD_PRODUCTION_PATTERN)
  425. _bind_normal(topology)
  426. try:
  427. topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
  428. topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
  429. except AssertionError:
  430. topology.master1.log.info("Exception (not really expected exception but that is fine as it fails to rename)")
  431. except Exception as e:
  432. topology.master1.log.info("Exception (expected): %s" % type(e).__name__)
  433. assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
  434. # successfull MOD with the both ACI
  435. _bind_manager(topology)
  436. _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_DELETE, target_from=STAGING_DN, target_to=BAD_PRODUCTION_PATTERN)
  437. _bind_normal(topology)
  438. def test_ticket47553_moddn_staging_prod_3(topology):
  439. '''
  440. This test case MOVE entry NEW_ACCOUNT3 from staging to prod
  441. target_to/target_from: equality/substring filter
  442. '''
  443. topology.master1.log.info("\n\n######################### MOVE staging -> Prod (3) ######################\n")
  444. _bind_normal(topology)
  445. old_rdn = "cn=%s3" % NEW_ACCOUNT
  446. old_dn = "%s,%s" % (old_rdn, STAGING_DN)
  447. new_rdn = old_rdn
  448. new_superior = PRODUCTION_DN
  449. #
  450. # Try to rename without the apropriate ACI => INSUFFICIENT_ACCESS
  451. #
  452. try:
  453. topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
  454. topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
  455. assert 0
  456. except AssertionError:
  457. topology.master1.log.info("Exception (not really expected exception but that is fine as it fails to rename)")
  458. except Exception as e:
  459. topology.master1.log.info("Exception (expected): %s" % type(e).__name__)
  460. assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
  461. # successfull MOD with the ACI
  462. topology.master1.log.info("\n\n######################### MOVE to:equality filter / from substring filter ######################\n")
  463. _bind_manager(topology)
  464. _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_ADD, target_from=STAGING_PATTERN, target_to=PRODUCTION_DN)
  465. _bind_normal(topology)
  466. topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
  467. topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
  468. # successfull MOD with the both ACI
  469. _bind_manager(topology)
  470. _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_DELETE, target_from=STAGING_PATTERN, target_to=PRODUCTION_DN)
  471. _bind_normal(topology)
  472. def test_ticket47553_moddn_staging_prod_4(topology):
  473. '''
  474. This test case fails to MOVE entry NEW_ACCOUNT4 from staging to prod
  475. because of bad pattern
  476. '''
  477. topology.master1.log.info("\n\n######################### MOVE staging -> Prod (4) ######################\n")
  478. _bind_normal(topology)
  479. old_rdn = "cn=%s4" % NEW_ACCOUNT
  480. old_dn = "%s,%s" % (old_rdn, STAGING_DN)
  481. new_rdn = old_rdn
  482. new_superior = PRODUCTION_DN
  483. #
  484. # Try to rename without the apropriate ACI => INSUFFICIENT_ACCESS
  485. #
  486. try:
  487. topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
  488. topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
  489. assert 0
  490. except AssertionError:
  491. topology.master1.log.info("Exception (not really expected exception but that is fine as it fails to rename)")
  492. except Exception as e:
  493. topology.master1.log.info("Exception (expected): %s" % type(e).__name__)
  494. assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
  495. # successfull MOD with the ACI
  496. topology.master1.log.info("\n\n######################### MOVE to: equality filter/ from: substring (BAD) ######################\n")
  497. _bind_manager(topology)
  498. _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_ADD, target_from=BAD_STAGING_PATTERN, target_to=PRODUCTION_DN)
  499. _bind_normal(topology)
  500. try:
  501. topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
  502. topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
  503. except AssertionError:
  504. topology.master1.log.info("Exception (not really expected exception but that is fine as it fails to rename)")
  505. except Exception as e:
  506. topology.master1.log.info("Exception (expected): %s" % type(e).__name__)
  507. assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
  508. # successfull MOD with the both ACI
  509. _bind_manager(topology)
  510. _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_DELETE, target_from=BAD_STAGING_PATTERN, target_to=PRODUCTION_DN)
  511. _bind_normal(topology)
  512. def test_ticket47553_moddn_staging_prod_5(topology):
  513. '''
  514. This test case MOVE entry NEW_ACCOUNT5 from staging to prod
  515. target_to/target_from: substring/substring filter
  516. '''
  517. topology.master1.log.info("\n\n######################### MOVE staging -> Prod (5) ######################\n")
  518. _bind_normal(topology)
  519. old_rdn = "cn=%s5" % NEW_ACCOUNT
  520. old_dn = "%s,%s" % (old_rdn, STAGING_DN)
  521. new_rdn = old_rdn
  522. new_superior = PRODUCTION_DN
  523. #
  524. # Try to rename without the apropriate ACI => INSUFFICIENT_ACCESS
  525. #
  526. try:
  527. topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
  528. topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
  529. assert 0
  530. except AssertionError:
  531. topology.master1.log.info("Exception (not really expected exception but that is fine as it fails to rename)")
  532. except Exception as e:
  533. topology.master1.log.info("Exception (expected): %s" % type(e).__name__)
  534. assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
  535. # successfull MOD with the ACI
  536. topology.master1.log.info("\n\n######################### MOVE to:substring filter / from: substring filter ######################\n")
  537. _bind_manager(topology)
  538. _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_ADD, target_from=STAGING_PATTERN, target_to=PRODUCTION_PATTERN)
  539. _bind_normal(topology)
  540. topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
  541. topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
  542. # successfull MOD with the both ACI
  543. _bind_manager(topology)
  544. _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_DELETE, target_from=STAGING_PATTERN, target_to=PRODUCTION_PATTERN)
  545. _bind_normal(topology)
  546. def test_ticket47553_moddn_staging_prod_6(topology):
  547. '''
  548. This test case MOVE entry NEW_ACCOUNT6 from staging to prod
  549. target_to/target_from: substring/<enmpty> filter
  550. '''
  551. topology.master1.log.info("\n\n######################### MOVE staging -> Prod (6) ######################\n")
  552. _bind_normal(topology)
  553. old_rdn = "cn=%s6" % NEW_ACCOUNT
  554. old_dn = "%s,%s" % (old_rdn, STAGING_DN)
  555. new_rdn = old_rdn
  556. new_superior = PRODUCTION_DN
  557. #
  558. # Try to rename without the apropriate ACI => INSUFFICIENT_ACCESS
  559. #
  560. try:
  561. topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
  562. topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
  563. assert 0
  564. except AssertionError:
  565. topology.master1.log.info("Exception (not really expected exception but that is fine as it fails to rename)")
  566. except Exception as e:
  567. topology.master1.log.info("Exception (expected): %s" % type(e).__name__)
  568. assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
  569. # successfull MOD with the ACI
  570. topology.master1.log.info("\n\n######################### MOVE to:substring filter / from: empty ######################\n")
  571. _bind_manager(topology)
  572. _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_ADD, target_from=None, target_to=PRODUCTION_PATTERN)
  573. _bind_normal(topology)
  574. topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
  575. topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
  576. # successfull MOD with the both ACI
  577. _bind_manager(topology)
  578. _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_DELETE, target_from=None, target_to=PRODUCTION_PATTERN)
  579. _bind_normal(topology)
  580. def test_ticket47553_moddn_staging_prod_7(topology):
  581. '''
  582. This test case MOVE entry NEW_ACCOUNT7 from staging to prod
  583. target_to/target_from: <empty>/substring filter
  584. '''
  585. topology.master1.log.info("\n\n######################### MOVE staging -> Prod (7) ######################\n")
  586. _bind_normal(topology)
  587. old_rdn = "cn=%s7" % NEW_ACCOUNT
  588. old_dn = "%s,%s" % (old_rdn, STAGING_DN)
  589. new_rdn = old_rdn
  590. new_superior = PRODUCTION_DN
  591. #
  592. # Try to rename without the apropriate ACI => INSUFFICIENT_ACCESS
  593. #
  594. try:
  595. topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
  596. topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
  597. assert 0
  598. except AssertionError:
  599. topology.master1.log.info("Exception (not really expected exception but that is fine as it fails to rename)")
  600. except Exception as e:
  601. topology.master1.log.info("Exception (expected): %s" % type(e).__name__)
  602. assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
  603. # successfull MOD with the ACI
  604. topology.master1.log.info("\n\n######################### MOVE to: empty/ from: substring filter ######################\n")
  605. _bind_manager(topology)
  606. _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_ADD, target_from=STAGING_PATTERN, target_to=None)
  607. _bind_normal(topology)
  608. topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
  609. topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
  610. # successfull MOD with the both ACI
  611. _bind_manager(topology)
  612. _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_DELETE, target_from=STAGING_PATTERN, target_to=None)
  613. _bind_normal(topology)
  614. def test_ticket47553_moddn_staging_prod_8(topology):
  615. '''
  616. This test case MOVE entry NEW_ACCOUNT8 from staging to prod
  617. target_to/target_from: <empty>/<empty> filter
  618. '''
  619. topology.master1.log.info("\n\n######################### MOVE staging -> Prod (8) ######################\n")
  620. _bind_normal(topology)
  621. old_rdn = "cn=%s8" % NEW_ACCOUNT
  622. old_dn = "%s,%s" % (old_rdn, STAGING_DN)
  623. new_rdn = old_rdn
  624. new_superior = PRODUCTION_DN
  625. #
  626. # Try to rename without the apropriate ACI => INSUFFICIENT_ACCESS
  627. #
  628. try:
  629. topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
  630. topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
  631. assert 0
  632. except AssertionError:
  633. topology.master1.log.info("Exception (not really expected exception but that is fine as it fails to rename)")
  634. except Exception as e:
  635. topology.master1.log.info("Exception (expected): %s" % type(e).__name__)
  636. assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
  637. # successfull MOD with the ACI
  638. topology.master1.log.info("\n\n######################### MOVE to: empty/ from: empty ######################\n")
  639. _bind_manager(topology)
  640. _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_ADD, target_from=None, target_to=None)
  641. _bind_normal(topology)
  642. topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
  643. topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
  644. # successfull MOD with the both ACI
  645. _bind_manager(topology)
  646. _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_DELETE, target_from=None, target_to=None)
  647. _bind_normal(topology)
  648. def test_ticket47553_moddn_staging_prod_9(topology):
  649. '''
  650. This test case disable the 'moddn' right so a MODDN requires a 'add' right
  651. to be successfull.
  652. It fails to MOVE entry NEW_ACCOUNT9 from staging to prod.
  653. Add a 'add' right to prod.
  654. Then it succeeds to MOVE NEW_ACCOUNT9 from staging to prod.
  655. Then enable the 'moddn' right so a MODDN requires a 'moddn' right
  656. It fails to MOVE entry NEW_ACCOUNT10 from staging to prod.
  657. Add a 'moddn' right to prod.
  658. Then it succeeds to MOVE NEW_ACCOUNT10 from staging to prod.
  659. '''
  660. topology.master1.log.info("\n\n######################### MOVE staging -> Prod (9) ######################\n")
  661. _bind_normal(topology)
  662. old_rdn = "cn=%s9" % NEW_ACCOUNT
  663. old_dn = "%s,%s" % (old_rdn, STAGING_DN)
  664. new_rdn = old_rdn
  665. new_superior = PRODUCTION_DN
  666. #
  667. # Try to rename without the apropriate ACI => INSUFFICIENT_ACCESS
  668. #
  669. try:
  670. topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
  671. topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
  672. assert 0
  673. except AssertionError:
  674. topology.master1.log.info("Exception (not really expected exception but that is fine as it fails to rename)")
  675. except Exception as e:
  676. topology.master1.log.info("Exception (expected): %s" % type(e).__name__)
  677. assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
  678. ############################################
  679. # Now do tests with no support of moddn aci
  680. ############################################
  681. topology.master1.log.info("Disable the moddn right" )
  682. _bind_manager(topology)
  683. mod = [(ldap.MOD_REPLACE, CONFIG_MODDN_ACI_ATTR, 'off')]
  684. topology.master1.modify_s(DN_CONFIG, mod)
  685. # Add the moddn aci that will not be evaluated because of the config flag
  686. topology.master1.log.info("\n\n######################### MOVE to and from equality filter ######################\n")
  687. _bind_manager(topology)
  688. _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_ADD, target_from=STAGING_DN, target_to=PRODUCTION_DN)
  689. _bind_normal(topology)
  690. # It will fail because it will test the ADD right
  691. try:
  692. topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
  693. topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
  694. assert 0
  695. except AssertionError:
  696. topology.master1.log.info("Exception (not really expected exception but that is fine as it fails to rename)")
  697. except Exception as e:
  698. topology.master1.log.info("Exception (expected): %s" % type(e).__name__)
  699. assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
  700. # remove the moddn aci
  701. _bind_manager(topology)
  702. _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_DELETE, target_from=STAGING_DN, target_to=PRODUCTION_DN)
  703. _bind_normal(topology)
  704. #
  705. # add the 'add' right to the production DN
  706. # Then do a successfull moddn
  707. #
  708. ACI_ALLOW = "(version 3.0; acl \"ADD rights to allow moddn\"; allow (add)"
  709. ACI_SUBJECT = " userdn = \"ldap:///%s\";)" % BIND_DN
  710. ACI_BODY = ACI_ALLOW + ACI_SUBJECT
  711. _bind_manager(topology)
  712. mod = [(ldap.MOD_ADD, 'aci', ACI_BODY)]
  713. topology.master1.modify_s(PRODUCTION_DN, mod)
  714. _bind_normal(topology)
  715. topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
  716. topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
  717. _bind_manager(topology)
  718. mod = [(ldap.MOD_DELETE, 'aci', ACI_BODY)]
  719. topology.master1.modify_s(PRODUCTION_DN, mod)
  720. _bind_normal(topology)
  721. ############################################
  722. # Now do tests with support of moddn aci
  723. ############################################
  724. topology.master1.log.info("Enable the moddn right" )
  725. _bind_manager(topology)
  726. mod = [(ldap.MOD_REPLACE, CONFIG_MODDN_ACI_ATTR, 'on')]
  727. topology.master1.modify_s(DN_CONFIG, mod)
  728. topology.master1.log.info("\n\n######################### MOVE staging -> Prod (10) ######################\n")
  729. _bind_normal(topology)
  730. old_rdn = "cn=%s10" % NEW_ACCOUNT
  731. old_dn = "%s,%s" % (old_rdn, STAGING_DN)
  732. new_rdn = old_rdn
  733. new_superior = PRODUCTION_DN
  734. #
  735. # Try to rename without the apropriate ACI => INSUFFICIENT_ACCESS
  736. #
  737. try:
  738. topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
  739. topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
  740. assert 0
  741. except AssertionError:
  742. topology.master1.log.info("Exception (not really expected exception but that is fine as it fails to rename)")
  743. except Exception as e:
  744. topology.master1.log.info("Exception (expected): %s" % type(e).__name__)
  745. assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
  746. #
  747. # add the 'add' right to the production DN
  748. # Then do a failing moddn
  749. #
  750. ACI_ALLOW = "(version 3.0; acl \"ADD rights to allow moddn\"; allow (add)"
  751. ACI_SUBJECT = " userdn = \"ldap:///%s\";)" % BIND_DN
  752. ACI_BODY = ACI_ALLOW + ACI_SUBJECT
  753. _bind_manager(topology)
  754. mod = [(ldap.MOD_ADD, 'aci', ACI_BODY)]
  755. topology.master1.modify_s(PRODUCTION_DN, mod)
  756. _bind_normal(topology)
  757. try:
  758. topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
  759. topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
  760. assert 0
  761. except AssertionError:
  762. topology.master1.log.info("Exception (not really expected exception but that is fine as it fails to rename)")
  763. except Exception as e:
  764. topology.master1.log.info("Exception (expected): %s" % type(e).__name__)
  765. assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
  766. _bind_manager(topology)
  767. mod = [(ldap.MOD_DELETE, 'aci', ACI_BODY)]
  768. topology.master1.modify_s(PRODUCTION_DN, mod)
  769. _bind_normal(topology)
  770. # Add the moddn aci that will be evaluated because of the config flag
  771. topology.master1.log.info("\n\n######################### MOVE to and from equality filter ######################\n")
  772. _bind_manager(topology)
  773. _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_ADD, target_from=STAGING_DN, target_to=PRODUCTION_DN)
  774. _bind_normal(topology)
  775. topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
  776. topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
  777. # remove the moddn aci
  778. _bind_manager(topology)
  779. _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_DELETE, target_from=STAGING_DN, target_to=PRODUCTION_DN)
  780. _bind_normal(topology)
  781. def test_ticket47553_moddn_prod_staging(topology):
  782. '''
  783. This test checks that we can move ACCOUNT11 from staging to prod
  784. but not move back ACCOUNT11 from prod to staging
  785. '''
  786. topology.master1.log.info("\n\n######################### MOVE staging -> Prod (11) ######################\n")
  787. _bind_normal(topology)
  788. old_rdn = "cn=%s11" % NEW_ACCOUNT
  789. old_dn = "%s,%s" % (old_rdn, STAGING_DN)
  790. new_rdn = old_rdn
  791. new_superior = PRODUCTION_DN
  792. #
  793. # Try to rename without the apropriate ACI => INSUFFICIENT_ACCESS
  794. #
  795. try:
  796. topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
  797. topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
  798. assert 0
  799. except AssertionError:
  800. topology.master1.log.info("Exception (not really expected exception but that is fine as it fails to rename)")
  801. except Exception as e:
  802. topology.master1.log.info("Exception (expected): %s" % type(e).__name__)
  803. assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
  804. # successfull MOD with the ACI
  805. topology.master1.log.info("\n\n######################### MOVE to and from equality filter ######################\n")
  806. _bind_manager(topology)
  807. _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_ADD, target_from=STAGING_DN, target_to=PRODUCTION_DN)
  808. _bind_normal(topology)
  809. topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
  810. topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
  811. #
  812. # Now check we can not move back the entry to staging
  813. old_rdn = "cn=%s11" % NEW_ACCOUNT
  814. old_dn = "%s,%s" % (old_rdn, PRODUCTION_DN)
  815. new_rdn = old_rdn
  816. new_superior = STAGING_DN
  817. try:
  818. topology.master1.log.info("Try to move back MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
  819. topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
  820. assert 0
  821. except AssertionError:
  822. topology.master1.log.info("Exception (not really expected exception but that is fine as it fails to rename)")
  823. except Exception as e:
  824. topology.master1.log.info("Exception (expected): %s" % type(e).__name__)
  825. assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
  826. # successfull MOD with the both ACI
  827. _bind_manager(topology)
  828. _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_DELETE, target_from=STAGING_DN, target_to=PRODUCTION_DN)
  829. _bind_normal(topology)
  830. def test_ticket47553_check_repl_M2_to_M1(topology):
  831. '''
  832. Checks that replication is still working M2->M1, using ACCOUNT12
  833. '''
  834. topology.master1.log.info("Bind as %s (M2)" % DN_DM)
  835. topology.master2.simple_bind_s(DN_DM, PASSWORD)
  836. rdn = "cn=%s12" % NEW_ACCOUNT
  837. dn = "%s,%s" % (rdn, STAGING_DN)
  838. # First wait for the ACCOUNT19 entry being replicated on M2
  839. loop = 0
  840. while loop <= 10:
  841. try:
  842. ent = topology.master2.getEntry(dn, ldap.SCOPE_BASE, "(objectclass=*)")
  843. break
  844. except ldap.NO_SUCH_OBJECT:
  845. time.sleep(1)
  846. loop += 1
  847. assert loop <= 10
  848. attribute = 'description'
  849. tested_value = 'Hello world'
  850. mod = [(ldap.MOD_ADD, attribute, tested_value)]
  851. topology.master1.log.info("Update (M2) %s (%s)" % (dn, attribute))
  852. topology.master2.modify_s(dn, mod)
  853. loop = 0
  854. while loop <= 10:
  855. ent = topology.master1.getEntry(dn, ldap.SCOPE_BASE, "(objectclass=*)")
  856. assert ent != None
  857. if ent.hasAttr(attribute) and (ent.getValue(attribute) == tested_value):
  858. break
  859. time.sleep(1)
  860. loop += 1
  861. assert loop < 10
  862. topology.master1.log.info("Update %s (%s) replicated on M1" % (dn, attribute))
  863. def test_ticket47553_moddn_staging_prod_except(topology):
  864. '''
  865. This test case MOVE entry NEW_ACCOUNT13 from staging to prod
  866. but fails to move entry NEW_ACCOUNT14 from staging to prod_except
  867. '''
  868. topology.master1.log.info("\n\n######################### MOVE staging -> Prod (13) ######################\n")
  869. _bind_normal(topology)
  870. old_rdn = "cn=%s13" % NEW_ACCOUNT
  871. old_dn = "%s,%s" % (old_rdn, STAGING_DN)
  872. new_rdn = old_rdn
  873. new_superior = PRODUCTION_DN
  874. #
  875. # Try to rename without the apropriate ACI => INSUFFICIENT_ACCESS
  876. #
  877. try:
  878. topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
  879. topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
  880. assert 0
  881. except AssertionError:
  882. topology.master1.log.info("Exception (not really expected exception but that is fine as it fails to rename)")
  883. except Exception as e:
  884. topology.master1.log.info("Exception (expected): %s" % type(e).__name__)
  885. assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
  886. # successfull MOD with the ACI
  887. topology.master1.log.info("\n\n######################### MOVE to and from equality filter ######################\n")
  888. _bind_manager(topology)
  889. _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_ADD, target_from=STAGING_DN, target_to=PRODUCTION_DN)
  890. _moddn_aci_deny_tree(topology, mod_type=ldap.MOD_ADD)
  891. _bind_normal(topology)
  892. topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
  893. topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
  894. #
  895. # Now try to move an entry under except
  896. #
  897. topology.master1.log.info("\n\n######################### MOVE staging -> Prod/Except (14) ######################\n")
  898. old_rdn = "cn=%s14" % NEW_ACCOUNT
  899. old_dn = "%s,%s" % (old_rdn, STAGING_DN)
  900. new_rdn = old_rdn
  901. new_superior = PROD_EXCEPT_DN
  902. try:
  903. topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
  904. topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
  905. assert 0
  906. except AssertionError:
  907. topology.master1.log.info("Exception (not really expected exception but that is fine as it fails to rename)")
  908. except Exception as e:
  909. topology.master1.log.info("Exception (expected): %s" % type(e).__name__)
  910. assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
  911. # successfull MOD with the both ACI
  912. _bind_manager(topology)
  913. _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_DELETE, target_from=STAGING_DN, target_to=PRODUCTION_DN)
  914. _moddn_aci_deny_tree(topology, mod_type=ldap.MOD_DELETE)
  915. _bind_normal(topology)
  916. def test_ticket47553_final(topology):
  917. topology.master1.stop(timeout=10)
  918. topology.master2.stop(timeout=10)
  919. def run_isolated():
  920. '''
  921. run_isolated is used to run these test cases independently of a test scheduler (xunit, py.test..)
  922. To run isolated without py.test, you need to
  923. - edit this file and comment '@pytest.fixture' line before 'topology' function.
  924. - set the installation prefix
  925. - run this program
  926. '''
  927. global installation1_prefix
  928. global installation2_prefix
  929. installation1_prefix = '/home/tbordaz/install'
  930. installation2_prefix = '/home/tbordaz/install'
  931. topo = topology(True)
  932. topo.master1.log.info("\n\n######################### Ticket 47553 ######################\n")
  933. test_ticket47553_init(topo)
  934. # Check that without appropriate aci we are not allowed to add/delete
  935. test_ticket47553_add(topo)
  936. test_ticket47553_delete(topo)
  937. # tests the ACI as equality/substring filter
  938. test_ticket47553_moddn_staging_prod_0(topo)
  939. test_ticket47553_moddn_staging_prod_1(topo)
  940. test_ticket47553_moddn_staging_prod_2(topo)
  941. test_ticket47553_moddn_staging_prod_3(topo)
  942. test_ticket47553_moddn_staging_prod_4(topo)
  943. test_ticket47553_moddn_staging_prod_5(topo)
  944. # tests the ACI with undefined 'target_to'/'target_from'
  945. test_ticket47553_moddn_staging_prod_6(topo)
  946. test_ticket47553_moddn_staging_prod_7(topo)
  947. test_ticket47553_moddn_staging_prod_8(topo)
  948. # Check we can control the behavior with nsslapd-moddn-aci
  949. test_ticket47553_moddn_staging_prod_9(topo)
  950. # Check we can move entry 'from' -> 'to' but not 'to' -> 'from'
  951. test_ticket47553_moddn_prod_staging(topo)
  952. # check replication is still working
  953. test_ticket47553_check_repl_M2_to_M1(topo)
  954. # check DENY rule is working
  955. test_ticket47553_moddn_staging_prod_except(topo)
  956. test_ticket47553_final(topo)
  957. if __name__ == '__main__':
  958. run_isolated()