ticket49064_test.py 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. import logging
  2. import pytest
  3. import os
  4. import time
  5. import ldap
  6. import subprocess
  7. from lib389.utils import ds_is_older
  8. from lib389.topologies import topology_m1h1c1 as topo
  9. from lib389._constants import *
  10. from lib389 import Entry
  11. # Skip on older versions
  12. pytestmark = pytest.mark.skipif(ds_is_older('1.3.7'), reason="Not implemented")
  13. USER_CN='user_'
  14. GROUP_CN='group_'
  15. FIXUP_FILTER = '(objectClass=*)'
  16. FIXUP_CMD = 'fixup-memberof.pl'
  17. DEBUGGING = os.getenv("DEBUGGING", default=False)
  18. if DEBUGGING:
  19. logging.getLogger(__name__).setLevel(logging.DEBUG)
  20. else:
  21. logging.getLogger(__name__).setLevel(logging.INFO)
  22. log = logging.getLogger(__name__)
  23. def memberof_fixup_task(server):
  24. sbin_dir = server.get_sbin_dir()
  25. memof_task = os.path.join(sbin_dir, FIXUP_CMD)
  26. try:
  27. output = subprocess.check_output(
  28. [memof_task, '-D', DN_DM, '-w', PASSWORD, '-b', SUFFIX, '-Z', SERVERID_CONSUMER_1, '-f', FIXUP_FILTER])
  29. except subprocess.CalledProcessError as err:
  30. output = err.output
  31. log.info('output: {}'.format(output))
  32. expected = "Successfully added task entry"
  33. assert expected in output
  34. def config_memberof(server):
  35. server.plugins.enable(name=PLUGIN_MEMBER_OF)
  36. MEMBEROF_PLUGIN_DN = ('cn=' + PLUGIN_MEMBER_OF + ',cn=plugins,cn=config')
  37. server.modify_s(MEMBEROF_PLUGIN_DN, [(ldap.MOD_REPLACE,
  38. 'memberOfAllBackends',
  39. 'on'),
  40. (ldap.MOD_REPLACE, 'memberOfAutoAddOC', 'nsMemberOf')])
  41. # Configure fractional to prevent total init to send memberof
  42. ents = server.agreement.list(suffix=DEFAULT_SUFFIX)
  43. for ent in ents:
  44. log.info('update %s to add nsDS5ReplicatedAttributeListTotal' % ent.dn)
  45. server.modify_s(ent.dn,
  46. [(ldap.MOD_REPLACE,
  47. 'nsDS5ReplicatedAttributeListTotal',
  48. '(objectclass=*) $ EXCLUDE '),
  49. (ldap.MOD_REPLACE,
  50. 'nsDS5ReplicatedAttributeList',
  51. '(objectclass=*) $ EXCLUDE memberOf')])
  52. def send_updates_now(server):
  53. ents = server.agreement.list(suffix=DEFAULT_SUFFIX)
  54. for ent in ents:
  55. server.agreement.pause(ent.dn)
  56. server.agreement.resume(ent.dn)
  57. def add_user(server, no, desc='dummy', sleep=True):
  58. cn = '%s%d' % (USER_CN, no)
  59. dn = 'cn=%s,ou=people,%s' % (cn, SUFFIX)
  60. log.fatal('Adding user (%s): ' % dn)
  61. server.add_s(Entry((dn, {'objectclass': ['top', 'person', 'inetuser'],
  62. 'sn': ['_%s' % cn],
  63. 'description': [desc]})))
  64. if sleep:
  65. time.sleep(2)
  66. def add_group(server, nr, sleep=True):
  67. cn = '%s%d' % (GROUP_CN, nr)
  68. dn = 'cn=%s,ou=groups,%s' % (cn, SUFFIX)
  69. server.add_s(Entry((dn, {'objectclass': ['top', 'groupofnames'],
  70. 'description': 'group %d' % nr})))
  71. if sleep:
  72. time.sleep(2)
  73. def update_member(server, member_dn, group_dn, op, sleep=True):
  74. mod = [(op, 'member', member_dn)]
  75. server.modify_s(group_dn, mod)
  76. if sleep:
  77. time.sleep(2)
  78. def _find_memberof(server, member_dn, group_dn, find_result=True):
  79. ent = server.getEntry(member_dn, ldap.SCOPE_BASE, "(objectclass=*)", ['memberof'])
  80. found = False
  81. if ent.hasAttr('memberof'):
  82. for val in ent.getValues('memberof'):
  83. server.log.info("!!!!!!! %s: memberof->%s" % (member_dn, val))
  84. server.log.info("!!!!!!! %s" % (val))
  85. server.log.info("!!!!!!! %s" % (group_dn))
  86. if val.lower() == group_dn.lower():
  87. found = True
  88. break
  89. if find_result:
  90. assert (found)
  91. else:
  92. assert (not found)
  93. def test_ticket49064(topo):
  94. """Specify a test case purpose or name here
  95. :id: 60c11636-55a1-4704-9e09-2c6bcc828de4
  96. :setup: 1 Master - 1 Hub - 1 Consumer
  97. :steps:
  98. 1. Configure replication to EXCLUDE memberof
  99. 2. Enable memberof plugin
  100. 3. Create users/groups
  101. 4. make user_1 member of group_1
  102. 5. Checks that user_1 is memberof group_1 on M,H,C
  103. 6. make group_1 member of group_2 (nest group)
  104. 7. Checks that user_1 is memberof group_1 and group_2 on M,H,C
  105. 8. Check group_1 is memberof group_2 on M,H,C
  106. 9. remove group_1 from group_2
  107. 10. Check group_1 and user_1 are NOT memberof group_2 on M,H,C
  108. 11. remove user_1 from group_1
  109. 12. Check user_1 is NOT memberof group_1 and group_2 on M,H,C
  110. 13. Disable memberof on C1
  111. 14. make user_1 member of group_1
  112. 15. Checks that user is memberof group_1 on M,H but not on C
  113. 16. Enable memberof on C1
  114. 17. Checks that user is memberof group_1 on M,H but not on C
  115. 18. Run memberof fixup task
  116. 19. Checks that user is memberof group_1 on M,H,C
  117. :expectedresults:
  118. no assert for membership check
  119. """
  120. M1 = topo.ms["master1"]
  121. H1 = topo.hs["hub1"]
  122. C1 = topo.cs["consumer1"]
  123. # Step 1 & 2
  124. M1.config.enable_log('audit')
  125. config_memberof(M1)
  126. M1.restart()
  127. H1.config.enable_log('audit')
  128. config_memberof(H1)
  129. H1.restart()
  130. C1.config.enable_log('audit')
  131. config_memberof(C1)
  132. C1.restart()
  133. # Step 3
  134. for i in range(10):
  135. add_user(M1, i, desc='add on m1')
  136. for i in range(3):
  137. add_group(M1, i)
  138. # Step 4
  139. member_dn = 'cn=%s%d,ou=people,%s' % (USER_CN, 1, SUFFIX)
  140. group_dn = 'cn=%s%d,ou=groups,%s' % (GROUP_CN, 1, SUFFIX)
  141. update_member(M1, member_dn, group_dn, ldap.MOD_ADD, sleep=True)
  142. # Step 5
  143. for i in [M1, H1, C1]:
  144. _find_memberof(i, member_dn, group_dn, find_result=True)
  145. # Step 6
  146. user_dn = 'cn=%s%d,ou=people,%s' % (USER_CN, 1, SUFFIX)
  147. grp1_dn = 'cn=%s%d,ou=groups,%s' % (GROUP_CN, 1, SUFFIX)
  148. grp2_dn = 'cn=%s%d,ou=groups,%s' % (GROUP_CN, 2, SUFFIX)
  149. update_member(M1, grp1_dn, grp2_dn, ldap.MOD_ADD, sleep=True)
  150. # Step 7
  151. for i in [grp1_dn, grp2_dn]:
  152. for inst in [M1, H1, C1]:
  153. _find_memberof(inst, user_dn, i, find_result=True)
  154. # Step 8
  155. for i in [M1, H1, C1]:
  156. _find_memberof(i, grp1_dn, grp2_dn, find_result=True)
  157. # Step 9
  158. user_dn = 'cn=%s%d,ou=people,%s' % (USER_CN, 1, SUFFIX)
  159. grp1_dn = 'cn=%s%d,ou=groups,%s' % (GROUP_CN, 1, SUFFIX)
  160. grp2_dn = 'cn=%s%d,ou=groups,%s' % (GROUP_CN, 2, SUFFIX)
  161. update_member(M1, grp1_dn, grp2_dn, ldap.MOD_DELETE, sleep=True)
  162. # Step 10
  163. for inst in [M1, H1, C1]:
  164. for i in [grp1_dn, user_dn]:
  165. _find_memberof(inst, i, grp2_dn, find_result=False)
  166. # Step 11
  167. member_dn = 'cn=%s%d,ou=people,%s' % (USER_CN, 1, SUFFIX)
  168. group_dn = 'cn=%s%d,ou=groups,%s' % (GROUP_CN, 1, SUFFIX)
  169. update_member(M1, member_dn, group_dn, ldap.MOD_DELETE, sleep=True)
  170. # Step 12
  171. for inst in [M1, H1, C1]:
  172. for grp in [grp1_dn, grp2_dn]:
  173. _find_memberof(inst, member_dn, grp, find_result=False)
  174. # Step 13
  175. C1.plugins.disable(name=PLUGIN_MEMBER_OF)
  176. C1.restart()
  177. # Step 14
  178. member_dn = 'cn=%s%d,ou=people,%s' % (USER_CN, 1, SUFFIX)
  179. group_dn = 'cn=%s%d,ou=groups,%s' % (GROUP_CN, 1, SUFFIX)
  180. update_member(M1, member_dn, group_dn, ldap.MOD_ADD, sleep=True)
  181. # to give time to the update to go up to the C1
  182. time.sleep(10)
  183. # Step 15
  184. for i in [M1, H1]:
  185. _find_memberof(i, member_dn, group_dn, find_result=True)
  186. _find_memberof(C1, member_dn, group_dn, find_result=False)
  187. # Step 16
  188. C1.plugins.enable(name=PLUGIN_MEMBER_OF)
  189. C1.restart()
  190. # Step 17
  191. for i in [M1, H1]:
  192. _find_memberof(i, member_dn, group_dn, find_result=True)
  193. _find_memberof(C1, member_dn, group_dn, find_result=False)
  194. # Step 18
  195. memberof_fixup_task(C1)
  196. time.sleep(5)
  197. # Step 19
  198. for i in [M1, H1, C1]:
  199. _find_memberof(i, member_dn, group_dn, find_result=True)
  200. # If you need any test suite initialization,
  201. # please, write additional fixture for that (including finalizer).
  202. # Topology for suites are predefined in lib389/topologies.py.
  203. # If you need host, port or any other data about instance,
  204. # Please, use the instance object attributes for that (for example, topo.ms["master1"].serverid)
  205. if DEBUGGING:
  206. # Add debugging steps(if any)...
  207. pass
  208. if __name__ == '__main__':
  209. # Run isolated
  210. # -s for DEBUG mode
  211. CURRENT_FILE = os.path.realpath(__file__)
  212. pytest.main("-s %s" % CURRENT_FILE)