valueacl_part2_test.py 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443
  1. # --- BEGIN COPYRIGHT BLOCK ---
  2. # Copyright (C) 2019 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. import pytest, os, ldap
  9. from lib389._constants import DEFAULT_SUFFIX, PW_DM
  10. from lib389.idm.user import UserAccount
  11. from lib389.idm.account import Anonymous
  12. from lib389.idm.organizationalunit import OrganizationalUnit
  13. from lib389.topologies import topology_st as topo
  14. from lib389.idm.domain import Domain
  15. pytestmark = pytest.mark.tier1
  16. CONTAINER_1_DELADD = "ou=Product Development,{}".format(DEFAULT_SUFFIX)
  17. CONTAINER_2_DELADD = "ou=Accounting,{}".format(DEFAULT_SUFFIX)
  18. USER_DELADD = "cn=Jeff Vedder,{}".format(CONTAINER_1_DELADD)
  19. USER_WITH_ACI_DELADD = "cn=Sam Carter,{}".format(CONTAINER_2_DELADD)
  20. FRED = "cn=FRED,ou=Accounting,{}".format(DEFAULT_SUFFIX)
  21. HARRY = "cn=HARRY,ou=Accounting,{}".format(DEFAULT_SUFFIX)
  22. KIRSTENVAUGHAN = "cn=Kirsten Vaughan,ou=Human Resources,{}".format(DEFAULT_SUFFIX)
  23. HUMAN_OU_GLOBAL = "ou=Human Resources,{}".format(DEFAULT_SUFFIX)
  24. @pytest.fixture(scope="function")
  25. def aci_of_user(request, topo):
  26. # Add anonymous access aci
  27. ACI_TARGET = "(targetattr != \"userpassword\")(target = \"ldap:///%s\")" % (DEFAULT_SUFFIX)
  28. ACI_ALLOW = "(version 3.0; acl \"Anonymous Read access\"; allow (read,search,compare)"
  29. ACI_SUBJECT = "(userdn=\"ldap:///anyone\");)"
  30. ANON_ACI = ACI_TARGET + ACI_ALLOW + ACI_SUBJECT
  31. suffix = Domain(topo.standalone, DEFAULT_SUFFIX)
  32. try:
  33. suffix.add('aci', ANON_ACI)
  34. except ldap.TYPE_OR_VALUE_EXISTS:
  35. pass
  36. aci_list = Domain(topo.standalone, DEFAULT_SUFFIX).get_attr_vals('aci')
  37. def finofaci():
  38. domain = Domain(topo.standalone, DEFAULT_SUFFIX)
  39. domain.set('aci', None)
  40. for i in aci_list:
  41. domain.add("aci", i)
  42. request.addfinalizer(finofaci)
  43. @pytest.fixture(scope="function")
  44. def _add_user(request, topo):
  45. for i in ["Product Development", 'Accounting', "Human Resources"]:
  46. ou = OrganizationalUnit(topo.standalone, "ou={},{}".format(i, DEFAULT_SUFFIX))
  47. ou.create(properties={'ou': i})
  48. properties = {
  49. 'uid': 'Jeff Vedder',
  50. 'cn': 'Jeff Vedder',
  51. 'sn': 'user',
  52. 'uidNumber': '1000',
  53. 'gidNumber': '2000',
  54. 'homeDirectory': '/home/' + 'JeffVedder',
  55. 'userPassword': 'password'
  56. }
  57. user = UserAccount(topo.standalone, 'cn=Jeff Vedder,{}'.format(CONTAINER_1_DELADD))
  58. user.create(properties=properties)
  59. user.set('secretary', 'cn=Arpitoo Borah, o=Red Hat, c=As')
  60. user.set('mail', '[email protected]')
  61. properties = {
  62. 'uid': 'Sam Carter',
  63. 'cn': 'Sam Carter',
  64. 'sn': 'user',
  65. 'uidNumber': '1000',
  66. 'gidNumber': '2000',
  67. 'homeDirectory': '/home/' + 'SamCarter',
  68. 'userPassword': 'password'
  69. }
  70. user = UserAccount(topo.standalone, 'cn=Sam Carter,{}'.format(CONTAINER_2_DELADD))
  71. user.create(properties=properties)
  72. properties = {
  73. 'uid': 'Kirsten Vaughan',
  74. 'cn': 'Kirsten Vaughan',
  75. 'sn': 'Kirsten Vaughan',
  76. 'uidNumber': '1000',
  77. 'gidNumber': '2000',
  78. 'homeDirectory': '/home/' + 'KirstenVaughan',
  79. 'userPassword': 'password'
  80. }
  81. user = UserAccount(topo.standalone, 'cn=Kirsten Vaughan, ou=Human Resources,{}'.format(DEFAULT_SUFFIX))
  82. user.create(properties=properties)
  83. properties = {
  84. 'uid': 'HARRY',
  85. 'cn': 'HARRY',
  86. 'sn': 'HARRY',
  87. 'uidNumber': '1000',
  88. 'gidNumber': '2000',
  89. 'homeDirectory': '/home/' + 'HARRY',
  90. 'userPassword': 'password'
  91. }
  92. user = UserAccount(topo.standalone, 'cn=HARRY, ou=Accounting,{}'.format(DEFAULT_SUFFIX))
  93. user.create(properties=properties)
  94. def fin():
  95. for DN in [USER_DELADD, USER_WITH_ACI_DELADD, FRED, HARRY, KIRSTENVAUGHAN,
  96. HUMAN_OU_GLOBAL, CONTAINER_2_DELADD,CONTAINER_1_DELADD]:
  97. ua = UserAccount(topo.standalone, DN)
  98. try:
  99. ua.delete()
  100. except:
  101. pass
  102. request.addfinalizer(fin)
  103. def test_we_can_search_as_expected(topo, _add_user, aci_of_user, request):
  104. """Testing the targattrfilters keyword that allows access control based on the value of the attributes being added (or deleted))
  105. Test that we can search as expected
  106. :id: e845dbba-7aa9-11e8-8988-8c16451d917b
  107. :setup: server
  108. :steps:
  109. 1. Add test entry
  110. 2. Add ACI
  111. 3. User should follow ACI role
  112. :expectedresults:
  113. 1. Entry should be added
  114. 2. Operation should succeed
  115. 3. Operation should succeed
  116. """
  117. ACI_BODY = '(target="ldap:///cn=*,ou=Product Development, {}")' \
  118. '(targetfilter="cn=Jeff*")(targetattr="secretary || objectclass || mail")' \
  119. '(targattrfilters = "add=title:(title=arch*)")(version 3.0; acl "{}"; ' \
  120. 'allow (write,read,search,compare) (userdn = "ldap:///anyone") ;)'.format(DEFAULT_SUFFIX, request.node.name)
  121. Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", ACI_BODY)
  122. conn = Anonymous(topo.standalone).bind()
  123. # aci will allow secretary , mail , objectclass
  124. user = UserAccount(conn, USER_DELADD)
  125. assert user.get_attr_vals('secretary')
  126. assert user.get_attr_vals('mail')
  127. assert user.get_attr_vals('objectclass')
  128. def test_we_can_mod_title_as_expected(topo, _add_user, aci_of_user, request):
  129. """Testing the targattrfilters keyword that allows access control based on the
  130. value of the attributes being added (or deleted))
  131. Test search will work with targattrfilters present.
  132. :id: f8c1ea88-7aa9-11e8-a55c-8c16451d917b
  133. :setup: server
  134. :steps:
  135. 1. Add test entry
  136. 2. Add ACI
  137. 3. User should follow ACI role
  138. :expectedresults:
  139. 1. Entry should be added
  140. 2. Operation should succeed
  141. 3. Operation should succeed
  142. """
  143. ACI_BODY = '(target="ldap:///cn=*,ou=Product Development, {}")' \
  144. '(targetfilter="cn=Jeff*")(targetattr="secretary || objectclass || mail")' \
  145. '(targattrfilters = "add=title:(title=arch*)")(version 3.0; acl "{}"; ' \
  146. 'allow (write,read,search,compare) (userdn = "ldap:///anyone") ;)'.format(DEFAULT_SUFFIX, request.node.name)
  147. Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", ACI_BODY)
  148. # aci will not allow 'title', 'topdog'
  149. conn = UserAccount(topo.standalone, USER_WITH_ACI_DELADD).bind(PW_DM)
  150. user = UserAccount(conn, USER_DELADD)
  151. with pytest.raises(ldap.INSUFFICIENT_ACCESS):
  152. user.add('title', 'topdog')
  153. def test_modify_with_multiple_filters(topo, _add_user, aci_of_user, request):
  154. """Testing the targattrfilters keyword that allows access control based on the
  155. value of the attributes being added (or deleted))
  156. Allowed by multiple filters
  157. :id: fd9d223e-7aa9-11e8-a83b-8c16451d917b
  158. :setup: server
  159. :steps:
  160. 1. Add test entry
  161. 2. Add ACI
  162. 3. User should follow ACI role
  163. :expectedresults:
  164. 1. Entry should be added
  165. 2. Operation should succeed
  166. 3. Operation should succeed
  167. """
  168. ACI_BODY = '(targattrfilters = "add=title:(title=architect) && secretary:' \
  169. '(secretary=cn=Meylan,{}), del=title:(title=architect) && secretary:' \
  170. '(secretary=cn=Meylan,{})")(version 3.0; acl "{}"; allow (write) ' \
  171. '(userdn = "ldap:///anyone") ;)'.format(
  172. DEFAULT_SUFFIX, DEFAULT_SUFFIX, request.node.name
  173. )
  174. Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", ACI_BODY)
  175. conn = UserAccount(topo.standalone, USER_WITH_ACI_DELADD).bind(PW_DM)
  176. # aci will allow title some attribute only
  177. user = UserAccount(conn, USER_DELADD)
  178. user.add("title", "architect")
  179. assert user.get_attr_val('title')
  180. user.add("secretary", "cn=Meylan,dc=example,dc=com")
  181. assert user.get_attr_val('secretary')
  182. def test_denied_by_multiple_filters(topo, _add_user, aci_of_user, request):
  183. """Testing the targattrfilters keyword that allows access control based on the value of the
  184. attributes being added (or deleted))
  185. Denied by multiple filters
  186. :id: 034c6c62-7aaa-11e8-8634-8c16451d917b
  187. :setup: server
  188. :steps:
  189. 1. Add test entry
  190. 2. Add ACI
  191. 3. User should follow ACI role
  192. :expectedresults:
  193. 1. Entry should be added
  194. 2. Operation should succeed
  195. 3. Operation should succeed
  196. """
  197. ACI_BODY = '(targattrfilters = "add=title:(title=architect) && secretary:' \
  198. '(secretary=cn=Meylan,{}), del=title:(title=architect) && secretary:' \
  199. '(secretary=cn=Meylan,{})")(version 3.0; acl "{}"; allow (write) ' \
  200. '(userdn = "ldap:///anyone") ;)'.format(DEFAULT_SUFFIX, DEFAULT_SUFFIX, request.node.name)
  201. Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", ACI_BODY)
  202. conn = UserAccount(topo.standalone, USER_WITH_ACI_DELADD).bind(PW_DM)
  203. # aci will allow title some attribute only
  204. user = UserAccount(conn, USER_DELADD)
  205. user.add("title", "architect")
  206. assert user.get_attr_val('title')
  207. user.add("secretary", "cn=Meylan,dc=example,dc=com")
  208. assert user.get_attr_val('secretary')
  209. # aci will allow title some attribute only
  210. with pytest.raises(ldap.INSUFFICIENT_ACCESS):
  211. user.add("secretary", "cn=Grenoble,dc=example,dc=com")
  212. def test_allowed_add_one_attribute(topo, _add_user, aci_of_user, request):
  213. """Testing the targattrfilters keyword that allows access control based on the value of the
  214. attributes being added (or deleted))
  215. Allowed add one attribute (in presence of multiple filters)
  216. :id: 086c7f0c-7aaa-11e8-b69f-8c16451d917b
  217. :setup: server
  218. :steps:
  219. 1. Add test entry
  220. 2. Add ACI
  221. 3. User should follow ACI role
  222. :expectedresults:
  223. 1. Entry should be added
  224. 2. Operation should succeed
  225. 3. Operation should succeed
  226. """
  227. ACI_BODY = '(targattrfilters = "add=title:(title=architect) && secretary:(secretary=cn=Meylan, {}), ' \
  228. 'del=title:(title=architect) && secretary:(secretary=cn=Meylan, {})")(version 3.0; acl "{}"; ' \
  229. 'allow (write) (userdn = "ldap:///{}") ;)'.format(
  230. DEFAULT_SUFFIX, DEFAULT_SUFFIX, request.node.name, USER_WITH_ACI_DELADD)
  231. Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", ACI_BODY)
  232. conn = UserAccount(topo.standalone, USER_WITH_ACI_DELADD).bind(PW_DM)
  233. user = UserAccount(conn, USER_DELADD)
  234. # aci will allow add ad delete
  235. user.add('title', 'architect')
  236. assert user.get_attr_val('title')
  237. user.remove('title', 'architect')
  238. def test_cannot_add_an_entry_with_attribute_values_we_are_not_allowed_add(
  239. topo, _add_user, aci_of_user, request
  240. ):
  241. """Testing the targattrfilters keyword that allows access control based on the value of the
  242. attributes being added (or deleted))
  243. Test not allowed add an entry
  244. :id: 0d0effee-7aaa-11e8-b673-8c16451d917b
  245. :setup: server
  246. :steps:
  247. 1. Add test entry
  248. 2. Add ACI
  249. 3. User should follow ACI role
  250. :expectedresults:
  251. 1. Entry should be added
  252. 2. Operation should succeed
  253. 3. Operation should succeed
  254. """
  255. ACI_BODY = '(targattrfilters = "add=title:(|(title=engineer)(title=cool dude)(title=scum)) ' \
  256. '&& secretary:(secretary=cn=Meylan, {}), del=title:(|(title=engineer)(title=cool dude)' \
  257. '(title=scum))")(version 3.0; aci "{}"; allow (add) userdn = "ldap:///{}";)'.format(
  258. DEFAULT_SUFFIX, request.node.name, DEFAULT_SUFFIX)
  259. Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", ACI_BODY)
  260. properties = {
  261. 'uid': 'FRED',
  262. 'cn': 'FRED',
  263. 'sn': 'user',
  264. 'uidNumber': '1000',
  265. 'gidNumber': '2000',
  266. 'homeDirectory': '/home/' + 'FRED'
  267. }
  268. user = UserAccount(topo.standalone, 'cn=FRED,ou=Accounting,{}'.format(DEFAULT_SUFFIX))
  269. user.create(properties=properties)
  270. user.set('title', ['anuj', 'kumar', 'borah'])
  271. conn = UserAccount(topo.standalone, USER_WITH_ACI_DELADD).bind(PW_DM)
  272. # aci will not allow adding objectclass
  273. user = UserAccount(conn, USER_WITH_ACI_DELADD)
  274. with pytest.raises(ldap.INSUFFICIENT_ACCESS):
  275. user.add("objectclass", "person")
  276. def test_on_modrdn(topo, _add_user, aci_of_user, request):
  277. """Testing the targattrfilters keyword that allows access control based on the value of the
  278. attributes being added (or deleted))
  279. Test that valuacls kick in for modrdn operation.
  280. :id: 12985dde-7aaa-11e8-abde-8c16451d917b
  281. :setup: server
  282. :steps:
  283. 1. Add test entry
  284. 2. Add ACI
  285. 3. User should follow ACI role
  286. :expectedresults:
  287. 1. Entry should be added
  288. 2. Operation should succeed
  289. 3. Operation should succeed
  290. """
  291. ACI_BODY = '(target="ldap:///cn=*,ou=Accounting,{}")(targattrfilters = "add=cn:(|(cn=engineer)), ' \
  292. 'del=title:(|(title=engineer)(title=cool dude)(title=scum))")(version 3.0; aci "{}"; ' \
  293. 'allow (write) userdn = "ldap:///{}";)'.format(DEFAULT_SUFFIX, request.node.name, USER_WITH_ACI_DELADD)
  294. Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", ACI_BODY)
  295. conn = UserAccount(topo.standalone, USER_WITH_ACI_DELADD).bind(PW_DM)
  296. # modrdn_s is not allowed with ou=OU1
  297. useraccount = UserAccount(conn, FRED)
  298. with pytest.raises(ldap.INSUFFICIENT_ACCESS):
  299. useraccount.rename("ou=OU1")
  300. def test_on_modrdn_allow(topo, _add_user, aci_of_user, request):
  301. """Testing the targattrfilters keyword that allows access control based on the value of the attributes being
  302. added (or deleted))
  303. Test modrdn still works (2)
  304. :id: 17720562-7aaa-11e8-82ee-8c16451d917b
  305. :setup: server
  306. :steps:
  307. 1. Add test entry
  308. 2. Add ACI
  309. 3. User should follow ACI role
  310. :expectedresults:
  311. 1. Entry should be added
  312. 2. Operation should succeed
  313. 3. Operation should succeed
  314. """
  315. ACI_BODY = '(target="ldap:///{}")(targattrfilters = "add=cn:((cn=engineer)), del=cn:((cn=jonny))")' \
  316. '(version 3.0; aci "{}"; allow (write) ' \
  317. 'userdn = "ldap:///{}";)'.format(DEFAULT_SUFFIX, request.node.name, USER_WITH_ACI_DELADD)
  318. Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", ACI_BODY)
  319. properties = {
  320. 'uid': 'jonny',
  321. 'cn': 'jonny',
  322. 'sn': 'user',
  323. 'uidNumber': '1000',
  324. 'gidNumber': '2000',
  325. 'homeDirectory': '/home/' + 'jonny'
  326. }
  327. user = UserAccount(topo.standalone, 'cn=jonny,{}'.format(DEFAULT_SUFFIX))
  328. user.create(properties=properties)
  329. conn = UserAccount(topo.standalone, USER_WITH_ACI_DELADD).bind(PW_DM)
  330. # aci will allow modrdn_s on cn=engineer
  331. useraccount = UserAccount(conn, "cn=jonny,{}".format(DEFAULT_SUFFIX))
  332. useraccount.rename("cn=engineer")
  333. assert useraccount.dn == 'cn=engineer,dc=example,dc=com'
  334. @pytest.mark.bz979515
  335. def test_targattrfilters_keyword(topo):
  336. """Testing the targattrfilters keyword that allows access control based on the value
  337. of the attributes being added (or deleted))
  338. "Bug #979515 - ACLs inoperative in some search scenarios [rhel-6.5]"
  339. "Bug #979516 is a clone for DS8.2 on RHEL5.9"
  340. "Bug #979514 is a clone for RHEL6.4 zStream errata"
  341. :id: 23f9e9d0-7aaa-11e8-b16b-8c16451d917b
  342. :setup: server
  343. :steps:
  344. 1. Add test entry
  345. 2. Add ACI
  346. 3. User should follow ACI role
  347. :expectedresults:
  348. 1. Entry should be added
  349. 2. Operation should succeed
  350. 3. Operation should succeed
  351. """
  352. domain = Domain(topo.standalone, DEFAULT_SUFFIX)
  353. domain.set('aci', None)
  354. ou = OrganizationalUnit(topo.standalone, 'ou=bug979515,{}'.format(DEFAULT_SUFFIX))
  355. ou.create(properties={'ou': 'bug979515'})
  356. Domain(topo.standalone, DEFAULT_SUFFIX).add("aci", '(target="ldap:///ou=bug979515,{}") '
  357. '(targetattr= "uid") ( version 3.0; acl "read other subscriber"; allow (compare, read, search) '
  358. 'userdn="ldap:///uid=*,ou=bug979515,{}" ; )'.format(DEFAULT_SUFFIX, DEFAULT_SUFFIX))
  359. properties = {
  360. 'uid': 'acientryusr1',
  361. 'cn': 'acientryusr1',
  362. 'sn': 'user',
  363. 'uidNumber': '1000',
  364. 'gidNumber': '2000',
  365. 'homeDirectory': '/home/' + 'acientryusr1'
  366. }
  367. user = UserAccount(topo.standalone, 'cn=acientryusr1,ou=bug979515,{}'.format(DEFAULT_SUFFIX))
  368. user.create(properties=properties)
  369. user.set('telephoneNumber', '99972566596')
  370. user.set('mail', '[email protected]')
  371. user.set("userPassword", "password")
  372. properties = {
  373. 'uid': 'newaciphoneusr1',
  374. 'cn': 'newaciphoneusr1',
  375. 'sn': 'user',
  376. 'uidNumber': '1000',
  377. 'gidNumber': '2000',
  378. 'homeDirectory': '/home/' + 'newaciphoneusr1'
  379. }
  380. user = UserAccount(topo.standalone, 'cn=newaciphoneusr1,ou=bug979515,{}'.format(DEFAULT_SUFFIX))
  381. user.create(properties=properties)
  382. user.set('telephoneNumber', '99972566596')
  383. user.set('mail', '[email protected]')
  384. conn = UserAccount(topo.standalone, "cn=acientryusr1,ou=bug979515,{}".format(DEFAULT_SUFFIX)).bind(PW_DM)
  385. # Testing the targattrfilters keyword that allows access control based on the value of the attributes being added (or deleted))
  386. user = UserAccount(conn, "cn=acientryusr1,ou=bug979515,{}".format(DEFAULT_SUFFIX))
  387. with pytest.raises(IndexError):
  388. user.get_attr_vals('mail')
  389. user.get_attr_vals('telephoneNumber')
  390. user.get_attr_vals('cn')
  391. user = UserAccount(topo.standalone, "cn=acientryusr1,ou=bug979515,{}".format(DEFAULT_SUFFIX))
  392. user.get_attr_vals('mail')
  393. user.get_attr_vals('telephoneNumber')
  394. user.get_attr_vals('cn')
  395. if __name__ == '__main__':
  396. CURRENT_FILE = os.path.realpath(__file__)
  397. pytest.main("-s -v %s" % CURRENT_FILE)