acl_test.py 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160
  1. # --- BEGIN COPYRIGHT BLOCK ---
  2. # Copyright (C) 2020 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 pytest
  10. from ldap.controls.simple import GetEffectiveRightsControl
  11. from lib389.tasks import *
  12. from lib389.utils import *
  13. from lib389.schema import Schema
  14. from lib389.idm.domain import Domain
  15. from lib389.idm.user import UserAccount, UserAccounts, TEST_USER_PROPERTIES
  16. from lib389.idm.organizationalrole import OrganizationalRole, OrganizationalRoles
  17. from lib389.topologies import topology_m2
  18. from lib389._constants import SUFFIX, DN_DM, DEFAULT_SUFFIX, PASSWORD
  19. pytestmark = pytest.mark.tier1
  20. logging.getLogger(__name__).setLevel(logging.DEBUG)
  21. log = logging.getLogger(__name__)
  22. TEST_REPL_DN = "cn=test_repl, %s" % SUFFIX
  23. STAGING_CN = "staged user"
  24. PRODUCTION_CN = "accounts"
  25. EXCEPT_CN = "excepts"
  26. STAGING_DN = "cn=%s,%s" % (STAGING_CN, SUFFIX)
  27. PRODUCTION_DN = "cn=%s,%s" % (PRODUCTION_CN, SUFFIX)
  28. PROD_EXCEPT_DN = "cn=%s,%s" % (EXCEPT_CN, PRODUCTION_DN)
  29. STAGING_PATTERN = "cn=%s*,%s" % (STAGING_CN[:2], SUFFIX)
  30. PRODUCTION_PATTERN = "cn=%s*,%s" % (PRODUCTION_CN[:2], SUFFIX)
  31. BAD_STAGING_PATTERN = "cn=bad*,%s" % (SUFFIX)
  32. BAD_PRODUCTION_PATTERN = "cn=bad*,%s" % (SUFFIX)
  33. BIND_RDN = "bind_entry"
  34. BIND_DN = "uid=%s,%s" % (BIND_RDN, SUFFIX)
  35. BIND_PW = "password"
  36. NEW_ACCOUNT = "new_account"
  37. MAX_ACCOUNTS = 20
  38. CONFIG_MODDN_ACI_ATTR = "nsslapd-moddn-aci"
  39. SRC_ENTRY_CN = "tuser"
  40. EXT_RDN = "01"
  41. DST_ENTRY_CN = SRC_ENTRY_CN + EXT_RDN
  42. SRC_ENTRY_DN = "cn=%s,%s" % (SRC_ENTRY_CN, SUFFIX)
  43. DST_ENTRY_DN = "cn=%s,%s" % (DST_ENTRY_CN, SUFFIX)
  44. def add_attr(topology_m2, attr_name):
  45. """Adds attribute to the schema"""
  46. ATTR_VALUE = """(NAME '%s' \
  47. DESC 'Attribute filteri-Multi-Valued' \
  48. SYNTAX 1.3.6.1.4.1.1466.115.121.1.27)""" % attr_name
  49. schema = Schema(topology_m2.ms["master1"])
  50. schema.add('attributeTypes', ATTR_VALUE)
  51. @pytest.fixture(params=["lang-ja", "binary", "phonetic"])
  52. def aci_with_attr_subtype(request, topology_m2):
  53. """Adds and deletes an ACI in the DEFAULT_SUFFIX"""
  54. TARGET_ATTR = 'protectedOperation'
  55. USER_ATTR = 'allowedToPerform'
  56. SUBTYPE = request.param
  57. suffix = Domain(topology_m2.ms["master1"], DEFAULT_SUFFIX)
  58. log.info("========Executing test with '%s' subtype========" % SUBTYPE)
  59. log.info(" Add a target attribute")
  60. add_attr(topology_m2, TARGET_ATTR)
  61. log.info(" Add a user attribute")
  62. add_attr(topology_m2, USER_ATTR)
  63. ACI_TARGET = '(targetattr=%s;%s)' % (TARGET_ATTR, SUBTYPE)
  64. ACI_ALLOW = '(version 3.0; acl "test aci for subtypes"; allow (read) '
  65. ACI_SUBJECT = 'userattr = "%s;%s#GROUPDN";)' % (USER_ATTR, SUBTYPE)
  66. ACI_BODY = ACI_TARGET + ACI_ALLOW + ACI_SUBJECT
  67. log.info("Add an ACI with attribute subtype")
  68. suffix.add('aci', ACI_BODY)
  69. def fin():
  70. log.info("Finally, delete an ACI with the '%s' subtype" %
  71. SUBTYPE)
  72. suffix.remove('aci', ACI_BODY)
  73. request.addfinalizer(fin)
  74. return ACI_BODY
  75. def test_aci_attr_subtype_targetattr(topology_m2, aci_with_attr_subtype):
  76. """Checks, that ACIs allow attribute subtypes in the targetattr keyword
  77. :id: a99ccda0-5d0b-4d41-99cc-c5e207b3b687
  78. :parametrized: yes
  79. :setup: MMR with two masters,
  80. Define two attributes in the schema - targetattr and userattr,
  81. Add an ACI with attribute subtypes - "lang-ja", "binary", "phonetic"
  82. one by one
  83. :steps:
  84. 1. Search for the added attribute during setup
  85. one by one for each subtypes "lang-ja", "binary", "phonetic"
  86. :expectedresults:
  87. 1. Attributes should be found successfully
  88. one by one for each subtypes "lang-ja", "binary", "phonetic"
  89. """
  90. log.info("Search for the added attribute")
  91. try:
  92. entries = topology_m2.ms["master1"].search_s(DEFAULT_SUFFIX,
  93. ldap.SCOPE_BASE,
  94. '(objectclass=*)', ['aci'])
  95. entry = str(entries[0])
  96. assert aci_with_attr_subtype in entry
  97. log.info("The added attribute was found")
  98. except ldap.LDAPError as e:
  99. log.fatal('Search failed, error: ' + e.message['desc'])
  100. assert False
  101. def _bind_manager(topology_m2):
  102. topology_m2.ms["master1"].log.info("Bind as %s " % DN_DM)
  103. topology_m2.ms["master1"].simple_bind_s(DN_DM, PASSWORD)
  104. def _bind_normal(topology_m2):
  105. # bind as bind_entry
  106. topology_m2.ms["master1"].log.info("Bind as %s" % BIND_DN)
  107. topology_m2.ms["master1"].simple_bind_s(BIND_DN, BIND_PW)
  108. def _moddn_aci_deny_tree(topology_m2, mod_type=None,
  109. target_from=STAGING_DN, target_to=PROD_EXCEPT_DN):
  110. """It denies the access moddn_to in cn=except,cn=accounts,SUFFIX"""
  111. assert mod_type is not None
  112. ACI_TARGET_FROM = ""
  113. ACI_TARGET_TO = ""
  114. if target_from:
  115. ACI_TARGET_FROM = "(target_from = \"ldap:///%s\")" % (target_from)
  116. if target_to:
  117. ACI_TARGET_TO = "(target_to = \"ldap:///%s\")" % (target_to)
  118. ACI_ALLOW = "(version 3.0; acl \"Deny MODDN to prod_except\"; deny (moddn)"
  119. ACI_SUBJECT = " userdn = \"ldap:///%s\";)" % BIND_DN
  120. ACI_BODY = ACI_TARGET_TO + ACI_TARGET_FROM + ACI_ALLOW + ACI_SUBJECT
  121. # topology_m2.ms["master1"].modify_s(SUFFIX, mod)
  122. topology_m2.ms["master1"].log.info("Add a DENY aci under %s " % PROD_EXCEPT_DN)
  123. prod_except = OrganizationalRole(topology_m2.ms["master1"], PROD_EXCEPT_DN)
  124. prod_except.set('aci', ACI_BODY, mod_type)
  125. def _write_aci_staging(topology_m2, mod_type=None):
  126. assert mod_type is not None
  127. ACI_TARGET = "(targetattr= \"uid\")(target=\"ldap:///uid=*,%s\")" % STAGING_DN
  128. ACI_ALLOW = "(version 3.0; acl \"write staging entries\"; allow (write)"
  129. ACI_SUBJECT = " userdn = \"ldap:///%s\";)" % BIND_DN
  130. ACI_BODY = ACI_TARGET + ACI_ALLOW + ACI_SUBJECT
  131. suffix = Domain(topology_m2.ms["master1"], SUFFIX)
  132. suffix.set('aci', ACI_BODY, mod_type)
  133. def _write_aci_production(topology_m2, mod_type=None):
  134. assert mod_type is not None
  135. ACI_TARGET = "(targetattr= \"uid\")(target=\"ldap:///uid=*,%s\")" % PRODUCTION_DN
  136. ACI_ALLOW = "(version 3.0; acl \"write production entries\"; allow (write)"
  137. ACI_SUBJECT = " userdn = \"ldap:///%s\";)" % BIND_DN
  138. ACI_BODY = ACI_TARGET + ACI_ALLOW + ACI_SUBJECT
  139. suffix = Domain(topology_m2.ms["master1"], SUFFIX)
  140. suffix.set('aci', ACI_BODY, mod_type)
  141. def _moddn_aci_staging_to_production(topology_m2, mod_type=None,
  142. target_from=STAGING_DN, target_to=PRODUCTION_DN):
  143. assert mod_type is not None
  144. ACI_TARGET_FROM = ""
  145. ACI_TARGET_TO = ""
  146. if target_from:
  147. ACI_TARGET_FROM = "(target_from = \"ldap:///%s\")" % (target_from)
  148. if target_to:
  149. ACI_TARGET_TO = "(target_to = \"ldap:///%s\")" % (target_to)
  150. ACI_ALLOW = "(version 3.0; acl \"MODDN from staging to production\"; allow (moddn)"
  151. ACI_SUBJECT = " userdn = \"ldap:///%s\";)" % BIND_DN
  152. ACI_BODY = ACI_TARGET_FROM + ACI_TARGET_TO + ACI_ALLOW + ACI_SUBJECT
  153. suffix = Domain(topology_m2.ms["master1"], SUFFIX)
  154. suffix.set('aci', ACI_BODY, mod_type)
  155. _write_aci_staging(topology_m2, mod_type=mod_type)
  156. def _moddn_aci_from_production_to_staging(topology_m2, mod_type=None):
  157. assert mod_type is not None
  158. ACI_TARGET = "(target_from = \"ldap:///%s\") (target_to = \"ldap:///%s\")" % (
  159. PRODUCTION_DN, STAGING_DN)
  160. ACI_ALLOW = "(version 3.0; acl \"MODDN from production to staging\"; allow (moddn)"
  161. ACI_SUBJECT = " userdn = \"ldap:///%s\";)" % BIND_DN
  162. ACI_BODY = ACI_TARGET + ACI_ALLOW + ACI_SUBJECT
  163. suffix = Domain(topology_m2.ms["master1"], SUFFIX)
  164. suffix.set('aci', ACI_BODY, mod_type)
  165. _write_aci_production(topology_m2, mod_type=mod_type)
  166. @pytest.fixture(scope="module")
  167. def moddn_setup(topology_m2):
  168. """Creates
  169. - a staging DIT
  170. - a production DIT
  171. - add accounts in staging DIT
  172. - enable ACL logging (commented for performance reason)
  173. """
  174. m1 = topology_m2.ms["master1"]
  175. o_roles = OrganizationalRoles(m1, SUFFIX)
  176. m1.log.info("\n\n######## INITIALIZATION ########\n")
  177. # entry used to bind with
  178. m1.log.info("Add {}".format(BIND_DN))
  179. user = UserAccount(m1, BIND_DN)
  180. user_props = TEST_USER_PROPERTIES.copy()
  181. user_props.update({'sn': BIND_RDN,
  182. 'cn': BIND_RDN,
  183. 'uid': BIND_RDN,
  184. 'userpassword': BIND_PW})
  185. user.create(properties=user_props, basedn=SUFFIX)
  186. # Add anonymous read aci
  187. ACI_TARGET = "(target = \"ldap:///%s\")(targetattr=\"*\")" % (SUFFIX)
  188. ACI_ALLOW = "(version 3.0; acl \"Anonymous Read access\"; allow (read,search,compare)"
  189. ACI_SUBJECT = " userdn = \"ldap:///anyone\";)"
  190. ACI_BODY = ACI_TARGET + ACI_ALLOW + ACI_SUBJECT
  191. suffix = Domain(m1, SUFFIX)
  192. suffix.add('aci', ACI_BODY)
  193. # DIT for staging
  194. m1.log.info("Add {}".format(STAGING_DN))
  195. o_roles.create(properties={'cn': STAGING_CN, 'description': "staging DIT"})
  196. # DIT for production
  197. m1.log.info("Add {}".format(PRODUCTION_DN))
  198. o_roles.create(properties={'cn': PRODUCTION_CN, 'description': "production DIT"})
  199. # DIT for production/except
  200. m1.log.info("Add {}".format(PROD_EXCEPT_DN))
  201. o_roles_prod = OrganizationalRoles(m1, PRODUCTION_DN)
  202. o_roles_prod.create(properties={'cn': EXCEPT_CN, 'description': "production except DIT"})
  203. # enable acl error logging
  204. # mod = [(ldap.MOD_REPLACE, 'nsslapd-errorlog-level', '128')]
  205. # m1.modify_s(DN_CONFIG, mod)
  206. # topology_m2.ms["master2"].modify_s(DN_CONFIG, mod)
  207. # add dummy entries in the staging DIT
  208. staging_users = UserAccounts(m1, SUFFIX, rdn="cn={}".format(STAGING_CN))
  209. user_props = TEST_USER_PROPERTIES.copy()
  210. for cpt in range(MAX_ACCOUNTS):
  211. name = "{}{}".format(NEW_ACCOUNT, cpt)
  212. user_props.update({'sn': name, 'cn': name, 'uid': name})
  213. staging_users.create(properties=user_props)
  214. def test_mode_default_add_deny(topology_m2, moddn_setup):
  215. """Tests that the ADD operation fails (no ADD aci on production)
  216. :id: 301d41d3-b8d8-44c5-8eb9-c2d2816b5a4f
  217. :setup: MMR with two masters,
  218. M1 - staging DIT
  219. M2 - production DIT
  220. add test accounts in staging DIT
  221. :steps:
  222. 1. Add an entry in production
  223. :expectedresults:
  224. 1. It should fail due to INSUFFICIENT_ACCESS
  225. """
  226. topology_m2.ms["master1"].log.info("\n\n######## mode moddn_aci : ADD (should fail) ########\n")
  227. _bind_normal(topology_m2)
  228. #
  229. # First try to add an entry in production => INSUFFICIENT_ACCESS
  230. #
  231. try:
  232. topology_m2.ms["master1"].log.info("Try to add %s" % PRODUCTION_DN)
  233. name = "%s%d" % (NEW_ACCOUNT, 0)
  234. topology_m2.ms["master1"].add_s(Entry(("uid=%s,%s" % (name, PRODUCTION_DN), {
  235. 'objectclass': "top person".split(),
  236. 'sn': name,
  237. 'cn': name,
  238. 'uid': name})))
  239. assert 0 # this is an error, we should not be allowed to add an entry in production
  240. except Exception as e:
  241. topology_m2.ms["master1"].log.info("Exception (expected): %s" % type(e).__name__)
  242. assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
  243. def test_mode_default_delete_deny(topology_m2, moddn_setup):
  244. """Tests that the DEL operation fails (no 'delete' aci on production)
  245. :id: 5dcb2213-3875-489a-8cb5-ace057120ad6
  246. :setup: MMR with two masters,
  247. M1 - staging DIT
  248. M2 - production DIT
  249. add test accounts in staging DIT
  250. :steps:
  251. 1. Delete an entry in staging
  252. :expectedresults:
  253. 1. It should fail due to INSUFFICIENT_ACCESS
  254. """
  255. topology_m2.ms["master1"].log.info("\n\n######## DELETE (should fail) ########\n")
  256. _bind_normal(topology_m2)
  257. #
  258. # Second try to delete an entry in staging => INSUFFICIENT_ACCESS
  259. #
  260. try:
  261. topology_m2.ms["master1"].log.info("Try to delete %s" % STAGING_DN)
  262. name = "%s%d" % (NEW_ACCOUNT, 0)
  263. topology_m2.ms["master1"].delete_s("uid=%s,%s" % (name, STAGING_DN))
  264. assert 0 # this is an error, we should not be allowed to add an entry in production
  265. except Exception as e:
  266. topology_m2.ms["master1"].log.info("Exception (expected): %s" % type(e).__name__)
  267. assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
  268. @pytest.mark.parametrize("index,tfrom,tto,failure",
  269. [(0, STAGING_DN, PRODUCTION_DN, False),
  270. (1, STAGING_DN, PRODUCTION_DN, False),
  271. (2, STAGING_DN, BAD_PRODUCTION_PATTERN, True),
  272. (3, STAGING_PATTERN, PRODUCTION_DN, False),
  273. (4, BAD_STAGING_PATTERN, PRODUCTION_DN, True),
  274. (5, STAGING_PATTERN, PRODUCTION_PATTERN, False),
  275. (6, None, PRODUCTION_PATTERN, False),
  276. (7, STAGING_PATTERN, None, False),
  277. (8, None, None, False)])
  278. def test_moddn_staging_prod(topology_m2, moddn_setup,
  279. index, tfrom, tto, failure):
  280. """This test case MOVE entry NEW_ACCOUNT0 from staging to prod
  281. target_to/target_from: equality filter
  282. :id: cbafdd68-64d6-431f-9f22-6fbf9ed23ca0
  283. :parametrized: yes
  284. :setup: MMR with two masters,
  285. M1 - staging DIT
  286. M2 - production DIT
  287. add test accounts in staging DIT
  288. :steps:
  289. 1. Try to modify DN with moddn for each value of
  290. STAGING_DN -> PRODUCTION_DN
  291. 2. Try to modify DN with moddn for each value of
  292. STAGING_DN -> PRODUCTION_DN with appropriate ACI
  293. :expectedresults:
  294. 1. It should fail due to INSUFFICIENT_ACCESS
  295. 2. It should pass due to appropriate ACI
  296. """
  297. topology_m2.ms["master1"].log.info("\n\n######## MOVE staging -> Prod (%s) ########\n" % index)
  298. _bind_normal(topology_m2)
  299. old_rdn = "uid=%s%s" % (NEW_ACCOUNT, index)
  300. old_dn = "%s,%s" % (old_rdn, STAGING_DN)
  301. new_rdn = old_rdn
  302. new_superior = PRODUCTION_DN
  303. #
  304. # Try to rename without the appropriate ACI => INSUFFICIENT_ACCESS
  305. #
  306. try:
  307. topology_m2.ms["master1"].log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
  308. topology_m2.ms["master1"].rename_s(old_dn, new_rdn, newsuperior=new_superior)
  309. assert 0
  310. except AssertionError:
  311. topology_m2.ms["master1"].log.info(
  312. "Exception (not really expected exception but that is fine as it fails to rename)")
  313. except Exception as e:
  314. topology_m2.ms["master1"].log.info("Exception (expected): %s" % type(e).__name__)
  315. assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
  316. # successful MOD with the ACI
  317. topology_m2.ms["master1"].log.info("\n\n######## MOVE to and from equality filter ########\n")
  318. _bind_manager(topology_m2)
  319. _moddn_aci_staging_to_production(topology_m2, mod_type=ldap.MOD_ADD,
  320. target_from=tfrom, target_to=tto)
  321. _bind_normal(topology_m2)
  322. try:
  323. topology_m2.ms["master1"].log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
  324. topology_m2.ms["master1"].rename_s(old_dn, new_rdn, newsuperior=new_superior)
  325. except Exception as e:
  326. topology_m2.ms["master1"].log.info("Exception (expected): %s" % type(e).__name__)
  327. if failure:
  328. assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
  329. # successful MOD with the both ACI
  330. _bind_manager(topology_m2)
  331. _moddn_aci_staging_to_production(topology_m2, mod_type=ldap.MOD_DELETE,
  332. target_from=tfrom, target_to=tto)
  333. _bind_normal(topology_m2)
  334. def test_moddn_staging_prod_9(topology_m2, moddn_setup):
  335. """Test with nsslapd-moddn-aci set to off so that MODDN requires an 'add' aci.
  336. :id: 222dd7e8-7ff1-40b8-ad26-6f8e42fbfcd9
  337. :setup: MMR with two masters,
  338. M1 - staging DIT
  339. M2 - production DIT
  340. add test accounts in staging DIT
  341. :steps:
  342. 1. Try to modify DN with moddn STAGING_DN -> PRODUCTION_DN
  343. 2. Add the moddn aci that will not be evaluated because of the config flag
  344. 3. Try to do modDN
  345. 4. Remove the moddn aci
  346. 5. Add the 'add' right to the production DN
  347. 6. Try to modify DN with moddn with 'add' right
  348. 7. Enable the moddn right
  349. 8. Try to rename without the appropriate ACI
  350. 9. Add the 'add' right to the production DN
  351. 10. Try to rename without the appropriate ACI
  352. 11. Remove the moddn aci
  353. :expectedresults:
  354. 1. It should fail due to INSUFFICIENT_ACCESS
  355. 2. It should pass
  356. 3. It should fail due to INSUFFICIENT_ACCESS
  357. 4. It should pass
  358. 5. It should pass
  359. 6. It should pass
  360. 7. It should pass
  361. 8. It should fail due to INSUFFICIENT_ACCESS
  362. 9. It should pass
  363. 10. It should fail due to INSUFFICIENT_ACCESS
  364. 11. It should pass
  365. """
  366. topology_m2.ms["master1"].log.info("\n\n######## MOVE staging -> Prod (9) ########\n")
  367. _bind_normal(topology_m2)
  368. old_rdn = "uid=%s9" % NEW_ACCOUNT
  369. old_dn = "%s,%s" % (old_rdn, STAGING_DN)
  370. new_rdn = old_rdn
  371. new_superior = PRODUCTION_DN
  372. prod = OrganizationalRole(topology_m2.ms["master1"], PRODUCTION_DN)
  373. #
  374. # Try to rename without the appropriate ACI => INSUFFICIENT_ACCESS
  375. #
  376. try:
  377. topology_m2.ms["master1"].log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
  378. topology_m2.ms["master1"].rename_s(old_dn, new_rdn, newsuperior=new_superior)
  379. assert 0
  380. except AssertionError:
  381. topology_m2.ms["master1"].log.info(
  382. "Exception (not really expected exception but that is fine as it fails to rename)")
  383. except Exception as e:
  384. topology_m2.ms["master1"].log.info("Exception (expected): %s" % type(e).__name__)
  385. assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
  386. #############
  387. # Now do tests with no support of moddn aci
  388. #############
  389. topology_m2.ms["master1"].log.info("Disable the moddn right")
  390. _bind_manager(topology_m2)
  391. topology_m2.ms["master1"].config.set(CONFIG_MODDN_ACI_ATTR, 'off')
  392. # Add the moddn aci that will not be evaluated because of the config flag
  393. topology_m2.ms["master1"].log.info("\n\n######## MOVE to and from equality filter ########\n")
  394. _bind_manager(topology_m2)
  395. _moddn_aci_staging_to_production(topology_m2, mod_type=ldap.MOD_ADD,
  396. target_from=STAGING_DN, target_to=PRODUCTION_DN)
  397. _bind_normal(topology_m2)
  398. # It will fail because it will test the ADD right
  399. try:
  400. topology_m2.ms["master1"].log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
  401. topology_m2.ms["master1"].rename_s(old_dn, new_rdn, newsuperior=new_superior)
  402. assert 0
  403. except AssertionError:
  404. topology_m2.ms["master1"].log.info(
  405. "Exception (not really expected exception but that is fine as it fails to rename)")
  406. except Exception as e:
  407. topology_m2.ms["master1"].log.info("Exception (expected): %s" % type(e).__name__)
  408. assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
  409. # remove the moddn aci
  410. _bind_manager(topology_m2)
  411. _moddn_aci_staging_to_production(topology_m2, mod_type=ldap.MOD_DELETE,
  412. target_from=STAGING_DN, target_to=PRODUCTION_DN)
  413. _bind_normal(topology_m2)
  414. #
  415. # add the 'add' right to the production DN
  416. # Then do a successful moddn
  417. #
  418. ACI_ALLOW = "(version 3.0; acl \"ADD rights to allow moddn\"; allow (add)"
  419. ACI_SUBJECT = " userdn = \"ldap:///%s\";)" % BIND_DN
  420. ACI_BODY = ACI_ALLOW + ACI_SUBJECT
  421. _bind_manager(topology_m2)
  422. prod.add('aci', ACI_BODY)
  423. _write_aci_staging(topology_m2, mod_type=ldap.MOD_ADD)
  424. _bind_normal(topology_m2)
  425. topology_m2.ms["master1"].log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
  426. topology_m2.ms["master1"].rename_s(old_dn, new_rdn, newsuperior=new_superior)
  427. _bind_manager(topology_m2)
  428. prod.remove('aci', ACI_BODY)
  429. _write_aci_staging(topology_m2, mod_type=ldap.MOD_DELETE)
  430. _bind_normal(topology_m2)
  431. #############
  432. # Now do tests with support of moddn aci
  433. #############
  434. topology_m2.ms["master1"].log.info("Enable the moddn right")
  435. _bind_manager(topology_m2)
  436. topology_m2.ms["master1"].config.set(CONFIG_MODDN_ACI_ATTR, 'on')
  437. topology_m2.ms["master1"].log.info("\n\n######## MOVE staging -> Prod (10) ########\n")
  438. _bind_normal(topology_m2)
  439. old_rdn = "uid=%s10" % NEW_ACCOUNT
  440. old_dn = "%s,%s" % (old_rdn, STAGING_DN)
  441. new_rdn = old_rdn
  442. new_superior = PRODUCTION_DN
  443. #
  444. # Try to rename without the appropriate ACI => INSUFFICIENT_ACCESS
  445. #
  446. try:
  447. topology_m2.ms["master1"].log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
  448. topology_m2.ms["master1"].rename_s(old_dn, new_rdn, newsuperior=new_superior)
  449. assert 0
  450. except AssertionError:
  451. topology_m2.ms["master1"].log.info(
  452. "Exception (not really expected exception but that is fine as it fails to rename)")
  453. except Exception as e:
  454. topology_m2.ms["master1"].log.info("Exception (expected): %s" % type(e).__name__)
  455. assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
  456. #
  457. # add the 'add' right to the production DN
  458. # Then do a failing moddn
  459. #
  460. ACI_ALLOW = "(version 3.0; acl \"ADD rights to allow moddn\"; allow (add)"
  461. ACI_SUBJECT = " userdn = \"ldap:///%s\";)" % BIND_DN
  462. ACI_BODY = ACI_ALLOW + ACI_SUBJECT
  463. _bind_manager(topology_m2)
  464. prod.add('aci', ACI_BODY)
  465. _write_aci_staging(topology_m2, mod_type=ldap.MOD_ADD)
  466. _bind_normal(topology_m2)
  467. try:
  468. topology_m2.ms["master1"].log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
  469. topology_m2.ms["master1"].rename_s(old_dn, new_rdn, newsuperior=new_superior)
  470. assert 0
  471. except AssertionError:
  472. topology_m2.ms["master1"].log.info(
  473. "Exception (not really expected exception but that is fine as it fails to rename)")
  474. except Exception as e:
  475. topology_m2.ms["master1"].log.info("Exception (expected): %s" % type(e).__name__)
  476. assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
  477. _bind_manager(topology_m2)
  478. prod.remove('aci', ACI_BODY)
  479. _write_aci_staging(topology_m2, mod_type=ldap.MOD_DELETE)
  480. _bind_normal(topology_m2)
  481. # Add the moddn aci that will be evaluated because of the config flag
  482. topology_m2.ms["master1"].log.info("\n\n######## MOVE to and from equality filter ########\n")
  483. _bind_manager(topology_m2)
  484. _moddn_aci_staging_to_production(topology_m2, mod_type=ldap.MOD_ADD,
  485. target_from=STAGING_DN, target_to=PRODUCTION_DN)
  486. _bind_normal(topology_m2)
  487. topology_m2.ms["master1"].log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
  488. topology_m2.ms["master1"].rename_s(old_dn, new_rdn, newsuperior=new_superior)
  489. # remove the moddn aci
  490. _bind_manager(topology_m2)
  491. _moddn_aci_staging_to_production(topology_m2, mod_type=ldap.MOD_DELETE,
  492. target_from=STAGING_DN, target_to=PRODUCTION_DN)
  493. _bind_normal(topology_m2)
  494. def test_moddn_prod_staging(topology_m2, moddn_setup):
  495. """This test checks that we can move ACCOUNT11 from staging to prod
  496. but not move back ACCOUNT11 from prod to staging
  497. :id: 2b061e92-483f-4399-9f56-8d1c1898b043
  498. :setup: MMR with two masters,
  499. M1 - staging DIT
  500. M2 - production DIT
  501. add test accounts in staging DIT
  502. :steps:
  503. 1. Try to rename without the appropriate ACI
  504. 2. Try to MOD with the ACI from stage to production
  505. 3. Try to move back the entry to staging from production
  506. :expectedresults:
  507. 1. It should fail due to INSUFFICIENT_ACCESS
  508. 2. It should pass
  509. 3. It should fail due to INSUFFICIENT_ACCESS
  510. """
  511. topology_m2.ms["master1"].log.info("\n\n######## MOVE staging -> Prod (11) ########\n")
  512. _bind_normal(topology_m2)
  513. old_rdn = "uid=%s11" % NEW_ACCOUNT
  514. old_dn = "%s,%s" % (old_rdn, STAGING_DN)
  515. new_rdn = old_rdn
  516. new_superior = PRODUCTION_DN
  517. #
  518. # Try to rename without the appropriate ACI => INSUFFICIENT_ACCESS
  519. #
  520. try:
  521. topology_m2.ms["master1"].log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
  522. topology_m2.ms["master1"].rename_s(old_dn, new_rdn, newsuperior=new_superior)
  523. assert 0
  524. except AssertionError:
  525. topology_m2.ms["master1"].log.info(
  526. "Exception (not really expected exception but that is fine as it fails to rename)")
  527. except Exception as e:
  528. topology_m2.ms["master1"].log.info("Exception (expected): %s" % type(e).__name__)
  529. assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
  530. # successful MOD with the ACI
  531. topology_m2.ms["master1"].log.info("\n\n######## MOVE to and from equality filter ########\n")
  532. _bind_manager(topology_m2)
  533. _moddn_aci_staging_to_production(topology_m2, mod_type=ldap.MOD_ADD,
  534. target_from=STAGING_DN, target_to=PRODUCTION_DN)
  535. _bind_normal(topology_m2)
  536. topology_m2.ms["master1"].log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
  537. topology_m2.ms["master1"].rename_s(old_dn, new_rdn, newsuperior=new_superior)
  538. # Now check we can not move back the entry to staging
  539. old_rdn = "uid=%s11" % NEW_ACCOUNT
  540. old_dn = "%s,%s" % (old_rdn, PRODUCTION_DN)
  541. new_rdn = old_rdn
  542. new_superior = STAGING_DN
  543. # add the write right because we want to check the moddn
  544. _bind_manager(topology_m2)
  545. _write_aci_production(topology_m2, mod_type=ldap.MOD_ADD)
  546. _bind_normal(topology_m2)
  547. try:
  548. topology_m2.ms["master1"].log.info("Try to move back MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
  549. topology_m2.ms["master1"].rename_s(old_dn, new_rdn, newsuperior=new_superior)
  550. assert 0
  551. except AssertionError:
  552. topology_m2.ms["master1"].log.info(
  553. "Exception (not really expected exception but that is fine as it fails to rename)")
  554. except Exception as e:
  555. topology_m2.ms["master1"].log.info("Exception (expected): %s" % type(e).__name__)
  556. assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
  557. _bind_manager(topology_m2)
  558. _write_aci_production(topology_m2, mod_type=ldap.MOD_DELETE)
  559. _bind_normal(topology_m2)
  560. # successful MOD with the both ACI
  561. _bind_manager(topology_m2)
  562. _moddn_aci_staging_to_production(topology_m2, mod_type=ldap.MOD_DELETE,
  563. target_from=STAGING_DN, target_to=PRODUCTION_DN)
  564. _bind_normal(topology_m2)
  565. def test_check_repl_M2_to_M1(topology_m2, moddn_setup):
  566. """Checks that replication is still working M2->M1, using ACCOUNT12
  567. :id: 08ac131d-34b7-443f-aacd-23025bbd7de1
  568. :setup: MMR with two masters,
  569. M1 - staging DIT
  570. M2 - production DIT
  571. add test accounts in staging DIT
  572. :steps:
  573. 1. Add an entry in M2
  574. 2. Search entry on M1
  575. :expectedresults:
  576. 1. It should pass
  577. 2. It should pass
  578. """
  579. topology_m2.ms["master1"].log.info("Bind as %s (M2)" % DN_DM)
  580. topology_m2.ms["master2"].simple_bind_s(DN_DM, PASSWORD)
  581. rdn = "uid=%s12" % NEW_ACCOUNT
  582. dn = "%s,%s" % (rdn, STAGING_DN)
  583. new_account = UserAccount(topology_m2.ms["master2"], dn)
  584. # First wait for the ACCOUNT19 entry being replicated on M2
  585. loop = 0
  586. while loop <= 10:
  587. try:
  588. ent = topology_m2.ms["master2"].getEntry(dn, ldap.SCOPE_BASE, "(objectclass=*)")
  589. break
  590. except ldap.NO_SUCH_OBJECT:
  591. time.sleep(1)
  592. loop += 1
  593. assert loop <= 10
  594. attribute = 'description'
  595. tested_value = b'Hello world'
  596. topology_m2.ms["master1"].log.info("Update (M2) %s (%s)" % (dn, attribute))
  597. new_account.add(attribute, tested_value)
  598. loop = 0
  599. while loop <= 10:
  600. ent = topology_m2.ms["master1"].getEntry(dn, ldap.SCOPE_BASE, "(objectclass=*)")
  601. assert ent is not None
  602. if ent.hasAttr(attribute) and (ent.getValue(attribute) == tested_value):
  603. break
  604. time.sleep(1)
  605. loop += 1
  606. assert loop < 10
  607. topology_m2.ms["master1"].log.info("Update %s (%s) replicated on M1" % (dn, attribute))
  608. def test_moddn_staging_prod_except(topology_m2, moddn_setup):
  609. """This test case MOVE entry NEW_ACCOUNT13 from staging to prod
  610. but fails to move entry NEW_ACCOUNT14 from staging to prod_except
  611. :id: 02d34f4c-8574-428d-b43f-31227426392c
  612. :setup: MMR with two masters,
  613. M1 - staging DIT
  614. M2 - production DIT
  615. add test accounts in staging DIT
  616. :steps:
  617. 1. Try to move entry staging -> Prod
  618. without the appropriate ACI
  619. 2. Do MOD with the appropriate ACI
  620. 3. Try to move an entry under Prod/Except from stage
  621. 4. Try to do MOD with appropriate ACI
  622. :expectedresults:
  623. 1. It should fail due to INSUFFICIENT_ACCESS
  624. 2. It should pass
  625. 3. It should fail due to INSUFFICIENT_ACCESS
  626. 4. It should pass
  627. """
  628. topology_m2.ms["master1"].log.info("\n\n######## MOVE staging -> Prod (13) ########\n")
  629. _bind_normal(topology_m2)
  630. old_rdn = "uid=%s13" % NEW_ACCOUNT
  631. old_dn = "%s,%s" % (old_rdn, STAGING_DN)
  632. new_rdn = old_rdn
  633. new_superior = PRODUCTION_DN
  634. #
  635. # Try to rename without the appropriate ACI => INSUFFICIENT_ACCESS
  636. #
  637. try:
  638. topology_m2.ms["master1"].log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
  639. topology_m2.ms["master1"].rename_s(old_dn, new_rdn, newsuperior=new_superior)
  640. assert 0
  641. except AssertionError:
  642. topology_m2.ms["master1"].log.info(
  643. "Exception (not really expected exception but that is fine as it fails to rename)")
  644. except Exception as e:
  645. topology_m2.ms["master1"].log.info("Exception (expected): %s" % type(e).__name__)
  646. assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
  647. # successful MOD with the ACI
  648. topology_m2.ms["master1"].log.info("\n\n######## MOVE to and from equality filter ########\n")
  649. _bind_manager(topology_m2)
  650. _moddn_aci_staging_to_production(topology_m2, mod_type=ldap.MOD_ADD,
  651. target_from=STAGING_DN, target_to=PRODUCTION_DN)
  652. _moddn_aci_deny_tree(topology_m2, mod_type=ldap.MOD_ADD)
  653. _bind_normal(topology_m2)
  654. topology_m2.ms["master1"].log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
  655. topology_m2.ms["master1"].rename_s(old_dn, new_rdn, newsuperior=new_superior)
  656. #
  657. # Now try to move an entry under except
  658. #
  659. topology_m2.ms["master1"].log.info("\n\n######## MOVE staging -> Prod/Except (14) ########\n")
  660. old_rdn = "uid=%s14" % NEW_ACCOUNT
  661. old_dn = "%s,%s" % (old_rdn, STAGING_DN)
  662. new_rdn = old_rdn
  663. new_superior = PROD_EXCEPT_DN
  664. try:
  665. topology_m2.ms["master1"].log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
  666. topology_m2.ms["master1"].rename_s(old_dn, new_rdn, newsuperior=new_superior)
  667. assert 0
  668. except AssertionError:
  669. topology_m2.ms["master1"].log.info(
  670. "Exception (not really expected exception but that is fine as it fails to rename)")
  671. except Exception as e:
  672. topology_m2.ms["master1"].log.info("Exception (expected): %s" % type(e).__name__)
  673. assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
  674. # successful MOD with the both ACI
  675. _bind_manager(topology_m2)
  676. _moddn_aci_staging_to_production(topology_m2, mod_type=ldap.MOD_DELETE,
  677. target_from=STAGING_DN, target_to=PRODUCTION_DN)
  678. _moddn_aci_deny_tree(topology_m2, mod_type=ldap.MOD_DELETE)
  679. _bind_normal(topology_m2)
  680. def test_mode_default_ger_no_moddn(topology_m2, moddn_setup):
  681. """mode moddn_aci : Check Get Effective Rights Controls for entries
  682. :id: f4785d73-3b14-49c0-b981-d6ff96fa3496
  683. :setup: MMR with two masters,
  684. M1 - staging DIT
  685. M2 - production DIT
  686. add test accounts in staging DIT
  687. :steps:
  688. 1. Search for GER controls on M1
  689. 2. Check 'n' is not in the entryLevelRights
  690. :expectedresults:
  691. 1. It should pass
  692. 2. It should pass
  693. """
  694. topology_m2.ms["master1"].log.info("\n\n######## mode moddn_aci : GER no moddn ########\n")
  695. request_ctrl = GetEffectiveRightsControl(criticality=True,
  696. authzId=ensure_bytes("dn: " + BIND_DN))
  697. msg_id = topology_m2.ms["master1"].search_ext(PRODUCTION_DN,
  698. ldap.SCOPE_SUBTREE,
  699. "objectclass=*",
  700. serverctrls=[request_ctrl])
  701. rtype, rdata, rmsgid, response_ctrl = topology_m2.ms["master1"].result3(msg_id)
  702. # ger={}
  703. value = ''
  704. for dn, attrs in rdata:
  705. topology_m2.ms["master1"].log.info("dn: %s" % dn)
  706. value = attrs['entryLevelRights'][0]
  707. topology_m2.ms["master1"].log.info("######## entryLevelRights: %r" % value)
  708. assert b'n' not in value
  709. def test_mode_default_ger_with_moddn(topology_m2, moddn_setup):
  710. """This test case adds the moddn aci and check ger contains 'n'
  711. :id: a752a461-432d-483a-89c0-dfb34045a969
  712. :setup: MMR with two masters,
  713. M1 - staging DIT
  714. M2 - production DIT
  715. add test accounts in staging DIT
  716. :steps:
  717. 1. Add moddn ACI on M2
  718. 2. Search for GER controls on M1
  719. 3. Check entryLevelRights value for entries
  720. 4. Check 'n' is in the entryLevelRights
  721. :expectedresults:
  722. 1. It should pass
  723. 2. It should pass
  724. 3. It should pass
  725. 4. It should pass
  726. """
  727. topology_m2.ms["master1"].log.info("\n\n######## mode moddn_aci: GER with moddn ########\n")
  728. # successful MOD with the ACI
  729. _bind_manager(topology_m2)
  730. _moddn_aci_staging_to_production(topology_m2, mod_type=ldap.MOD_ADD,
  731. target_from=STAGING_DN, target_to=PRODUCTION_DN)
  732. _bind_normal(topology_m2)
  733. request_ctrl = GetEffectiveRightsControl(criticality=True,
  734. authzId=ensure_bytes("dn: " + BIND_DN))
  735. msg_id = topology_m2.ms["master1"].search_ext(PRODUCTION_DN,
  736. ldap.SCOPE_SUBTREE,
  737. "objectclass=*",
  738. serverctrls=[request_ctrl])
  739. rtype, rdata, rmsgid, response_ctrl = topology_m2.ms["master1"].result3(msg_id)
  740. # ger={}
  741. value = ''
  742. for dn, attrs in rdata:
  743. topology_m2.ms["master1"].log.info("dn: %s" % dn)
  744. value = attrs['entryLevelRights'][0]
  745. topology_m2.ms["master1"].log.info("######## entryLevelRights: %r" % value)
  746. assert b'n' in value
  747. # successful MOD with the both ACI
  748. _bind_manager(topology_m2)
  749. _moddn_aci_staging_to_production(topology_m2, mod_type=ldap.MOD_DELETE,
  750. target_from=STAGING_DN, target_to=PRODUCTION_DN)
  751. _bind_normal(topology_m2)
  752. def test_mode_legacy_ger_no_moddn1(topology_m2, moddn_setup):
  753. """This test checks mode legacy : GER no moddn
  754. :id: e783e05b-d0d0-4fd4-9572-258a81b7bd24
  755. :setup: MMR with two masters,
  756. M1 - staging DIT
  757. M2 - production DIT
  758. add test accounts in staging DIT
  759. :steps:
  760. 1. Disable ACI checks - set nsslapd-moddn-aci: off
  761. 2. Search for GER controls on M1
  762. 3. Check entryLevelRights value for entries
  763. 4. Check 'n' is not in the entryLevelRights
  764. :expectedresults:
  765. 1. It should pass
  766. 2. It should pass
  767. 3. It should pass
  768. 4. It should pass
  769. """
  770. topology_m2.ms["master1"].log.info("\n\n######## Disable the moddn aci mod ########\n")
  771. _bind_manager(topology_m2)
  772. topology_m2.ms["master1"].config.set(CONFIG_MODDN_ACI_ATTR, 'off')
  773. topology_m2.ms["master1"].log.info("\n\n######## mode legacy 1: GER no moddn ########\n")
  774. request_ctrl = GetEffectiveRightsControl(criticality=True, authzId=ensure_bytes("dn: " + BIND_DN))
  775. msg_id = topology_m2.ms["master1"].search_ext(PRODUCTION_DN,
  776. ldap.SCOPE_SUBTREE,
  777. "objectclass=*",
  778. serverctrls=[request_ctrl])
  779. rtype, rdata, rmsgid, response_ctrl = topology_m2.ms["master1"].result3(msg_id)
  780. # ger={}
  781. value = ''
  782. for dn, attrs in rdata:
  783. topology_m2.ms["master1"].log.info("dn: %s" % dn)
  784. value = attrs['entryLevelRights'][0]
  785. topology_m2.ms["master1"].log.info("######## entryLevelRights: %r" % value)
  786. assert b'n' not in value
  787. def test_mode_legacy_ger_no_moddn2(topology_m2, moddn_setup):
  788. """This test checks mode legacy : GER no moddn
  789. :id: af87e024-1744-4f1d-a2d3-ea2687e2351d
  790. :setup: MMR with two masters,
  791. M1 - staging DIT
  792. M2 - production DIT
  793. add test accounts in staging DIT
  794. :steps:
  795. 1. Disable ACI checks - set nsslapd-moddn-aci: off
  796. 2. Add moddn ACI on M1
  797. 3. Search for GER controls on M1
  798. 4. Check entryLevelRights value for entries
  799. 5. Check 'n' is not in the entryLevelRights
  800. :expectedresults:
  801. 1. It should pass
  802. 2. It should pass
  803. 3. It should pass
  804. 4. It should be pass
  805. 5. It should pass
  806. """
  807. topology_m2.ms["master1"].log.info("\n\n######## Disable the moddn aci mod ########\n")
  808. _bind_manager(topology_m2)
  809. topology_m2.ms["master1"].config.set(CONFIG_MODDN_ACI_ATTR, 'off')
  810. topology_m2.ms["master1"].log.info("\n\n######## mode legacy 2: GER no moddn ########\n")
  811. # successful MOD with the ACI
  812. _bind_manager(topology_m2)
  813. _moddn_aci_staging_to_production(topology_m2, mod_type=ldap.MOD_ADD,
  814. target_from=STAGING_DN, target_to=PRODUCTION_DN)
  815. _bind_normal(topology_m2)
  816. request_ctrl = GetEffectiveRightsControl(criticality=True,
  817. authzId=ensure_bytes("dn: " + BIND_DN))
  818. msg_id = topology_m2.ms["master1"].search_ext(PRODUCTION_DN,
  819. ldap.SCOPE_SUBTREE,
  820. "objectclass=*",
  821. serverctrls=[request_ctrl])
  822. rtype, rdata, rmsgid, response_ctrl = topology_m2.ms["master1"].result3(msg_id)
  823. # ger={}
  824. value = ''
  825. for dn, attrs in rdata:
  826. topology_m2.ms["master1"].log.info("dn: %s" % dn)
  827. value = attrs['entryLevelRights'][0]
  828. topology_m2.ms["master1"].log.info("######## entryLevelRights: %r" % value)
  829. assert b'n' not in value
  830. # successful MOD with the both ACI
  831. _bind_manager(topology_m2)
  832. _moddn_aci_staging_to_production(topology_m2, mod_type=ldap.MOD_DELETE,
  833. target_from=STAGING_DN, target_to=PRODUCTION_DN)
  834. _bind_normal(topology_m2)
  835. def test_mode_legacy_ger_with_moddn(topology_m2, moddn_setup):
  836. """This test checks mode legacy : GER with moddn
  837. :id: 37c1e537-1b5d-4fab-b62a-50cd8c5b3493
  838. :setup: MMR with two masters,
  839. M1 - staging DIT
  840. M2 - production DIT
  841. add test accounts in staging DIT
  842. :steps:
  843. 1. Disable ACI checks - set nsslapd-moddn-aci: off
  844. 2. Add moddn ACI on M1
  845. 3. Search for GER controls on M1
  846. 4. Check entryLevelRights value for entries
  847. 5. Check 'n' is in the entryLevelRights
  848. 6. Try MOD with the both ACI
  849. :expectedresults:
  850. 1. It should pass
  851. 2. It should pass
  852. 3. It should pass
  853. 4. It should pass
  854. 5. It should pass
  855. 6. It should pass
  856. """
  857. suffix = Domain(topology_m2.ms["master1"], SUFFIX)
  858. topology_m2.ms["master1"].log.info("\n\n######## Disable the moddn aci mod ########\n")
  859. _bind_manager(topology_m2)
  860. topology_m2.ms["master1"].config.set(CONFIG_MODDN_ACI_ATTR, 'off')
  861. topology_m2.ms["master1"].log.info("\n\n######## mode legacy : GER with moddn ########\n")
  862. # being allowed to read/write the RDN attribute use to allow the RDN
  863. ACI_TARGET = "(target = \"ldap:///%s\")(targetattr=\"uid\")" % (PRODUCTION_DN)
  864. ACI_ALLOW = "(version 3.0; acl \"MODDN production changing the RDN attribute\"; allow (read,search,write)"
  865. ACI_SUBJECT = " userdn = \"ldap:///%s\";)" % BIND_DN
  866. ACI_BODY = ACI_TARGET + ACI_ALLOW + ACI_SUBJECT
  867. # successful MOD with the ACI
  868. _bind_manager(topology_m2)
  869. suffix.add('aci', ACI_BODY)
  870. _bind_normal(topology_m2)
  871. request_ctrl = GetEffectiveRightsControl(criticality=True, authzId=ensure_bytes("dn: " + BIND_DN))
  872. msg_id = topology_m2.ms["master1"].search_ext(PRODUCTION_DN,
  873. ldap.SCOPE_SUBTREE,
  874. "objectclass=*",
  875. serverctrls=[request_ctrl])
  876. rtype, rdata, rmsgid, response_ctrl = topology_m2.ms["master1"].result3(msg_id)
  877. # ger={}
  878. value = ''
  879. for dn, attrs in rdata:
  880. topology_m2.ms["master1"].log.info("dn: %s" % dn)
  881. value = attrs['entryLevelRights'][0]
  882. topology_m2.ms["master1"].log.info("######## entryLevelRights: %r" % value)
  883. assert b'n' in value
  884. # successful MOD with the both ACI
  885. _bind_manager(topology_m2)
  886. suffix.remove('aci', ACI_BODY)
  887. # _bind_normal(topology_m2)
  888. @pytest.fixture(scope="module")
  889. def rdn_write_setup(topology_m2):
  890. topology_m2.ms["master1"].log.info("\n\n######## Add entry tuser ########\n")
  891. user = UserAccount(topology_m2.ms["master1"], SRC_ENTRY_DN)
  892. user_props = TEST_USER_PROPERTIES.copy()
  893. user_props.update({'sn': SRC_ENTRY_CN,
  894. 'cn': SRC_ENTRY_CN,
  895. 'userpassword': BIND_PW})
  896. user.create(properties=user_props, basedn=SUFFIX)
  897. def test_rdn_write_get_ger(topology_m2, rdn_write_setup):
  898. """This test checks GER rights for anonymous
  899. :id: d5d85f87-b53d-4f50-8fa6-a9e55c75419b
  900. :setup: MMR with two masters,
  901. Add entry tuser
  902. :steps:
  903. 1. Search for GER controls on M1
  904. 2. Check entryLevelRights value for entries
  905. 3. Check 'n' is not in the entryLevelRights
  906. :expectedresults:
  907. 1. It should pass
  908. 2. It should be pass
  909. 3. It should pass
  910. """
  911. ANONYMOUS_DN = ""
  912. topology_m2.ms["master1"].log.info("\n\n######## GER rights for anonymous ########\n")
  913. request_ctrl = GetEffectiveRightsControl(criticality=True,
  914. authzId=ensure_bytes("dn:" + ANONYMOUS_DN))
  915. msg_id = topology_m2.ms["master1"].search_ext(SUFFIX,
  916. ldap.SCOPE_SUBTREE,
  917. "objectclass=*",
  918. serverctrls=[request_ctrl])
  919. rtype, rdata, rmsgid, response_ctrl = topology_m2.ms["master1"].result3(msg_id)
  920. value = ''
  921. for dn, attrs in rdata:
  922. topology_m2.ms["master1"].log.info("dn: %s" % dn)
  923. for value in attrs['entryLevelRights']:
  924. topology_m2.ms["master1"].log.info("######## entryLevelRights: %r" % value)
  925. assert b'n' not in value
  926. def test_rdn_write_modrdn_anonymous(topology_m2, rdn_write_setup):
  927. """Tests anonymous user for modrdn
  928. :id: fc07be23-3341-44ab-a53c-c68c5f9569c7
  929. :setup: MMR with two masters,
  930. Add entry tuser
  931. :steps:
  932. 1. Bind as anonymous user
  933. 2. Try to perform MODRDN operation (SRC_ENTRY_DN -> DST_ENTRY_CN)
  934. 3. Try to search DST_ENTRY_CN
  935. :expectedresults:
  936. 1. It should pass
  937. 2. It should fails with INSUFFICIENT_ACCESS
  938. 3. It should fails with NO_SUCH_OBJECT
  939. """
  940. ANONYMOUS_DN = ""
  941. topology_m2.ms["master1"].close()
  942. topology_m2.ms["master1"].binddn = ANONYMOUS_DN
  943. topology_m2.ms["master1"].open()
  944. msg_id = topology_m2.ms["master1"].search_ext("", ldap.SCOPE_BASE, "objectclass=*")
  945. rtype, rdata, rmsgid, response_ctrl = topology_m2.ms["master1"].result3(msg_id)
  946. for dn, attrs in rdata:
  947. topology_m2.ms["master1"].log.info("dn: %s" % dn)
  948. for attr in attrs:
  949. topology_m2.ms["master1"].log.info("######## %r: %r" % (attr, attrs[attr]))
  950. try:
  951. topology_m2.ms["master1"].rename_s(SRC_ENTRY_DN, "cn=%s" % DST_ENTRY_CN, delold=True)
  952. except Exception as e:
  953. topology_m2.ms["master1"].log.info("Exception (expected): %s" % type(e).__name__)
  954. isinstance(e, ldap.INSUFFICIENT_ACCESS)
  955. try:
  956. topology_m2.ms["master1"].getEntry(DST_ENTRY_DN, ldap.SCOPE_BASE, "objectclass=*")
  957. assert False
  958. except Exception as e:
  959. topology_m2.ms["master1"].log.info("The entry was not renamed (expected)")
  960. isinstance(e, ldap.NO_SUCH_OBJECT)
  961. _bind_manager(topology_m2)
  962. if __name__ == '__main__':
  963. # Run isolated
  964. # -s for DEBUG mode
  965. CURRENT_FILE = os.path.realpath(__file__)
  966. pytest.main("-s %s" % CURRENT_FILE)