basic_test.py 52 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487
  1. # --- BEGIN COPYRIGHT BLOCK ---
  2. # Copyright (C) 2020 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. """
  10. :Requirement: Basic Directory Server Operations
  11. """
  12. from subprocess import check_output, PIPE, run
  13. from lib389 import DirSrv
  14. from lib389.idm.user import UserAccounts
  15. import pytest
  16. from lib389.tasks import *
  17. from lib389.utils import *
  18. from lib389.topologies import topology_st
  19. from lib389.dbgen import dbgen_users
  20. from lib389.idm.organizationalunit import OrganizationalUnits
  21. from lib389._constants import DN_DM, PASSWORD, PW_DM
  22. from lib389.paths import Paths
  23. from lib389.idm.directorymanager import DirectoryManager
  24. from lib389.config import LDBMConfig
  25. from lib389.dseldif import DSEldif
  26. from lib389.rootdse import RootDSE
  27. pytestmark = pytest.mark.tier0
  28. default_paths = Paths()
  29. log = logging.getLogger(__name__)
  30. # Globals
  31. USER1_DN = 'uid=user1,' + DEFAULT_SUFFIX
  32. USER2_DN = 'uid=user2,' + DEFAULT_SUFFIX
  33. USER3_DN = 'uid=user3,' + DEFAULT_SUFFIX
  34. USER4_DN = 'uid=user4,' + DEFAULT_SUFFIX
  35. ROOTDSE_DEF_ATTR_LIST = ('namingContexts',
  36. 'supportedLDAPVersion',
  37. 'supportedControl',
  38. 'supportedExtension',
  39. 'supportedSASLMechanisms',
  40. 'vendorName',
  41. 'vendorVersion')
  42. @pytest.fixture(scope="module")
  43. def import_example_ldif(topology_st):
  44. """Import the Example LDIF for the tests in this suite"""
  45. log.info('Initializing the "basic" test suite')
  46. ldif = '%s/dirsrv/data/Example.ldif' % topology_st.standalone.get_data_dir()
  47. import_ldif = topology_st.standalone.get_ldif_dir() + "/Example.ldif"
  48. shutil.copy(ldif, import_ldif)
  49. import_task = ImportTask(topology_st.standalone)
  50. import_task.import_suffix_from_ldif(ldiffile=import_ldif, suffix=DEFAULT_SUFFIX)
  51. import_task.wait()
  52. @pytest.fixture(params=ROOTDSE_DEF_ATTR_LIST)
  53. def rootdse_attr(topology_st, request):
  54. """Adds an attr from the list
  55. as the default attr to the rootDSE
  56. """
  57. # Ensure the server is started and connected
  58. topology_st.standalone.start()
  59. RETURN_DEFAULT_OPATTR = "nsslapd-return-default-opattr"
  60. rootdse_attr_name = ensure_bytes(request.param)
  61. log.info(" Add the %s: %s to rootdse" % (RETURN_DEFAULT_OPATTR,
  62. rootdse_attr_name))
  63. mod = [(ldap.MOD_ADD, RETURN_DEFAULT_OPATTR, rootdse_attr_name)]
  64. try:
  65. topology_st.standalone.modify_s("", mod)
  66. except ldap.LDAPError as e:
  67. log.fatal('Failed to add attr: error (%s)' % (e.args[0]['desc']))
  68. assert False
  69. def fin():
  70. log.info(" Delete the %s: %s from rootdse" % (RETURN_DEFAULT_OPATTR,
  71. rootdse_attr_name))
  72. mod = [(ldap.MOD_DELETE, RETURN_DEFAULT_OPATTR, rootdse_attr_name)]
  73. try:
  74. topology_st.standalone.modify_s("", mod)
  75. except ldap.LDAPError as e:
  76. log.fatal('Failed to delete attr: error (%s)' % (e.args[0]['desc']))
  77. assert False
  78. request.addfinalizer(fin)
  79. return rootdse_attr_name
  80. def test_basic_ops(topology_st, import_example_ldif):
  81. """Tests adds, mods, modrdns, and deletes operations
  82. :id: 33f97f55-60bf-46c7-b880-6c488517ae19
  83. :setup: Standalone instance
  84. :steps:
  85. 1. Add 3 test users USER1, USER2 and USER3 to database
  86. 2. Modify (ADD, REPLACE and DELETE) description for USER1 in database
  87. 3. Rename USER1, USER2 and USER3 using Modrds
  88. 4. Delete test entries USER1, USER2 and USER3
  89. :expectedresults:
  90. 1. Add operation should PASS.
  91. 2. Modify operations should PASS.
  92. 3. Rename operations should PASS.
  93. 4. Delete operations should PASS.
  94. """
  95. log.info('Running test_basic_ops...')
  96. USER1_NEWDN = 'cn=user1'
  97. USER2_NEWDN = 'cn=user2'
  98. USER3_NEWDN = 'cn=user3'
  99. NEW_SUPERIOR = 'ou=people,' + DEFAULT_SUFFIX
  100. USER1_RDN_DN = 'cn=user1,' + DEFAULT_SUFFIX
  101. USER2_RDN_DN = 'cn=user2,' + DEFAULT_SUFFIX
  102. USER3_RDN_DN = 'cn=user3,' + NEW_SUPERIOR # New superior test
  103. #
  104. # Adds#
  105. try:
  106. topology_st.standalone.add_s(Entry((USER1_DN,
  107. {'objectclass': "top extensibleObject".split(),
  108. 'sn': '1',
  109. 'cn': 'user1',
  110. 'uid': 'user1',
  111. 'userpassword': 'password'})))
  112. except ldap.LDAPError as e:
  113. log.error('Failed to add test user' + USER1_DN + ': error ' + e.args[0]['desc'])
  114. assert False
  115. try:
  116. topology_st.standalone.add_s(Entry((USER2_DN,
  117. {'objectclass': "top extensibleObject".split(),
  118. 'sn': '2',
  119. 'cn': 'user2',
  120. 'uid': 'user2',
  121. 'userpassword': 'password'})))
  122. except ldap.LDAPError as e:
  123. log.error('Failed to add test user' + USER2_DN + ': error ' + e.args[0]['desc'])
  124. assert False
  125. try:
  126. topology_st.standalone.add_s(Entry((USER3_DN,
  127. {'objectclass': "top extensibleObject".split(),
  128. 'sn': '3',
  129. 'cn': 'user3',
  130. 'uid': 'user3',
  131. 'userpassword': 'password'})))
  132. except ldap.LDAPError as e:
  133. log.error('Failed to add test user' + USER3_DN + ': error ' + e.args[0]['desc'])
  134. assert False
  135. #
  136. # Mods
  137. #
  138. try:
  139. topology_st.standalone.modify_s(USER1_DN, [(ldap.MOD_ADD, 'description',
  140. b'New description')])
  141. except ldap.LDAPError as e:
  142. log.error('Failed to add description: error ' + e.args[0]['desc'])
  143. assert False
  144. try:
  145. topology_st.standalone.modify_s(USER1_DN, [(ldap.MOD_REPLACE, 'description',
  146. b'Modified description')])
  147. except ldap.LDAPError as e:
  148. log.error('Failed to modify description: error ' + e.args[0]['desc'])
  149. assert False
  150. try:
  151. topology_st.standalone.modify_s(USER1_DN, [(ldap.MOD_DELETE, 'description',
  152. None)])
  153. except ldap.LDAPError as e:
  154. log.error('Failed to delete description: error ' + e.args[0]['desc'])
  155. assert False
  156. #
  157. # Modrdns
  158. #
  159. try:
  160. topology_st.standalone.rename_s(USER1_DN, USER1_NEWDN, delold=1)
  161. except ldap.LDAPError as e:
  162. log.error('Failed to modrdn user1: error ' + e.args[0]['desc'])
  163. assert False
  164. try:
  165. topology_st.standalone.rename_s(USER2_DN, USER2_NEWDN, delold=0)
  166. except ldap.LDAPError as e:
  167. log.error('Failed to modrdn user2: error ' + e.args[0]['desc'])
  168. assert False # Modrdn - New superior
  169. try:
  170. topology_st.standalone.rename_s(USER3_DN, USER3_NEWDN,
  171. newsuperior=NEW_SUPERIOR, delold=1)
  172. except ldap.LDAPError as e:
  173. log.error('Failed to modrdn(new superior) user3: error ' + e.args[0]['desc'])
  174. assert False
  175. #
  176. # Deletes
  177. #
  178. try:
  179. topology_st.standalone.delete_s(USER1_RDN_DN)
  180. except ldap.LDAPError as e:
  181. log.error('Failed to delete test entry1: ' + e.args[0]['desc'])
  182. assert False
  183. try:
  184. topology_st.standalone.delete_s(USER2_RDN_DN)
  185. except ldap.LDAPError as e:
  186. log.error('Failed to delete test entry2: ' + e.args[0]['desc'])
  187. assert False
  188. try:
  189. topology_st.standalone.delete_s(USER3_RDN_DN)
  190. except ldap.LDAPError as e:
  191. log.error('Failed to delete test entry3: ' + e.args[0]['desc'])
  192. assert False
  193. log.info('test_basic_ops: PASSED')
  194. def test_basic_import_export(topology_st, import_example_ldif):
  195. """Test online and offline LDIF import & export
  196. :id: 3ceeea11-9235-4e20-b80e-7203b2c6e149
  197. :setup: Standalone instance
  198. :steps:
  199. 1. Generate a test ldif (50k entries)
  200. 2. Import test ldif file using Online import.
  201. 3. Import test ldif file using Offline import (ldif2db).
  202. 4. Export test ldif file using Online export.
  203. 5. Export test ldif file using Offline export (db2ldif).
  204. 6. Cleanup - Import the Example LDIF for the other tests in this suite
  205. :expectedresults:
  206. 1. Test ldif file creation should PASS.
  207. 2. Online import should PASS.
  208. 3. Offline import should PASS.
  209. 4. Online export should PASS.
  210. 5. Offline export should PASS.
  211. 6. Cleanup should PASS.
  212. """
  213. log.info('Running test_basic_import_export...')
  214. #
  215. # Test online/offline LDIF imports
  216. #
  217. topology_st.standalone.start()
  218. # Generate a test ldif (50k entries)
  219. log.info("Generating LDIF...")
  220. ldif_dir = topology_st.standalone.get_ldif_dir()
  221. import_ldif = ldif_dir + '/basic_import.ldif'
  222. dbgen_users(topology_st.standalone, 50000, import_ldif, DEFAULT_SUFFIX)
  223. # Online
  224. log.info("Importing LDIF online...")
  225. import_task = ImportTask(topology_st.standalone)
  226. import_task.import_suffix_from_ldif(ldiffile=import_ldif, suffix=DEFAULT_SUFFIX)
  227. # Wait a bit till the task is created and available for searching
  228. time.sleep(0.5)
  229. # Good as place as any to quick test the task has some expected attributes
  230. if ds_is_newer('1.4.1.2'):
  231. assert import_task.present('nstaskcreated')
  232. assert import_task.present('nstasklog')
  233. assert import_task.present('nstaskcurrentitem')
  234. assert import_task.present('nstasktotalitems')
  235. assert import_task.present('ttl')
  236. import_task.wait()
  237. # Offline
  238. log.info("Importing LDIF offline...")
  239. topology_st.standalone.stop()
  240. if not topology_st.standalone.ldif2db(DEFAULT_BENAME, None, None, None, import_ldif):
  241. log.fatal('test_basic_import_export: Offline import failed')
  242. assert False
  243. topology_st.standalone.start()
  244. #
  245. # Test online and offline LDIF export
  246. #
  247. # Online export
  248. log.info("Exporting LDIF online...")
  249. export_ldif = ldif_dir + '/export.ldif'
  250. export_task = ExportTask(topology_st.standalone)
  251. export_task.export_suffix_to_ldif(ldiffile=export_ldif, suffix=DEFAULT_SUFFIX)
  252. export_task.wait()
  253. # Offline export
  254. log.info("Exporting LDIF offline...")
  255. topology_st.standalone.stop()
  256. if not topology_st.standalone.db2ldif(DEFAULT_BENAME, (DEFAULT_SUFFIX,),
  257. None, None, None, export_ldif):
  258. log.fatal('test_basic_import_export: Failed to run offline db2ldif')
  259. assert False
  260. topology_st.standalone.start()
  261. #
  262. # Cleanup - Import the Example LDIF for the other tests in this suite
  263. #
  264. log.info("Restore datrabase, import initial LDIF...")
  265. ldif = '%s/dirsrv/data/Example.ldif' % topology_st.standalone.get_data_dir()
  266. import_ldif = topology_st.standalone.get_ldif_dir() + "/Example.ldif"
  267. shutil.copyfile(ldif, import_ldif)
  268. import_task = ImportTask(topology_st.standalone)
  269. import_task.import_suffix_from_ldif(ldiffile=import_ldif, suffix=DEFAULT_SUFFIX)
  270. import_task.wait()
  271. log.info('test_basic_import_export: PASSED')
  272. def test_basic_backup(topology_st, import_example_ldif):
  273. """Tests online and offline backup and restore
  274. :id: 0e9d91f8-8748-40b6-ab03-fbd1998eb985
  275. :setup: Standalone instance and import example.ldif
  276. :steps:
  277. 1. Test online backup using db2bak.
  278. 2. Test online restore using bak2db.
  279. 3. Test offline backup using db2bak.
  280. 4. Test offline restore using bak2db.
  281. :expectedresults:
  282. 1. Online backup should PASS.
  283. 2. Online restore should PASS.
  284. 3. Offline backup should PASS.
  285. 4. Offline restore should PASS.
  286. """
  287. log.info('Running test_basic_backup...')
  288. backup_dir = topology_st.standalone.get_bak_dir() + '/backup_test'
  289. # Test online backup
  290. try:
  291. topology_st.standalone.tasks.db2bak(backup_dir=backup_dir,
  292. args={TASK_WAIT: True})
  293. except ValueError:
  294. log.fatal('test_basic_backup: Online backup failed')
  295. assert False
  296. # Test online restore
  297. try:
  298. topology_st.standalone.tasks.bak2db(backup_dir=backup_dir,
  299. args={TASK_WAIT: True})
  300. except ValueError:
  301. log.fatal('test_basic_backup: Online restore failed')
  302. assert False
  303. # Test offline backup
  304. topology_st.standalone.stop()
  305. if not topology_st.standalone.db2bak(backup_dir):
  306. log.fatal('test_basic_backup: Offline backup failed')
  307. assert False
  308. # Test offline restore
  309. if not topology_st.standalone.bak2db(backup_dir):
  310. log.fatal('test_basic_backup: Offline backup failed')
  311. assert False
  312. topology_st.standalone.start()
  313. log.info('test_basic_backup: PASSED')
  314. def test_basic_db2index(topology_st, import_example_ldif):
  315. """Assert db2index can operate correctly.
  316. :id: 191fc0fd-9722-46b5-a7c3-e8760effe119
  317. :setup: Standalone instance
  318. :steps:
  319. 1: call db2index
  320. :expectedresults:
  321. 1: Index succeeds.
  322. """
  323. topology_st.standalone.stop()
  324. topology_st.standalone.db2index()
  325. topology_st.standalone.db2index(suffixes=[DEFAULT_SUFFIX], attrs=['uid'])
  326. topology_st.standalone.start()
  327. def test_basic_acl(topology_st, import_example_ldif):
  328. """Run some basic access control (ACL) tests
  329. :id: 4f4e705f-32f4-4065-b3a8-2b0c2525798b
  330. :setup: Standalone instance
  331. :steps:
  332. 1. Add two test users USER1_DN and USER2_DN.
  333. 2. Add an aci that denies USER1 from doing anything.
  334. 3. Set the default anonymous access for USER2.
  335. 4. Try searching entries using USER1.
  336. 5. Try searching entries using USER2.
  337. 6. Try searching entries using root dn.
  338. 7. Cleanup - delete test users and test ACI.
  339. :expectedresults:
  340. 1. Test Users should be added.
  341. 2. ACI should be added.
  342. 3. This operation should PASS.
  343. 4. USER1 should not be able to search anything.
  344. 5. USER2 should be able to search everything except password.
  345. 6. RootDN should be allowed to search everything.
  346. 7. Cleanup should PASS.
  347. """
  348. """Run some basic access control(ACL) tests"""
  349. log.info('Running test_basic_acl...')
  350. DENY_ACI = ensure_bytes('(targetattr = "*")(version 3.0;acl "deny user";deny (all)(userdn = "ldap:///%s");)' % USER1_DN)
  351. #
  352. # Add two users
  353. #
  354. try:
  355. topology_st.standalone.add_s(Entry((USER1_DN,
  356. {'objectclass': "top extensibleObject".split(),
  357. 'sn': '1',
  358. 'cn': 'user 1',
  359. 'uid': 'user1',
  360. 'userpassword': PASSWORD})))
  361. except ldap.LDAPError as e:
  362. log.fatal('test_basic_acl: Failed to add test user ' + USER1_DN +
  363. ': error ' + e.args[0]['desc'])
  364. assert False
  365. try:
  366. topology_st.standalone.add_s(Entry((USER2_DN,
  367. {'objectclass': "top extensibleObject".split(),
  368. 'sn': '2',
  369. 'cn': 'user 2',
  370. 'uid': 'user2',
  371. 'userpassword': PASSWORD})))
  372. except ldap.LDAPError as e:
  373. log.fatal('test_basic_acl: Failed to add test user ' + USER1_DN +
  374. ': error ' + e.args[0]['desc'])
  375. assert False
  376. #
  377. # Add an aci that denies USER1 from doing anything,
  378. # and also set the default anonymous access
  379. #
  380. try:
  381. topology_st.standalone.modify_s(DEFAULT_SUFFIX, [(ldap.MOD_ADD, 'aci', DENY_ACI)])
  382. except ldap.LDAPError as e:
  383. log.fatal('test_basic_acl: Failed to add DENY ACI: error ' + e.args[0]['desc'])
  384. assert False
  385. #
  386. # Make sure USER1_DN can not search anything, but USER2_dn can...
  387. #
  388. try:
  389. topology_st.standalone.simple_bind_s(USER1_DN, PASSWORD)
  390. except ldap.LDAPError as e:
  391. log.fatal('test_basic_acl: Failed to bind as user1, error: ' + e.args[0]['desc'])
  392. assert False
  393. try:
  394. entries = topology_st.standalone.search_s(DEFAULT_SUFFIX,
  395. ldap.SCOPE_SUBTREE,
  396. '(uid=*)')
  397. if entries:
  398. log.fatal('test_basic_acl: User1 was incorrectly able to search the suffix!')
  399. assert False
  400. except ldap.LDAPError as e:
  401. log.fatal('test_basic_acl: Search suffix failed(as user1): ' + e.args[0]['desc'])
  402. assert False
  403. # Now try user2... Also check that userpassword is stripped out
  404. try:
  405. topology_st.standalone.simple_bind_s(USER2_DN, PASSWORD)
  406. except ldap.LDAPError as e:
  407. log.fatal('test_basic_acl: Failed to bind as user2, error: ' + e.args[0]['desc'])
  408. assert False
  409. try:
  410. entries = topology_st.standalone.search_s(DEFAULT_SUFFIX,
  411. ldap.SCOPE_SUBTREE,
  412. '(uid=user1)')
  413. if not entries:
  414. log.fatal('test_basic_acl: User1 incorrectly not able to search the suffix')
  415. assert False
  416. if entries[0].hasAttr('userpassword'):
  417. # The default anonymous access aci should have stripped out userpassword
  418. log.fatal('test_basic_acl: User2 was incorrectly able to see userpassword')
  419. assert False
  420. except ldap.LDAPError as e:
  421. log.fatal('test_basic_acl: Search for user1 failed(as user2): ' + e.args[0]['desc'])
  422. assert False
  423. # Make sure RootDN can also search (this also resets the bind dn to the
  424. # Root DN for future operations)
  425. try:
  426. topology_st.standalone.simple_bind_s(DN_DM, PW_DM)
  427. except ldap.LDAPError as e:
  428. log.fatal('test_basic_acl: Failed to bind as ROotDN, error: ' + e.args[0]['desc'])
  429. assert False
  430. try:
  431. entries = topology_st.standalone.search_s(DEFAULT_SUFFIX,
  432. ldap.SCOPE_SUBTREE,
  433. '(uid=*)')
  434. if not entries:
  435. log.fatal('test_basic_acl: Root DN incorrectly not able to search the suffix')
  436. assert False
  437. except ldap.LDAPError as e:
  438. log.fatal('test_basic_acl: Search for user1 failed(as user2): ' + e.args[0]['desc'])
  439. assert False
  440. #
  441. # Cleanup
  442. #
  443. try:
  444. topology_st.standalone.modify_s(DEFAULT_SUFFIX, [(ldap.MOD_DELETE, 'aci', DENY_ACI)])
  445. except ldap.LDAPError as e:
  446. log.fatal('test_basic_acl: Failed to delete DENY ACI: error ' + e.args[0]['desc'])
  447. assert False
  448. try:
  449. topology_st.standalone.delete_s(USER1_DN)
  450. except ldap.LDAPError as e:
  451. log.fatal('test_basic_acl: Failed to delete test entry1: ' + e.args[0]['desc'])
  452. assert False
  453. try:
  454. topology_st.standalone.delete_s(USER2_DN)
  455. except ldap.LDAPError as e:
  456. log.fatal('test_basic_acl: Failed to delete test entry2: ' + e.args[0]['desc'])
  457. assert False
  458. log.info('test_basic_acl: PASSED')
  459. def test_basic_searches(topology_st, import_example_ldif):
  460. """Tests basic search operations with filters.
  461. :id: 426a59ff-49b8-4a70-b377-0c0634a29b6f
  462. :setup: Standalone instance, add example.ldif to the database
  463. :steps:
  464. 1. Execute search command while using different filters.
  465. 2. Check number of entries returned by search filters.
  466. :expectedresults:
  467. 1. Search command should PASS.
  468. 2. Number of result entries returned should match number of the database entries according to the search filter.
  469. """
  470. log.info('Running test_basic_searches...')
  471. filters = (('(uid=scarter)', 1),
  472. ('(uid=tmorris*)', 1),
  473. ('(uid=*hunt*)', 4),
  474. ('(uid=*cope)', 2),
  475. ('(mail=*)', 150),
  476. ('(roomnumber>=4000)', 35),
  477. ('(roomnumber<=4000)', 115),
  478. ('(&(roomnumber>=4000)(roomnumber<=4500))', 18),
  479. ('(!(l=sunnyvale))', 120),
  480. ('(&(uid=t*)(l=santa clara))', 7),
  481. ('(|(uid=k*)(uid=r*))', 18),
  482. ('(|(uid=t*)(l=sunnyvale))', 50),
  483. ('(&(!(uid=r*))(ou=people))', 139),
  484. ('(&(uid=m*)(l=sunnyvale)(ou=people)(mail=*example*)(roomNumber=*))', 3),
  485. ('(&(|(uid=m*)(l=santa clara))(roomNumber=22*))', 5),
  486. ('(&(|(uid=m*)(l=santa clara))(roomNumber=22*)(!(roomnumber=2254)))', 4),)
  487. for (search_filter, search_result) in filters:
  488. try:
  489. entries = topology_st.standalone.search_s(DEFAULT_SUFFIX,
  490. ldap.SCOPE_SUBTREE,
  491. search_filter)
  492. if len(entries) != search_result:
  493. log.fatal('test_basic_searches: An incorrect number of entries\
  494. was returned from filter (%s): (%d) expected (%d)' %
  495. (search_filter, len(entries), search_result))
  496. assert False
  497. except ldap.LDAPError as e:
  498. log.fatal('Search failed: ' + e.args[0]['desc'])
  499. assert False
  500. log.info('test_basic_searches: PASSED')
  501. @pytest.fixture(scope="module")
  502. def add_test_entry(topology_st, request):
  503. # Add test entry
  504. topology_st.standalone.add_s(Entry((USER4_DN,
  505. {'objectclass': "top extensibleObject".split(),
  506. 'cn': 'user1', 'uid': 'user1'})))
  507. search_params = [(['1.1'], 'cn', False),
  508. (['1.1', 'cn'], 'cn', True),
  509. (['+'], 'nsUniqueId', True),
  510. (['*'], 'cn', True),
  511. (['cn'], 'cn', True)]
  512. @pytest.mark.skipif(ds_is_older("1.4.2.0"), reason="Not implemented")
  513. @pytest.mark.parametrize("attrs, attr, present", search_params)
  514. def test_search_req_attrs(topology_st, add_test_entry, attrs, attr, present):
  515. """Test requested attributes in search operations.
  516. :id: 426a59ff-49b8-4a70-b377-0c0634a29b6e
  517. :parametrized: yes
  518. :setup: Standalone instance
  519. :steps:
  520. 1. Test "1.1" does not return any attributes.
  521. 2. Test "1.1" is ignored if there are other requested attributes
  522. 3. Test "+" returns all operational attributes
  523. 4. Test "*" returns all attributes
  524. 5. Test requested attributes
  525. :expectedresults:
  526. 1. Success
  527. 2. Success
  528. 3. Success
  529. 4. Success
  530. 5. Success
  531. """
  532. log.info("Testing attrs: {} attr: {} present: {}".format(attrs, attr, present))
  533. entry = topology_st.standalone.search_s(USER4_DN,
  534. ldap.SCOPE_BASE,
  535. 'objectclass=top',
  536. attrs)
  537. if present:
  538. assert entry[0].hasAttr(attr)
  539. else:
  540. assert not entry[0].hasAttr(attr)
  541. def test_basic_referrals(topology_st, import_example_ldif):
  542. """Test LDAP server in referral mode.
  543. :id: c586aede-7ac3-4e8d-a1cf-bfa8b8d78cc2
  544. :setup: Standalone instance
  545. :steps:
  546. 1. Set the referral and the backend state
  547. 2. Set backend state to referral mode.
  548. 3. Set server to not follow referral.
  549. 4. Search using referral.
  550. 5. Make sure server can restart in referral mode.
  551. 6. Cleanup - Delete referral.
  552. :expectedresults:
  553. 1. Set the referral, and the backend state should PASS.
  554. 2. Set backend state to referral mode should PASS.
  555. 3. Set server to not follow referral should PASS.
  556. 4. referral error(10) should occur.
  557. 5. Restart should PASS.
  558. 6. Cleanup should PASS.
  559. """
  560. log.info('Running test_basic_referrals...')
  561. SUFFIX_CONFIG = 'cn="dc=example,dc=com",cn=mapping tree,cn=config'
  562. #
  563. # Set the referral, and the backend state
  564. #
  565. try:
  566. topology_st.standalone.modify_s(SUFFIX_CONFIG,
  567. [(ldap.MOD_REPLACE,
  568. 'nsslapd-referral',
  569. b'ldap://localhost.localdomain:389/o%3dnetscaperoot')])
  570. except ldap.LDAPError as e:
  571. log.fatal('test_basic_referrals: Failed to set referral: error ' + e.args[0]['desc'])
  572. assert False
  573. try:
  574. topology_st.standalone.modify_s(SUFFIX_CONFIG, [(ldap.MOD_REPLACE,
  575. 'nsslapd-state', b'Referral')])
  576. except ldap.LDAPError as e:
  577. log.fatal('test_basic_referrals: Failed to set backend state: error '
  578. + e.args[0]['desc'])
  579. assert False
  580. #
  581. # Test that a referral error is returned
  582. #
  583. topology_st.standalone.set_option(ldap.OPT_REFERRALS, 0) # Do not follow referral
  584. try:
  585. topology_st.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, 'objectclass=top')
  586. except ldap.REFERRAL:
  587. pass
  588. except ldap.LDAPError as e:
  589. log.fatal('test_basic_referrals: Search failed: ' + e.args[0]['desc'])
  590. assert False
  591. #
  592. # Make sure server can restart in referral mode
  593. #
  594. topology_st.standalone.restart(timeout=10)
  595. #
  596. # Cleanup
  597. #
  598. try:
  599. topology_st.standalone.modify_s(SUFFIX_CONFIG, [(ldap.MOD_REPLACE,
  600. 'nsslapd-state', b'Backend')])
  601. except ldap.LDAPError as e:
  602. log.fatal('test_basic_referrals: Failed to set backend state: error '
  603. + e.args[0]['desc'])
  604. assert False
  605. try:
  606. topology_st.standalone.modify_s(SUFFIX_CONFIG, [(ldap.MOD_DELETE,
  607. 'nsslapd-referral', None)])
  608. except ldap.LDAPError as e:
  609. log.fatal('test_basic_referrals: Failed to delete referral: error '
  610. + e.args[0]['desc'])
  611. assert False
  612. topology_st.standalone.set_option(ldap.OPT_REFERRALS, 1)
  613. log.info('test_basic_referrals: PASSED')
  614. def test_basic_systemctl(topology_st, import_example_ldif):
  615. """Tests systemctl/lib389 can stop and start the server.
  616. :id: a92a7438-ecfa-4583-a89c-5fbfc0220b69
  617. :setup: Standalone instance
  618. :steps:
  619. 1. Stop the server.
  620. 2. Start the server.
  621. 3. Stop the server, break the dse.ldif and dse.ldif.bak, so a start fails.
  622. 4. Verify that systemctl detects the failed start.
  623. 5. Fix the dse.ldif, and make sure the server starts up.
  624. 6. Verify systemctl correctly identifies the successful start.
  625. :expectedresults:
  626. 1. Server should be stopped.
  627. 2. Server should start
  628. 3. Stop should work but start after breaking dse.ldif should fail.
  629. 4. Systemctl should be able to detect the failed start.
  630. 5. Server should start.
  631. 6. Systemctl should be able to detect the successful start.
  632. """
  633. log.info('Running test_basic_systemctl...')
  634. config_dir = topology_st.standalone.get_config_dir()
  635. #
  636. # Stop the server
  637. #
  638. log.info('Stopping the server...')
  639. topology_st.standalone.stop()
  640. log.info('Stopped the server.')
  641. #
  642. # Start the server
  643. #
  644. log.info('Starting the server...')
  645. topology_st.standalone.start()
  646. log.info('Started the server.')
  647. #
  648. # Stop the server, break the dse.ldif so a start fails,
  649. # and verify that systemctl detects the failed start
  650. #
  651. log.info('Stopping the server...')
  652. topology_st.standalone.stop()
  653. log.info('Stopped the server before breaking the dse.ldif.')
  654. shutil.copy(config_dir + '/dse.ldif', config_dir + '/dse.ldif.correct')
  655. open(config_dir + '/dse.ldif', 'w').close()
  656. # We need to kill the .bak file too, DS is just too smart!
  657. open(config_dir + '/dse.ldif.bak', 'w').close()
  658. log.info('Attempting to start the server with broken dse.ldif...')
  659. try:
  660. topology_st.standalone.start()
  661. except Exception as e:
  662. log.info('Server failed to start as expected: ' + str(e))
  663. log.info('Check the status...')
  664. assert (not topology_st.standalone.status())
  665. log.info('Server failed to start as expected')
  666. time.sleep(5)
  667. #
  668. # Fix the dse.ldif, and make sure the server starts up,
  669. # and systemctl correctly identifies the successful start
  670. #
  671. shutil.copy(config_dir + '/dse.ldif.correct', config_dir + '/dse.ldif')
  672. log.info('Starting the server with good dse.ldif...')
  673. topology_st.standalone.start()
  674. log.info('Check the status...')
  675. assert (topology_st.standalone.status())
  676. log.info('Server started after fixing dse.ldif.')
  677. log.info('test_basic_systemctl: PASSED')
  678. def test_basic_ldapagent(topology_st, import_example_ldif):
  679. """Tests that the ldap agent starts
  680. :id: da1d1846-8fc4-4b8c-8e53-4c9c16eff1ba
  681. :setup: Standalone instance
  682. :steps:
  683. 1. Start SNMP ldap agent using command.
  684. 2. Cleanup - Kill SNMP agent process.
  685. :expectedresults:
  686. 1. SNMP agent should start.
  687. 2. SNMP agent process should be successfully killed.
  688. """
  689. log.info('Running test_basic_ldapagent...')
  690. var_dir = topology_st.standalone.get_local_state_dir()
  691. config_file = os.path.join(topology_st.standalone.get_sysconf_dir(), 'dirsrv/config/agent.conf')
  692. agent_config_file = open(config_file, 'w')
  693. agent_config_file.write('agentx-master ' + var_dir + '/agentx/master\n')
  694. agent_config_file.write('agent-logdir ' + var_dir + '/log/dirsrv\n')
  695. agent_config_file.write('server slapd-' + topology_st.standalone.serverid + '\n')
  696. agent_config_file.close()
  697. # Remember, this is *forking*
  698. check_output([os.path.join(topology_st.standalone.get_sbin_dir(), 'ldap-agent'), config_file])
  699. # First kill any previous agents ....
  700. pidpath = os.path.join(var_dir, 'run/ldap-agent.pid')
  701. pid = None
  702. with open(pidpath, 'r') as pf:
  703. pid = pf.readlines()[0].strip()
  704. if pid:
  705. log.debug('test_basic_ldapagent: Terminating agent %s', pid)
  706. check_output(['kill', pid])
  707. log.info('test_basic_ldapagent: PASSED')
  708. @pytest.mark.skipif(not get_user_is_ds_owner(),
  709. reason="process ownership permission is required")
  710. def test_basic_dse_survives_kill9(topology_st, import_example_ldif):
  711. """Tests that the dse.ldif is not wiped out after the process is killed (bug 910581)
  712. :id: 10f141da-9b22-443a-885c-87271dcd7a59
  713. :setup: Standalone instance
  714. :steps:
  715. 1. Check out pid of ns-slapd process and Kill ns-slapd process.
  716. 2. Check the contents of dse.ldif file.
  717. 3. Start server.
  718. :expectedresults:
  719. 1. ns-slapd process should be killed.
  720. 2. dse.ldif should not be corrupted.
  721. 3. Server should start successfully.
  722. """
  723. log.info('Running test_basic_dse...')
  724. dse_file = topology_st.standalone.confdir + '/dse.ldif'
  725. pid = check_output(['pidof', '-s', 'ns-slapd']).strip()
  726. # We can't guarantee we have access to sudo in any environment ... Either
  727. # run py.test with sudo, or as the same user as the dirsrv.
  728. check_output(['kill', '-9', ensure_str(pid)])
  729. if os.path.getsize(dse_file) == 0:
  730. log.fatal('test_basic_dse: dse.ldif\'s content was incorrectly removed!')
  731. assert False
  732. topology_st.standalone.start(timeout=60)
  733. log.info('dse.ldif was not corrupted, and the server was restarted')
  734. log.info('test_basic_dse: PASSED')
  735. # Give the server time to startup, in some conditions this can be racey without systemd notification. Only affects this one test though...
  736. time.sleep(10)
  737. @pytest.mark.parametrize("rootdse_attr_name", ROOTDSE_DEF_ATTR_LIST)
  738. def test_def_rootdse_attr(topology_st, import_example_ldif, rootdse_attr_name):
  739. """Tests that operational attributes are not returned by default in rootDSE searches
  740. :id: 4fee33cc-4019-4c27-89e8-998e6c770dc0
  741. :parametrized: yes
  742. :setup: Standalone instance
  743. :steps:
  744. 1. Make an ldapsearch for rootdse attribute
  745. 2. Check the returned entries.
  746. :expectedresults:
  747. 1. Search should not fail
  748. 2. Operational attributes should not be returned.
  749. """
  750. topology_st.standalone.start()
  751. log.info(" Assert rootdse search hasn't %s attr" % rootdse_attr_name)
  752. try:
  753. entry = topology_st.standalone.search_s("", ldap.SCOPE_BASE)[0]
  754. assert not entry.hasAttr(rootdse_attr_name)
  755. except ldap.LDAPError as e:
  756. log.fatal('Search failed, error: ' + e.args[0]['desc'])
  757. assert False
  758. def test_mod_def_rootdse_attr(topology_st, import_example_ldif, rootdse_attr):
  759. """Tests that operational attributes are returned by default in rootDSE searches after config modification
  760. :id: c7831e04-f458-4e23-83c7-b6f66109f639
  761. :parametrized: yes
  762. :setup: Standalone instance and we are using rootdse_attr fixture which
  763. adds nsslapd-return-default-opattr attr with value of one operation attribute.
  764. :steps:
  765. 1. Make an ldapsearch for rootdse attribute
  766. 2. Check the returned entries.
  767. :expectedresults:
  768. 1. Search should not fail
  769. 2. Operational attributes should be returned after the config modification
  770. """
  771. log.info(" Assert rootdse search has %s attr" % rootdse_attr)
  772. try:
  773. entry = topology_st.standalone.search_s("", ldap.SCOPE_BASE)[0]
  774. assert entry.hasAttr(rootdse_attr)
  775. except ldap.LDAPError as e:
  776. log.fatal('Search failed, error: ' + e.args[0]['desc'])
  777. assert False
  778. @pytest.fixture(scope="module")
  779. def create_users(topology_st):
  780. """Add users to the default suffix
  781. """
  782. users = UserAccounts(topology_st.standalone, DEFAULT_SUFFIX)
  783. user_names = ["Directory", "Server", "389", "lib389", "pytest"]
  784. log.info('Adding 5 test users')
  785. for name in user_names:
  786. users.create(properties={
  787. 'uid': name,
  788. 'sn': name,
  789. 'cn': name,
  790. 'uidNumber': '1000',
  791. 'gidNumber': '1000',
  792. 'homeDirectory': '/home/%s' % name,
  793. 'mail': '%[email protected]' % name,
  794. 'userpassword': 'pass%s' % name,
  795. })
  796. def test_basic_anonymous_search(topology_st, create_users):
  797. """Tests basic anonymous search operations
  798. :id: c7831e04-f458-4e50-83c7-b6f77109f639
  799. :setup: Standalone instance
  800. Add 5 test users with different user names
  801. :steps:
  802. 1. Execute anonymous search with different filters
  803. :expectedresults:
  804. 1. Search should be successful
  805. """
  806. filters = ["uid=Directory", "(|(uid=S*)(uid=3*))", "(&(uid=l*)(mail=l*))", "(&(!(uid=D*))(ou=People))"]
  807. log.info("Execute anonymous search with different filters")
  808. for filtr in filters:
  809. entries = topology_st.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, filtr)
  810. assert len(entries) != 0
  811. @pytest.mark.ds604
  812. @pytest.mark.bz915801
  813. def test_search_original_type(topology_st, create_users):
  814. """Test ldapsearch returning original attributes
  815. using nsslapd-search-return-original-type-switch
  816. :id: d7831d04-f558-4e50-93c7-b6f77109f640
  817. :setup: Standalone instance
  818. Add some test entries
  819. :steps:
  820. 1. Set nsslapd-search-return-original-type-switch to ON
  821. 2. Check that ldapsearch *does* return unknown attributes
  822. 3. Turn off nsslapd-search-return-original-type-switch
  823. 4. Check that ldapsearch doesn't return any unknown attributes
  824. :expectedresults:
  825. 1. nsslapd-search-return-original-type-switch should be set to ON
  826. 2. ldapsearch should return unknown attributes
  827. 3. nsslapd-search-return-original-type-switch should be OFF
  828. 4. ldapsearch should not return any unknown attributes
  829. """
  830. log.info("Set nsslapd-search-return-original-type-switch to ON")
  831. topology_st.standalone.config.set('nsslapd-search-return-original-type-switch', 'on')
  832. log.info("Check that ldapsearch *does* return unknown attributes")
  833. entries = topology_st.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, 'uid=Directory',
  834. ['objectclass overflow', 'unknown'])
  835. assert "objectclass overflow" in entries[0].getAttrs()
  836. log.info("Set nsslapd-search-return-original-type-switch to Off")
  837. topology_st.standalone.config.set('nsslapd-search-return-original-type-switch', 'off')
  838. log.info("Check that ldapsearch *does not* return unknown attributes")
  839. entries = topology_st.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, 'uid=Directory',
  840. ['objectclass overflow', 'unknown'])
  841. assert "objectclass overflow" not in entries[0].getAttrs()
  842. @pytest.mark.bz192901
  843. def test_search_ou(topology_st):
  844. """Test that DS should not return an entry that does not match the filter
  845. :id: d7831d05-f117-4e89-93c7-b6f77109f640
  846. :setup: Standalone instance
  847. :steps:
  848. 1. Create an OU entry without sub entries
  849. 2. Search from the OU with the filter that does not match the OU
  850. :expectedresults:
  851. 1. Creation of OU should be successful
  852. 2. Search should not return any results
  853. """
  854. log.info("Create a test OU without sub entries")
  855. ou = OrganizationalUnits(topology_st.standalone, DEFAULT_SUFFIX)
  856. ou.create(properties={
  857. 'ou': 'test_ou',
  858. })
  859. search_base = ("ou=test_ou,%s" % DEFAULT_SUFFIX)
  860. log.info("Search from the OU with the filter that does not match the OU, it should not return anything")
  861. entries = topology_st.standalone.search_s(search_base, ldap.SCOPE_SUBTREE, 'uid=*', ['dn'])
  862. assert len(entries) == 0
  863. @pytest.mark.bz1044135
  864. @pytest.mark.ds47319
  865. def test_connection_buffer_size(topology_st):
  866. """Test connection buffer size adjustable with different values(valid values and invalid)
  867. :id: e7831d05-f117-4ec9-1203-b6f77109f117
  868. :setup: Standalone instance
  869. :steps:
  870. 1. Set nsslapd-connection-buffer to some valid values (2, 0 , 1)
  871. 2. Set nsslapd-connection-buffer to some invalid values (-1, a)
  872. :expectedresults:
  873. 1. This should pass
  874. 2. This should fail
  875. """
  876. valid_values = ['2', '0', '1']
  877. for value in valid_values:
  878. topology_st.standalone.config.replace('nsslapd-connection-buffer', value)
  879. invalid_values = ['-1', 'a']
  880. for value in invalid_values:
  881. with pytest.raises(ldap.OPERATIONS_ERROR):
  882. topology_st.standalone.config.replace('nsslapd-connection-buffer', value)
  883. @pytest.mark.bz1637439
  884. def test_critical_msg_on_empty_range_idl(topology_st):
  885. """Doing a range index lookup should not report a critical message even if IDL is empty
  886. :id: a07a2222-0551-44a6-b113-401d23799364
  887. :setup: Standalone instance
  888. :steps:
  889. 1. Create an index for internationalISDNNumber. (attribute chosen because it is
  890. unlikely that previous tests used it)
  891. 2. telephoneNumber being indexed by default create 20 users without telephoneNumber
  892. 3. add a telephoneNumber value and delete it to trigger an empty index database
  893. 4. Do a search that triggers a range lookup on empty telephoneNumber
  894. 5. Check that the critical message is not logged in error logs
  895. :expectedresults:
  896. 1. This should pass
  897. 2. This should pass
  898. 3. This should pass
  899. 4. This should pass on normal build but could abort a debug build
  900. 4. This should pass
  901. """
  902. indexedAttr = 'internationalISDNNumber'
  903. # Step 1
  904. from lib389.index import Indexes
  905. indexes = Indexes(topology_st.standalone)
  906. indexes.create(properties={
  907. 'cn': indexedAttr,
  908. 'nsSystemIndex': 'false',
  909. 'nsIndexType': 'eq'
  910. })
  911. topology_st.standalone.restart()
  912. # Step 2
  913. users = UserAccounts(topology_st.standalone, DEFAULT_SUFFIX)
  914. log.info('Adding 20 users without "%s"' % indexedAttr)
  915. for i in range(20):
  916. name = 'user_%d' % i
  917. last_user = users.create(properties={
  918. 'uid': name,
  919. 'sn': name,
  920. 'cn': name,
  921. 'uidNumber': '1000',
  922. 'gidNumber': '1000',
  923. 'homeDirectory': '/home/%s' % name,
  924. 'mail': '%[email protected]' % name,
  925. 'userpassword': 'pass%s' % name,
  926. })
  927. # Step 3
  928. # required update to create the indexAttr (i.e. 'loginShell') database, and then make it empty
  929. topology_st.standalone.modify_s(last_user.dn, [(ldap.MOD_ADD, indexedAttr, b'1234')])
  930. ent = topology_st.standalone.getEntry(last_user.dn, ldap.SCOPE_BASE,)
  931. assert ent
  932. assert ent.hasAttr(indexedAttr)
  933. topology_st.standalone.modify_s(last_user.dn, [(ldap.MOD_DELETE, indexedAttr, None)])
  934. ent = topology_st.standalone.getEntry(last_user.dn, ldap.SCOPE_BASE,)
  935. assert ent
  936. assert not ent.hasAttr(indexedAttr)
  937. # Step 4
  938. # The first component being not indexed the range on second is evaluated
  939. try:
  940. ents = topology_st.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(&(sudoNotAfter=*)(%s>=111))' % indexedAttr)
  941. assert len(ents) == 0
  942. except ldap.SERVER_DOWN:
  943. log.error('Likely testing against a debug version that asserted')
  944. pass
  945. # Step 5
  946. assert not topology_st.standalone.searchErrorsLog('CRIT - list_candidates - NULL idl was recieved from filter_candidates_ext.')
  947. @pytest.mark.bz1647099
  948. @pytest.mark.ds50026
  949. def test_ldbm_modification_audit_log(topology_st):
  950. """When updating LDBM config attributes, those attributes/values are not listed
  951. in the audit log
  952. :id: 5bf75c47-a283-430e-a65c-3c5fd8dbadb8
  953. :setup: Standalone Instance
  954. :steps:
  955. 1. Bind as DM
  956. 2. Enable audit log
  957. 3. Update a set of config attrs in LDBM config
  958. 4. Restart the server
  959. 5. Check that config attrs are listed in the audit log
  960. :expectedresults:
  961. 1. Operation successful
  962. 2. Operation successful
  963. 3. Operation successful
  964. 4. Operation successful
  965. 5. Audit log should contain modification of attrs"
  966. """
  967. VALUE = '10001'
  968. d_manager = DirectoryManager(topology_st.standalone)
  969. conn = d_manager.bind()
  970. config_ldbm = LDBMConfig(conn)
  971. log.info("Enable audit logging")
  972. conn.config.enable_log('audit')
  973. attrs = ['nsslapd-lookthroughlimit', 'nsslapd-pagedidlistscanlimit', 'nsslapd-idlistscanlimit', 'nsslapd-db-locks']
  974. for attr in attrs:
  975. log.info("Set attribute %s to value %s" % (attr, VALUE))
  976. config_ldbm.set(attr, VALUE)
  977. log.info('Restart the server to flush the logs')
  978. conn.restart()
  979. for attr in attrs:
  980. log.info("Check if attribute %s is replaced in the audit log" % attr)
  981. assert conn.searchAuditLog('replace: %s' % attr)
  982. assert conn.searchAuditLog('%s: %s' % (attr, VALUE))
  983. @pytest.mark.skipif(not get_user_is_root() or not default_paths.perl_enabled or ds_is_older('1.4.0.0'),
  984. reason="This test is only required if perl is enabled, and requires root.")
  985. def test_dscreate(request):
  986. """Test that dscreate works, we need this for now until setup-ds.pl is
  987. fully discontinued.
  988. :id: 5bf75c47-a283-430e-a65c-3c5fd8dbadb9
  989. :setup: None
  990. :steps:
  991. 1. Create template file for dscreate
  992. 2. Create instance using template file
  993. :expectedresults:
  994. 1. Should succeeds
  995. 2. Should succeeds
  996. """
  997. template_file = "/tmp/dssetup.inf"
  998. template_text = """[general]
  999. config_version = 2
  1000. # This invalid hostname ...
  1001. full_machine_name = localhost.localdomain
  1002. # Means we absolutely require this.
  1003. strict_host_checking = False
  1004. # In tests, we can be run in containers, NEVER trust
  1005. # that systemd is there, or functional in any capacity
  1006. systemd = False
  1007. [slapd]
  1008. instance_name = test_dscreate
  1009. root_dn = cn=directory manager
  1010. root_password = someLongPassword_123
  1011. # We do not have access to high ports in containers,
  1012. # so default to something higher.
  1013. port = 38999
  1014. secure_port = 63699
  1015. [backend-userroot]
  1016. suffix = dc=example,dc=com
  1017. sample_entries = yes
  1018. """
  1019. with open(template_file, "w") as template_fd:
  1020. template_fd.write(template_text)
  1021. # Unset PYTHONPATH to avoid mixing old CLI tools and new lib389
  1022. tmp_env = os.environ
  1023. if "PYTHONPATH" in tmp_env:
  1024. del tmp_env["PYTHONPATH"]
  1025. try:
  1026. subprocess.check_call([
  1027. 'dscreate',
  1028. 'from-file',
  1029. template_file
  1030. ], env=tmp_env)
  1031. except subprocess.CalledProcessError as e:
  1032. log.fatal("dscreate failed! Error ({}) {}".format(e.returncode, e.output))
  1033. assert False
  1034. def fin():
  1035. os.remove(template_file)
  1036. try:
  1037. subprocess.check_call(['dsctl', 'test_dscreate', 'remove', '--do-it'])
  1038. except subprocess.CalledProcessError as e:
  1039. log.fatal("Failed to remove test instance Error ({}) {}".format(e.returncode, e.output))
  1040. request.addfinalizer(fin)
  1041. @pytest.fixture(scope="function")
  1042. def dscreate_long_instance(request):
  1043. template_file = "/tmp/dssetup.inf"
  1044. longname_serverid = "test-longname-deadbeef-deadbeef-deadbeef-deadbeef-deadbeef"
  1045. template_text = """[general]
  1046. config_version = 2
  1047. # This invalid hostname ...
  1048. full_machine_name = localhost.localdomain
  1049. # Means we absolutely require this.
  1050. strict_host_checking = False
  1051. # In tests, we can be run in containers, NEVER trust
  1052. # that systemd is there, or functional in any capacity
  1053. systemd = False
  1054. [slapd]
  1055. instance_name = %s
  1056. root_dn = cn=directory manager
  1057. root_password = someLongPassword_123
  1058. # We do not have access to high ports in containers,
  1059. # so default to something higher.
  1060. port = 38999
  1061. secure_port = 63699
  1062. [backend-userroot]
  1063. suffix = dc=example,dc=com
  1064. sample_entries = yes
  1065. """ % longname_serverid
  1066. with open(template_file, "w") as template_fd:
  1067. template_fd.write(template_text)
  1068. # Unset PYTHONPATH to avoid mixing old CLI tools and new lib389
  1069. tmp_env = os.environ
  1070. if "PYTHONPATH" in tmp_env:
  1071. del tmp_env["PYTHONPATH"]
  1072. try:
  1073. subprocess.check_call([
  1074. 'dscreate',
  1075. 'from-file',
  1076. template_file
  1077. ], env=tmp_env)
  1078. except subprocess.CalledProcessError as e:
  1079. log.fatal("dscreate failed! Error ({}) {}".format(e.returncode, e.output))
  1080. assert False
  1081. inst = DirSrv(verbose=True, external_log=log)
  1082. dse_ldif = DSEldif(inst,
  1083. serverid=longname_serverid)
  1084. socket_path = dse_ldif.get("cn=config", "nsslapd-ldapifilepath")
  1085. inst.local_simple_allocate(
  1086. serverid=longname_serverid,
  1087. ldapuri=f"ldapi://{socket_path[0].replace('/', '%2f')}",
  1088. password="someLongPassword_123"
  1089. )
  1090. inst.ldapi_enabled = 'on'
  1091. inst.ldapi_socket = socket_path
  1092. inst.ldapi_autobind = 'off'
  1093. try:
  1094. inst.open()
  1095. except:
  1096. log.fatal("Failed to connect via ldapi to %s instance" % longname_serverid)
  1097. os.remove(template_file)
  1098. try:
  1099. subprocess.check_call(['dsctl', longname_serverid, 'remove', '--do-it'])
  1100. except subprocess.CalledProcessError as e:
  1101. log.fatal("Failed to remove test instance Error ({}) {}".format(e.returncode, e.output))
  1102. def fin():
  1103. os.remove(template_file)
  1104. try:
  1105. subprocess.check_call(['dsctl', longname_serverid, 'remove', '--do-it'])
  1106. except subprocess.CalledProcessError as e:
  1107. log.fatal("Failed to remove test instance Error ({}) {}".format(e.returncode, e.output))
  1108. request.addfinalizer(fin)
  1109. return inst
  1110. @pytest.mark.skipif(not get_user_is_root() or not default_paths.perl_enabled or ds_is_older('1.4.2.0'),
  1111. reason="This test is only required with new admin cli, and requires root.")
  1112. @pytest.mark.bz1748016
  1113. @pytest.mark.ds50581
  1114. def test_dscreate_ldapi(dscreate_long_instance):
  1115. """Test that an instance with a long name can
  1116. handle ldapi connection using a long socket name
  1117. :id: 5d72d955-aff8-4741-8c9a-32c1c707cf1f
  1118. :setup: None
  1119. :steps:
  1120. 1. create an instance with a long serverId name, that open a ldapi connection
  1121. 2. Connect with ldapi, that hit 50581 and crash the instance
  1122. :expectedresults:
  1123. 1. Should succeeds
  1124. 2. Should succeeds
  1125. """
  1126. root_dse = RootDSE(dscreate_long_instance)
  1127. log.info(root_dse.get_supported_ctrls())
  1128. @pytest.mark.skipif(not get_user_is_root() or not default_paths.perl_enabled or ds_is_older('1.4.2.0'),
  1129. reason="This test is only required with new admin cli, and requires root.")
  1130. @pytest.mark.bz1715406
  1131. @pytest.mark.ds50923
  1132. def test_dscreate_multiple_dashes_name(dscreate_long_instance):
  1133. """Test that an instance with a multiple dashes in the name
  1134. can be removed with dsctl --remove-all
  1135. :id: 265c3ac7-5ba6-4278-b8f4-4e7692afd1a5
  1136. :setup: An instance with a few dashes in its name
  1137. :steps:
  1138. 1. Run 'dsctl --remove-all' command
  1139. 2. Check if the instance exists
  1140. :expectedresults:
  1141. 1. Should succeeds
  1142. 2. Instance doesn't exists
  1143. """
  1144. p = run(['dsctl', '--remove-all'], stdout=PIPE, input='Yes\n', encoding='ascii')
  1145. assert not dscreate_long_instance.exists()
  1146. @pytest.fixture(scope="module", params=('c=uk', 'cn=test_user', 'dc=example,dc=com', 'o=south', 'ou=sales', 'wrong=some_value'))
  1147. def dscreate_test_rdn_value(request):
  1148. template_file = "/tmp/dssetup.inf"
  1149. template_text = f"""[general]
  1150. config_version = 2
  1151. # This invalid hostname ...
  1152. full_machine_name = localhost.localdomain
  1153. # Means we absolutely require this.
  1154. strict_host_checking = False
  1155. # In tests, we can be run in containers, NEVER trust
  1156. # that systemd is there, or functional in any capacity
  1157. systemd = False
  1158. [slapd]
  1159. instance_name = test_different_rdn
  1160. root_dn = cn=directory manager
  1161. root_password = someLongPassword_123
  1162. # We do not have access to high ports in containers,
  1163. # so default to something higher.
  1164. port = 38999
  1165. secure_port = 63699
  1166. [backend-userroot]
  1167. create_suffix_entry = True
  1168. suffix = {request.param}
  1169. """
  1170. with open(template_file, "w") as template_fd:
  1171. template_fd.write(template_text)
  1172. # Unset PYTHONPATH to avoid mixing old CLI tools and new lib389
  1173. tmp_env = os.environ
  1174. if "PYTHONPATH" in tmp_env:
  1175. del tmp_env["PYTHONPATH"]
  1176. def fin():
  1177. os.remove(template_file)
  1178. if request.param != "wrong=some_value":
  1179. try:
  1180. subprocess.check_call(['dsctl', 'test_different_rdn', 'remove', '--do-it'])
  1181. except subprocess.CalledProcessError as e:
  1182. log.fatal(f"Failed to remove test instance Error ({e.returncode}) {e.output}")
  1183. else:
  1184. log.info("Wrong RDN is passed, instance not created")
  1185. request.addfinalizer(fin)
  1186. return template_file, tmp_env, request.param,
  1187. @pytest.mark.skipif(not get_user_is_root() or ds_is_older('1.4.0.0'),
  1188. reason="This test is only required with new admin cli, and requires root.")
  1189. @pytest.mark.bz1807419
  1190. @pytest.mark.ds50928
  1191. def test_dscreate_with_different_rdn(dscreate_test_rdn_value):
  1192. """Test that dscreate works with different RDN attributes as suffix
  1193. :id: 77ed6300-6a2f-4e79-a862-1f1105f1e3ef
  1194. :setup: None
  1195. :steps:
  1196. 1. Create template file for dscreate with different RDN attributes as suffix
  1197. 2. Create instance using template file
  1198. 3. Create instance with 'wrong=some_value' as suffix's RDN attribute
  1199. :expectedresults:
  1200. 1. Should succeeds
  1201. 2. Should succeeds
  1202. 3. Should fail
  1203. """
  1204. try:
  1205. subprocess.check_call([
  1206. 'dscreate',
  1207. 'from-file',
  1208. dscreate_test_rdn_value[0]
  1209. ], env=dscreate_test_rdn_value[1])
  1210. except subprocess.CalledProcessError as e:
  1211. log.fatal(f"dscreate failed! Error ({e.returncode}) {e.output}")
  1212. if dscreate_test_rdn_value[2] != "wrong=some_value":
  1213. assert False
  1214. else:
  1215. assert True
  1216. if __name__ == '__main__':
  1217. # Run isolated
  1218. # -s for DEBUG mode
  1219. CURRENT_FILE = os.path.realpath(__file__)
  1220. pytest.main("-s %s" % CURRENT_FILE)