test_win_dacl.py 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679
  1. # -*- coding: utf-8 -*-
  2. # Import Python Libs
  3. from __future__ import absolute_import, unicode_literals, print_function
  4. import os
  5. import tempfile
  6. # Import Salt Testing Libs
  7. from tests.support.helpers import destructiveTest, generate_random_name, patch
  8. from tests.support.mixins import LoaderModuleMockMixin
  9. from tests.support.unit import TestCase, skipIf
  10. # Import Salt Libs
  11. import salt.utils.platform
  12. import salt.utils.win_dacl as win_dacl
  13. import salt.utils.win_reg as win_reg
  14. try:
  15. import pywintypes
  16. import win32security
  17. HAS_WIN32 = True
  18. except ImportError:
  19. HAS_WIN32 = False
  20. FAKE_KEY = 'SOFTWARE\\{0}'.format(generate_random_name('SaltTesting-'))
  21. @skipIf(not HAS_WIN32, 'Requires pywin32')
  22. @skipIf(not salt.utils.platform.is_windows(), 'System is not Windows')
  23. class WinDaclTestCase(TestCase):
  24. '''
  25. Test cases for salt.utils.win_dacl in the registry
  26. '''
  27. def test_get_sid_string(self):
  28. '''
  29. Validate getting a pysid object from a name
  30. '''
  31. sid_obj = win_dacl.get_sid('Administrators')
  32. self.assertTrue(
  33. isinstance(sid_obj, pywintypes.SIDType))
  34. self.assertEqual(
  35. win32security.LookupAccountSid(None, sid_obj)[0],
  36. 'Administrators')
  37. def test_get_sid_sid_string(self):
  38. '''
  39. Validate getting a pysid object from a SID string
  40. '''
  41. sid_obj = win_dacl.get_sid('S-1-5-32-544')
  42. self.assertTrue(isinstance(sid_obj, pywintypes.SIDType))
  43. self.assertEqual(win32security.LookupAccountSid(None, sid_obj)[0],
  44. 'Administrators')
  45. def test_get_sid_string_name(self):
  46. '''
  47. Validate getting a pysid object from a SID string
  48. '''
  49. sid_obj = win_dacl.get_sid('Administrators')
  50. self.assertTrue(isinstance(sid_obj, pywintypes.SIDType))
  51. self.assertEqual(win_dacl.get_sid_string(sid_obj), 'S-1-5-32-544')
  52. def test_get_sid_string_none(self):
  53. '''
  54. Validate getting a pysid object from None (NULL SID)
  55. '''
  56. sid_obj = win_dacl.get_sid(None)
  57. self.assertTrue(isinstance(sid_obj, pywintypes.SIDType))
  58. self.assertEqual(win_dacl.get_sid_string(sid_obj), 'S-1-0-0')
  59. def test_get_name(self):
  60. '''
  61. Get the name
  62. '''
  63. # Case
  64. self.assertEqual(win_dacl.get_name('adMiniStrAtorS'), 'Administrators')
  65. # SID String
  66. self.assertEqual(win_dacl.get_name('S-1-5-32-544'), 'Administrators')
  67. # SID Object
  68. sid_obj = win_dacl.get_sid('Administrators')
  69. self.assertTrue(isinstance(sid_obj, pywintypes.SIDType))
  70. self.assertEqual(win_dacl.get_name(sid_obj), 'Administrators')
  71. @skipIf(not HAS_WIN32, 'Requires pywin32')
  72. @skipIf(not salt.utils.platform.is_windows(), 'System is not Windows')
  73. class WinDaclRegTestCase(TestCase, LoaderModuleMockMixin):
  74. obj_name = 'HKLM\\' + FAKE_KEY
  75. obj_type = 'registry'
  76. '''
  77. Test cases for salt.utils.win_dacl in the registry
  78. '''
  79. def setup_loader_modules(self):
  80. return {win_dacl: {}}
  81. def setUp(self):
  82. self.assertTrue(win_reg.set_value(hive='HKLM',
  83. key=FAKE_KEY,
  84. vname='fake_name',
  85. vdata='fake_data'))
  86. def tearDown(self):
  87. win_reg.delete_key_recursive(hive='HKLM', key=FAKE_KEY)
  88. @destructiveTest
  89. def test_owner(self):
  90. '''
  91. Test the set_owner function
  92. Test the get_owner function
  93. '''
  94. self.assertTrue(win_dacl.set_owner(obj_name=self.obj_name,
  95. principal='Backup Operators',
  96. obj_type=self.obj_type))
  97. self.assertEqual(win_dacl.get_owner(obj_name=self.obj_name,
  98. obj_type=self.obj_type),
  99. 'Backup Operators')
  100. @destructiveTest
  101. def test_primary_group(self):
  102. '''
  103. Test the set_primary_group function
  104. Test the get_primary_group function
  105. '''
  106. self.assertTrue(win_dacl.set_primary_group(obj_name=self.obj_name,
  107. principal='Backup Operators',
  108. obj_type=self.obj_type))
  109. self.assertEqual(win_dacl.get_primary_group(obj_name=self.obj_name,
  110. obj_type=self.obj_type),
  111. 'Backup Operators')
  112. @destructiveTest
  113. def test_set_permissions(self):
  114. '''
  115. Test the set_permissions function
  116. '''
  117. self.assertTrue(win_dacl.set_permissions(obj_name=self.obj_name,
  118. principal='Backup Operators',
  119. permissions='full_control',
  120. access_mode='grant',
  121. obj_type=self.obj_type,
  122. reset_perms=False,
  123. protected=None))
  124. expected = {
  125. 'Not Inherited': {
  126. 'Backup Operators': {
  127. 'grant': {
  128. 'applies to': 'This key and subkeys',
  129. 'permissions': 'Full Control'}}}}
  130. self.assertEqual(win_dacl.get_permissions(obj_name=self.obj_name,
  131. principal='Backup Operators',
  132. obj_type=self.obj_type),
  133. expected)
  134. @destructiveTest
  135. def test_get_permissions(self):
  136. '''
  137. Test the get_permissions function
  138. '''
  139. self.assertTrue(win_dacl.set_permissions(obj_name=self.obj_name,
  140. principal='Backup Operators',
  141. permissions='full_control',
  142. access_mode='grant',
  143. obj_type=self.obj_type,
  144. reset_perms=False,
  145. protected=None))
  146. expected = {
  147. 'Not Inherited': {
  148. 'Backup Operators': {
  149. 'grant': {
  150. 'applies to': 'This key and subkeys',
  151. 'permissions': 'Full Control'}}}}
  152. self.assertEqual(win_dacl.get_permissions(obj_name=self.obj_name,
  153. principal='Backup Operators',
  154. obj_type=self.obj_type),
  155. expected)
  156. @destructiveTest
  157. def test_has_permission(self):
  158. '''
  159. Test the has_permission function
  160. '''
  161. self.assertTrue(win_dacl.set_permissions(obj_name=self.obj_name,
  162. principal='Backup Operators',
  163. permissions='full_control',
  164. access_mode='grant',
  165. obj_type=self.obj_type,
  166. reset_perms=False,
  167. protected=None))
  168. # Test has_permission exact
  169. self.assertTrue(win_dacl.has_permission(obj_name=self.obj_name,
  170. principal='Backup Operators',
  171. permission='full_control',
  172. access_mode='grant',
  173. obj_type=self.obj_type,
  174. exact=True))
  175. # Test has_permission contains
  176. self.assertTrue(win_dacl.has_permission(obj_name=self.obj_name,
  177. principal='Backup Operators',
  178. permission='read',
  179. access_mode='grant',
  180. obj_type=self.obj_type,
  181. exact=False))
  182. @destructiveTest
  183. def test_rm_permissions(self):
  184. '''
  185. Test the rm_permissions function
  186. '''
  187. self.assertTrue(win_dacl.set_permissions(obj_name=self.obj_name,
  188. principal='Backup Operators',
  189. permissions='full_control',
  190. access_mode='grant',
  191. obj_type=self.obj_type,
  192. reset_perms=False,
  193. protected=None))
  194. self.assertTrue(win_dacl.rm_permissions(obj_name=self.obj_name,
  195. principal='Backup Operators',
  196. obj_type=self.obj_type))
  197. self.assertEqual(win_dacl.get_permissions(obj_name=self.obj_name,
  198. principal='Backup Operators',
  199. obj_type=self.obj_type),
  200. {})
  201. @destructiveTest
  202. def test_inheritance(self):
  203. '''
  204. Test the set_inheritance function
  205. Test the get_inheritance function
  206. '''
  207. self.assertTrue(win_dacl.set_inheritance(obj_name=self.obj_name,
  208. enabled=True,
  209. obj_type=self.obj_type,
  210. clear=False))
  211. self.assertTrue(win_dacl.get_inheritance(obj_name=self.obj_name,
  212. obj_type=self.obj_type))
  213. self.assertTrue(win_dacl.set_inheritance(obj_name=self.obj_name,
  214. enabled=False,
  215. obj_type=self.obj_type,
  216. clear=False))
  217. self.assertFalse(win_dacl.get_inheritance(obj_name=self.obj_name,
  218. obj_type=self.obj_type))
  219. @destructiveTest
  220. def test_check_perms(self):
  221. '''
  222. Test the check_perms function
  223. '''
  224. with patch.dict(win_dacl.__opts__, {"test": False}):
  225. result = win_dacl.check_perms(
  226. obj_name=self.obj_name,
  227. obj_type=self.obj_type,
  228. ret={},
  229. owner='Users',
  230. grant_perms={'Backup Operators': {'perms': 'read'}},
  231. deny_perms={'Backup Operators': {'perms': ['delete']},
  232. 'NETWORK SERVICE': {'perms': ['delete',
  233. 'set_value',
  234. 'write_dac',
  235. 'write_owner']}},
  236. inheritance=True,
  237. reset=False)
  238. expected = {'changes': {'owner': 'Users',
  239. 'perms': {'Backup Operators': {'grant': 'read',
  240. 'deny': ['delete']},
  241. 'NETWORK SERVICE': {'deny': ['delete',
  242. 'set_value',
  243. 'write_dac',
  244. 'write_owner']}}},
  245. 'comment': '',
  246. 'name': self.obj_name,
  247. 'result': True}
  248. self.assertDictEqual(result, expected)
  249. expected = {
  250. 'Not Inherited': {
  251. 'Backup Operators': {
  252. 'grant': {
  253. 'applies to': 'This key and subkeys',
  254. 'permissions': 'Read'},
  255. 'deny': {
  256. 'applies to': 'This key and subkeys',
  257. 'permissions': ['Delete']}}}}
  258. self.assertDictEqual(
  259. win_dacl.get_permissions(
  260. obj_name=self.obj_name,
  261. principal='Backup Operators',
  262. obj_type=self.obj_type),
  263. expected)
  264. expected = {
  265. 'Not Inherited': {
  266. 'NETWORK SERVICE': {
  267. 'deny': {
  268. 'applies to': 'This key and subkeys',
  269. 'permissions': ['Delete',
  270. 'Set Value',
  271. 'Write DAC',
  272. 'Write Owner']}}}}
  273. self.assertDictEqual(
  274. win_dacl.get_permissions(
  275. obj_name=self.obj_name,
  276. principal='NETWORK SERVICE',
  277. obj_type=self.obj_type),
  278. expected)
  279. self.assertEqual(
  280. win_dacl.get_owner(
  281. obj_name=self.obj_name,
  282. obj_type=self.obj_type),
  283. 'Users')
  284. @destructiveTest
  285. def test_check_perms_test_true(self):
  286. '''
  287. Test the check_perms function
  288. '''
  289. with patch.dict(win_dacl.__opts__, {"test": True}):
  290. result = win_dacl.check_perms(
  291. obj_name=self.obj_name,
  292. obj_type=self.obj_type,
  293. ret=None,
  294. owner='Users',
  295. grant_perms={'Backup Operators': {'perms': 'read'}},
  296. deny_perms={'NETWORK SERVICE': {'perms': ['delete',
  297. 'set_value',
  298. 'write_dac',
  299. 'write_owner']},
  300. 'Backup Operators': {'perms': ['delete']}},
  301. inheritance=True,
  302. reset=False)
  303. expected = {
  304. 'changes': {'owner': 'Users',
  305. 'perms': {'Backup Operators': {'grant': 'read',
  306. 'deny': ['delete']},
  307. 'NETWORK SERVICE': {'deny': ['delete',
  308. 'set_value',
  309. 'write_dac',
  310. 'write_owner']}}},
  311. 'comment': '',
  312. 'name': self.obj_name,
  313. 'result': None}
  314. self.assertDictEqual(result, expected)
  315. self.assertNotEqual(
  316. win_dacl.get_owner(
  317. obj_name=self.obj_name,
  318. obj_type=self.obj_type),
  319. 'Users')
  320. self.assertEqual(
  321. win_dacl.get_permissions(
  322. obj_name=self.obj_name,
  323. principal='Backup Operators',
  324. obj_type=self.obj_type),
  325. {})
  326. def test_set_perms(self):
  327. '''
  328. Test the set_perms function
  329. '''
  330. result = win_dacl.set_perms(
  331. obj_name=self.obj_name,
  332. obj_type=self.obj_type,
  333. grant_perms={'Backup Operators': {'perms': 'read'}},
  334. deny_perms={'NETWORK SERVICE': {'perms': ['delete',
  335. 'set_value',
  336. 'write_dac',
  337. 'write_owner']}},
  338. inheritance=True,
  339. reset=False)
  340. expected = {
  341. 'deny': {'NETWORK SERVICE': {'perms': ['delete',
  342. 'set_value',
  343. 'write_dac',
  344. 'write_owner']}},
  345. 'grant': {'Backup Operators': {'perms': 'read'}}}
  346. self.assertDictEqual(result, expected)
  347. @skipIf(not HAS_WIN32, 'Requires pywin32')
  348. @skipIf(not salt.utils.platform.is_windows(), 'System is not Windows')
  349. class WinDaclFileTestCase(TestCase, LoaderModuleMockMixin):
  350. obj_name = ''
  351. obj_type = 'file'
  352. '''
  353. Test cases for salt.utils.win_dacl in the file system
  354. '''
  355. def setup_loader_modules(self):
  356. return {win_dacl: {}}
  357. def setUp(self):
  358. config_file_fd, self.obj_name = tempfile.mkstemp(prefix='SaltTesting-',
  359. suffix='txt')
  360. os.close(config_file_fd)
  361. def tearDown(self):
  362. os.remove(self.obj_name)
  363. @destructiveTest
  364. def test_owner(self):
  365. '''
  366. Test the set_owner function
  367. Test the get_owner function
  368. '''
  369. self.assertTrue(win_dacl.set_owner(obj_name=self.obj_name,
  370. principal='Backup Operators',
  371. obj_type=self.obj_type))
  372. self.assertEqual(win_dacl.get_owner(obj_name=self.obj_name,
  373. obj_type=self.obj_type),
  374. 'Backup Operators')
  375. @destructiveTest
  376. def test_primary_group(self):
  377. '''
  378. Test the set_primary_group function
  379. Test the get_primary_group function
  380. '''
  381. self.assertTrue(win_dacl.set_primary_group(obj_name=self.obj_name,
  382. principal='Backup Operators',
  383. obj_type=self.obj_type))
  384. self.assertEqual(win_dacl.get_primary_group(obj_name=self.obj_name,
  385. obj_type=self.obj_type),
  386. 'Backup Operators')
  387. @destructiveTest
  388. def test_set_permissions(self):
  389. '''
  390. Test the set_permissions function
  391. '''
  392. self.assertTrue(win_dacl.set_permissions(obj_name=self.obj_name,
  393. principal='Backup Operators',
  394. permissions='full_control',
  395. access_mode='grant',
  396. obj_type=self.obj_type,
  397. reset_perms=False,
  398. protected=None))
  399. expected = {
  400. 'Not Inherited': {
  401. 'Backup Operators': {
  402. 'grant': {
  403. 'applies to': 'Not Inherited (file)',
  404. 'permissions': 'Full control'}}}}
  405. self.assertEqual(win_dacl.get_permissions(obj_name=self.obj_name,
  406. principal='Backup Operators',
  407. obj_type=self.obj_type),
  408. expected)
  409. @destructiveTest
  410. def test_get_permissions(self):
  411. '''
  412. Test the get_permissions function
  413. '''
  414. self.assertTrue(win_dacl.set_permissions(obj_name=self.obj_name,
  415. principal='Backup Operators',
  416. permissions='full_control',
  417. access_mode='grant',
  418. obj_type=self.obj_type,
  419. reset_perms=False,
  420. protected=None))
  421. expected = {
  422. 'Not Inherited': {
  423. 'Backup Operators': {
  424. 'grant': {
  425. 'applies to': 'Not Inherited (file)',
  426. 'permissions': 'Full control'}}}}
  427. self.assertEqual(win_dacl.get_permissions(obj_name=self.obj_name,
  428. principal='Backup Operators',
  429. obj_type=self.obj_type),
  430. expected)
  431. @destructiveTest
  432. def test_has_permission(self):
  433. '''
  434. Test the has_permission function
  435. '''
  436. self.assertTrue(win_dacl.set_permissions(obj_name=self.obj_name,
  437. principal='Backup Operators',
  438. permissions='full_control',
  439. access_mode='grant',
  440. obj_type=self.obj_type,
  441. reset_perms=False,
  442. protected=None))
  443. # Test has_permission exact
  444. self.assertTrue(win_dacl.has_permission(obj_name=self.obj_name,
  445. principal='Backup Operators',
  446. permission='full_control',
  447. access_mode='grant',
  448. obj_type=self.obj_type,
  449. exact=True))
  450. # Test has_permission contains
  451. self.assertTrue(win_dacl.has_permission(obj_name=self.obj_name,
  452. principal='Backup Operators',
  453. permission='read',
  454. access_mode='grant',
  455. obj_type=self.obj_type,
  456. exact=False))
  457. @destructiveTest
  458. def test_rm_permissions(self):
  459. '''
  460. Test the rm_permissions function
  461. '''
  462. self.assertTrue(win_dacl.set_permissions(obj_name=self.obj_name,
  463. principal='Backup Operators',
  464. permissions='full_control',
  465. access_mode='grant',
  466. obj_type=self.obj_type,
  467. reset_perms=False,
  468. protected=None))
  469. self.assertTrue(win_dacl.rm_permissions(obj_name=self.obj_name,
  470. principal='Backup Operators',
  471. obj_type=self.obj_type))
  472. self.assertEqual(win_dacl.get_permissions(obj_name=self.obj_name,
  473. principal='Backup Operators',
  474. obj_type=self.obj_type),
  475. {})
  476. @destructiveTest
  477. def test_inheritance(self):
  478. '''
  479. Test the set_inheritance function
  480. Test the get_inheritance function
  481. '''
  482. self.assertTrue(win_dacl.set_inheritance(obj_name=self.obj_name,
  483. enabled=True,
  484. obj_type=self.obj_type,
  485. clear=False))
  486. self.assertTrue(win_dacl.get_inheritance(obj_name=self.obj_name,
  487. obj_type=self.obj_type))
  488. self.assertTrue(win_dacl.set_inheritance(obj_name=self.obj_name,
  489. enabled=False,
  490. obj_type=self.obj_type,
  491. clear=False))
  492. self.assertFalse(win_dacl.get_inheritance(obj_name=self.obj_name,
  493. obj_type=self.obj_type))
  494. @destructiveTest
  495. def test_check_perms(self):
  496. '''
  497. Test the check_perms function
  498. '''
  499. with patch.dict(win_dacl.__opts__, {"test": False}):
  500. result = win_dacl.check_perms(
  501. obj_name=self.obj_name,
  502. obj_type=self.obj_type,
  503. ret={},
  504. owner='Users',
  505. grant_perms={'Backup Operators': {'perms': 'read'}},
  506. deny_perms={'Backup Operators': {'perms': ['delete']},
  507. 'NETWORK SERVICE': {'perms': ['delete',
  508. 'change_permissions',
  509. 'write_attributes',
  510. 'write_data']}},
  511. inheritance=True,
  512. reset=False)
  513. expected = {
  514. 'changes': {'owner': 'Users',
  515. 'perms': {'Backup Operators': {'grant': 'read',
  516. 'deny': ['delete']},
  517. 'NETWORK SERVICE': {'deny': ['delete',
  518. 'change_permissions',
  519. 'write_attributes',
  520. 'write_data']}}},
  521. 'comment': '',
  522. 'name': self.obj_name,
  523. 'result': True}
  524. self.assertDictEqual(result, expected)
  525. expected = {
  526. 'Not Inherited': {
  527. 'Backup Operators': {
  528. 'grant': {
  529. 'applies to': 'Not Inherited (file)',
  530. 'permissions': 'Read'},
  531. 'deny': {
  532. 'applies to': 'Not Inherited (file)',
  533. 'permissions': ['Delete']}}}}
  534. self.assertDictEqual(
  535. win_dacl.get_permissions(
  536. obj_name=self.obj_name,
  537. principal='Backup Operators',
  538. obj_type=self.obj_type),
  539. expected)
  540. expected = {
  541. 'Not Inherited': {
  542. 'NETWORK SERVICE': {
  543. 'deny': {
  544. 'applies to': 'Not Inherited (file)',
  545. 'permissions': ['Change permissions',
  546. 'Create files / write data',
  547. 'Delete',
  548. 'Write attributes']}}}}
  549. self.assertDictEqual(
  550. win_dacl.get_permissions(
  551. obj_name=self.obj_name,
  552. principal='NETWORK SERVICE',
  553. obj_type=self.obj_type),
  554. expected)
  555. self.assertEqual(
  556. win_dacl.get_owner(
  557. obj_name=self.obj_name,
  558. obj_type=self.obj_type),
  559. 'Users')
  560. @destructiveTest
  561. def test_check_perms_test_true(self):
  562. '''
  563. Test the check_perms function
  564. '''
  565. with patch.dict(win_dacl.__opts__, {"test": True}):
  566. result = win_dacl.check_perms(
  567. obj_name=self.obj_name,
  568. obj_type=self.obj_type,
  569. ret=None,
  570. owner='Users',
  571. grant_perms={'Backup Operators': {'perms': 'read'}},
  572. deny_perms={'NETWORK SERVICE': {'perms': ['delete',
  573. 'set_value',
  574. 'write_dac',
  575. 'write_owner']},
  576. 'Backup Operators': {'perms': ['delete']}},
  577. inheritance=True,
  578. reset=False)
  579. expected = {
  580. 'changes': {'owner': 'Users',
  581. 'perms': {'Backup Operators': {'grant': 'read',
  582. 'deny': ['delete']},
  583. 'NETWORK SERVICE': {'deny': ['delete',
  584. 'set_value',
  585. 'write_dac',
  586. 'write_owner']}}},
  587. 'comment': '',
  588. 'name': self.obj_name,
  589. 'result': None}
  590. self.assertDictEqual(result, expected)
  591. self.assertNotEqual(
  592. win_dacl.get_owner(
  593. obj_name=self.obj_name,
  594. obj_type=self.obj_type),
  595. 'Users')
  596. self.assertEqual(
  597. win_dacl.get_permissions(
  598. obj_name=self.obj_name,
  599. principal='Backup Operators',
  600. obj_type=self.obj_type),
  601. {})
  602. def test_set_perms(self):
  603. '''
  604. Test the set_perms function
  605. '''
  606. result = win_dacl.set_perms(
  607. obj_name=self.obj_name,
  608. obj_type=self.obj_type,
  609. grant_perms={'Backup Operators': {'perms': 'read'}},
  610. deny_perms={'NETWORK SERVICE': {'perms': ['delete',
  611. 'change_permissions',
  612. 'write_attributes',
  613. 'write_data']}},
  614. inheritance=True,
  615. reset=False)
  616. expected = {
  617. 'deny': {'NETWORK SERVICE': {'perms': ['delete',
  618. 'change_permissions',
  619. 'write_attributes',
  620. 'write_data']}},
  621. 'grant': {'Backup Operators': {'perms': 'read'}}}
  622. self.assertDictEqual(result, expected)