1
0

ticket47980_test.py 30 KB

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