mirror of
https://github.com/saltstack/salt.git
synced 2025-04-17 10:10:20 +00:00
Merge branch '2018.3' into 41342_beacon_state_module_fixes
This commit is contained in:
commit
8885d1ff3d
2 changed files with 549 additions and 18 deletions
|
@ -2605,8 +2605,8 @@ class _policy_info(object):
|
|||
userSid = '{0}'.format(userSid[0])
|
||||
# TODO: This needs to be more specific
|
||||
except Exception:
|
||||
log.exception('Handle this explicitly')
|
||||
userSid = win32security.ConvertSidToStringSid(_sid)
|
||||
log.warning('Unable to convert SID "%s" to a friendly name. The SID will be disaplayed instead of a user/group name.', userSid)
|
||||
usernames.append(userSid)
|
||||
return usernames
|
||||
|
||||
|
@ -2925,8 +2925,8 @@ def _findOptionValueInSeceditFile(option):
|
|||
return True, _line.split('=')[1].strip()
|
||||
return True, 'Not Defined'
|
||||
# TODO: This needs to be more specific
|
||||
except Exception:
|
||||
log.exception('error occurred while trying to get secedit data')
|
||||
except Exception as e:
|
||||
log.exception('error %s occurred while trying to get secedit data', e)
|
||||
return False, None
|
||||
|
||||
|
||||
|
@ -3094,9 +3094,9 @@ def _getAdmlPresentationRefId(adml_data, ref_id):
|
|||
else:
|
||||
if etree.QName(p_item.tag).localname == 'text':
|
||||
if prepended_text:
|
||||
prepended_text = ' '.join([prepended_text, p_item.text.rstrip()])
|
||||
prepended_text = ' '.join((text for text in (prepended_text, getattr(p_item, 'text', '').rstrip()) if text))
|
||||
else:
|
||||
prepended_text = p_item.text.rstrip()
|
||||
prepended_text = getattr(p_item, 'text', '').rstrip()
|
||||
else:
|
||||
prepended_text = ''
|
||||
if prepended_text.endswith('.'):
|
||||
|
@ -3491,7 +3491,7 @@ def _processValueItem(element, reg_key, reg_valuename, policy, parent_element,
|
|||
encoded_semicolon,
|
||||
chr(registry.vtype[this_vtype]).encode('utf-32-le'),
|
||||
encoded_semicolon,
|
||||
chr(len(' {0}'.format(chr(0)).encode('utf-16-le'))).encode('utf-32-le'),
|
||||
six.unichr(len(' {0}'.format(chr(0)).encode('utf-16-le'))).encode('utf-32-le'),
|
||||
encoded_semicolon,
|
||||
' '.encode('utf-16-le'),
|
||||
encoded_null,
|
||||
|
@ -3552,7 +3552,7 @@ def _processValueItem(element, reg_key, reg_valuename, policy, parent_element,
|
|||
encoded_semicolon,
|
||||
chr(registry.vtype[this_vtype]).encode('utf-32-le'),
|
||||
encoded_semicolon,
|
||||
chr(len(' {0}'.format(chr(0)))).encode('utf-32-le'),
|
||||
six.unichr(len(' {0}'.format(chr(0)).encode('utf-16-le'))).encode('utf-32-le'),
|
||||
encoded_semicolon,
|
||||
' '.encode('utf-16-le'),
|
||||
encoded_null,
|
||||
|
@ -4179,7 +4179,9 @@ def _regexSearchKeyValueCombo(policy_data, policy_regpath, policy_regkey):
|
|||
b'\00;'])
|
||||
match = re.search(_thisSearch, policy_data, re.IGNORECASE)
|
||||
if match:
|
||||
return policy_data[match.start():(policy_data.index(']', match.end())) + 1]
|
||||
# add 2 so we get the ']' and the \00
|
||||
# to return the full policy entry
|
||||
return policy_data[match.start():(policy_data.index(b']', match.end())) + 2]
|
||||
|
||||
return None
|
||||
|
||||
|
@ -4683,8 +4685,8 @@ def _writeAdminTemplateRegPolFile(admtemplate_data,
|
|||
policy_data.admx_registry_classes[registry_class]['gpt_extension_location'],
|
||||
policy_data.admx_registry_classes[registry_class]['gpt_extension_guid'])
|
||||
# TODO: This needs to be more specific or removed
|
||||
except Exception:
|
||||
log.exception('Unhandled exception %s occurred while attempting to write Adm Template Policy File')
|
||||
except Exception as e:
|
||||
log.exception('Unhandled exception %s occurred while attempting to write Adm Template Policy File', e)
|
||||
return False
|
||||
return True
|
||||
|
||||
|
@ -4832,12 +4834,14 @@ def _lookup_admin_template(policy_name,
|
|||
suggested_policies = ''
|
||||
adml_to_remove = []
|
||||
if len(adml_search_results) > 1:
|
||||
log.debug('multiple ADML entries found matching the policy name %s', policy_name)
|
||||
multiple_adml_entries = True
|
||||
for adml_search_result in adml_search_results:
|
||||
if not getattr(adml_search_result, 'text', '').strip() == policy_name:
|
||||
adml_to_remove.append(adml_search_result)
|
||||
else:
|
||||
if hierarchy:
|
||||
log.debug('we have hierarchy of %s', hierarchy)
|
||||
display_name_searchval = '$({0}.{1})'.format(
|
||||
adml_search_result.tag.split('}')[1],
|
||||
adml_search_result.attrib['id'])
|
||||
|
@ -4847,8 +4851,11 @@ def _lookup_admin_template(policy_name,
|
|||
display_name_searchval,
|
||||
policy_class)
|
||||
admx_results = []
|
||||
admx_search_results = admx_policy_definitions.xpath(policy_search_string, namespaces=adml_search_result.nsmap)
|
||||
for search_result in admx_search_results:
|
||||
these_admx_search_results = admx_policy_definitions.xpath(policy_search_string, namespaces=adml_search_result.nsmap)
|
||||
if not these_admx_search_results:
|
||||
log.debug('No admx was found for the adml entry %s, it will be removed', display_name_searchval)
|
||||
adml_to_remove.append(adml_search_result)
|
||||
for search_result in these_admx_search_results:
|
||||
log.debug('policy_name == %s', policy_name)
|
||||
this_hierarchy = _build_parent_list(search_result,
|
||||
admx_policy_definitions,
|
||||
|
@ -4856,11 +4863,29 @@ def _lookup_admin_template(policy_name,
|
|||
adml_policy_resources)
|
||||
this_hierarchy.reverse()
|
||||
if hierarchy != this_hierarchy:
|
||||
adml_to_remove.append(adml_search_result)
|
||||
msg = 'hierarchy %s does not match this item\'s hierarchy of %s'
|
||||
log.debug(msg, hierarchy, this_hierarchy)
|
||||
if len(these_admx_search_results) == 1:
|
||||
log.debug('only 1 admx was found and it does not match this adml, it is safe to remove from the list')
|
||||
adml_to_remove.append(adml_search_result)
|
||||
else:
|
||||
log.debug('hierarchy %s matches item\'s hierarchy of %s', hierarchy, this_hierarchy)
|
||||
log.debug('search_result %s added to results', search_result)
|
||||
admx_results.append(search_result)
|
||||
if len(admx_results) == 1:
|
||||
admx_search_results = admx_results
|
||||
admx_search_results.append(admx_results[0])
|
||||
else:
|
||||
# verify the ADMX correlated to this ADML is in the same class
|
||||
# that we are looking for
|
||||
display_name_searchval = '$({0}.{1})'.format(
|
||||
adml_search_result.tag.split('}')[1],
|
||||
adml_search_result.attrib['id'])
|
||||
these_admx_search_results = ADMX_DISPLAYNAME_SEARCH_XPATH(
|
||||
admx_policy_definitions,
|
||||
display_name=display_name_searchval,
|
||||
registry_class=policy_class)
|
||||
if not these_admx_search_results:
|
||||
adml_to_remove.append(adml_search_result)
|
||||
for adml in adml_to_remove:
|
||||
if adml in adml_search_results:
|
||||
adml_search_results.remove(adml)
|
||||
|
@ -4875,12 +4900,15 @@ def _lookup_admin_template(policy_name,
|
|||
adml_search_result.attrib['id'])
|
||||
log.debug('searching for displayName == %s', display_name_searchval)
|
||||
if not admx_search_results:
|
||||
log.debug('search for an admx entry matching display_name %s and registry_class %s', display_name_searchval, policy_class)
|
||||
admx_search_results = ADMX_DISPLAYNAME_SEARCH_XPATH(
|
||||
admx_policy_definitions,
|
||||
display_name=display_name_searchval,
|
||||
registry_class=policy_class)
|
||||
if admx_search_results:
|
||||
if len(admx_search_results) == 1 or hierarchy and not multiple_adml_entries:
|
||||
log.debug('processing admx_search_results of {0}'.format(admx_search_results))
|
||||
log.debug('multiple_adml_entries is {0}'.format(multiple_adml_entries))
|
||||
if (len(admx_search_results) == 1 or hierarchy) and not multiple_adml_entries:
|
||||
found = False
|
||||
for search_result in admx_search_results:
|
||||
found = False
|
||||
|
@ -4936,9 +4964,6 @@ def _lookup_admin_template(policy_name,
|
|||
'\\'.join(this_parent_list)])
|
||||
else:
|
||||
suggested_policies = '\\'.join(this_parent_list)
|
||||
else:
|
||||
msg = 'Unable to find a policy with the name "{0}".'.format(policy_name)
|
||||
return (False, None, [], msg)
|
||||
if suggested_policies:
|
||||
msg = ('ADML policy name "{0}" is used as the display name'
|
||||
' for multiple policies.'
|
||||
|
|
506
tests/integration/modules/test_win_lgpo.py
Normal file
506
tests/integration/modules/test_win_lgpo.py
Normal file
|
@ -0,0 +1,506 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Import Python libs
|
||||
from __future__ import absolute_import, print_function, unicode_literals
|
||||
import os
|
||||
import re
|
||||
import io
|
||||
import logging
|
||||
|
||||
# Import Salt Testing libs
|
||||
from tests.support.case import ModuleCase
|
||||
from tests.support.unit import skipIf
|
||||
from tests.support.helpers import destructiveTest, generate_random_name
|
||||
from tests.support.runtests import RUNTIME_VARS
|
||||
|
||||
# Import Salt libs
|
||||
import salt.utils.files
|
||||
import salt.utils.platform
|
||||
import salt.utils.win_reg as reg
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@skipIf(not salt.utils.platform.is_windows(), 'windows test only')
|
||||
class WinLgpoTest(ModuleCase):
|
||||
'''
|
||||
Tests for salt.modules.win_lgpo
|
||||
'''
|
||||
osrelease = None
|
||||
|
||||
def _testRegistryPolicy(self,
|
||||
policy_name,
|
||||
policy_config,
|
||||
registry_value_hive,
|
||||
registry_value_path,
|
||||
registry_value_vname,
|
||||
expected_value_data):
|
||||
'''
|
||||
Takes a registry based policy name and config and validates taht the
|
||||
expected registry value exists and has the correct data
|
||||
|
||||
policy_name
|
||||
name of the registry based policy to configure
|
||||
policy_config
|
||||
the configuration of the policy
|
||||
registry_value_hive
|
||||
the registry hive that the policy registry path is in
|
||||
registry_value_path
|
||||
the registry value path that the policy updates
|
||||
registry_value_vname
|
||||
the registry value name
|
||||
expected_value_data
|
||||
the expected data that the value will contain
|
||||
'''
|
||||
ret = self.run_function('lgpo.set_computer_policy',
|
||||
(policy_name, policy_config))
|
||||
self.assertTrue(ret)
|
||||
val = reg.read_value(
|
||||
registry_value_hive,
|
||||
registry_value_path,
|
||||
registry_value_vname)
|
||||
self.assertTrue(val['success'], msg='Failed to obtain the registry data for policy {0}'.format(policy_name))
|
||||
if val['success']:
|
||||
self.assertEqual(val['vdata'], expected_value_data, 'The registry value data {0} does not match the expected value {1} for policy {2}'.format(
|
||||
val['vdata'],
|
||||
expected_value_data,
|
||||
policy_name))
|
||||
|
||||
def _testSeceditPolicy(self,
|
||||
policy_name,
|
||||
policy_config,
|
||||
expected_regexes,
|
||||
cumulative_rights_assignments=True):
|
||||
'''
|
||||
Takes a secedit policy name and config and validates that the expected
|
||||
output is returned from secedit
|
||||
|
||||
policy_name
|
||||
name of the secedit policy to configure
|
||||
policy_config
|
||||
the configuration of the policy
|
||||
expected_regexes
|
||||
the expected regexes to be found in the secedit output file
|
||||
'''
|
||||
ret = self.run_function('lgpo.set_computer_policy',
|
||||
(policy_name, policy_config),
|
||||
cumulative_rights_assignments=cumulative_rights_assignments)
|
||||
self.assertTrue(ret)
|
||||
secedit_output_file = os.path.join(RUNTIME_VARS.TMP, generate_random_name('secedit-output-'))
|
||||
secedit_output = self.run_function(
|
||||
'cmd.run',
|
||||
(),
|
||||
cmd='secedit /export /cfg {0}'.format(secedit_output_file))
|
||||
secedit_file_content = None
|
||||
if secedit_output:
|
||||
with io.open(secedit_output_file, encoding='utf-16') as _reader:
|
||||
secedit_file_content = _reader.read()
|
||||
for expected_regex in expected_regexes:
|
||||
match = re.search(
|
||||
expected_regex,
|
||||
secedit_file_content,
|
||||
re.IGNORECASE | re.MULTILINE)
|
||||
self.assertIsNotNone(match, 'Failed validating policy "{0}" configuration, regex "{1}" not found in secedit output'.format(policy_name, expected_regex))
|
||||
|
||||
def _testComputerAdmxPolicy(self,
|
||||
policy_name,
|
||||
policy_config,
|
||||
expected_regexes,
|
||||
assert_true=True):
|
||||
'''
|
||||
Takes a ADMX policy name and config and validates that the expected
|
||||
output is returned from lgpo looking at the Registry.pol file
|
||||
|
||||
policy_name
|
||||
name of the ADMX policy to configure
|
||||
policy_config
|
||||
the configuration of the policy
|
||||
expected_regexes
|
||||
the expected regexes to be found in the lgpo parse output
|
||||
assert_true
|
||||
set to false if expecting the module run to fail
|
||||
'''
|
||||
ret = self.run_function('lgpo.set_computer_policy',
|
||||
(policy_name, policy_config))
|
||||
log.debug('lgpo set_computer_policy ret == %s', ret)
|
||||
if assert_true:
|
||||
self.assertTrue(ret)
|
||||
lgpo_output = self.run_function(
|
||||
'cmd.run',
|
||||
(),
|
||||
cmd='lgpo.exe /parse /m c:\\Windows\\System32\\GroupPolicy\\Machine\\Registry.pol')
|
||||
# validate that the lgpo output doesn't say the format is invalid
|
||||
self.assertIsNone(
|
||||
re.search(
|
||||
r'Invalid file format\.',
|
||||
lgpo_output,
|
||||
re.IGNORECASE), 'Failed validating Registry.pol file format')
|
||||
# validate that the regexes we expect are in the output
|
||||
for expected_regex in expected_regexes:
|
||||
match = re.search(
|
||||
expected_regex,
|
||||
lgpo_output,
|
||||
re.IGNORECASE)
|
||||
self.assertIsNotNone(match, 'Failed validating policy "{0}" configuration, regex "{1}" not found in lgpo output'.format(policy_name, expected_regex))
|
||||
else:
|
||||
# expecting it to fail
|
||||
self.assertNotEqual(ret, True)
|
||||
|
||||
def runTest(self):
|
||||
'''
|
||||
runTest method
|
||||
'''
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
'''
|
||||
class setup function, only runs once
|
||||
|
||||
downloads and extracts the lgpo.exe tool into c:/windows/system32
|
||||
for use in validating the registry.pol files
|
||||
|
||||
gets osrelease grain for tests that are only applicable to certain
|
||||
windows versions
|
||||
'''
|
||||
osrelease_grains = cls().run_function('grains.item', ['osrelease'])
|
||||
if 'osrelease' in osrelease_grains:
|
||||
cls.osrelease = osrelease_grains['osrelease']
|
||||
else:
|
||||
log.debug('Unable to get osrelease grain')
|
||||
if not os.path.exists(r'c:\windows\system32\lgpo.exe'):
|
||||
log.debug('lgpo.exe does not exist, attempting to download/extract')
|
||||
ret = cls().run_function('state.single',
|
||||
('archive.extracted', r'c:\windows\system32'),
|
||||
source='https://download.microsoft.com/download/8/5/C/85C25433-A1B0-4FFA-9429-7E023E7DA8D8/LGPO.zip',
|
||||
archive_format='zip',
|
||||
source_hash='sha256=6ffb6416366652993c992280e29faea3507b5b5aa661c33ba1af31f48acea9c4',
|
||||
enforce_toplevel=False)
|
||||
log.debug('ret from archive.unzip == %s', ret)
|
||||
|
||||
@destructiveTest
|
||||
def test_set_computer_policy_NTP_Client(self):
|
||||
'''
|
||||
Test setting/unsetting/changing NTP Client policies
|
||||
'''
|
||||
# Disable Configure NTP Client
|
||||
self._testComputerAdmxPolicy(r'System\Windows Time Service\Time Providers\Configure Windows NTP Client',
|
||||
'Disabled',
|
||||
[
|
||||
r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\Parameters[\s]*NtpServer[\s]*DELETE',
|
||||
r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\Parameters[\s]*Type[\s]*DELETE',
|
||||
r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\TimeProviders\\NtpClient[\s]*CrossSiteSyncFlags[\s]*DELETE',
|
||||
r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\TimeProviders\\NtpClient[\s]*ResolvePeerBackoffMinutes[\s]*DELETE',
|
||||
r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\TimeProviders\\NtpClient[\s]*ResolvePeerBackoffMaxTimes[\s]*DELETE',
|
||||
r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\TimeProviders\\NtpClient[\s]*SpecialPollInterval[\s]*DELETE',
|
||||
r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\TimeProviders\\NtpClient[\s]*EventLogFlags[\s]*DELETE'
|
||||
])
|
||||
# Enable Configure NTP Client
|
||||
self._testComputerAdmxPolicy(r'System\Windows Time Service\Time Providers\Configure Windows NTP Client',
|
||||
{
|
||||
'NtpServer': 'time.windows.com,0x9',
|
||||
'Type': 'NT5DS',
|
||||
'CrossSiteSyncFlags': 2,
|
||||
'ResolvePeerBackoffMinutes': 15,
|
||||
'ResolvePeerBackoffMaxTimes': 7,
|
||||
'W32TIME_SpecialPollInterval': 3600,
|
||||
'W32TIME_NtpClientEventLogFlags': 0
|
||||
},
|
||||
[
|
||||
r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\Parameters[\s]*NtpServer[\s]*SZ:time.windows.com,0x9',
|
||||
r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\Parameters[\s]*Type[\s]*SZ:NT5DS',
|
||||
r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\TimeProviders\\NtpClient[\s]*CrossSiteSyncFlags[\s]*DWORD:2',
|
||||
r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\TimeProviders\\NtpClient[\s]*ResolvePeerBackoffMinutes[\s]*DWORD:15',
|
||||
r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\TimeProviders\\NtpClient[\s]*ResolvePeerBackoffMaxTimes[\s]*DWORD:7',
|
||||
r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\TimeProviders\\NtpClient[\s]*SpecialPollInterval[\s]*DWORD:3600',
|
||||
r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\TimeProviders\\NtpClient[\s]*EventLogFlags[\s]*DWORD:0',
|
||||
])
|
||||
# set Configure NTP Client to 'Not Configured'
|
||||
self._testComputerAdmxPolicy(r'System\Windows Time Service\Time Providers\Configure Windows NTP Client',
|
||||
'Not Configured',
|
||||
[r'; Source file: c:\\windows\\system32\\grouppolicy\\machine\\registry.pol[\s]*; PARSING COMPLETED.'])
|
||||
|
||||
@destructiveTest
|
||||
def test_set_computer_policy_RA_Unsolicit(self):
|
||||
'''
|
||||
Test setting/unsetting/changing RA_Unsolicit policy
|
||||
'''
|
||||
|
||||
# Disable RA_Unsolicit
|
||||
log.debug('Attempting to disable RA_Unsolicit')
|
||||
self._testComputerAdmxPolicy('RA_Unsolicit',
|
||||
'Disabled',
|
||||
[
|
||||
r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services[\s]*fAllowUnsolicited[\s]*DWORD:0',
|
||||
r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services[\s]*fAllowUnsolicitedFullControl[\s]*DELETE',
|
||||
r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services\\RAUnsolicit[\s]*\*[\s]*DELETEALLVALUES',
|
||||
])
|
||||
# configure RA_Unsolicit
|
||||
log.debug('Attempting to configure RA_Unsolicit')
|
||||
self._testComputerAdmxPolicy('RA_Unsolicit',
|
||||
{
|
||||
'Configure Offer Remote Access': 'Enabled',
|
||||
'Permit remote control of this computer': 'Allow helpers to remotely control the computer',
|
||||
'Helpers': ['administrators', 'user1']
|
||||
},
|
||||
[
|
||||
r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services\\RAUnsolicit[\s]*user1[\s]*SZ:user1[\s]*',
|
||||
r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services\\RAUnsolicit[\s]*administrators[\s]*SZ:administrators[\s]*',
|
||||
r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services[\s]*fAllowUnsolicited[\s]*DWORD:1',
|
||||
r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services[\s]*fAllowUnsolicitedFullControl[\s]*DWORD:1',
|
||||
])
|
||||
# Not Configure RA_Unsolicit
|
||||
log.debug('Attempting to set RA_Unsolicit to Not Configured')
|
||||
self._testComputerAdmxPolicy('RA_Unsolicit',
|
||||
'Not Configured',
|
||||
[r'; Source file: c:\\windows\\system32\\grouppolicy\\machine\\registry.pol[\s]*; PARSING COMPLETED.'])
|
||||
|
||||
@destructiveTest
|
||||
def test_set_computer_policy_WindowsUpdate(self):
|
||||
'''
|
||||
Test setting/unsetting/changing WindowsUpdate policy
|
||||
'''
|
||||
# disable Configure Automatic Updates
|
||||
self._testComputerAdmxPolicy(r'Windows Components\Windows Update\Configure Automatic Updates',
|
||||
'Disabled',
|
||||
[
|
||||
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*NoAutoUpdate[\s]*DWORD:1',
|
||||
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*AUOptions[\s]*DELETE',
|
||||
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*AutomaticMaintenanceEnabled[\s]*DELETE',
|
||||
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*ScheduledInstallDay[\s]*DELETE',
|
||||
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*ScheduledInstallTime[\s]*DELETE',
|
||||
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*AllowMUUpdateService[\s]*DELETE'
|
||||
])
|
||||
# set Configure Automatic Updates to 'Not Configured'
|
||||
self._testComputerAdmxPolicy(r'Windows Components\Windows Update\Configure Automatic Updates',
|
||||
'Not Configured',
|
||||
[r'; Source file: c:\\windows\\system32\\grouppolicy\\machine\\registry.pol[\s]*; PARSING COMPLETED.'])
|
||||
|
||||
@destructiveTest
|
||||
def test_set_computer_policy_ClipboardRedirection(self):
|
||||
'''
|
||||
Test setting/unsetting/changing ClipboardRedirection policy
|
||||
'''
|
||||
# Enable/Disable/Not Configured "Do not allow Clipboard redirection"
|
||||
self._testComputerAdmxPolicy(r'Windows Components\Remote Desktop Services\Remote Desktop Session Host\Device and Resource Redirection\Do not allow Clipboard redirection',
|
||||
'Enabled',
|
||||
[r'Computer[\s]*Software\\Policies\\Microsoft\\Windows NT\\Terminal Services[\s]*fDisableClip[\s]*DWORD:1'])
|
||||
self._testComputerAdmxPolicy(r'Windows Components\Remote Desktop Services\Remote Desktop Session Host\Device and Resource Redirection\Do not allow Clipboard redirection',
|
||||
'Disabled',
|
||||
[r'Computer[\s]*Software\\Policies\\Microsoft\\Windows NT\\Terminal Services[\s]*fDisableClip[\s]*DWORD:0'])
|
||||
self._testComputerAdmxPolicy(r'Windows Components\Remote Desktop Services\Remote Desktop Session Host\Device and Resource Redirection\Do not allow Clipboard redirection',
|
||||
'Not Configured',
|
||||
[r'; Source file: c:\\windows\\system32\\grouppolicy\\machine\\registry.pol[\s]*; PARSING COMPLETED.'])
|
||||
|
||||
@destructiveTest
|
||||
def test_set_computer_policy_PasswordComplexity(self):
|
||||
'''
|
||||
Test setting/unsetting/changing PasswordComplexity
|
||||
'''
|
||||
# disable PasswordComplexity
|
||||
self._testSeceditPolicy('Password must meet complexity requirements',
|
||||
'Disabled',
|
||||
[r'^PasswordComplexity = 0'])
|
||||
# enable PasswordComplexity
|
||||
self._testSeceditPolicy('PasswordComplexity',
|
||||
'Enabled',
|
||||
[r'^PasswordComplexity = 1'])
|
||||
|
||||
@destructiveTest
|
||||
def test_set_computer_policy_PasswordLen(self):
|
||||
'''
|
||||
Test setting/unsetting/changing PasswordLength
|
||||
'''
|
||||
# set Minimum password length
|
||||
self._testSeceditPolicy('Minimum password length',
|
||||
10,
|
||||
[r'^MinimumPasswordLength = 10'])
|
||||
# set MinimumPasswordLength = 0
|
||||
self._testSeceditPolicy('MinPasswordLen',
|
||||
0,
|
||||
[r'^MinimumPasswordLength = 0'])
|
||||
|
||||
@destructiveTest
|
||||
def test_set_computer_policy_SeNetworkLogonRight(self):
|
||||
'''
|
||||
Test setting/unsetting/changing PasswordLength
|
||||
'''
|
||||
# set SeNetworkLogonRight to only Administrators
|
||||
self._testSeceditPolicy('Access this computer from the network',
|
||||
['Administrators'],
|
||||
[r'^SeNetworkLogonRight = \*S-1-5-32-544'],
|
||||
cumulative_rights_assignments=False)
|
||||
# set SeNetworkLogonRight back to the default
|
||||
self._testSeceditPolicy('SeNetworkLogonRight',
|
||||
['Everyone', 'Administrators', 'Users', 'Backup Operators'],
|
||||
[r'^SeNetworkLogonRight = \*S-1-1-0,\*S-1-5-32-544,\*S-1-5-32-545,\*S-1-5-32-551'])
|
||||
|
||||
@destructiveTest
|
||||
def test_set_computer_policy_multipleAdmxPolicies(self):
|
||||
'''
|
||||
Tests setting several ADMX policies in succession and validating the configuration w/lgop
|
||||
'''
|
||||
# set one policy
|
||||
self._testComputerAdmxPolicy(r'Windows Components\Remote Desktop Services\Remote Desktop Session Host\Device and Resource Redirection\Do not allow Clipboard redirection',
|
||||
'Disabled',
|
||||
[r'Computer[\s]*Software\\Policies\\Microsoft\\Windows NT\\Terminal Services[\s]*fDisableClip[\s]*DWORD:0'])
|
||||
|
||||
# set another policy and make sure both this policy and the previous are okay
|
||||
self._testComputerAdmxPolicy('RA_Unsolicit',
|
||||
{
|
||||
'Configure Offer Remote Access': 'Enabled',
|
||||
'Permit remote control of this computer': 'Allow helpers to remotely control the computer',
|
||||
'Helpers': ['administrators', 'user1']
|
||||
},
|
||||
[
|
||||
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows NT\\Terminal Services[\s]*fDisableClip[\s]*DWORD:0',
|
||||
r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services\\RAUnsolicit[\s]*user1[\s]*SZ:user1[\s]*',
|
||||
r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services\\RAUnsolicit[\s]*administrators[\s]*SZ:administrators[\s]*',
|
||||
r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services[\s]*fAllowUnsolicited[\s]*DWORD:1',
|
||||
r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services[\s]*fAllowUnsolicitedFullControl[\s]*DWORD:1',
|
||||
])
|
||||
# Configure Automatic Updates and validate everything is still okay
|
||||
self._testComputerAdmxPolicy(r'Windows Components\Windows Update\Configure Automatic Updates',
|
||||
'Disabled',
|
||||
[
|
||||
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows NT\\Terminal Services[\s]*fDisableClip[\s]*DWORD:0',
|
||||
r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services\\RAUnsolicit[\s]*user1[\s]*SZ:user1[\s]*',
|
||||
r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services\\RAUnsolicit[\s]*administrators[\s]*SZ:administrators[\s]*',
|
||||
r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services[\s]*fAllowUnsolicited[\s]*DWORD:1',
|
||||
r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services[\s]*fAllowUnsolicitedFullControl[\s]*DWORD:1',
|
||||
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*NoAutoUpdate[\s]*DWORD:1',
|
||||
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*AUOptions[\s]*DELETE',
|
||||
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*AutomaticMaintenanceEnabled[\s]*DELETE',
|
||||
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*ScheduledInstallDay[\s]*DELETE',
|
||||
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*ScheduledInstallTime[\s]*DELETE',
|
||||
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*AllowMUUpdateService[\s]*DELETE'
|
||||
])
|
||||
|
||||
@destructiveTest
|
||||
def test_set_computer_policy_DisableDomainCreds(self):
|
||||
'''
|
||||
Tests Enable/Disable of DisableDomainCreds policy
|
||||
'''
|
||||
self._testRegistryPolicy('DisableDomainCreds',
|
||||
'Enabled',
|
||||
'HKEY_LOCAL_MACHINE',
|
||||
'SYSTEM\\CurrentControlSet\\Control\\Lsa',
|
||||
'DisableDomainCreds',
|
||||
1)
|
||||
self._testRegistryPolicy(
|
||||
'Network access: Do not allow storage of passwords and credentials for network authentication',
|
||||
'Disabled',
|
||||
'HKEY_LOCAL_MACHINE',
|
||||
'SYSTEM\\CurrentControlSet\\Control\\Lsa',
|
||||
'DisableDomainCreds',
|
||||
0)
|
||||
|
||||
@destructiveTest
|
||||
def test_set_computer_policy_ForceGuest(self):
|
||||
'''
|
||||
Tests changing ForceGuest policy
|
||||
'''
|
||||
self._testRegistryPolicy('ForceGuest',
|
||||
'Guest only - local users authenticate as Guest',
|
||||
'HKEY_LOCAL_MACHINE',
|
||||
'SYSTEM\\CurrentControlSet\\Control\\Lsa',
|
||||
'ForceGuest',
|
||||
1)
|
||||
self._testRegistryPolicy(
|
||||
'Network access: Sharing and security model for local accounts',
|
||||
'Classic - local users authenticate as themselves',
|
||||
'HKEY_LOCAL_MACHINE',
|
||||
'SYSTEM\\CurrentControlSet\\Control\\Lsa',
|
||||
'ForceGuest',
|
||||
0)
|
||||
|
||||
@destructiveTest
|
||||
def test_set_computer_policy_DisableUXWUAccess(self):
|
||||
'''
|
||||
Tests changing DisableUXWUAccess
|
||||
#50079 shows using the 'Remove access to use all Windows Update features' failed
|
||||
Policy only exists on 2016
|
||||
'''
|
||||
valid_osreleases = ['2016Server']
|
||||
if self.osrelease not in valid_osreleases:
|
||||
self.skipTest('DisableUXWUAccess policy is only applicable if the osrelease grain is {0}'.format(' or '.join(valid_osreleases)))
|
||||
else:
|
||||
self._testComputerAdmxPolicy(r'DisableUXWUAccess',
|
||||
'Enabled',
|
||||
[r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate[\s]*SetDisableUXWUAccess[\s]*DWORD:1'])
|
||||
self._testComputerAdmxPolicy(r'Remove access to use all Windows Update features',
|
||||
'Disabled',
|
||||
[r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate[\s]*SetDisableUXWUAccess[\s]*DWORD:0'])
|
||||
self._testComputerAdmxPolicy(r'Windows Components\Windows Update\Remove access to use all Windows Update features',
|
||||
'Not Configured',
|
||||
[r'; Source file: c:\\windows\\system32\\grouppolicy\\machine\\registry.pol[\s]*; PARSING COMPLETED.'])
|
||||
|
||||
@destructiveTest
|
||||
def test_set_computer_policy_Access_data_sources_across_domains(self):
|
||||
'''
|
||||
Tests that a policy that has multiple names
|
||||
'''
|
||||
self._testComputerAdmxPolicy(r'Access data sources across domains',
|
||||
'Enabled',
|
||||
[],
|
||||
assert_true=False)
|
||||
self._testComputerAdmxPolicy(r'Windows Components\Internet Explorer\Internet Control Panel\Security Page\Internet Zone\Access data sources across domains',
|
||||
{'Access data sources across domains': 'Prompt'},
|
||||
[r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Zones\\3[\s]*1406[\s]*DWORD:1'])
|
||||
self._testComputerAdmxPolicy(r'Windows Components\Internet Explorer\Internet Control Panel\Security Page\Internet Zone\Access data sources across domains',
|
||||
{'Access data sources across domains': 'Enable'},
|
||||
[r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Zones\\3[\s]*1406[\s]*DWORD:0'])
|
||||
self._testComputerAdmxPolicy(r'Windows Components\Internet Explorer\Internet Control Panel\Security Page\Internet Zone\Access data sources across domains',
|
||||
'Disabled',
|
||||
[r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Zones\\3[\s]*1406[\s]*DELETE'])
|
||||
|
||||
@destructiveTest
|
||||
def test_set_computer_policy_ActiveHours(self):
|
||||
'''
|
||||
Test configuring the ActiveHours policy, #47784
|
||||
Only applies to 2016Server
|
||||
# activehours.sls
|
||||
active_hours_policy:
|
||||
lgpo.set:
|
||||
- computer_policy:
|
||||
'ActiveHours':
|
||||
'ActiveHoursStartTime': '8 AM'
|
||||
'ActiveHoursEndTime': '7 PM'
|
||||
'''
|
||||
valid_osreleases = ['2016Server']
|
||||
if self.osrelease not in valid_osreleases:
|
||||
self.skipTest('ActiveHours policy is only applicable if the osrelease grain is {0}'.format(' or '.join(valid_osreleases)))
|
||||
else:
|
||||
self._testComputerAdmxPolicy(r'ActiveHours',
|
||||
{'ActiveHoursStartTime': '8 AM', 'ActiveHoursEndTime': '7 PM'},
|
||||
[
|
||||
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate[\s]*SetActiveHours[\s]*DWORD:1',
|
||||
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate[\s]*ActiveHoursStart[\s]*DWORD:8',
|
||||
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate[\s]*ActiveHoursEnd[\s]*DWORD:19'
|
||||
])
|
||||
self._testComputerAdmxPolicy(r'ActiveHours',
|
||||
{'ActiveHoursStartTime': '5 AM', 'ActiveHoursEndTime': '10 PM'},
|
||||
[
|
||||
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate[\s]*SetActiveHours[\s]*DWORD:1',
|
||||
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate[\s]*ActiveHoursStart[\s]*DWORD:5',
|
||||
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate[\s]*ActiveHoursEnd[\s]*DWORD:22'
|
||||
])
|
||||
self._testComputerAdmxPolicy('Turn off auto-restart for updates during active hours',
|
||||
'Disabled',
|
||||
[
|
||||
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate[\s]*SetActiveHours[\s]*DWORD:0',
|
||||
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate[\s]*ActiveHoursStart[\s]*DELETE',
|
||||
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate[\s]*ActiveHoursEnd[\s]*DELETE'
|
||||
])
|
||||
self._testComputerAdmxPolicy(r'Windows Components\Windows Update\Turn off auto-restart for updates during active hours',
|
||||
'Not Configured',
|
||||
[r'; Source file: c:\\windows\\system32\\grouppolicy\\machine\\registry.pol[\s]*; PARSING COMPLETED.'])
|
||||
|
||||
def tearDown(self):
|
||||
'''
|
||||
tearDown method, runs after each test
|
||||
'''
|
||||
ret = self.run_function('state.single',
|
||||
('file.absent', 'c:\\windows\\system32\\grouppolicy\\machine\\registry.pol'))
|
||||
ret = self.run_function('state.single',
|
||||
('file.absent', 'c:\\windows\\system32\\grouppolicy\\user\\registry.pol'))
|
Loading…
Add table
Reference in a new issue