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. # clear the tmp directory
  100. standalone.clearTmpDir(__file__)
  101. # Here we have standalone instance up and running
  102. return TopologyStandalone(standalone)
  103. def test_ticket47980(topology):
  104. """
  105. Multiple COS pointer definitions that use the same attribute are not correctly ordered.
  106. The cos plugin was incorrectly sorting the attribute indexes based on subtree, which lead
  107. to the wrong cos attribute value being applied to the entry.
  108. """
  109. log.info('Testing Ticket 47980 - Testing multiple nested COS pointer definitions are processed correctly')
  110. # Add our nested branches
  111. try:
  112. topology.standalone.add_s(Entry((BRANCH1, {
  113. 'objectclass': 'top extensibleObject'.split(),
  114. 'ou': 'level1'
  115. })))
  116. except ldap.LDAPError as e:
  117. log.error('Failed to add level1: error ' + e.message['desc'])
  118. assert False
  119. try:
  120. topology.standalone.add_s(Entry((BRANCH2, {
  121. 'objectclass': 'top extensibleObject'.split(),
  122. 'ou': 'level2'
  123. })))
  124. except ldap.LDAPError as e:
  125. log.error('Failed to add level2: error ' + e.message['desc'])
  126. assert False
  127. try:
  128. topology.standalone.add_s(Entry((BRANCH3, {
  129. 'objectclass': 'top extensibleObject'.split(),
  130. 'uid': 'level3'
  131. })))
  132. except ldap.LDAPError as e:
  133. log.error('Failed to add level3: error ' + e.message['desc'])
  134. assert False
  135. # People branch, might already exist
  136. try:
  137. topology.standalone.add_s(Entry((BRANCH4, {
  138. 'objectclass': 'top extensibleObject'.split(),
  139. 'ou': 'level4'
  140. })))
  141. except ldap.ALREADY_EXISTS:
  142. pass
  143. except ldap.LDAPError as e:
  144. log.error('Failed to add level4: error ' + e.message['desc'])
  145. assert False
  146. try:
  147. topology.standalone.add_s(Entry((BRANCH5, {
  148. 'objectclass': 'top extensibleObject'.split(),
  149. 'ou': 'level5'
  150. })))
  151. except ldap.LDAPError as e:
  152. log.error('Failed to add level5: error ' + e.message['desc'])
  153. assert False
  154. try:
  155. topology.standalone.add_s(Entry((BRANCH6, {
  156. 'objectclass': 'top extensibleObject'.split(),
  157. 'uid': 'level6'
  158. })))
  159. except ldap.LDAPError as e:
  160. log.error('Failed to add level6: error ' + e.message['desc'])
  161. assert False
  162. # Add users to each branch
  163. try:
  164. topology.standalone.add_s(Entry((USER1_DN, {
  165. 'objectclass': 'top extensibleObject'.split(),
  166. 'uid': 'user1'
  167. })))
  168. except ldap.LDAPError as e:
  169. log.error('Failed to add user1: error ' + e.message['desc'])
  170. assert False
  171. try:
  172. topology.standalone.add_s(Entry((USER2_DN, {
  173. 'objectclass': 'top extensibleObject'.split(),
  174. 'uid': 'user2'
  175. })))
  176. except ldap.LDAPError as e:
  177. log.error('Failed to add user2: error ' + e.message['desc'])
  178. assert False
  179. try:
  180. topology.standalone.add_s(Entry((USER3_DN, {
  181. 'objectclass': 'top extensibleObject'.split(),
  182. 'uid': 'user3'
  183. })))
  184. except ldap.LDAPError as e:
  185. log.error('Failed to add user3: error ' + e.message['desc'])
  186. assert False
  187. try:
  188. topology.standalone.add_s(Entry((USER4_DN, {
  189. 'objectclass': 'top extensibleObject'.split(),
  190. 'uid': 'user4'
  191. })))
  192. except ldap.LDAPError as e:
  193. log.error('Failed to add user4: error ' + e.message['desc'])
  194. assert False
  195. try:
  196. topology.standalone.add_s(Entry((USER5_DN, {
  197. 'objectclass': 'top extensibleObject'.split(),
  198. 'uid': 'user5'
  199. })))
  200. except ldap.LDAPError as e:
  201. log.error('Failed to add user5: error ' + e.message['desc'])
  202. assert False
  203. try:
  204. topology.standalone.add_s(Entry((USER6_DN, {
  205. 'objectclass': 'top extensibleObject'.split(),
  206. 'uid': 'user6'
  207. })))
  208. except ldap.LDAPError as e:
  209. log.error('Failed to add user6: error ' + e.message['desc'])
  210. assert False
  211. # Enable password policy
  212. try:
  213. topology.standalone.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE, 'nsslapd-pwpolicy-local', 'on')])
  214. except ldap.LDAPError as e:
  215. log.error('Failed to set pwpolicy-local: error ' + e.message['desc'])
  216. assert False
  217. #
  218. # Add subtree policy to branch 1
  219. #
  220. # Add the container
  221. try:
  222. topology.standalone.add_s(Entry((BRANCH1_CONTAINER, {
  223. 'objectclass': 'top nsContainer'.split(),
  224. 'cn': 'nsPwPolicyContainer'
  225. })))
  226. except ldap.LDAPError as e:
  227. log.error('Failed to add subtree container for level1: error ' + e.message['desc'])
  228. assert False
  229. # Add the password policy subentry
  230. try:
  231. topology.standalone.add_s(Entry((BRANCH1_PWP, {
  232. 'objectclass': 'top ldapsubentry passwordpolicy'.split(),
  233. 'cn': 'cn=nsPwPolicyEntry,ou=level1,dc=example,dc=com',
  234. 'passwordMustChange': 'off',
  235. 'passwordExp': 'off',
  236. 'passwordHistory': 'off',
  237. 'passwordMinAge': '0',
  238. 'passwordChange': 'off',
  239. 'passwordStorageScheme': 'ssha'
  240. })))
  241. except ldap.LDAPError as e:
  242. log.error('Failed to add passwordpolicy for level1: error ' + e.message['desc'])
  243. assert False
  244. # Add the COS template
  245. try:
  246. topology.standalone.add_s(Entry((BRANCH1_COS_TMPL, {
  247. 'objectclass': 'top ldapsubentry costemplate extensibleObject'.split(),
  248. 'cn': 'cn=nsPwPolicyEntry,ou=level1,dc=example,dc=com',
  249. 'cosPriority': '1',
  250. 'cn': 'cn=nsPwTemplateEntry,ou=level1,dc=example,dc=com',
  251. 'pwdpolicysubentry': BRANCH1_PWP
  252. })))
  253. except ldap.LDAPError as e:
  254. log.error('Failed to add COS template for level1: error ' + e.message['desc'])
  255. assert False
  256. # Add the COS definition
  257. try:
  258. topology.standalone.add_s(Entry((BRANCH1_COS_DEF, {
  259. 'objectclass': 'top ldapsubentry cosSuperDefinition cosPointerDefinition'.split(),
  260. 'cn': 'cn=nsPwPolicyEntry,ou=level1,dc=example,dc=com',
  261. 'costemplatedn': BRANCH1_COS_TMPL,
  262. 'cosAttribute': 'pwdpolicysubentry default operational-default'
  263. })))
  264. except ldap.LDAPError as e:
  265. log.error('Failed to add COS def for level1: error ' + e.message['desc'])
  266. assert False
  267. #
  268. # Add subtree policy to branch 2
  269. #
  270. # Add the container
  271. try:
  272. topology.standalone.add_s(Entry((BRANCH2_CONTAINER, {
  273. 'objectclass': 'top nsContainer'.split(),
  274. 'cn': 'nsPwPolicyContainer'
  275. })))
  276. except ldap.LDAPError as e:
  277. log.error('Failed to add subtree container for level2: error ' + e.message['desc'])
  278. assert False
  279. # Add the password policy subentry
  280. try:
  281. topology.standalone.add_s(Entry((BRANCH2_PWP, {
  282. 'objectclass': 'top ldapsubentry passwordpolicy'.split(),
  283. 'cn': 'cn=nsPwPolicyEntry,ou=level2,dc=example,dc=com',
  284. 'passwordMustChange': 'off',
  285. 'passwordExp': 'off',
  286. 'passwordHistory': 'off',
  287. 'passwordMinAge': '0',
  288. 'passwordChange': 'off',
  289. 'passwordStorageScheme': 'ssha'
  290. })))
  291. except ldap.LDAPError as e:
  292. log.error('Failed to add passwordpolicy for level2: error ' + e.message['desc'])
  293. assert False
  294. # Add the COS template
  295. try:
  296. topology.standalone.add_s(Entry((BRANCH2_COS_TMPL, {
  297. 'objectclass': 'top ldapsubentry costemplate extensibleObject'.split(),
  298. 'cn': 'cn=nsPwPolicyEntry,ou=level2,dc=example,dc=com',
  299. 'cosPriority': '1',
  300. 'cn': 'cn=nsPwTemplateEntry,ou=level2,dc=example,dc=com',
  301. 'pwdpolicysubentry': BRANCH2_PWP
  302. })))
  303. except ldap.LDAPError as e:
  304. log.error('Failed to add COS template for level2: error ' + e.message['desc'])
  305. assert False
  306. # Add the COS definition
  307. try:
  308. topology.standalone.add_s(Entry((BRANCH2_COS_DEF, {
  309. 'objectclass': 'top ldapsubentry cosSuperDefinition cosPointerDefinition'.split(),
  310. 'cn': 'cn=nsPwPolicyEntry,ou=level2,dc=example,dc=com',
  311. 'costemplatedn': BRANCH2_COS_TMPL,
  312. 'cosAttribute': 'pwdpolicysubentry default operational-default'
  313. })))
  314. except ldap.LDAPError as e:
  315. log.error('Failed to add COS def for level2: error ' + e.message['desc'])
  316. assert False
  317. #
  318. # Add subtree policy to branch 3
  319. #
  320. # Add the container
  321. try:
  322. topology.standalone.add_s(Entry((BRANCH3_CONTAINER, {
  323. 'objectclass': 'top nsContainer'.split(),
  324. 'cn': 'nsPwPolicyContainer'
  325. })))
  326. except ldap.LDAPError as e:
  327. log.error('Failed to add subtree container for level3: error ' + e.message['desc'])
  328. assert False
  329. # Add the password policy subentry
  330. try:
  331. topology.standalone.add_s(Entry((BRANCH3_PWP, {
  332. 'objectclass': 'top ldapsubentry passwordpolicy'.split(),
  333. 'cn': 'cn=nsPwPolicyEntry,ou=level3,dc=example,dc=com',
  334. 'passwordMustChange': 'off',
  335. 'passwordExp': 'off',
  336. 'passwordHistory': 'off',
  337. 'passwordMinAge': '0',
  338. 'passwordChange': 'off',
  339. 'passwordStorageScheme': 'ssha'
  340. })))
  341. except ldap.LDAPError as e:
  342. log.error('Failed to add passwordpolicy for level3: error ' + e.message['desc'])
  343. assert False
  344. # Add the COS template
  345. try:
  346. topology.standalone.add_s(Entry((BRANCH3_COS_TMPL, {
  347. 'objectclass': 'top ldapsubentry costemplate extensibleObject'.split(),
  348. 'cn': 'cn=nsPwPolicyEntry,ou=level3,dc=example,dc=com',
  349. 'cosPriority': '1',
  350. 'cn': 'cn=nsPwTemplateEntry,ou=level3,dc=example,dc=com',
  351. 'pwdpolicysubentry': BRANCH3_PWP
  352. })))
  353. except ldap.LDAPError as e:
  354. log.error('Failed to add COS template for level3: error ' + e.message['desc'])
  355. assert False
  356. # Add the COS definition
  357. try:
  358. topology.standalone.add_s(Entry((BRANCH3_COS_DEF, {
  359. 'objectclass': 'top ldapsubentry cosSuperDefinition cosPointerDefinition'.split(),
  360. 'cn': 'cn=nsPwPolicyEntry,ou=level3,dc=example,dc=com',
  361. 'costemplatedn': BRANCH3_COS_TMPL,
  362. 'cosAttribute': 'pwdpolicysubentry default operational-default'
  363. })))
  364. except ldap.LDAPError as e:
  365. log.error('Failed to add COS def for level3: error ' + e.message['desc'])
  366. assert False
  367. #
  368. # Add subtree policy to branch 4
  369. #
  370. # Add the container
  371. try:
  372. topology.standalone.add_s(Entry((BRANCH4_CONTAINER, {
  373. 'objectclass': 'top nsContainer'.split(),
  374. 'cn': 'nsPwPolicyContainer'
  375. })))
  376. except ldap.LDAPError as e:
  377. log.error('Failed to add subtree container for level3: error ' + e.message['desc'])
  378. assert False
  379. # Add the password policy subentry
  380. try:
  381. topology.standalone.add_s(Entry((BRANCH4_PWP, {
  382. 'objectclass': 'top ldapsubentry passwordpolicy'.split(),
  383. 'cn': 'cn=nsPwPolicyEntry,ou=people,dc=example,dc=com',
  384. 'passwordMustChange': 'off',
  385. 'passwordExp': 'off',
  386. 'passwordHistory': 'off',
  387. 'passwordMinAge': '0',
  388. 'passwordChange': 'off',
  389. 'passwordStorageScheme': 'ssha'
  390. })))
  391. except ldap.LDAPError as e:
  392. log.error('Failed to add passwordpolicy for branch4: error ' + e.message['desc'])
  393. assert False
  394. # Add the COS template
  395. try:
  396. topology.standalone.add_s(Entry((BRANCH4_COS_TMPL, {
  397. 'objectclass': 'top ldapsubentry costemplate extensibleObject'.split(),
  398. 'cn': 'cn=nsPwPolicyEntry,ou=people,dc=example,dc=com',
  399. 'cosPriority': '1',
  400. 'cn': 'cn=nsPwTemplateEntry,ou=people,dc=example,dc=com',
  401. 'pwdpolicysubentry': BRANCH4_PWP
  402. })))
  403. except ldap.LDAPError as e:
  404. log.error('Failed to add COS template for level3: error ' + e.message['desc'])
  405. assert False
  406. # Add the COS definition
  407. try:
  408. topology.standalone.add_s(Entry((BRANCH4_COS_DEF, {
  409. 'objectclass': 'top ldapsubentry cosSuperDefinition cosPointerDefinition'.split(),
  410. 'cn': 'cn=nsPwPolicyEntry,ou=people,dc=example,dc=com',
  411. 'costemplatedn': BRANCH4_COS_TMPL,
  412. 'cosAttribute': 'pwdpolicysubentry default operational-default'
  413. })))
  414. except ldap.LDAPError as e:
  415. log.error('Failed to add COS def for branch4: error ' + e.message['desc'])
  416. assert False
  417. #
  418. # Add subtree policy to branch 5
  419. #
  420. # Add the container
  421. try:
  422. topology.standalone.add_s(Entry((BRANCH5_CONTAINER, {
  423. 'objectclass': 'top nsContainer'.split(),
  424. 'cn': 'nsPwPolicyContainer'
  425. })))
  426. except ldap.LDAPError as e:
  427. log.error('Failed to add subtree container for branch5: error ' + e.message['desc'])
  428. assert False
  429. # Add the password policy subentry
  430. try:
  431. topology.standalone.add_s(Entry((BRANCH5_PWP, {
  432. 'objectclass': 'top ldapsubentry passwordpolicy'.split(),
  433. 'cn': 'cn=nsPwPolicyEntry,ou=lower,ou=people,dc=example,dc=com',
  434. 'passwordMustChange': 'off',
  435. 'passwordExp': 'off',
  436. 'passwordHistory': 'off',
  437. 'passwordMinAge': '0',
  438. 'passwordChange': 'off',
  439. 'passwordStorageScheme': 'ssha'
  440. })))
  441. except ldap.LDAPError as e:
  442. log.error('Failed to add passwordpolicy for branch5: error ' + e.message['desc'])
  443. assert False
  444. # Add the COS template
  445. try:
  446. topology.standalone.add_s(Entry((BRANCH5_COS_TMPL, {
  447. 'objectclass': 'top ldapsubentry costemplate extensibleObject'.split(),
  448. 'cn': 'cn=nsPwPolicyEntry,ou=lower,ou=people,dc=example,dc=com',
  449. 'cosPriority': '1',
  450. 'cn': 'cn=nsPwTemplateEntry,ou=lower,ou=people,dc=example,dc=com',
  451. 'pwdpolicysubentry': BRANCH5_PWP
  452. })))
  453. except ldap.LDAPError as e:
  454. log.error('Failed to add COS template for branch5: error ' + e.message['desc'])
  455. assert False
  456. # Add the COS definition
  457. try:
  458. topology.standalone.add_s(Entry((BRANCH5_COS_DEF, {
  459. 'objectclass': 'top ldapsubentry cosSuperDefinition cosPointerDefinition'.split(),
  460. 'cn': 'cn=nsPwPolicyEntry,ou=lower,ou=people,dc=example,dc=com',
  461. 'costemplatedn': BRANCH5_COS_TMPL,
  462. 'cosAttribute': 'pwdpolicysubentry default operational-default'
  463. })))
  464. except ldap.LDAPError as e:
  465. log.error('Failed to add COS def for level3: error ' + e.message['desc'])
  466. assert False
  467. #
  468. # Add subtree policy to branch 6
  469. #
  470. # Add the container
  471. try:
  472. topology.standalone.add_s(Entry((BRANCH6_CONTAINER, {
  473. 'objectclass': 'top nsContainer'.split(),
  474. 'cn': 'nsPwPolicyContainer'
  475. })))
  476. except ldap.LDAPError as e:
  477. log.error('Failed to add subtree container for branch6: error ' + e.message['desc'])
  478. assert False
  479. # Add the password policy subentry
  480. try:
  481. topology.standalone.add_s(Entry((BRANCH6_PWP, {
  482. 'objectclass': 'top ldapsubentry passwordpolicy'.split(),
  483. 'cn': 'cn=nsPwPolicyEntry,ou=level3,dc=example,dc=com',
  484. 'passwordMustChange': 'off',
  485. 'passwordExp': 'off',
  486. 'passwordHistory': 'off',
  487. 'passwordMinAge': '0',
  488. 'passwordChange': 'off',
  489. 'passwordStorageScheme': 'ssha'
  490. })))
  491. except ldap.LDAPError as e:
  492. log.error('Failed to add passwordpolicy for branch6: error ' + e.message['desc'])
  493. assert False
  494. # Add the COS template
  495. try:
  496. topology.standalone.add_s(Entry((BRANCH6_COS_TMPL, {
  497. 'objectclass': 'top ldapsubentry costemplate extensibleObject'.split(),
  498. 'cn': 'cn=nsPwPolicyEntry,ou=lower,ou=lower,ou=people,dc=example,dc=com',
  499. 'cosPriority': '1',
  500. 'cn': 'cn=nsPwTemplateEntry,ou=lower,ou=lower,ou=people,dc=example,dc=com',
  501. 'pwdpolicysubentry': BRANCH6_PWP
  502. })))
  503. except ldap.LDAPError as e:
  504. log.error('Failed to add COS template for branch6: error ' + e.message['desc'])
  505. assert False
  506. # Add the COS definition
  507. try:
  508. topology.standalone.add_s(Entry((BRANCH6_COS_DEF, {
  509. 'objectclass': 'top ldapsubentry cosSuperDefinition cosPointerDefinition'.split(),
  510. 'cn': 'cn=nsPwPolicyEntry,ou=lower,ou=lower,ou=people,dc=example,dc=com',
  511. 'costemplatedn': BRANCH6_COS_TMPL,
  512. 'cosAttribute': 'pwdpolicysubentry default operational-default'
  513. })))
  514. except ldap.LDAPError as e:
  515. log.error('Failed to add COS def for branch6: error ' + e.message['desc'])
  516. assert False
  517. time.sleep(2)
  518. #
  519. # Now check that each user has its expected passwordPolicy subentry
  520. #
  521. try:
  522. entries = topology.standalone.search_s(USER1_DN, ldap.SCOPE_BASE, '(objectclass=top)', ['pwdpolicysubentry'])
  523. if not entries[0].hasValue('pwdpolicysubentry', BRANCH1_PWP):
  524. log.fatal('User %s does not have expected pwdpolicysubentry!')
  525. assert False
  526. except ldap.LDAPError as e:
  527. log.fatal('Unable to search for entry %s: error %s' % (USER1_DN, e.message['desc']))
  528. assert False
  529. try:
  530. entries = topology.standalone.search_s(USER2_DN, ldap.SCOPE_BASE, '(objectclass=top)', ['pwdpolicysubentry'])
  531. if not entries[0].hasValue('pwdpolicysubentry', BRANCH2_PWP):
  532. log.fatal('User %s does not have expected pwdpolicysubentry!' % USER2_DN)
  533. assert False
  534. except ldap.LDAPError as e:
  535. log.fatal('Unable to search for entry %s: error %s' % (USER2_DN, e.message['desc']))
  536. assert False
  537. try:
  538. entries = topology.standalone.search_s(USER3_DN, ldap.SCOPE_BASE, '(objectclass=top)', ['pwdpolicysubentry'])
  539. if not entries[0].hasValue('pwdpolicysubentry', BRANCH3_PWP):
  540. log.fatal('User %s does not have expected pwdpolicysubentry!' % USER3_DN)
  541. assert False
  542. except ldap.LDAPError as e:
  543. log.fatal('Unable to search for entry %s: error %s' % (USER3_DN, e.message['desc']))
  544. assert False
  545. try:
  546. entries = topology.standalone.search_s(USER4_DN, ldap.SCOPE_BASE, '(objectclass=top)', ['pwdpolicysubentry'])
  547. if not entries[0].hasValue('pwdpolicysubentry', BRANCH4_PWP):
  548. log.fatal('User %s does not have expected pwdpolicysubentry!' % USER4_DN)
  549. assert False
  550. except ldap.LDAPError as e:
  551. log.fatal('Unable to search for entry %s: error %s' % (USER4_DN, e.message['desc']))
  552. assert False
  553. try:
  554. entries = topology.standalone.search_s(USER5_DN, ldap.SCOPE_BASE, '(objectclass=top)', ['pwdpolicysubentry'])
  555. if not entries[0].hasValue('pwdpolicysubentry', BRANCH5_PWP):
  556. log.fatal('User %s does not have expected pwdpolicysubentry!' % USER5_DN)
  557. assert False
  558. except ldap.LDAPError as e:
  559. log.fatal('Unable to search for entry %s: error %s' % (USER5_DN, e.message['desc']))
  560. assert False
  561. try:
  562. entries = topology.standalone.search_s(USER6_DN, ldap.SCOPE_BASE, '(objectclass=top)', ['pwdpolicysubentry'])
  563. if not entries[0].hasValue('pwdpolicysubentry', BRANCH6_PWP):
  564. log.fatal('User %s does not have expected pwdpolicysubentry!' % USER6_DN)
  565. assert False
  566. except ldap.LDAPError as e:
  567. log.fatal('Unable to search for entry %s: error %s' % (USER6_DN, e.message['desc']))
  568. assert False
  569. def test_ticket47980_final(topology):
  570. topology.standalone.delete()
  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()