ticket48366_test.py 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. # --- BEGIN COPYRIGHT BLOCK ---
  2. # Copyright (C) 2015 Red Hat, Inc.
  3. # All rights reserved.
  4. #
  5. # License: GPL (version 3 or any later version).
  6. # See LICENSE for details.
  7. # --- END COPYRIGHT BLOCK ---
  8. #
  9. import os
  10. import sys
  11. import time
  12. import ldap
  13. import logging
  14. import pytest
  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 ldap.controls.simple import ProxyAuthzControl
  20. log = logging.getLogger(__name__)
  21. installation_prefix = None
  22. PROXY_USER_DN = 'cn=proxy,ou=people,%s' % SUFFIX
  23. TEST_USER_DN = 'cn=test,ou=people,%s' % SUFFIX
  24. USER_PW = 'password'
  25. # subtrees used in test
  26. SUBTREE_GREEN = "ou=green,%s" % SUFFIX
  27. SUBTREE_RED = "ou=red,%s" % SUFFIX
  28. SUBTREES = (SUBTREE_GREEN, SUBTREE_RED)
  29. class TopologyStandalone(object):
  30. def __init__(self, standalone):
  31. standalone.open()
  32. self.standalone = standalone
  33. @pytest.fixture(scope="module")
  34. def topology(request):
  35. global installation_prefix
  36. if installation_prefix:
  37. args_instance[SER_DEPLOYED_DIR] = installation_prefix
  38. standalone = DirSrv(verbose=False)
  39. # Args for the standalone instance
  40. args_instance[SER_HOST] = HOST_STANDALONE
  41. args_instance[SER_PORT] = PORT_STANDALONE
  42. args_instance[SER_SERVERID_PROP] = SERVERID_STANDALONE
  43. args_standalone = args_instance.copy()
  44. standalone.allocate(args_standalone)
  45. # Get the status of the instance and restart it if it exists
  46. instance_standalone = standalone.exists()
  47. # Remove the instance
  48. if instance_standalone:
  49. standalone.delete()
  50. # Create the instance
  51. standalone.create()
  52. # Used to retrieve configuration information (dbdir, confdir...)
  53. standalone.open()
  54. # clear the tmp directory
  55. standalone.clearTmpDir(__file__)
  56. # Here we have standalone instance up and running
  57. return TopologyStandalone(standalone)
  58. def test_ticket48366_init(topology):
  59. """
  60. It creates identical entries in 3 subtrees
  61. It creates aci which allow access to a set of attrs
  62. in two of these subtrees for bound users
  63. It creates a user to be used for test
  64. """
  65. topology.standalone.log.info("Add subtree: %s" % SUBTREE_GREEN)
  66. topology.standalone.add_s(Entry((SUBTREE_GREEN, {
  67. 'objectclass': "top organizationalunit".split(),
  68. 'ou': "green_one"})))
  69. topology.standalone.log.info("Add subtree: %s" % SUBTREE_RED)
  70. topology.standalone.add_s(Entry((SUBTREE_RED, {
  71. 'objectclass': "top organizationalunit".split(),
  72. 'ou': "red"})))
  73. # add proxy user and test user
  74. topology.standalone.log.info("Add %s" % TEST_USER_DN)
  75. topology.standalone.add_s(Entry((TEST_USER_DN, {
  76. 'objectclass': "top person".split(),
  77. 'sn': 'test',
  78. 'cn': 'test',
  79. 'userpassword': USER_PW})))
  80. topology.standalone.log.info("Add %s" % PROXY_USER_DN)
  81. topology.standalone.add_s(Entry((PROXY_USER_DN, {
  82. 'objectclass': "top person".split(),
  83. 'sn': 'proxy',
  84. 'cn': 'proxy',
  85. 'userpassword': USER_PW})))
  86. # enable acl error logging
  87. # mod = [(ldap.MOD_REPLACE, 'nsslapd-errorlog-level', '128')]
  88. # topology.standalone.modify_s(DN_CONFIG, mod)
  89. # get rid of default ACIs
  90. mod = [(ldap.MOD_DELETE, 'aci', None)]
  91. topology.standalone.modify_s(SUFFIX, mod)
  92. # Ok Now add the proper ACIs
  93. ACI_TARGET = "(target = \"ldap:///%s\")" % SUBTREE_GREEN
  94. ACI_TARGETATTR = "(targetattr = \"objectclass || cn || sn || uid || givenname \")"
  95. ACI_ALLOW = "(version 3.0; acl \"Allow search-read to green subtree\"; allow (read, search, compare)"
  96. ACI_SUBJECT = " userdn = \"ldap:///%s\";)" % TEST_USER_DN
  97. ACI_BODY = ACI_TARGET + ACI_TARGETATTR + ACI_ALLOW + ACI_SUBJECT
  98. mod = [(ldap.MOD_ADD, 'aci', ACI_BODY)]
  99. topology.standalone.modify_s(SUFFIX, mod)
  100. ACI_ALLOW = "(version 3.0; acl \"Allow use pf proxy auth to green subtree\"; allow (proxy)"
  101. ACI_SUBJECT = " userdn = \"ldap:///%s\";)" % PROXY_USER_DN
  102. ACI_BODY = ACI_TARGET + ACI_TARGETATTR + ACI_ALLOW + ACI_SUBJECT
  103. mod = [(ldap.MOD_ADD, 'aci', ACI_BODY)]
  104. topology.standalone.modify_s(SUFFIX, mod)
  105. log.info("Adding %d test entries...")
  106. for id in range(2):
  107. name = "%s%d" % ('test', id)
  108. mail = "%[email protected]" % name
  109. for subtree in SUBTREES:
  110. topology.standalone.add_s(Entry(("cn=%s,%s" % (name, subtree), {
  111. 'objectclass': "top person organizationalPerson inetOrgPerson".split(),
  112. 'sn': name,
  113. 'cn': name,
  114. 'uid': name,
  115. 'givenname': 'test',
  116. 'mail': mail,
  117. 'description': 'description',
  118. 'employeenumber': "%d" % id,
  119. 'telephonenumber': "%d%d%d" % (id,id,id),
  120. 'mobile': "%d%d%d" % (id,id,id),
  121. 'l': 'MV',
  122. 'title': 'Engineer'})))
  123. def test_ticket48366_search_user(topology):
  124. proxy_ctrl = ProxyAuthzControl(criticality=True, authzId="dn: "+TEST_USER_DN)
  125. # searching as test user should return one entry from the green subtree
  126. topology.standalone.simple_bind_s(TEST_USER_DN, PASSWORD)
  127. ents = topology.standalone.search_s(SUFFIX, ldap.SCOPE_SUBTREE, 'uid=test1')
  128. assert (len(ents) == 1)
  129. # searching as proxy user should return no entry
  130. topology.standalone.simple_bind_s(PROXY_USER_DN, PASSWORD)
  131. ents = topology.standalone.search_s(SUFFIX, ldap.SCOPE_SUBTREE, 'uid=test1')
  132. assert (len(ents) == 0)
  133. # serching as proxy user, authorizing as test user should return 1 entry
  134. ents = topology.standalone.search_ext_s(SUFFIX, ldap.SCOPE_SUBTREE, 'uid=test1', serverctrls=[proxy_ctrl])
  135. assert (len(ents) == 1)
  136. def test_ticket48366_search_dm(topology):
  137. # searching as directory manager should return one entries from both subtrees
  138. topology.standalone.simple_bind_s(DN_DM, PASSWORD)
  139. ents = topology.standalone.search_s(SUFFIX, ldap.SCOPE_SUBTREE, 'uid=test1')
  140. assert (len(ents) == 2)
  141. # searching as directory manager proxying test user should return one entry
  142. proxy_ctrl = ProxyAuthzControl(criticality=True, authzId="dn: "+TEST_USER_DN)
  143. ents = topology.standalone.search_ext_s(SUFFIX, ldap.SCOPE_SUBTREE, 'uid=test1', serverctrls=[proxy_ctrl])
  144. assert (len(ents) == 1)
  145. # searching as directory manager proxying proxy user should return no entry
  146. proxy_ctrl = ProxyAuthzControl(criticality=True, authzId="dn: "+PROXY_USER_DN)
  147. ents = topology.standalone.search_ext_s(SUFFIX, ldap.SCOPE_SUBTREE, 'uid=test1', serverctrls=[proxy_ctrl])
  148. assert (len(ents) == 0)
  149. def test_ticket48366_final(topology):
  150. topology.standalone.delete()
  151. log.info('Testcase PASSED')
  152. def run_isolated():
  153. '''
  154. run_isolated is used to run these test cases independently of a test scheduler (xunit, py.test..)
  155. To run isolated without py.test, you need to
  156. - edit this file and comment '@pytest.fixture' line before 'topology' function.
  157. - set the installation prefix
  158. - run this program
  159. '''
  160. global installation_prefix
  161. installation_prefix = None
  162. topo = topology(True)
  163. test_ticket48366_init(topo)
  164. test_ticket48366_search_dm(topo)
  165. test_ticket48366_final(topo)
  166. if __name__ == '__main__':
  167. run_isolated()