1
0

ticket47980_test.py 27 KB

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