ticket47980_test.py 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662
  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 ldap.sasl
  14. import logging
  15. import pytest
  16. from lib389 import DirSrv, Entry, tools, tasks
  17. from lib389.tools import DirSrvTools
  18. from lib389._constants import *
  19. from lib389.properties import *
  20. from lib389.tasks import *
  21. log = logging.getLogger(__name__)
  22. installation_prefix = None
  23. BRANCH1 = 'ou=level1,' + DEFAULT_SUFFIX
  24. BRANCH2 = 'ou=level2,ou=level1,' + DEFAULT_SUFFIX
  25. BRANCH3 = 'ou=level3,ou=level2,ou=level1,' + DEFAULT_SUFFIX
  26. BRANCH4 = 'ou=people,' + DEFAULT_SUFFIX
  27. BRANCH5 = 'ou=lower,ou=people,' + DEFAULT_SUFFIX
  28. BRANCH6 = 'ou=lower,ou=lower,ou=people,' + DEFAULT_SUFFIX
  29. USER1_DN = 'uid=user1,%s' % (BRANCH1)
  30. USER2_DN = 'uid=user2,%s' % (BRANCH2)
  31. USER3_DN = 'uid=user3,%s' % (BRANCH3)
  32. USER4_DN = 'uid=user4,%s' % (BRANCH4)
  33. USER5_DN = 'uid=user5,%s' % (BRANCH5)
  34. USER6_DN = 'uid=user6,%s' % (BRANCH6)
  35. BRANCH1_CONTAINER = 'cn=nsPwPolicyContainer,ou=level1,dc=example,dc=com'
  36. BRANCH1_PWP = 'cn=cn\3DnsPwPolicyEntry\2Cou\3Dlevel1\2Cdc\3Dexample\2Cdc\3Dcom,' + \
  37. 'cn=nsPwPolicyContainer,ou=level1,dc=example,dc=com'
  38. BRANCH1_COS_TMPL = 'cn=cn\3DnsPwTemplateEntry\2Cou\3Dlevel1\2Cdc\3Dexample\2Cdc\3Dcom,' + \
  39. 'cn=nsPwPolicyContainer,ou=level1,dc=example,dc=com'
  40. BRANCH1_COS_DEF = 'cn=nsPwPolicy_CoS,ou=level1,dc=example,dc=com'
  41. BRANCH2_CONTAINER = 'cn=nsPwPolicyContainer,ou=level2,ou=level1,dc=example,dc=com'
  42. BRANCH2_PWP = 'cn=cn\3DnsPwPolicyEntry\2Cou\3Dlevel2\2Cou\3Dlevel1\2Cdc\3Dexample\2Cdc\3Dcom,' + \
  43. 'cn=nsPwPolicyContainer,ou=level2,ou=level1,dc=example,dc=com'
  44. BRANCH2_COS_TMPL = 'cn=cn\3DnsPwTemplateEntry\2Cou\3Dlevel2\2Cou\3Dlevel1\2Cdc\3Dexample\2Cdc\3Dcom,' + \
  45. 'cn=nsPwPolicyContainer,ou=level2,ou=level1,dc=example,dc=com'
  46. BRANCH2_COS_DEF = 'cn=nsPwPolicy_CoS,ou=level2,ou=level1,dc=example,dc=com'
  47. BRANCH3_CONTAINER = 'cn=nsPwPolicyContainer,ou=level3,ou=level2,ou=level1,dc=example,dc=com'
  48. BRANCH3_PWP = 'cn=cn\3DnsPwPolicyEntry\2Cou\3Dlevel3\2Cou\3Dlevel2\2Cou\3Dlevel1\2Cdc\3Dexample\2Cdc\3Dcom,' + \
  49. 'cn=nsPwPolicyContainer,ou=level3,ou=level2,ou=level1,dc=example,dc=com'
  50. BRANCH3_COS_TMPL = 'cn=cn\3DnsPwTemplateEntry\2Cou\3Dlevel3\2Cou\3Dlevel2\2Cou\3Dlevel1\2Cdc\3Dexample\2Cdc\3Dcom,' + \
  51. 'cn=nsPwPolicyContainer,ou=level3,ou=level2,ou=level1,dc=example,dc=com'
  52. BRANCH3_COS_DEF = 'cn=nsPwPolicy_CoS,ou=level3,ou=level2,ou=level1,dc=example,dc=com'
  53. BRANCH4_CONTAINER = 'cn=nsPwPolicyContainer,ou=people,dc=example,dc=com'
  54. BRANCH4_PWP = 'cn=cn\3DnsPwPolicyEntry\2Cou\3DPeople\2Cdc\3Dexample\2Cdc\3Dcom,' + \
  55. 'cn=nsPwPolicyContainer,ou=People,dc=example,dc=com'
  56. BRANCH4_COS_TMPL = 'cn=cn\3DnsPwTemplateEntry\2Cou\3DPeople\2Cdc\3Dexample\2Cdc\3Dcom,' + \
  57. 'cn=nsPwPolicyContainer,ou=People,dc=example,dc=com'
  58. BRANCH4_COS_DEF = 'cn=nsPwPolicy_CoS,ou=people,dc=example,dc=com'
  59. BRANCH5_CONTAINER = 'cn=nsPwPolicyContainer,ou=lower,ou=people,dc=example,dc=com'
  60. BRANCH5_PWP = 'cn=cn\3DnsPwPolicyEntry\2Cou\3Dlower\2Cou\3DPeople\2Cdc\3Dexample\2Cdc\3Dcom,' + \
  61. 'cn=nsPwPolicyContainer,ou=lower,ou=People,dc=example,dc=com'
  62. BRANCH5_COS_TMPL = 'cn=cn\3DnsPwTemplateEntry\2Cou\3Dlower\2Cou\3DPeople\2Cdc\3Dexample\2Cdc\3Dcom,' + \
  63. 'cn=nsPwPolicyContainer,ou=lower,ou=People,dc=example,dc=com'
  64. BRANCH5_COS_DEF = 'cn=nsPwPolicy_CoS,ou=lower,ou=People,dc=example,dc=com'
  65. BRANCH6_CONTAINER = 'cn=nsPwPolicyContainer,ou=lower,ou=lower,ou=People,dc=example,dc=com'
  66. BRANCH6_PWP = 'cn=cn\3DnsPwPolicyEntry\2Cou\3Dlower\2Cou\3Dlower\2Cou\3DPeople\2Cdc\3Dexample\2Cdc\3Dcom,' + \
  67. 'cn=nsPwPolicyContainer,ou=lower,ou=lower,ou=People,dc=example,dc=com'
  68. BRANCH6_COS_TMPL = 'cn=cn\3DnsPwTemplateEntry\2Cou\3Dlower\2Cou\3Dlower\2Cou\3DPeople\2Cdc\3Dexample\2Cdc\3Dcom,' + \
  69. 'cn=nsPwPolicyContainer,ou=lower,ou=lower,ou=People,dc=example,dc=com'
  70. BRANCH6_COS_DEF = 'cn=nsPwPolicy_CoS,ou=lower,ou=lower,ou=People,dc=example,dc=com'
  71. class TopologyStandalone(object):
  72. def __init__(self, standalone):
  73. standalone.open()
  74. self.standalone = standalone
  75. @pytest.fixture(scope="module")
  76. def topology(request):
  77. '''
  78. This fixture is used to standalone topology for the 'module'.
  79. '''
  80. global installation_prefix
  81. if installation_prefix:
  82. args_instance[SER_DEPLOYED_DIR] = installation_prefix
  83. standalone = DirSrv(verbose=False)
  84. # Args for the standalone instance
  85. args_instance[SER_HOST] = HOST_STANDALONE
  86. args_instance[SER_PORT] = PORT_STANDALONE
  87. args_instance[SER_SERVERID_PROP] = SERVERID_STANDALONE
  88. args_standalone = args_instance.copy()
  89. standalone.allocate(args_standalone)
  90. # Get the status of the instance and restart it if it exists
  91. instance_standalone = standalone.exists()
  92. # Remove the instance
  93. if instance_standalone:
  94. standalone.delete()
  95. # Create the instance
  96. standalone.create()
  97. # Used to retrieve configuration information (dbdir, confdir...)
  98. standalone.open()
  99. def fin():
  100. standalone.delete()
  101. request.addfinalizer(fin)
  102. # Here we have standalone instance up and running
  103. return TopologyStandalone(standalone)
  104. def test_ticket47980(topology):
  105. """
  106. Multiple COS pointer definitions that use the same attribute are not correctly ordered.
  107. The cos plugin was incorrectly sorting the attribute indexes based on subtree, which lead
  108. to the wrong cos attribute value being applied to the entry.
  109. """
  110. log.info('Testing Ticket 47980 - Testing multiple nested COS pointer definitions are processed correctly')
  111. # Add our nested branches
  112. try:
  113. topology.standalone.add_s(Entry((BRANCH1, {
  114. 'objectclass': 'top extensibleObject'.split(),
  115. 'ou': 'level1'
  116. })))
  117. except ldap.LDAPError as e:
  118. log.error('Failed to add level1: error ' + e.message['desc'])
  119. assert False
  120. try:
  121. topology.standalone.add_s(Entry((BRANCH2, {
  122. 'objectclass': 'top extensibleObject'.split(),
  123. 'ou': 'level2'
  124. })))
  125. except ldap.LDAPError as e:
  126. log.error('Failed to add level2: error ' + e.message['desc'])
  127. assert False
  128. try:
  129. topology.standalone.add_s(Entry((BRANCH3, {
  130. 'objectclass': 'top extensibleObject'.split(),
  131. 'uid': 'level3'
  132. })))
  133. except ldap.LDAPError as e:
  134. log.error('Failed to add level3: error ' + e.message['desc'])
  135. assert False
  136. # People branch, might already exist
  137. try:
  138. topology.standalone.add_s(Entry((BRANCH4, {
  139. 'objectclass': 'top extensibleObject'.split(),
  140. 'ou': 'level4'
  141. })))
  142. except ldap.ALREADY_EXISTS:
  143. pass
  144. except ldap.LDAPError as e:
  145. log.error('Failed to add level4: error ' + e.message['desc'])
  146. assert False
  147. try:
  148. topology.standalone.add_s(Entry((BRANCH5, {
  149. 'objectclass': 'top extensibleObject'.split(),
  150. 'ou': 'level5'
  151. })))
  152. except ldap.LDAPError as e:
  153. log.error('Failed to add level5: error ' + e.message['desc'])
  154. assert False
  155. try:
  156. topology.standalone.add_s(Entry((BRANCH6, {
  157. 'objectclass': 'top extensibleObject'.split(),
  158. 'uid': 'level6'
  159. })))
  160. except ldap.LDAPError as e:
  161. log.error('Failed to add level6: error ' + e.message['desc'])
  162. assert False
  163. # Add users to each branch
  164. try:
  165. topology.standalone.add_s(Entry((USER1_DN, {
  166. 'objectclass': 'top extensibleObject'.split(),
  167. 'uid': 'user1'
  168. })))
  169. except ldap.LDAPError as e:
  170. log.error('Failed to add user1: error ' + e.message['desc'])
  171. assert False
  172. try:
  173. topology.standalone.add_s(Entry((USER2_DN, {
  174. 'objectclass': 'top extensibleObject'.split(),
  175. 'uid': 'user2'
  176. })))
  177. except ldap.LDAPError as e:
  178. log.error('Failed to add user2: error ' + e.message['desc'])
  179. assert False
  180. try:
  181. topology.standalone.add_s(Entry((USER3_DN, {
  182. 'objectclass': 'top extensibleObject'.split(),
  183. 'uid': 'user3'
  184. })))
  185. except ldap.LDAPError as e:
  186. log.error('Failed to add user3: error ' + e.message['desc'])
  187. assert False
  188. try:
  189. topology.standalone.add_s(Entry((USER4_DN, {
  190. 'objectclass': 'top extensibleObject'.split(),
  191. 'uid': 'user4'
  192. })))
  193. except ldap.LDAPError as e:
  194. log.error('Failed to add user4: error ' + e.message['desc'])
  195. assert False
  196. try:
  197. topology.standalone.add_s(Entry((USER5_DN, {
  198. 'objectclass': 'top extensibleObject'.split(),
  199. 'uid': 'user5'
  200. })))
  201. except ldap.LDAPError as e:
  202. log.error('Failed to add user5: error ' + e.message['desc'])
  203. assert False
  204. try:
  205. topology.standalone.add_s(Entry((USER6_DN, {
  206. 'objectclass': 'top extensibleObject'.split(),
  207. 'uid': 'user6'
  208. })))
  209. except ldap.LDAPError as e:
  210. log.error('Failed to add user6: error ' + e.message['desc'])
  211. assert False
  212. # Enable password policy
  213. try:
  214. topology.standalone.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE, 'nsslapd-pwpolicy-local', 'on')])
  215. except ldap.LDAPError as e:
  216. log.error('Failed to set pwpolicy-local: error ' + e.message['desc'])
  217. assert False
  218. #
  219. # Add subtree policy to branch 1
  220. #
  221. # Add the container
  222. try:
  223. topology.standalone.add_s(Entry((BRANCH1_CONTAINER, {
  224. 'objectclass': 'top nsContainer'.split(),
  225. 'cn': 'nsPwPolicyContainer'
  226. })))
  227. except ldap.LDAPError as e:
  228. log.error('Failed to add subtree container for level1: error ' + e.message['desc'])
  229. assert False
  230. # Add the password policy subentry
  231. try:
  232. topology.standalone.add_s(Entry((BRANCH1_PWP, {
  233. 'objectclass': 'top ldapsubentry passwordpolicy'.split(),
  234. 'cn': 'cn=nsPwPolicyEntry,ou=level1,dc=example,dc=com',
  235. 'passwordMustChange': 'off',
  236. 'passwordExp': 'off',
  237. 'passwordHistory': 'off',
  238. 'passwordMinAge': '0',
  239. 'passwordChange': 'off',
  240. 'passwordStorageScheme': 'ssha'
  241. })))
  242. except ldap.LDAPError as e:
  243. log.error('Failed to add passwordpolicy for level1: error ' + e.message['desc'])
  244. assert False
  245. # Add the COS template
  246. try:
  247. topology.standalone.add_s(Entry((BRANCH1_COS_TMPL, {
  248. 'objectclass': 'top ldapsubentry costemplate extensibleObject'.split(),
  249. 'cn': 'cn=nsPwPolicyEntry,ou=level1,dc=example,dc=com',
  250. 'cosPriority': '1',
  251. 'cn': 'cn=nsPwTemplateEntry,ou=level1,dc=example,dc=com',
  252. 'pwdpolicysubentry': BRANCH1_PWP
  253. })))
  254. except ldap.LDAPError as e:
  255. log.error('Failed to add COS template for level1: error ' + e.message['desc'])
  256. assert False
  257. # Add the COS definition
  258. try:
  259. topology.standalone.add_s(Entry((BRANCH1_COS_DEF, {
  260. 'objectclass': 'top ldapsubentry cosSuperDefinition cosPointerDefinition'.split(),
  261. 'cn': 'cn=nsPwPolicyEntry,ou=level1,dc=example,dc=com',
  262. 'costemplatedn': BRANCH1_COS_TMPL,
  263. 'cosAttribute': 'pwdpolicysubentry default operational-default'
  264. })))
  265. except ldap.LDAPError as e:
  266. log.error('Failed to add COS def for level1: error ' + e.message['desc'])
  267. assert False
  268. #
  269. # Add subtree policy to branch 2
  270. #
  271. # Add the container
  272. try:
  273. topology.standalone.add_s(Entry((BRANCH2_CONTAINER, {
  274. 'objectclass': 'top nsContainer'.split(),
  275. 'cn': 'nsPwPolicyContainer'
  276. })))
  277. except ldap.LDAPError as e:
  278. log.error('Failed to add subtree container for level2: error ' + e.message['desc'])
  279. assert False
  280. # Add the password policy subentry
  281. try:
  282. topology.standalone.add_s(Entry((BRANCH2_PWP, {
  283. 'objectclass': 'top ldapsubentry passwordpolicy'.split(),
  284. 'cn': 'cn=nsPwPolicyEntry,ou=level2,dc=example,dc=com',
  285. 'passwordMustChange': 'off',
  286. 'passwordExp': 'off',
  287. 'passwordHistory': 'off',
  288. 'passwordMinAge': '0',
  289. 'passwordChange': 'off',
  290. 'passwordStorageScheme': 'ssha'
  291. })))
  292. except ldap.LDAPError as e:
  293. log.error('Failed to add passwordpolicy for level2: error ' + e.message['desc'])
  294. assert False
  295. # Add the COS template
  296. try:
  297. topology.standalone.add_s(Entry((BRANCH2_COS_TMPL, {
  298. 'objectclass': 'top ldapsubentry costemplate extensibleObject'.split(),
  299. 'cn': 'cn=nsPwPolicyEntry,ou=level2,dc=example,dc=com',
  300. 'cosPriority': '1',
  301. 'cn': 'cn=nsPwTemplateEntry,ou=level2,dc=example,dc=com',
  302. 'pwdpolicysubentry': BRANCH2_PWP
  303. })))
  304. except ldap.LDAPError as e:
  305. log.error('Failed to add COS template for level2: error ' + e.message['desc'])
  306. assert False
  307. # Add the COS definition
  308. try:
  309. topology.standalone.add_s(Entry((BRANCH2_COS_DEF, {
  310. 'objectclass': 'top ldapsubentry cosSuperDefinition cosPointerDefinition'.split(),
  311. 'cn': 'cn=nsPwPolicyEntry,ou=level2,dc=example,dc=com',
  312. 'costemplatedn': BRANCH2_COS_TMPL,
  313. 'cosAttribute': 'pwdpolicysubentry default operational-default'
  314. })))
  315. except ldap.LDAPError as e:
  316. log.error('Failed to add COS def for level2: error ' + e.message['desc'])
  317. assert False
  318. #
  319. # Add subtree policy to branch 3
  320. #
  321. # Add the container
  322. try:
  323. topology.standalone.add_s(Entry((BRANCH3_CONTAINER, {
  324. 'objectclass': 'top nsContainer'.split(),
  325. 'cn': 'nsPwPolicyContainer'
  326. })))
  327. except ldap.LDAPError as e:
  328. log.error('Failed to add subtree container for level3: error ' + e.message['desc'])
  329. assert False
  330. # Add the password policy subentry
  331. try:
  332. topology.standalone.add_s(Entry((BRANCH3_PWP, {
  333. 'objectclass': 'top ldapsubentry passwordpolicy'.split(),
  334. 'cn': 'cn=nsPwPolicyEntry,ou=level3,dc=example,dc=com',
  335. 'passwordMustChange': 'off',
  336. 'passwordExp': 'off',
  337. 'passwordHistory': 'off',
  338. 'passwordMinAge': '0',
  339. 'passwordChange': 'off',
  340. 'passwordStorageScheme': 'ssha'
  341. })))
  342. except ldap.LDAPError as e:
  343. log.error('Failed to add passwordpolicy for level3: error ' + e.message['desc'])
  344. assert False
  345. # Add the COS template
  346. try:
  347. topology.standalone.add_s(Entry((BRANCH3_COS_TMPL, {
  348. 'objectclass': 'top ldapsubentry costemplate extensibleObject'.split(),
  349. 'cn': 'cn=nsPwPolicyEntry,ou=level3,dc=example,dc=com',
  350. 'cosPriority': '1',
  351. 'cn': 'cn=nsPwTemplateEntry,ou=level3,dc=example,dc=com',
  352. 'pwdpolicysubentry': BRANCH3_PWP
  353. })))
  354. except ldap.LDAPError as e:
  355. log.error('Failed to add COS template for level3: error ' + e.message['desc'])
  356. assert False
  357. # Add the COS definition
  358. try:
  359. topology.standalone.add_s(Entry((BRANCH3_COS_DEF, {
  360. 'objectclass': 'top ldapsubentry cosSuperDefinition cosPointerDefinition'.split(),
  361. 'cn': 'cn=nsPwPolicyEntry,ou=level3,dc=example,dc=com',
  362. 'costemplatedn': BRANCH3_COS_TMPL,
  363. 'cosAttribute': 'pwdpolicysubentry default operational-default'
  364. })))
  365. except ldap.LDAPError as e:
  366. log.error('Failed to add COS def for level3: error ' + e.message['desc'])
  367. assert False
  368. #
  369. # Add subtree policy to branch 4
  370. #
  371. # Add the container
  372. try:
  373. topology.standalone.add_s(Entry((BRANCH4_CONTAINER, {
  374. 'objectclass': 'top nsContainer'.split(),
  375. 'cn': 'nsPwPolicyContainer'
  376. })))
  377. except ldap.LDAPError as e:
  378. log.error('Failed to add subtree container for level3: error ' + e.message['desc'])
  379. assert False
  380. # Add the password policy subentry
  381. try:
  382. topology.standalone.add_s(Entry((BRANCH4_PWP, {
  383. 'objectclass': 'top ldapsubentry passwordpolicy'.split(),
  384. 'cn': 'cn=nsPwPolicyEntry,ou=people,dc=example,dc=com',
  385. 'passwordMustChange': 'off',
  386. 'passwordExp': 'off',
  387. 'passwordHistory': 'off',
  388. 'passwordMinAge': '0',
  389. 'passwordChange': 'off',
  390. 'passwordStorageScheme': 'ssha'
  391. })))
  392. except ldap.LDAPError as e:
  393. log.error('Failed to add passwordpolicy for branch4: error ' + e.message['desc'])
  394. assert False
  395. # Add the COS template
  396. try:
  397. topology.standalone.add_s(Entry((BRANCH4_COS_TMPL, {
  398. 'objectclass': 'top ldapsubentry costemplate extensibleObject'.split(),
  399. 'cn': 'cn=nsPwPolicyEntry,ou=people,dc=example,dc=com',
  400. 'cosPriority': '1',
  401. 'cn': 'cn=nsPwTemplateEntry,ou=people,dc=example,dc=com',
  402. 'pwdpolicysubentry': BRANCH4_PWP
  403. })))
  404. except ldap.LDAPError as e:
  405. log.error('Failed to add COS template for level3: error ' + e.message['desc'])
  406. assert False
  407. # Add the COS definition
  408. try:
  409. topology.standalone.add_s(Entry((BRANCH4_COS_DEF, {
  410. 'objectclass': 'top ldapsubentry cosSuperDefinition cosPointerDefinition'.split(),
  411. 'cn': 'cn=nsPwPolicyEntry,ou=people,dc=example,dc=com',
  412. 'costemplatedn': BRANCH4_COS_TMPL,
  413. 'cosAttribute': 'pwdpolicysubentry default operational-default'
  414. })))
  415. except ldap.LDAPError as e:
  416. log.error('Failed to add COS def for branch4: error ' + e.message['desc'])
  417. assert False
  418. #
  419. # Add subtree policy to branch 5
  420. #
  421. # Add the container
  422. try:
  423. topology.standalone.add_s(Entry((BRANCH5_CONTAINER, {
  424. 'objectclass': 'top nsContainer'.split(),
  425. 'cn': 'nsPwPolicyContainer'
  426. })))
  427. except ldap.LDAPError as e:
  428. log.error('Failed to add subtree container for branch5: error ' + e.message['desc'])
  429. assert False
  430. # Add the password policy subentry
  431. try:
  432. topology.standalone.add_s(Entry((BRANCH5_PWP, {
  433. 'objectclass': 'top ldapsubentry passwordpolicy'.split(),
  434. 'cn': 'cn=nsPwPolicyEntry,ou=lower,ou=people,dc=example,dc=com',
  435. 'passwordMustChange': 'off',
  436. 'passwordExp': 'off',
  437. 'passwordHistory': 'off',
  438. 'passwordMinAge': '0',
  439. 'passwordChange': 'off',
  440. 'passwordStorageScheme': 'ssha'
  441. })))
  442. except ldap.LDAPError as e:
  443. log.error('Failed to add passwordpolicy for branch5: error ' + e.message['desc'])
  444. assert False
  445. # Add the COS template
  446. try:
  447. topology.standalone.add_s(Entry((BRANCH5_COS_TMPL, {
  448. 'objectclass': 'top ldapsubentry costemplate extensibleObject'.split(),
  449. 'cn': 'cn=nsPwPolicyEntry,ou=lower,ou=people,dc=example,dc=com',
  450. 'cosPriority': '1',
  451. 'cn': 'cn=nsPwTemplateEntry,ou=lower,ou=people,dc=example,dc=com',
  452. 'pwdpolicysubentry': BRANCH5_PWP
  453. })))
  454. except ldap.LDAPError as e:
  455. log.error('Failed to add COS template for branch5: error ' + e.message['desc'])
  456. assert False
  457. # Add the COS definition
  458. try:
  459. topology.standalone.add_s(Entry((BRANCH5_COS_DEF, {
  460. 'objectclass': 'top ldapsubentry cosSuperDefinition cosPointerDefinition'.split(),
  461. 'cn': 'cn=nsPwPolicyEntry,ou=lower,ou=people,dc=example,dc=com',
  462. 'costemplatedn': BRANCH5_COS_TMPL,
  463. 'cosAttribute': 'pwdpolicysubentry default operational-default'
  464. })))
  465. except ldap.LDAPError as e:
  466. log.error('Failed to add COS def for level3: error ' + e.message['desc'])
  467. assert False
  468. #
  469. # Add subtree policy to branch 6
  470. #
  471. # Add the container
  472. try:
  473. topology.standalone.add_s(Entry((BRANCH6_CONTAINER, {
  474. 'objectclass': 'top nsContainer'.split(),
  475. 'cn': 'nsPwPolicyContainer'
  476. })))
  477. except ldap.LDAPError as e:
  478. log.error('Failed to add subtree container for branch6: error ' + e.message['desc'])
  479. assert False
  480. # Add the password policy subentry
  481. try:
  482. topology.standalone.add_s(Entry((BRANCH6_PWP, {
  483. 'objectclass': 'top ldapsubentry passwordpolicy'.split(),
  484. 'cn': 'cn=nsPwPolicyEntry,ou=level3,dc=example,dc=com',
  485. 'passwordMustChange': 'off',
  486. 'passwordExp': 'off',
  487. 'passwordHistory': 'off',
  488. 'passwordMinAge': '0',
  489. 'passwordChange': 'off',
  490. 'passwordStorageScheme': 'ssha'
  491. })))
  492. except ldap.LDAPError as e:
  493. log.error('Failed to add passwordpolicy for branch6: error ' + e.message['desc'])
  494. assert False
  495. # Add the COS template
  496. try:
  497. topology.standalone.add_s(Entry((BRANCH6_COS_TMPL, {
  498. 'objectclass': 'top ldapsubentry costemplate extensibleObject'.split(),
  499. 'cn': 'cn=nsPwPolicyEntry,ou=lower,ou=lower,ou=people,dc=example,dc=com',
  500. 'cosPriority': '1',
  501. 'cn': 'cn=nsPwTemplateEntry,ou=lower,ou=lower,ou=people,dc=example,dc=com',
  502. 'pwdpolicysubentry': BRANCH6_PWP
  503. })))
  504. except ldap.LDAPError as e:
  505. log.error('Failed to add COS template for branch6: error ' + e.message['desc'])
  506. assert False
  507. # Add the COS definition
  508. try:
  509. topology.standalone.add_s(Entry((BRANCH6_COS_DEF, {
  510. 'objectclass': 'top ldapsubentry cosSuperDefinition cosPointerDefinition'.split(),
  511. 'cn': 'cn=nsPwPolicyEntry,ou=lower,ou=lower,ou=people,dc=example,dc=com',
  512. 'costemplatedn': BRANCH6_COS_TMPL,
  513. 'cosAttribute': 'pwdpolicysubentry default operational-default'
  514. })))
  515. except ldap.LDAPError as e:
  516. log.error('Failed to add COS def for branch6: error ' + e.message['desc'])
  517. assert False
  518. time.sleep(2)
  519. #
  520. # Now check that each user has its expected passwordPolicy subentry
  521. #
  522. try:
  523. entries = topology.standalone.search_s(USER1_DN, ldap.SCOPE_BASE, '(objectclass=top)', ['pwdpolicysubentry'])
  524. if not entries[0].hasValue('pwdpolicysubentry', BRANCH1_PWP):
  525. log.fatal('User %s does not have expected pwdpolicysubentry!')
  526. assert False
  527. except ldap.LDAPError as e:
  528. log.fatal('Unable to search for entry %s: error %s' % (USER1_DN, e.message['desc']))
  529. assert False
  530. try:
  531. entries = topology.standalone.search_s(USER2_DN, ldap.SCOPE_BASE, '(objectclass=top)', ['pwdpolicysubentry'])
  532. if not entries[0].hasValue('pwdpolicysubentry', BRANCH2_PWP):
  533. log.fatal('User %s does not have expected pwdpolicysubentry!' % USER2_DN)
  534. assert False
  535. except ldap.LDAPError as e:
  536. log.fatal('Unable to search for entry %s: error %s' % (USER2_DN, e.message['desc']))
  537. assert False
  538. try:
  539. entries = topology.standalone.search_s(USER3_DN, ldap.SCOPE_BASE, '(objectclass=top)', ['pwdpolicysubentry'])
  540. if not entries[0].hasValue('pwdpolicysubentry', BRANCH3_PWP):
  541. log.fatal('User %s does not have expected pwdpolicysubentry!' % USER3_DN)
  542. assert False
  543. except ldap.LDAPError as e:
  544. log.fatal('Unable to search for entry %s: error %s' % (USER3_DN, e.message['desc']))
  545. assert False
  546. try:
  547. entries = topology.standalone.search_s(USER4_DN, ldap.SCOPE_BASE, '(objectclass=top)', ['pwdpolicysubentry'])
  548. if not entries[0].hasValue('pwdpolicysubentry', BRANCH4_PWP):
  549. log.fatal('User %s does not have expected pwdpolicysubentry!' % USER4_DN)
  550. assert False
  551. except ldap.LDAPError as e:
  552. log.fatal('Unable to search for entry %s: error %s' % (USER4_DN, e.message['desc']))
  553. assert False
  554. try:
  555. entries = topology.standalone.search_s(USER5_DN, ldap.SCOPE_BASE, '(objectclass=top)', ['pwdpolicysubentry'])
  556. if not entries[0].hasValue('pwdpolicysubentry', BRANCH5_PWP):
  557. log.fatal('User %s does not have expected pwdpolicysubentry!' % USER5_DN)
  558. assert False
  559. except ldap.LDAPError as e:
  560. log.fatal('Unable to search for entry %s: error %s' % (USER5_DN, e.message['desc']))
  561. assert False
  562. try:
  563. entries = topology.standalone.search_s(USER6_DN, ldap.SCOPE_BASE, '(objectclass=top)', ['pwdpolicysubentry'])
  564. if not entries[0].hasValue('pwdpolicysubentry', BRANCH6_PWP):
  565. log.fatal('User %s does not have expected pwdpolicysubentry!' % USER6_DN)
  566. assert False
  567. except ldap.LDAPError as e:
  568. log.fatal('Unable to search for entry %s: error %s' % (USER6_DN, e.message['desc']))
  569. assert False
  570. def test_ticket47980_final(topology):
  571. log.info('Testcase PASSED')
  572. def run_isolated():
  573. '''
  574. run_isolated is used to run these test cases independently of a test scheduler (xunit, py.test..)
  575. To run isolated without py.test, you need to
  576. - edit this file and comment '@pytest.fixture' line before 'topology' function.
  577. - set the installation prefix
  578. - run this program
  579. '''
  580. global installation_prefix
  581. installation_prefix = None
  582. topo = topology(True)
  583. test_ticket47980(topo)
  584. test_ticket47980_final(topo)
  585. if __name__ == '__main__':
  586. run_isolated()