test_win_lgpo.py 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682
  1. # -*- coding: utf-8 -*-
  2. # Import Python libs
  3. from __future__ import absolute_import, print_function, unicode_literals
  4. import os
  5. import re
  6. import io
  7. import logging
  8. # Import Salt Testing libs
  9. from tests.support.case import ModuleCase
  10. from tests.support.unit import skipIf
  11. from tests.support.helpers import destructiveTest, generate_random_name
  12. from tests.support.runtests import RUNTIME_VARS
  13. # Import Salt libs
  14. import salt.utils.files
  15. import salt.utils.platform
  16. import salt.utils.win_reg as reg
  17. log = logging.getLogger(__name__)
  18. @skipIf(not salt.utils.platform.is_windows(), 'windows test only')
  19. class WinLgpoTest(ModuleCase):
  20. '''
  21. Tests for salt.modules.win_lgpo
  22. '''
  23. osrelease = None
  24. def _testRegistryPolicy(self,
  25. policy_name,
  26. policy_config,
  27. registry_value_hive,
  28. registry_value_path,
  29. registry_value_vname,
  30. expected_value_data):
  31. '''
  32. Takes a registry based policy name and config and validates that the
  33. expected registry value exists and has the correct data
  34. policy_name
  35. name of the registry based policy to configure
  36. policy_config
  37. the configuration of the policy
  38. registry_value_hive
  39. the registry hive that the policy registry path is in
  40. registry_value_path
  41. the registry value path that the policy updates
  42. registry_value_vname
  43. the registry value name
  44. expected_value_data
  45. the expected data that the value will contain
  46. '''
  47. ret = self.run_function('lgpo.set_computer_policy',
  48. (policy_name, policy_config))
  49. self.assertTrue(ret)
  50. val = reg.read_value(
  51. registry_value_hive,
  52. registry_value_path,
  53. registry_value_vname)
  54. self.assertTrue(val['success'], msg='Failed to obtain the registry data for policy {0}'.format(policy_name))
  55. if val['success']:
  56. self.assertEqual(val['vdata'], expected_value_data, 'The registry value data {0} does not match the expected value {1} for policy {2}'.format(
  57. val['vdata'],
  58. expected_value_data,
  59. policy_name))
  60. def _testSeceditPolicy(self,
  61. policy_name,
  62. policy_config,
  63. expected_regexes,
  64. cumulative_rights_assignments=True):
  65. '''
  66. Takes a secedit policy name and config and validates that the expected
  67. output is returned from secedit
  68. policy_name
  69. name of the secedit policy to configure
  70. policy_config
  71. the configuration of the policy
  72. expected_regexes
  73. the expected regexes to be found in the secedit output file
  74. '''
  75. ret = self.run_function('lgpo.set_computer_policy',
  76. (policy_name, policy_config),
  77. cumulative_rights_assignments=cumulative_rights_assignments)
  78. self.assertTrue(ret)
  79. secedit_output_file = os.path.join(RUNTIME_VARS.TMP, generate_random_name('secedit-output-'))
  80. secedit_output = self.run_function(
  81. 'cmd.run',
  82. (),
  83. cmd='secedit /export /cfg {0}'.format(secedit_output_file))
  84. secedit_file_content = None
  85. if secedit_output:
  86. with io.open(secedit_output_file, encoding='utf-16') as _reader:
  87. secedit_file_content = _reader.read()
  88. for expected_regex in expected_regexes:
  89. match = re.search(
  90. expected_regex,
  91. secedit_file_content,
  92. re.IGNORECASE | re.MULTILINE)
  93. self.assertIsNotNone(match, 'Failed validating policy "{0}" configuration, regex "{1}" not found in secedit output'.format(policy_name, expected_regex))
  94. def _testAdmxPolicy(self,
  95. policy_name,
  96. policy_config,
  97. expected_regexes,
  98. assert_true=True,
  99. policy_class='Machine'):
  100. '''
  101. Takes a ADMX policy name and config and validates that the expected
  102. output is returned from lgpo looking at the Registry.pol file
  103. policy_name
  104. name of the ADMX policy to configure
  105. policy_config
  106. the configuration of the policy
  107. expected_regexes
  108. the expected regexes to be found in the lgpo parse output
  109. assert_true
  110. set to false if expecting the module run to fail
  111. policy_class
  112. the policy class this policy belongs to, either Machine or User
  113. '''
  114. lgpo_function = 'set_computer_policy'
  115. lgpo_class = '/m'
  116. lgpo_folder = 'Machine'
  117. if policy_class.lower() == 'user':
  118. lgpo_function = 'set_user_policy'
  119. lgpo_class = '/u'
  120. lgpo_folder = 'User'
  121. ret = self.run_function('lgpo.{0}'.format(lgpo_function),
  122. (policy_name, policy_config))
  123. log.debug('lgpo set_computer_policy ret == %s', ret)
  124. cmd = ['lgpo.exe',
  125. '/parse',
  126. lgpo_class,
  127. r'c:\Windows\System32\GroupPolicy\{}\Registry.pol'.format(lgpo_folder)]
  128. if assert_true:
  129. self.assertTrue(ret)
  130. lgpo_output = self.run_function('cmd.run', (), cmd=' '.join(cmd))
  131. # validate that the lgpo output doesn't say the format is invalid
  132. self.assertIsNone(
  133. re.search(r'Invalid file format\.', lgpo_output, re.IGNORECASE),
  134. msg='Failed validating Registry.pol file format')
  135. # validate that the regexes we expect are in the output
  136. for expected_regex in expected_regexes:
  137. match = re.search(expected_regex, lgpo_output, re.IGNORECASE)
  138. self.assertIsNotNone(
  139. match,
  140. msg='Failed validating policy "{0}" configuration, regex '
  141. '"{1}" not found in lgpo output:\n{2}'
  142. ''.format(policy_name, expected_regex, lgpo_output))
  143. else:
  144. # expecting it to fail
  145. self.assertNotEqual(ret, True)
  146. def runTest(self):
  147. '''
  148. runTest method
  149. '''
  150. pass
  151. @classmethod
  152. def setUpClass(cls):
  153. '''
  154. class setup function, only runs once
  155. downloads and extracts the lgpo.exe tool into c:/windows/system32
  156. for use in validating the registry.pol files
  157. gets osrelease grain for tests that are only applicable to certain
  158. windows versions
  159. '''
  160. osrelease_grains = cls().run_function('grains.item', ['osrelease'])
  161. if 'osrelease' in osrelease_grains:
  162. cls.osrelease = osrelease_grains['osrelease']
  163. else:
  164. log.debug('Unable to get osrelease grain')
  165. if not os.path.exists(r'c:\windows\system32\lgpo.exe'):
  166. log.debug('lgpo.exe does not exist, attempting to download/extract')
  167. ret = cls().run_function('state.single',
  168. ('archive.extracted', r'c:\windows\system32'),
  169. source='https://download.microsoft.com/download/8/5/C/85C25433-A1B0-4FFA-9429-7E023E7DA8D8/LGPO.zip',
  170. archive_format='zip',
  171. source_hash='sha256=6ffb6416366652993c992280e29faea3507b5b5aa661c33ba1af31f48acea9c4',
  172. enforce_toplevel=False)
  173. log.debug('ret from archive.unzip == %s', ret)
  174. @destructiveTest
  175. def test_set_user_policy_point_and_print_restrictions(self):
  176. '''
  177. Test setting/unsetting/changing the PointAndPrint_Restrictions user policy
  178. '''
  179. # Disable Point and Print Restrictions
  180. self._testAdmxPolicy(
  181. r'Control Panel\Printers\Point and Print Restrictions',
  182. 'Disabled',
  183. [
  184. r'User[\s]*Software\\Policies\\Microsoft\\Windows NT\\Printers\\PointAndPrint[\s]*Restricted[\s]*DWORD:0',
  185. r'User[\s]*Software\\Policies\\Microsoft\\Windows NT\\Printers\\PointAndPrint[\s]*TrustedServers[\s]*DELETE',
  186. r'User[\s]*Software\\Policies\\Microsoft\\Windows NT\\Printers\\PointAndPrint[\s]*ServerList[\s]*DELETE',
  187. r'User[\s]*Software\\Policies\\Microsoft\\Windows NT\\Printers\\PointAndPrint[\s]*InForest[\s]*DELETE',
  188. r'User[\s]*Software\\Policies\\Microsoft\\Windows NT\\Printers\\PointAndPrint[\s]*NoWarningNoElevationOnInstall[\s]*DELETE',
  189. r'User[\s]*Software\\Policies\\Microsoft\\Windows NT\\Printers\\PointAndPrint[\s]*UpdatePromptSettings[\s]*DELETE',
  190. ],
  191. policy_class='User')
  192. # Enable Point and Print Restrictions
  193. self._testAdmxPolicy(
  194. r'Control Panel\Printers\Point and Print Restrictions',
  195. {
  196. 'Users can only point and print to these servers': True,
  197. 'Enter fully qualified server names separated by semicolons': 'fakeserver1;fakeserver2',
  198. 'Users can only point and print to machines in their forest': True,
  199. 'Security Prompts: When installing drivers for a new connection': 'Show warning and elevation prompt',
  200. 'When updating drivers for an existing connection': 'Do not show warning or elevation prompt',
  201. },
  202. [
  203. r'User[\s]*Software\\Policies\\Microsoft\\Windows NT\\Printers\\PointAndPrint[\s]*Restricted[\s]*DWORD:1',
  204. r'User[\s]*Software\\Policies\\Microsoft\\Windows NT\\Printers\\PointAndPrint[\s]*TrustedServers[\s]*DWORD:1',
  205. r'User[\s]*Software\\Policies\\Microsoft\\Windows NT\\Printers\\PointAndPrint[\s]*ServerList[\s]*SZ:fakeserver1;fakeserver2',
  206. r'User[\s]*Software\\Policies\\Microsoft\\Windows NT\\Printers\\PointAndPrint[\s]*InForest[\s]*DWORD:1',
  207. r'User[\s]*Software\\Policies\\Microsoft\\Windows NT\\Printers\\PointAndPrint[\s]*NoWarningNoElevationOnInstall[\s]*DWORD:0',
  208. r'User[\s]*Software\\Policies\\Microsoft\\Windows NT\\Printers\\PointAndPrint[\s]*UpdatePromptSettings[\s]*DWORD:2',
  209. ],
  210. policy_class='User')
  211. # set Point and Print Restrictions to 'Not Configured'
  212. self._testAdmxPolicy(
  213. r'Control Panel\Printers\Point and Print Restrictions',
  214. 'Not Configured',
  215. [
  216. r'; Source file: c:\\windows\\system32\\grouppolicy\\user\\registry.pol[\s]*; PARSING COMPLETED.'],
  217. policy_class='User')
  218. @destructiveTest
  219. def test_set_computer_policy_NTP_Client(self):
  220. '''
  221. Test setting/unsetting/changing NTP Client policies
  222. '''
  223. # Disable Configure NTP Client
  224. self._testAdmxPolicy(r'System\Windows Time Service\Time Providers\Configure Windows NTP Client',
  225. 'Disabled',
  226. [
  227. r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\Parameters[\s]*NtpServer[\s]*DELETE',
  228. r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\Parameters[\s]*Type[\s]*DELETE',
  229. r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\TimeProviders\\NtpClient[\s]*CrossSiteSyncFlags[\s]*DELETE',
  230. r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\TimeProviders\\NtpClient[\s]*ResolvePeerBackoffMinutes[\s]*DELETE',
  231. r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\TimeProviders\\NtpClient[\s]*ResolvePeerBackoffMaxTimes[\s]*DELETE',
  232. r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\TimeProviders\\NtpClient[\s]*SpecialPollInterval[\s]*DELETE',
  233. r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\TimeProviders\\NtpClient[\s]*EventLogFlags[\s]*DELETE'
  234. ])
  235. # Enable Configure NTP Client
  236. self._testAdmxPolicy(r'System\Windows Time Service\Time Providers\Configure Windows NTP Client',
  237. {
  238. 'NtpServer': 'time.windows.com,0x9',
  239. 'Type': 'NT5DS',
  240. 'CrossSiteSyncFlags': 2,
  241. 'ResolvePeerBackoffMinutes': 15,
  242. 'ResolvePeerBackoffMaxTimes': 7,
  243. 'W32TIME_SpecialPollInterval': 3600,
  244. 'W32TIME_NtpClientEventLogFlags': 0
  245. },
  246. [
  247. r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\Parameters[\s]*NtpServer[\s]*SZ:time.windows.com,0x9',
  248. r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\Parameters[\s]*Type[\s]*SZ:NT5DS',
  249. r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\TimeProviders\\NtpClient[\s]*CrossSiteSyncFlags[\s]*DWORD:2',
  250. r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\TimeProviders\\NtpClient[\s]*ResolvePeerBackoffMinutes[\s]*DWORD:15',
  251. r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\TimeProviders\\NtpClient[\s]*ResolvePeerBackoffMaxTimes[\s]*DWORD:7',
  252. r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\TimeProviders\\NtpClient[\s]*SpecialPollInterval[\s]*DWORD:3600',
  253. r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\TimeProviders\\NtpClient[\s]*EventLogFlags[\s]*DWORD:0',
  254. ])
  255. # set Configure NTP Client to 'Not Configured'
  256. self._testAdmxPolicy(r'System\Windows Time Service\Time Providers\Configure Windows NTP Client',
  257. 'Not Configured',
  258. [r'; Source file: c:\\windows\\system32\\grouppolicy\\machine\\registry.pol[\s]*; PARSING COMPLETED.'])
  259. @destructiveTest
  260. def test_set_computer_policy_RA_Unsolicit(self):
  261. '''
  262. Test setting/unsetting/changing RA_Unsolicit policy
  263. '''
  264. # Disable RA_Unsolicit
  265. log.debug('Attempting to disable RA_Unsolicit')
  266. self._testAdmxPolicy('RA_Unsolicit',
  267. 'Disabled',
  268. [
  269. r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services[\s]*fAllowUnsolicited[\s]*DWORD:0',
  270. r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services[\s]*fAllowUnsolicitedFullControl[\s]*DELETE',
  271. r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services\\RAUnsolicit[\s]*\*[\s]*DELETEALLVALUES',
  272. ])
  273. # configure RA_Unsolicit
  274. log.debug('Attempting to configure RA_Unsolicit')
  275. self._testAdmxPolicy('RA_Unsolicit',
  276. {
  277. 'Configure Offer Remote Access': 'Enabled',
  278. 'Permit remote control of this computer': 'Allow helpers to remotely control the computer',
  279. 'Helpers': ['administrators', 'user1']
  280. },
  281. [
  282. r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services\\RAUnsolicit[\s]*user1[\s]*SZ:user1[\s]*',
  283. r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services\\RAUnsolicit[\s]*administrators[\s]*SZ:administrators[\s]*',
  284. r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services[\s]*fAllowUnsolicited[\s]*DWORD:1',
  285. r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services[\s]*fAllowUnsolicitedFullControl[\s]*DWORD:1',
  286. ])
  287. # Not Configure RA_Unsolicit
  288. log.debug('Attempting to set RA_Unsolicit to Not Configured')
  289. self._testAdmxPolicy('RA_Unsolicit',
  290. 'Not Configured',
  291. [r'; Source file: c:\\windows\\system32\\grouppolicy\\machine\\registry.pol[\s]*; PARSING COMPLETED.'])
  292. @destructiveTest
  293. def test_set_computer_policy_Pol_HardenedPaths(self):
  294. # Disable Pol_HardenedPaths
  295. log.debug('Attempting to disable Pol_HardenedPaths')
  296. self._testAdmxPolicy(
  297. 'Pol_HardenedPaths',
  298. 'Disabled',
  299. [r'Computer[\s]*Software\\policies\\Microsoft\\Windows\\NetworkProvider\\HardenedPaths[\s]*\*[\s]*DELETEALLVALUES'])
  300. # Configure Pol_HardenedPaths
  301. log.debug('Attempting to configure Pol_HardenedPaths')
  302. self._testAdmxPolicy(
  303. 'Pol_HardenedPaths',
  304. {
  305. 'Hardened UNC Paths': {
  306. r'\\*\NETLOGON': 'RequireMutualAuthentication=1, RequireIntegrity=1',
  307. r'\\*\SYSVOL': 'RequireMutualAuthentication=1, RequireIntegrity=1'
  308. }
  309. },
  310. [
  311. r'Computer[\s]*Software\\policies\\Microsoft\\Windows\\NetworkProvider\\HardenedPaths[\s]*\\\\\*\\NETLOGON[\s]*SZ:RequireMutualAuthentication=1, RequireIntegrity=1[\s]*',
  312. r'Computer[\s]*Software\\policies\\Microsoft\\Windows\\NetworkProvider\\HardenedPaths[\s]*\\\\\*\\SYSVOL[\s]*SZ:RequireMutualAuthentication=1, RequireIntegrity=1[\s]*',
  313. ])
  314. # Not Configure Pol_HardenedPaths
  315. log.debug('Attempting to set Pol_HardenedPaths to Not Configured')
  316. self._testAdmxPolicy(
  317. 'Pol_HardenedPaths',
  318. 'Not Configured',
  319. [r'; Source file: c:\\windows\\system32\\grouppolicy\\machine\\registry.pol[\s]*; PARSING COMPLETED.'])
  320. @destructiveTest
  321. def test_set_computer_policy_WindowsUpdate(self):
  322. '''
  323. Test setting/unsetting/changing WindowsUpdate policy
  324. '''
  325. the_policy = {
  326. 'Configure automatic updating': '4 - Auto download and schedule the install',
  327. 'Install during automatic maintenance': False,
  328. 'Scheduled install day': '7 - Every Saturday',
  329. 'Scheduled install time': '17:00',
  330. 'Install updates for other Microsoft products': True
  331. }
  332. the_policy_check = [
  333. r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*NoAutoUpdate[\s]*DWORD:0',
  334. r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*AUOptions[\s]*DWORD:4',
  335. r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*AutomaticMaintenanceEnabled[\s]*DELETE',
  336. r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*ScheduledInstallDay[\s]*DWORD:7',
  337. r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*ScheduledInstallTime[\s]*DWORD:17',
  338. r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*AllowMUUpdateService[\s]*DWORD:1\s*'
  339. ]
  340. # Configure Automatic Updates has different options in 2016 than in 2012
  341. # and has only one boolean item, so we'll test it "False" in this block
  342. # and then "True" in next block
  343. if self.osrelease in ['2012Server', '2012ServerR2']:
  344. the_policy = {
  345. 'Configure automatic updating': '4 - Auto download and schedule the install',
  346. 'Install during automatic maintenance': False,
  347. 'Schedule install day': '7 - Every Saturday',
  348. 'Schedule install time': '17:00',
  349. }
  350. the_policy_check = [
  351. r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*NoAutoUpdate[\s]*DWORD:0',
  352. r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*AUOptions[\s]*DWORD:4',
  353. r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*AutomaticMaintenanceEnabled[\s]*DELETE',
  354. r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*ScheduledInstallDay[\s]*DWORD:7',
  355. r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*ScheduledInstallTime[\s]*DWORD:17',
  356. ]
  357. # test as False
  358. self._testAdmxPolicy(r'Windows Components\Windows Update\Configure Automatic Updates',
  359. the_policy,
  360. the_policy_check)
  361. # configure as True for "enable Automatic Updates" test below
  362. the_policy = {
  363. 'Configure automatic updating': '4 - Auto download and schedule the install',
  364. 'Install during automatic maintenance': True,
  365. 'Schedule install day': '7 - Every Saturday',
  366. 'Schedule install time': '17:00',
  367. }
  368. the_policy_check = [
  369. r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*NoAutoUpdate[\s]*DWORD:0',
  370. r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*AUOptions[\s]*DWORD:4',
  371. r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*AutomaticMaintenanceEnabled[\s]*DWORD:1\s*',
  372. r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*ScheduledInstallDay[\s]*DWORD:7',
  373. r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*ScheduledInstallTime[\s]*DWORD:17',
  374. ]
  375. # enable Automatic Updates
  376. self._testAdmxPolicy(r'Windows Components\Windows Update\Configure Automatic Updates',
  377. the_policy,
  378. the_policy_check)
  379. # disable Configure Automatic Updates
  380. self._testAdmxPolicy(r'Windows Components\Windows Update\Configure Automatic Updates',
  381. 'Disabled',
  382. [
  383. r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*NoAutoUpdate[\s]*DWORD:1',
  384. r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*AUOptions[\s]*DELETE',
  385. r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*AutomaticMaintenanceEnabled[\s]*DELETE',
  386. r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*ScheduledInstallDay[\s]*DELETE',
  387. r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*ScheduledInstallTime[\s]*DELETE',
  388. r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*AllowMUUpdateService[\s]*DELETE'
  389. ])
  390. # set Configure Automatic Updates to 'Not Configured'
  391. self._testAdmxPolicy(r'Windows Components\Windows Update\Configure Automatic Updates',
  392. 'Not Configured',
  393. [r'; Source file: c:\\windows\\system32\\grouppolicy\\machine\\registry.pol[\s]*; PARSING COMPLETED.'])
  394. @destructiveTest
  395. def test_set_computer_policy_ClipboardRedirection(self):
  396. '''
  397. Test setting/unsetting/changing ClipboardRedirection policy
  398. '''
  399. # Enable/Disable/Not Configured "Do not allow Clipboard redirection"
  400. self._testAdmxPolicy(r'Windows Components\Remote Desktop Services\Remote Desktop Session Host\Device and Resource Redirection\Do not allow Clipboard redirection',
  401. 'Enabled',
  402. [r'Computer[\s]*Software\\Policies\\Microsoft\\Windows NT\\Terminal Services[\s]*fDisableClip[\s]*DWORD:1'])
  403. self._testAdmxPolicy(r'Windows Components\Remote Desktop Services\Remote Desktop Session Host\Device and Resource Redirection\Do not allow Clipboard redirection',
  404. 'Disabled',
  405. [r'Computer[\s]*Software\\Policies\\Microsoft\\Windows NT\\Terminal Services[\s]*fDisableClip[\s]*DWORD:0'])
  406. self._testAdmxPolicy(r'Windows Components\Remote Desktop Services\Remote Desktop Session Host\Device and Resource Redirection\Do not allow Clipboard redirection',
  407. 'Not Configured',
  408. [r'; Source file: c:\\windows\\system32\\grouppolicy\\machine\\registry.pol[\s]*; PARSING COMPLETED.'])
  409. @destructiveTest
  410. def test_set_computer_policy_PasswordComplexity(self):
  411. '''
  412. Test setting/unsetting/changing PasswordComplexity
  413. '''
  414. # disable PasswordComplexity
  415. self._testSeceditPolicy('Password must meet complexity requirements',
  416. 'Disabled',
  417. [r'^PasswordComplexity = 0'])
  418. # enable PasswordComplexity
  419. self._testSeceditPolicy('PasswordComplexity',
  420. 'Enabled',
  421. [r'^PasswordComplexity = 1'])
  422. @destructiveTest
  423. def test_set_computer_policy_PasswordLen(self):
  424. '''
  425. Test setting/unsetting/changing PasswordLength
  426. '''
  427. # set Minimum password length
  428. self._testSeceditPolicy('Minimum password length',
  429. 10,
  430. [r'^MinimumPasswordLength = 10'])
  431. # set MinimumPasswordLength = 0
  432. self._testSeceditPolicy('MinPasswordLen',
  433. 0,
  434. [r'^MinimumPasswordLength = 0'])
  435. @destructiveTest
  436. def test_set_computer_policy_SeNetworkLogonRight(self):
  437. '''
  438. Test setting/unsetting/changing PasswordLength
  439. '''
  440. # set SeNetworkLogonRight to only Administrators
  441. self._testSeceditPolicy('Access this computer from the network',
  442. ['Administrators'],
  443. [r'^SeNetworkLogonRight = \*S-1-5-32-544'],
  444. cumulative_rights_assignments=False)
  445. # set SeNetworkLogonRight back to the default
  446. self._testSeceditPolicy('SeNetworkLogonRight',
  447. ['Everyone', 'Administrators', 'Users', 'Backup Operators'],
  448. [r'^SeNetworkLogonRight = \*S-1-1-0,\*S-1-5-32-544,\*S-1-5-32-545,\*S-1-5-32-551'])
  449. @destructiveTest
  450. def test_set_computer_policy_multipleAdmxPolicies(self):
  451. '''
  452. Tests setting several ADMX policies in succession and validating the configuration w/lgop
  453. '''
  454. # set one policy
  455. self._testAdmxPolicy(r'Windows Components\Remote Desktop Services\Remote Desktop Session Host\Device and Resource Redirection\Do not allow Clipboard redirection',
  456. 'Disabled',
  457. [r'Computer[\s]*Software\\Policies\\Microsoft\\Windows NT\\Terminal Services[\s]*fDisableClip[\s]*DWORD:0'])
  458. # set another policy and make sure both this policy and the previous are okay
  459. self._testAdmxPolicy('RA_Unsolicit',
  460. {
  461. 'Configure Offer Remote Access': 'Enabled',
  462. 'Permit remote control of this computer': 'Allow helpers to remotely control the computer',
  463. 'Helpers': ['administrators', 'user1']
  464. },
  465. [
  466. r'Computer[\s]*Software\\Policies\\Microsoft\\Windows NT\\Terminal Services[\s]*fDisableClip[\s]*DWORD:0',
  467. r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services\\RAUnsolicit[\s]*user1[\s]*SZ:user1[\s]*',
  468. r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services\\RAUnsolicit[\s]*administrators[\s]*SZ:administrators[\s]*',
  469. r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services[\s]*fAllowUnsolicited[\s]*DWORD:1',
  470. r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services[\s]*fAllowUnsolicitedFullControl[\s]*DWORD:1',
  471. ])
  472. # Configure Automatic Updates and validate everything is still okay
  473. self._testAdmxPolicy(r'Windows Components\Windows Update\Configure Automatic Updates',
  474. 'Disabled',
  475. [
  476. r'Computer[\s]*Software\\Policies\\Microsoft\\Windows NT\\Terminal Services[\s]*fDisableClip[\s]*DWORD:0',
  477. r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services\\RAUnsolicit[\s]*user1[\s]*SZ:user1[\s]*',
  478. r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services\\RAUnsolicit[\s]*administrators[\s]*SZ:administrators[\s]*',
  479. r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services[\s]*fAllowUnsolicited[\s]*DWORD:1',
  480. r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services[\s]*fAllowUnsolicitedFullControl[\s]*DWORD:1',
  481. r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*NoAutoUpdate[\s]*DWORD:1',
  482. r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*AUOptions[\s]*DELETE',
  483. r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*AutomaticMaintenanceEnabled[\s]*DELETE',
  484. r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*ScheduledInstallDay[\s]*DELETE',
  485. r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*ScheduledInstallTime[\s]*DELETE',
  486. r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*AllowMUUpdateService[\s]*DELETE'
  487. ])
  488. @destructiveTest
  489. def test_set_computer_policy_DisableDomainCreds(self):
  490. '''
  491. Tests Enable/Disable of DisableDomainCreds policy
  492. '''
  493. self._testRegistryPolicy('DisableDomainCreds',
  494. 'Enabled',
  495. 'HKEY_LOCAL_MACHINE',
  496. 'SYSTEM\\CurrentControlSet\\Control\\Lsa',
  497. 'DisableDomainCreds',
  498. 1)
  499. self._testRegistryPolicy(
  500. 'Network access: Do not allow storage of passwords and credentials for network authentication',
  501. 'Disabled',
  502. 'HKEY_LOCAL_MACHINE',
  503. 'SYSTEM\\CurrentControlSet\\Control\\Lsa',
  504. 'DisableDomainCreds',
  505. 0)
  506. @destructiveTest
  507. def test_set_computer_policy_ForceGuest(self):
  508. '''
  509. Tests changing ForceGuest policy
  510. '''
  511. self._testRegistryPolicy('ForceGuest',
  512. 'Guest only - local users authenticate as Guest',
  513. 'HKEY_LOCAL_MACHINE',
  514. 'SYSTEM\\CurrentControlSet\\Control\\Lsa',
  515. 'ForceGuest',
  516. 1)
  517. self._testRegistryPolicy(
  518. 'Network access: Sharing and security model for local accounts',
  519. 'Classic - local users authenticate as themselves',
  520. 'HKEY_LOCAL_MACHINE',
  521. 'SYSTEM\\CurrentControlSet\\Control\\Lsa',
  522. 'ForceGuest',
  523. 0)
  524. @destructiveTest
  525. def test_set_computer_policy_DisableUXWUAccess(self):
  526. '''
  527. Tests changing DisableUXWUAccess
  528. #50079 shows using the 'Remove access to use all Windows Update features' failed
  529. Policy only exists on 2016
  530. '''
  531. valid_osreleases = ['2016Server']
  532. if self.osrelease not in valid_osreleases:
  533. self.skipTest('DisableUXWUAccess policy is only applicable if the osrelease grain is {0}'.format(' or '.join(valid_osreleases)))
  534. else:
  535. self._testAdmxPolicy(r'DisableUXWUAccess',
  536. 'Enabled',
  537. [r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate[\s]*SetDisableUXWUAccess[\s]*DWORD:1'])
  538. self._testAdmxPolicy(r'Remove access to use all Windows Update features',
  539. 'Disabled',
  540. [r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate[\s]*SetDisableUXWUAccess[\s]*DWORD:0'])
  541. self._testAdmxPolicy(r'Windows Components\Windows Update\Remove access to use all Windows Update features',
  542. 'Not Configured',
  543. [r'; Source file: c:\\windows\\system32\\grouppolicy\\machine\\registry.pol[\s]*; PARSING COMPLETED.'])
  544. @destructiveTest
  545. def test_set_computer_policy_Access_data_sources_across_domains(self):
  546. '''
  547. Tests that a policy that has multiple names
  548. '''
  549. self._testAdmxPolicy(r'Access data sources across domains',
  550. 'Enabled',
  551. [],
  552. assert_true=False)
  553. self._testAdmxPolicy(r'Windows Components\Internet Explorer\Internet Control Panel\Security Page\Internet Zone\Access data sources across domains',
  554. {'Access data sources across domains': 'Prompt'},
  555. [r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Zones\\3[\s]*1406[\s]*DWORD:1'])
  556. self._testAdmxPolicy(r'Windows Components\Internet Explorer\Internet Control Panel\Security Page\Internet Zone\Access data sources across domains',
  557. {'Access data sources across domains': 'Enable'},
  558. [r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Zones\\3[\s]*1406[\s]*DWORD:0'])
  559. self._testAdmxPolicy(r'Windows Components\Internet Explorer\Internet Control Panel\Security Page\Internet Zone\Access data sources across domains',
  560. 'Disabled',
  561. [r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Zones\\3[\s]*1406[\s]*DELETE'])
  562. @destructiveTest
  563. def test_set_computer_policy_ActiveHours(self):
  564. '''
  565. Test configuring the ActiveHours policy, #47784
  566. Only applies to 2016Server
  567. # activehours.sls
  568. active_hours_policy:
  569. lgpo.set:
  570. - computer_policy:
  571. 'ActiveHours':
  572. 'ActiveHoursStartTime': '8 AM'
  573. 'ActiveHoursEndTime': '7 PM'
  574. '''
  575. valid_osreleases = ['2016Server']
  576. if self.osrelease not in valid_osreleases:
  577. self.skipTest('ActiveHours policy is only applicable if the osrelease grain is {0}'.format(' or '.join(valid_osreleases)))
  578. else:
  579. self._testAdmxPolicy(r'ActiveHours',
  580. {'ActiveHoursStartTime': '8 AM', 'ActiveHoursEndTime': '7 PM'},
  581. [
  582. r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate[\s]*SetActiveHours[\s]*DWORD:1',
  583. r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate[\s]*ActiveHoursStart[\s]*DWORD:8',
  584. r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate[\s]*ActiveHoursEnd[\s]*DWORD:19'
  585. ])
  586. self._testAdmxPolicy(r'ActiveHours',
  587. {'ActiveHoursStartTime': '5 AM', 'ActiveHoursEndTime': '10 PM'},
  588. [
  589. r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate[\s]*SetActiveHours[\s]*DWORD:1',
  590. r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate[\s]*ActiveHoursStart[\s]*DWORD:5',
  591. r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate[\s]*ActiveHoursEnd[\s]*DWORD:22'
  592. ])
  593. self._testAdmxPolicy('Turn off auto-restart for updates during active hours',
  594. 'Disabled',
  595. [
  596. r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate[\s]*SetActiveHours[\s]*DWORD:0',
  597. r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate[\s]*ActiveHoursStart[\s]*DELETE',
  598. r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate[\s]*ActiveHoursEnd[\s]*DELETE'
  599. ])
  600. self._testAdmxPolicy(r'Windows Components\Windows Update\Turn off auto-restart for updates during active hours',
  601. 'Not Configured',
  602. [r'; Source file: c:\\windows\\system32\\grouppolicy\\machine\\registry.pol[\s]*; PARSING COMPLETED.'])
  603. @destructiveTest
  604. def test_set_computer_policy_AllowTelemetry(self):
  605. '''
  606. Tests that a the AllowTelemetry policy is applied correctly and that it
  607. doesn't appear in subsequent group policy states as having changed
  608. '''
  609. valid_osreleases = ['10', '2016Server', '2019Server']
  610. if self.osrelease not in valid_osreleases:
  611. self.skipTest('Allow Telemetry policy is only applicable if the '
  612. 'osrelease grain is {0}'.format(' or '.join(valid_osreleases)))
  613. else:
  614. self._testAdmxPolicy(
  615. 'Allow Telemetry',
  616. {'AllowTelemetry': '1 - Basic'},
  617. [r'Software\\Policies\\Microsoft\\Windows\\DataCollection[\s]*AllowTelemetry[\s]*DWORD:1'],
  618. assert_true=True)
  619. result = self.run_function(
  620. 'state.single',
  621. ['lgpo.set'],
  622. name='state',
  623. computer_policy={
  624. 'Disable pre-release features or settings': 'Disabled'
  625. }
  626. )
  627. name = 'lgpo_|-state_|-state_|-set'
  628. expected = {
  629. 'new': {
  630. 'Computer Configuration': {
  631. 'Windows Components\\Data Collection and Preview Builds\\Disable pre-release features or settings': 'Disabled'}},
  632. 'old': {'Computer Configuration': {}}}
  633. self.assertDictEqual(result[name]['changes'], expected)
  634. def tearDown(self):
  635. '''
  636. tearDown method, runs after each test
  637. '''
  638. self.run_state(
  639. 'file.absent',
  640. name='c:\\windows\\system32\\grouppolicy\\machine\\registry.pol')
  641. self.run_state(
  642. 'file.absent',
  643. name='c:\\windows\\system32\\grouppolicy\\user\\registry.pol')