1
0

ticket47980_test.py 28 KB

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