From 4d1f1d2eb6471cdd96d3587d28e87474ea36292f Mon Sep 17 00:00:00 2001 From: Ethan Moore Date: Tue, 1 Nov 2016 14:12:44 +0000 Subject: [PATCH] add updating gpt.ini file when ADM template policies are modified (gpt.ini file must exist with proper data for ADM policies to apply) --- salt/modules/win_lgpo.py | 90 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 87 insertions(+), 3 deletions(-) diff --git a/salt/modules/win_lgpo.py b/salt/modules/win_lgpo.py index 9880faa1b2..95e86df580 100644 --- a/salt/modules/win_lgpo.py +++ b/salt/modules/win_lgpo.py @@ -2319,7 +2319,8 @@ class _policy_info(object): 'GroupPolicy', 'User', 'Registry.pol'), 'hive': 'HKEY_USERS', - 'lgpo_section': 'User Configuration' + 'lgpo_section': 'User Configuration', + 'gpt_extension_location': 'gPCUserExtensionNames' }, 'Machine': { 'policy_path': os.path.join(os.getenv('WINDIR'), 'System32', @@ -2327,9 +2328,15 @@ class _policy_info(object): 'Registry.pol'), 'hive': 'HKEY_LOCAL_MACHINE', 'lgpo_section': 'Computer Configuration', + 'gpt_extension_location': 'gPCMachineExtensionNames' }, } self.reg_pol_header = u'\u5250\u6765\x01\x00' + self.gpt_ini_info = { + 'path': os.path.join(os.getenv('WINDIR'), 'System32', + 'GroupPolicy', 'gpt.ini'), + 'admxExtension': '[{35378EAC-683F-11D2-A89A-00C04FBBCFA2}{D02B1F72-3407-48AE-BA88-E8213C6761F1}]' + } @classmethod def _notEmpty(cls, val, **kwargs): @@ -3915,9 +3922,18 @@ def _regexSearchKeyValueCombo(policy_data, policy_regpath, policy_regkey): return None -def _write_regpol_data(data_to_write, policy_file_path): +def _write_regpol_data(data_to_write, policy_file_path, gpt_ini, gpt_extension): ''' helper function to actually write the data to a Registry.pol file + + also updates/edits the gpt.ini file to include the ADM policy extensions + to let the computer know user and/or machine registyr policy files need + to be processed + + data_to_write: data to write into the user/machine registry.pol file + policy_file_path: path to the registry.pol file + gpt_ini: gpt_ini_info dict from the _policy_info class + gpt_extension: gpt extension list name from _policy_info class for this registry class gpt_extension_location ''' try: if data_to_write: @@ -3928,6 +3944,71 @@ def _write_regpol_data(data_to_write, policy_file_path): if not data_to_write.startswith(reg_pol_header): pol_file.write(reg_pol_header.encode('utf-16-le')) pol_file.write(data_to_write.encode('utf-16-le')) + try: + gpt_ini_data = '' + if os.path.exists(gpt_ini['path']): + with open(gpt_ini['path'], 'rb') as gpt_file: + gpt_ini_data = gpt_file.read() + if not _regexSearchRegPolData(r'\[General\]\r\n', gpt_ini_data): + gpt_ini_data = '[General]\r\n' + gpt_ini_data + if _regexSearchRegPolData(r'{0}='.format(re.escape(gpt_extension)), gpt_ini_data): + # ensure the line contains the ADM guid + gpt_ext_loc = re.search(r'^{0}=.*\r\n'.format(re.escape(gpt_extension)), + gpt_ini_data, + re.IGNORECASE | re.MULTILINE) + gpt_ext_str = gpt_ini_data[gpt_ext_loc.start():gpt_ext_loc.end()] + if not _regexSearchRegPolData(r'{0}'.format(re.escape(gpt_ini['admxExtension'])), + gpt_ext_str): + gpt_ext_str = gpt_ext_str.split('=') + gpt_ext_str[1] = gpt_ini['admxExtension'] + gpt_ext_str[1] + gpt_ext_str = '='.join(gpt_ext_str) + gpt_ini_data = gpt_ini_data[0:gpt_ext_loc.start()] + gpt_ext_str + gpt_ini_data[gpt_ext_loc.end():] + else: + general_location = re.search(r'^\[General\]\r\n', + gpt_ini_data, + re.IGNORECASE | re.MULTILINE) + gpt_ini_data = "{0}{1}={2}\r\n{3}".format( + gpt_ini_data[general_location.start():general_location.end()], + gpt_extension, gpt_ini['admxExtension'], + gpt_ini_data[general_location.end():]) + # https://technet.microsoft.com/en-us/library/cc978247.aspx + if _regexSearchRegPolData(r'Version=', gpt_ini_data): + version_loc = re.search(r'^Version=.*\r\n', + gpt_ini_data, + re.IGNORECASE | re.MULTILINE) + version_str = gpt_ini_data[version_loc.start():version_loc.end()] + version_str = version_str.split('=') + version_nums = struct.unpack('>2H', struct.pack('>I', int(version_str[1]))) + if gpt_extension.lower() == 'gPCMachineExtensionNames'.lower(): + version_nums = (version_nums[0], version_nums[1] + 1) + elif gpt_extension.lower() == 'gPCUserExtensionNames'.lower(): + version_nums = (version_nums[0] + 1, version_nums[1]) + version_num = int("{0}{1}".format(str(version_nums[0]).zfill(4), + str(version_nums[1]).zfill(4)), 16) + gpt_ini_data = "{0}{1}={2}\r\n{3}".format( + gpt_ini_data[0:version_loc.start()], + 'Version', version_num, + gpt_ini_data[version_loc.end():]) + else: + general_location = re.search(r'^\[General\]\r\n', + gpt_ini_data, + re.IGNORECASE | re.MULTILINE) + if gpt_extension.lower() == 'gPCMachineExtensionNames'.lower(): + version_nums = (0, 1) + elif gpt_extension.lower() == 'gPCUserExtensionNames'.lower(): + version_nums = (1, 0) + gpt_ini_data = "{0}{1}={2}\r\n{3}".format( + gpt_ini_data[general_location.start():general_location.end()], + 'Version', + int("{0}{1}".format(str(version_nums[0]).zfill(4), str(version_nums[1]).zfill(4)), 16), + gpt_ini_data[general_location.end():]) + if gpt_ini_data: + with open(gpt_ini['path'], 'wb') as gpt_file: + gpt_file.write(gpt_ini_data) + except Exception as e: + msg = 'An error occurred attempting to write to {0}, the exception was {1}'.format( + gpt_ini['path'], e) + raise CommandExecutionError(msg) except Exception as e: msg = 'An error occurred attempting to write to {0}, the exception was {1}'.format(policy_file_path, e) raise CommandExecutionError(msg) @@ -4311,7 +4392,10 @@ def _writeAdminTemplateRegPolFile(admtemplate_data, enabled_value_string, existing_data, append_only=True) - _write_regpol_data(existing_data, policy_data.admx_registry_classes[registry_class]['policy_path']) + _write_regpol_data(existing_data, + policy_data.admx_registry_classes[registry_class]['policy_path'], + policy_data.gpt_ini_info, + policy_data.admx_registry_classes[registry_class]['gpt_extension_location']) except Exception as e: log.error('Unhandled exception {0} occurred while attempting to write Adm Template Policy File'.format(e)) return False