ticket47950_test.py 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. import os
  2. import sys
  3. import time
  4. import ldap
  5. import logging
  6. import socket
  7. import pytest
  8. from lib389 import DirSrv, Entry, tools, tasks
  9. from lib389.tools import DirSrvTools
  10. from lib389._constants import *
  11. from lib389.properties import *
  12. from lib389.tasks import *
  13. from constants import *
  14. log = logging.getLogger(__name__)
  15. installation_prefix = None
  16. USER1_DN = "uid=user1,%s" % DEFAULT_SUFFIX
  17. USER2_DN = "uid=user2,%s" % DEFAULT_SUFFIX
  18. class TopologyStandalone(object):
  19. def __init__(self, standalone):
  20. standalone.open()
  21. self.standalone = standalone
  22. @pytest.fixture(scope="module")
  23. def topology(request):
  24. '''
  25. This fixture is used to standalone topology for the 'module'.
  26. At the beginning, It may exists a standalone instance.
  27. It may also exists a backup for the standalone instance.
  28. Principle:
  29. If standalone instance exists:
  30. restart it
  31. If backup of standalone exists:
  32. create/rebind to standalone
  33. restore standalone instance from backup
  34. else:
  35. Cleanup everything
  36. remove instance
  37. remove backup
  38. Create instance
  39. Create backup
  40. '''
  41. global installation_prefix
  42. if installation_prefix:
  43. args_instance[SER_DEPLOYED_DIR] = installation_prefix
  44. standalone = DirSrv(verbose=False)
  45. # Args for the standalone instance
  46. args_instance[SER_HOST] = HOST_STANDALONE
  47. args_instance[SER_PORT] = PORT_STANDALONE
  48. args_instance[SER_SERVERID_PROP] = SERVERID_STANDALONE
  49. args_standalone = args_instance.copy()
  50. standalone.allocate(args_standalone)
  51. # Get the status of the backups
  52. backup_standalone = standalone.checkBackupFS()
  53. # Get the status of the instance and restart it if it exists
  54. instance_standalone = standalone.exists()
  55. if instance_standalone:
  56. # assuming the instance is already stopped, just wait 5 sec max
  57. standalone.stop(timeout=5)
  58. standalone.start(timeout=10)
  59. if backup_standalone:
  60. # The backup exist, assuming it is correct
  61. # we just re-init the instance with it
  62. if not instance_standalone:
  63. standalone.create()
  64. # Used to retrieve configuration information (dbdir, confdir...)
  65. standalone.open()
  66. # restore standalone instance from backup
  67. standalone.stop(timeout=10)
  68. standalone.restoreFS(backup_standalone)
  69. standalone.start(timeout=10)
  70. else:
  71. # We should be here only in two conditions
  72. # - This is the first time a test involve standalone instance
  73. # - Something weird happened (instance/backup destroyed)
  74. # so we discard everything and recreate all
  75. # Remove the backup. So even if we have a specific backup file
  76. # (e.g backup_standalone) we clear backup that an instance may have created
  77. if backup_standalone:
  78. standalone.clearBackupFS()
  79. # Remove the instance
  80. if instance_standalone:
  81. standalone.delete()
  82. # Create the instance
  83. standalone.create()
  84. # Used to retrieve configuration information (dbdir, confdir...)
  85. standalone.open()
  86. # Time to create the backups
  87. standalone.stop(timeout=10)
  88. standalone.backupfile = standalone.backupFS()
  89. standalone.start(timeout=10)
  90. # clear the tmp directory
  91. standalone.clearTmpDir(__file__)
  92. #
  93. # Here we have standalone instance up and running
  94. # Either coming from a backup recovery
  95. # or from a fresh (re)init
  96. # Time to return the topology
  97. return TopologyStandalone(standalone)
  98. def test_ticket47950(topology):
  99. """
  100. Testing nsslapd-plugin-binddn-tracking does not cause issues around
  101. access control and reconfiguring replication/repl agmt.
  102. """
  103. log.info('Testing Ticket 47950 - Testing nsslapd-plugin-binddn-tracking')
  104. #
  105. # Turn on bind dn tracking
  106. #
  107. try:
  108. topology.standalone.modify_s("cn=config", [(ldap.MOD_REPLACE, 'nsslapd-plugin-binddn-tracking', 'on')])
  109. log.info('nsslapd-plugin-binddn-tracking enabled.')
  110. except ldap.LDAPError, e:
  111. log.error('Failed to enable bind dn tracking: ' + e.message['desc'])
  112. assert False
  113. #
  114. # Add two users
  115. #
  116. try:
  117. topology.standalone.add_s(Entry((USER1_DN, {
  118. 'objectclass': "top person inetuser".split(),
  119. 'userpassword': "password",
  120. 'sn': "1",
  121. 'cn': "user 1"})))
  122. log.info('Added test user %s' % USER1_DN)
  123. except ldap.LDAPError, e:
  124. log.error('Failed to add %s: %s' % (USER1_DN, e.message['desc']))
  125. assert False
  126. try:
  127. topology.standalone.add_s(Entry((USER2_DN, {
  128. 'objectclass': "top person inetuser".split(),
  129. 'sn': "2",
  130. 'cn': "user 2"})))
  131. log.info('Added test user %s' % USER2_DN)
  132. except ldap.LDAPError, e:
  133. log.error('Failed to add user1: ' + e.message['desc'])
  134. assert False
  135. #
  136. # Add an aci
  137. #
  138. try:
  139. acival = '(targetattr ="cn")(version 3.0;acl "Test bind dn tracking"' + \
  140. ';allow (all) (userdn = "ldap:///%s");)' % USER1_DN
  141. topology.standalone.modify_s(DEFAULT_SUFFIX, [(ldap.MOD_ADD, 'aci', acival)])
  142. log.info('Added aci')
  143. except ldap.LDAPError, e:
  144. log.error('Failed to add aci: ' + e.message['desc'])
  145. assert False
  146. #
  147. # Make modification as user
  148. #
  149. try:
  150. topology.standalone.simple_bind_s(USER1_DN, "password")
  151. log.info('Bind as user %s successful' % USER1_DN)
  152. except ldap.LDAPError, e:
  153. log.error('Failed to bind as user1: ' + e.message['desc'])
  154. assert False
  155. try:
  156. topology.standalone.modify_s(USER2_DN, [(ldap.MOD_REPLACE, 'cn', 'new value')])
  157. log.info('%s successfully modified user %s' % (USER1_DN, USER2_DN))
  158. except ldap.LDAPError, e:
  159. log.error('Failed to update user2: ' + e.message['desc'])
  160. assert False
  161. #
  162. # Setup replica and create a repl agmt
  163. #
  164. try:
  165. topology.standalone.simple_bind_s(DN_DM, PASSWORD)
  166. log.info('Bind as %s successful' % DN_DM)
  167. except ldap.LDAPError, e:
  168. log.error('Failed to bind as rootDN: ' + e.message['desc'])
  169. assert False
  170. try:
  171. topology.standalone.replica.enableReplication(suffix=DEFAULT_SUFFIX, role=REPLICAROLE_MASTER,
  172. replicaId=REPLICAID_MASTER)
  173. log.info('Successfully enabled replication.')
  174. except ValueError:
  175. log.error('Failed to enable replication')
  176. assert False
  177. properties = {RA_NAME: r'test plugin internal bind dn',
  178. RA_BINDDN: defaultProperties[REPLICATION_BIND_DN],
  179. RA_BINDPW: defaultProperties[REPLICATION_BIND_PW],
  180. RA_METHOD: defaultProperties[REPLICATION_BIND_METHOD],
  181. RA_TRANSPORT_PROT: defaultProperties[REPLICATION_TRANSPORT]}
  182. try:
  183. repl_agreement = topology.standalone.agreement.create(suffix=DEFAULT_SUFFIX, host="127.0.0.1",
  184. port="7777", properties=properties)
  185. log.info('Successfully created replication agreement')
  186. except InvalidArgumentError, e:
  187. log.error('Failed to create replication agreement: ' + e.message['desc'])
  188. assert False
  189. #
  190. # modify replica
  191. #
  192. try:
  193. properties = {REPLICA_ID: "7"}
  194. topology.standalone.replica.setProperties(DEFAULT_SUFFIX, None, None, properties)
  195. log.info('Successfully modified replica')
  196. except ldap.LDAPError, e:
  197. log.error('Failed to update replica config: ' + e.message['desc'])
  198. assert False
  199. #
  200. # modify repl agmt
  201. #
  202. try:
  203. properties = {RA_CONSUMER_PORT: "8888"}
  204. topology.standalone.agreement.setProperties(None, repl_agreement, None, properties)
  205. log.info('Successfully modified replication agreement')
  206. except ValueError:
  207. log.error('Failed to update replica agreement: ' + repl_agreement)
  208. assert False
  209. # We passed
  210. log.info("Test Passed.")
  211. def test_ticket47953_final(topology):
  212. topology.standalone.stop(timeout=10)
  213. def run_isolated():
  214. '''
  215. run_isolated is used to run these test cases independently of a test scheduler (xunit, py.test..)
  216. To run isolated without py.test, you need to
  217. - edit this file and comment '@pytest.fixture' line before 'topology' function.
  218. - set the installation prefix
  219. - run this program
  220. '''
  221. global installation_prefix
  222. installation_prefix = None
  223. topo = topology(True)
  224. test_ticket47950(topo)
  225. if __name__ == '__main__':
  226. run_isolated()