Last active
February 4, 2016 22:01
-
-
Save lorengordon/a1d1c08e8587d92d3612 to your computer and use it in GitHub Desktop.
Salt execution module to manage local group policy via Apply_LGPO_Delta.exe
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
r''' | |
Manage Local Policy Group Policy Objects on Windows | |
This module uses ``Apply_LGPO_Delta.exe``, the license for which restricts it | |
from being distributed by a third-party application. According to Microsoft[1], | |
users must obtain it from the site below[2] and may then distribute it within | |
their own organization. | |
[1] https://blogs.technet.microsoft.com/fdcc/2010/03/24/sample-files-for | |
-apply_lgpo_delta/#comment-163 | |
[2] https://blogs.technet.microsoft.com/fdcc/2010/01/15/updated-lgpo-utility | |
-sources/ | |
:maintainer: Loren Gordon <loren.gordon@plus3it.com> | |
:depends: Apply_LGPO_Delta.exe in %SystemRoot%\System32\ | |
:platform: Windows | |
''' | |
import collections | |
import logging | |
import os | |
import salt.utils | |
from salt.exceptions import CommandExecutionError, SaltInvocationError | |
log = logging.getLogger(__name__) | |
__virtualname__ = 'lgpo' | |
LGPO_EXE = '{0}\\system32\\Apply_LGPO_Delta.exe'.format(os.environ.get( | |
'SYSTEMROOT')) | |
HAS_LGPO = os.path.isfile(LGPO_EXE) | |
class PolicyHelper(object): | |
def __init__(self): | |
self.LGPO_VTYPE_KEYS = ['key', 'value', 'vtype'] | |
self.LGPO_ACTION_KEYS = ['key', 'action'] | |
self.LGPO_SECEDIT_KEYS = ['name', 'value'] | |
self.REGISTRY_MAP = { | |
'actions': { | |
'DELETE': 'DELETE', | |
'DELETEALLVALUES': 'DELETEALLVALUES', | |
'CREATEKEY': 'CREATEKEY', | |
# 'SETVALUE' : 'SETVALUE', | |
}, | |
'vtypes': { | |
'DWORD': 'DWORD', | |
'REG_DWORD': 'DWORD', | |
'SZ': 'SZ', | |
'REG_SZ': 'SZ', | |
'EXSZ': 'EXSZ', | |
'REG_EXPAND_SZ': 'EXSZ', | |
}, | |
'hives': { | |
'COMPUTER': 'Computer', | |
'HKLM': 'Computer', | |
'MACHINE': 'Computer', | |
'HKEY_LOCAL_MACHINE': 'Computer', | |
'USER': 'User', | |
'HKCU': 'User', | |
'HKEY_CURRENT_USER': 'User', | |
}, | |
} | |
self.SECEDIT_MAP = { | |
'MINIMUMPASSWORDAGE': { | |
'type': 'SYSTEM_ACCESS', | |
'name': 'MinimumPasswordAge', | |
}, | |
'MAXIMUMPASSWORDAGE': { | |
'type': 'SYSTEM_ACCESS', | |
'name': 'MaximumPasswordAge', | |
}, | |
'MINIMUMPASSWORDLENGTH': { | |
'type': 'SYSTEM_ACCESS', | |
'name': 'MinimumPasswordLength', | |
}, | |
'PASSWORDCOMPLEXITY': { | |
'type': 'SYSTEM_ACCESS', | |
'name': 'PasswordComplexity', | |
}, | |
'PASSWORDHISTORYSIZE': { | |
'type': 'SYSTEM_ACCESS', | |
'name': 'PasswordHistorySize', | |
}, | |
'LOCKOUTBADCOUNT': { | |
'type': 'SYSTEM_ACCESS', | |
'name': 'LockoutBadCount', | |
}, | |
'RESETLOCKOUTCOUNT': { | |
'type': 'SYSTEM_ACCESS', | |
'name': 'ResetLockoutCount', | |
}, | |
'LOCKOUTDURATION': { | |
'type': 'SYSTEM_ACCESS', | |
'name': 'LockoutDuration', | |
}, | |
'FORCELOGOFFWHENHOUREXPIRE': { | |
'type': 'SYSTEM_ACCESS', | |
'name': 'ForceLogoffWhenHourExpire', | |
}, | |
'CLEARTEXTPASSWORD': { | |
'type': 'SYSTEM_ACCESS', | |
'name': 'ClearTextPassword', | |
}, | |
'LSAANONYMOUSNAMELOOKUP': { | |
'type': 'SYSTEM_ACCESS', | |
'name': 'LsaAnonymousLookup', | |
}, | |
'ENABLEGUESTACCOUNT': { | |
'type': 'SYSTEM_ACCESS', | |
'name': 'EnableGuestAccount', | |
}, | |
'SESECURITYPRIVILEGE': { | |
'type': 'PRIVILEGE_RIGHTS', | |
'name': 'SeSecurityPrivilege', | |
}, | |
'SEASSIGNPRIMARYTOKENPRIVILEGE': { | |
'type': 'PRIVILEGE_RIGHTS', | |
'name': 'SeAssignPrimaryTokenPrivilege', | |
}, | |
'SERELABELPRIVILEGE': { | |
'type': 'PRIVILEGE_RIGHTS', | |
'name': 'SeRelabelPrivilege', | |
}, | |
'SECREATETOKENPRIVILEGE': { | |
'type': 'PRIVILEGE_RIGHTS', | |
'name': 'SeCreateTokenPrivilege', | |
}, | |
'SETRUSTEDCREDMANACCESSPRIVILEGE': { | |
'type': 'PRIVILEGE_RIGHTS', | |
'name': 'SeTrustedCredManAccessPrivilege', | |
}, | |
'SEREMOTEINTERACTIVELOGONRIGHT': { | |
'type': 'PRIVILEGE_RIGHTS', | |
'name': 'SeRemoteInteractiveLogonRight', | |
}, | |
'SECREATEPAGEFILEPRIVILEGE': { | |
'type': 'PRIVILEGE_RIGHTS', | |
'name': 'SeCreatePagefilePrivilege', | |
}, | |
'SEREMOTESHUTDOWNPRIVILEGE': { | |
'type': 'PRIVILEGE_RIGHTS', | |
'name': 'SeRemoteShutdownPrivilege', | |
}, | |
'SEDENYINTERACTIVELOGONRIGHT': { | |
'type': 'PRIVILEGE_RIGHTS', | |
'name': 'SeDenyInteractiveLogonRight', | |
}, | |
'SEINCREASEBASEPRIORITYPRIVILEGE': { | |
'type': 'PRIVILEGE_RIGHTS', | |
'name': 'SeIncreaseBasePriorityPrivilege', | |
}, | |
'SELOADDRIVERPRIVILEGE': { | |
'type': 'PRIVILEGE_RIGHTS', | |
'name': 'SeLoadDriverPrivilege', | |
}, | |
'SERESTOREPRIVILEGE': { | |
'type': 'PRIVILEGE_RIGHTS', | |
'name': 'SeRestorePrivilege', | |
}, | |
'SESYSTEMTIMEPRIVILEGE': { | |
'type': 'PRIVILEGE_RIGHTS', | |
'name': 'SeSystemTimePrivilege', | |
}, | |
'SECREATEGLOBALPRIVILEGE': { | |
'type': 'PRIVILEGE_RIGHTS', | |
'name': 'SeCreateGlobalPrivilege', | |
}, | |
'SEMANAGEVOLUMEPRIVILEGE': { | |
'type': 'PRIVILEGE_RIGHTS', | |
'name': 'SeManageVolumePrivilege', | |
}, | |
'SEDENYBATCHLOGONRIGHT': { | |
'type': 'PRIVILEGE_RIGHTS', | |
'name': 'SeDenyBatchLogonRight', | |
}, | |
'SEINTERACTIVELOGONRIGHT': { | |
'type': 'PRIVILEGE_RIGHTS', | |
'name': 'SeInteractiveLogonRight', | |
}, | |
'SEENABLEDELEGATIONPRIVILEGE': { | |
'type': 'PRIVILEGE_RIGHTS', | |
'name': 'SeEnableDelegationPrivilege', | |
}, | |
'SECREATEPERMANENTPRIVILEGE': { | |
'type': 'PRIVILEGE_RIGHTS', | |
'name': 'SeCreatePermanentPrivilege', | |
}, | |
'SEDEBUGPRIVILEGE': { | |
'type': 'PRIVILEGE_RIGHTS', | |
'name': 'SeDebugPrivilege', | |
}, | |
'SESYSTEMPROFILEPRIVILEGE': { | |
'type': 'PRIVILEGE_RIGHTS', | |
'name': 'SeSystemProfilePrivilege', | |
}, | |
'SEPROFILESINGLEPROCESSPRIVILEGE': { | |
'type': 'PRIVILEGE_RIGHTS', | |
'name': 'SeProfileSingleProcessPrivilege', | |
}, | |
'SEBACKUPPRIVILEGE': { | |
'type': 'PRIVILEGE_RIGHTS', | |
'name': 'SeBackupPrivilege', | |
}, | |
'SENETWORKLOGONRIGHT': { | |
'type': 'PRIVILEGE_RIGHTS', | |
'name': 'SeNetworkLogonRight', | |
}, | |
'SEINCREASEQUOTAPRIVILEGE': { | |
'type': 'PRIVILEGE_RIGHTS', | |
'name': 'SeIncreaseQuotaPrivilege', | |
}, | |
'SESHUTDOWNPRIVILEGE': { | |
'type': 'PRIVILEGE_RIGHTS', | |
'name': 'SeShutdownPrivilege', | |
}, | |
'SECREATESYMBOLICLINKPRIVILEGE': { | |
'type': 'PRIVILEGE_RIGHTS', | |
'name': 'SeCreateSymbolicLinkPrivilege', | |
}, | |
'SETIMEZONEPRIVILEGE': { | |
'type': 'PRIVILEGE_RIGHTS', | |
'name': 'SeTimeZonePrivilege', | |
}, | |
'SEDENYNETWORKLOGONRIGHT': { | |
'type': 'PRIVILEGE_RIGHTS', | |
'name': 'SeDenyNetworkLogonRight', | |
}, | |
'SEIMPERSONATEPRIVILEGE': { | |
'type': 'PRIVILEGE_RIGHTS', | |
'name': 'SeImpersonatePrivilege', | |
}, | |
'SESYSTEMENVIRONMENTPRIVILEGE': { | |
'type': 'PRIVILEGE_RIGHTS', | |
'name': 'SeSystemEnvironmentPrivilege', | |
}, | |
'SELOCKMEMORYPRIVILEGE': { | |
'type': 'PRIVILEGE_RIGHTS', | |
'name': 'SeLockMemoryPrivilege', | |
}, | |
'SETCBPRIVILEGE': { | |
'type': 'PRIVILEGE_RIGHTS', | |
'name': 'SeTcbPrivilege', | |
}, | |
'SEAUDITPRIVILEGE': { | |
'type': 'PRIVILEGE_RIGHTS', | |
'name': 'SeAuditPrivilege', | |
}, | |
'SETAKEOWNERSHIPPRIVILEGE': { | |
'type': 'PRIVILEGE_RIGHTS', | |
'name': 'SeTakeOwnershipPrivilege', | |
}, | |
'SEDENYREMOTEINTERACTIVELOGONRIGHT': { | |
'type': 'PRIVILEGE_RIGHTS', | |
'name': 'SeDenyRemoteInteractiveLogonRight', | |
}, | |
'SEDENYSERVICELOGONRIGHT': { | |
'type': 'PRIVILEGE_RIGHTS', | |
'name': 'SeDenyServiceLogonRight', | |
}, | |
} | |
def _regpol_hive(self, hive): | |
try: | |
return self.REGISTRY_MAP['hives'][hive.upper()] | |
except KeyError: | |
pass | |
return None | |
def _regpol_key(self, key): | |
try: | |
hive = self._regpol_hive(key.split('\\')[0]) | |
key_path = '\\'.join(key.split('\\')[1:-1]) | |
vname = key.split('\\')[-1] | |
return hive, key_path, vname | |
except AttributeError: | |
pass | |
return None, None, None | |
def _regpol_vtype(self, vtype): | |
try: | |
return self.REGISTRY_MAP['vtypes'][vtype.upper()] | |
except KeyError: | |
pass | |
return None | |
def _regpol_action(self, action): | |
try: | |
return self.REGISTRY_MAP['actions'][action.upper()] | |
except KeyError: | |
pass | |
return None | |
def _key_path_picker(self, key_path, vname, action): | |
if not action or action in ['DELETE']: | |
# Action is setvalue or delete | |
return key_path | |
# Action is deleteallkeys or createkey | |
return '\\'.join([key_path, vname]) | |
def _vname_picker(self, vname, action): | |
if not action or action in ['DELETE']: | |
# Action is setvalue or delete | |
return vname | |
# Action is deleteallkeys or createkey | |
return '*' | |
def _action_picker(self, vtype, value, action): | |
return action if action else '{0}:{1}'.format(vtype, value) | |
def validate_regpol(self, policy): | |
if not all(key in policy for key in self.LGPO_VTYPE_KEYS) and not \ | |
all(key in policy for key in self.LGPO_ACTION_KEYS): | |
return False, 'Registry policy dictionary is malformed' | |
hive, key_path, vname = self._regpol_key(policy.get('key', '')) | |
value = policy.get('value', '') | |
vtype = self._regpol_vtype(policy.get('vtype', '')) | |
action = self._regpol_action(policy.get('action', '')) | |
if not key_path: | |
return (False, 'Value of "key" is malformed, it must contain the ' | |
'"hive" and the path to the registry key or ' | |
'registry value') | |
if not hive: | |
return (False, 'Value of "hive" (the first token in "key") is ' | |
'invalid') | |
if policy.get('vtype') and not vtype: | |
return False, 'Value of "vtype" is invalid' | |
if policy.get('action') and not action: | |
return False, 'Value of "action" is invalid' | |
if vtype and action: | |
return (False, 'Detected both "vtype" and "action", ensure only ' | |
'one is present') | |
return ( | |
{ | |
'hive': hive, | |
'key_path': self._key_path_picker(key_path, vname, action), | |
'vname': self._vname_picker(vname, action), | |
'action': self._action_picker(vtype, value, action), | |
}, | |
'' | |
) | |
def _secedit_name(self, name): | |
try: | |
return self.SECEDIT_MAP[name.upper()]['name'] | |
except KeyError: | |
pass | |
return None | |
def validate_secedit(self, policy): | |
if not all(key in policy for key in self.LGPO_SECEDIT_KEYS): | |
return False, 'Secedit policy dictionary is malformed' | |
name = self._secedit_name(policy.get('name', '')) | |
value = policy.get('value', '') | |
if not name: | |
return False, 'Secedit policy name "{0}" is unknown'.format(name) | |
return ( | |
{ | |
'name': name, | |
'value': value | |
}, | |
'' | |
) | |
def policy_template_regpol(self, policies): | |
policy_template = [] | |
for policy in policies: | |
policy_template.extend( | |
[ | |
policy['hive'], | |
policy['key_path'], | |
policy['vname'], | |
policy['action'], | |
';' | |
] | |
) | |
return policy_template | |
def policy_template_secedit(self, policies): | |
policy_template = [ | |
'[Unicode]', | |
'Unicode=yes', | |
'[Version]', | |
'signature="$CHICAGO$"', | |
'Revision=1' | |
] | |
system_access_template = [ | |
'[System Access]' | |
] | |
privilege_rights_template = [ | |
'[Privilege Rights]' | |
] | |
for policy in policies: | |
policy_map = self.SECEDIT_MAP[policy['name'].upper()] | |
if policy_map['type'] == 'SYSTEM_ACCESS': | |
system_access_template.append('{0} = {1}' | |
.format(policy_map['name'], | |
policy['value'])) | |
elif policy_map['type'] == 'PRIVILEGE_RIGHTS': | |
privilege_rights_template.append('{0} = {1}' | |
.format(policy_map['name'], | |
policy['value'])) | |
return (policy_template + system_access_template + | |
privilege_rights_template) | |
def __virtual__(): | |
''' | |
Load only on Windows and only if Apply_LGPO_Delta is present. | |
''' | |
if not salt.utils.is_windows(): | |
return False | |
if not HAS_LGPO: | |
return (False, 'Module "{0}" not loaded because "{1}" could not be ' | |
'found'.format(__virtualname__, LGPO_EXE)) | |
return __virtualname__ | |
def validate_policies(policies): | |
r''' | |
Validate a policy to manage Local Group Policy Objects, without applying | |
the policy. | |
Returns a tuple of (valid_policies, reason, policy). | |
If any policy is invalid, ``valid_policies`` is ``False``, ``reason`` | |
contains a string explaining why the policy is invalid, and ``policy`` | |
contains the policy that failed validation. | |
If all policies are valid, ``valid_policies`` is a dictionary of policy | |
types, where each ``policy_type`` key contains a list of policy | |
dictionaries that an be easily written to a file and executed with | |
Apply_LGPO_Delta.exe. `reason`` will be an empty string, and ``policy`` | |
will be an empty dictionary. | |
:param policies: | |
A policy dictionary, or a list of policy dictionaries. Each policy | |
dictionary must be of one of the forms below: | |
{ | |
'policy_type' : 'regpol', | |
'key' : '<hive>\path\to\registry\key\value_name', | |
'value' : 'value of the registry key', | |
'vtype' : 'DWORD' | 'SZ' | 'EXSZ' | |
} | |
-OR- | |
{ | |
'policy_type' : 'regpol', | |
'key' : '<hive>\path\to\registry\key\name', | |
'action' : 'DELETE' | 'DELETEALLVALUES' | 'CREATEKEY' | |
} | |
-OR- | |
{ | |
'policy_type' : 'secedit', | |
'name' : 'name of the secedit inf setting', | |
'value' : 'value to apply to the setting' | |
} | |
Policy dictionaries support the same aliases as the individual policy | |
parameters. See ``lgpo.set_registry_value`` for the aliases. | |
CLI Examples: | |
.. code-block:: bash | |
policies="[{'policy_type':'regpol', \ | |
'key':'HKLM\Software\Salt\Policies\Foo', \ | |
'value':'0', \ | |
'vtype':'DWORD'}]" | |
salt '*' lgpo.validate_policies policies="${policies}" | |
''' | |
ret = {} | |
policy_helper = PolicyHelper() | |
if not isinstance(policies, collections.Sequence): | |
policies = [policies] | |
for policy in policies: | |
if not isinstance(policy, collections.Mapping): | |
return False, 'Policy is not a dictionary object', policy | |
policy_type = policy.get('policy_type', '').lower() | |
try: | |
result, reason = getattr(policy_helper, 'validate_{0}' | |
.format(policy_type))(policy) | |
except AttributeError: | |
return (False, '`policy_type` is missing or the value is invalid ', | |
policy) | |
if not result: | |
return False, reason, policy | |
try: | |
ret[policy_type].append(result) | |
except KeyError: | |
ret[policy_type] = [result] | |
return ret, '', {} | |
def _write_policy_file(policy_template): | |
tmp_ = None | |
policy_file = '' | |
try: | |
tmp_, policy_file = salt.utils.mkstemp(close_fd=False) | |
os.write(tmp_, os.linesep.join(policy_template)) | |
return policy_file | |
except Exception as exc: | |
raise CommandExecutionError('Error saving LGPO policy file "{0}". ' | |
'Exception: {1}'.format(policy_file, exc)) | |
finally: | |
os.close(tmp_) | |
def _write_policy_files(valid_policies): | |
policy_files = {} | |
policy_helper = PolicyHelper() | |
for policy_type, policy_data in valid_policies.items(): | |
policy_template = getattr(policy_helper, 'policy_template_{0}' | |
.format(policy_type))(policy_data) | |
policy_files[policy_type] = _write_policy_file(policy_template) | |
return policy_files | |
def apply_policies(policies=None, logfile=True, errorfile=True): | |
r''' | |
Apply a policy that manages Local Group Policy Objects. | |
:param policies: | |
A policy dictionary, or a list of policy dictionaries. Each policy | |
dictionary must be of one of the forms below: | |
{ | |
'policy_type' : 'regpol', | |
'key' : '<hive>\path\to\registry\key\value_name', | |
'value' : 'value of the registry key', | |
'vtype' : 'DWORD' | 'SZ' | 'EXSZ' | |
} | |
-OR- | |
{ | |
'policy_type' : 'regpol', | |
'key' : '<hive>\path\to\registry\key\name', | |
'action' : 'DELETE' | 'DELETEALLVALUES' | 'CREATEKEY' | |
} | |
-OR- | |
{ | |
'policy_type' : 'secedit', | |
'name' : 'name of the secedit inf setting', | |
'value' : 'value to apply to the setting' | |
} | |
Policy dictionaries support the same aliases as the individual policy | |
parameters. See ``lgpo.set_registry_value`` for the aliases. | |
:param logfile: | |
The path to the log file where the results of applying the policy will | |
be saved. If set to ``True`` (the Default), then the log file will be | |
created in the system temp directory. If set to ``False``, then no log | |
file will be created. | |
:param errorfile: | |
The path to the error file where errors resulting from applying the | |
policy will be saved. If set to ``True`` (the Default), then the error | |
file will be created in the system temp directory. If set to | |
``False``, then no error file will be created. | |
CLI Examples: | |
.. code-block:: bash | |
policies="[{'policy_type':'regpol', \ | |
'key':'HKLM\Software\Salt\Policies\Foo', \ | |
'value':'0', \ | |
'vtype':'DWORD'}]" | |
salt '*' lgpo.apply_policies policies="${policies}" | |
''' | |
valid_policies, reason, policy = validate_policies(policies) | |
if not valid_policies: | |
raise SaltInvocationError('{0}; policy={1}'.format(reason, policy)) | |
policy_files = _write_policy_files(valid_policies) | |
command = ' '.join([LGPO_EXE, policy_files.get('regpol', ''), | |
policy_files.get('secedit', '')]) | |
if logfile is True: | |
logfile = salt.utils.mkstemp(prefix='lgpo_', suffix='.log') | |
if logfile: | |
try: | |
__salt__['file.makedirs'](path=logfile) | |
except Exception as exc: | |
raise CommandExecutionError('Error creating directory for logfile ' | |
'"{0}". Exception: {1}'.format(logfile, | |
exc)) | |
log.info('LGPO log file is "{0}"'.format(logfile)) | |
command = ' '.join([command, '/log', logfile]) | |
if errorfile is True: | |
errorfile = salt.utils.mkstemp(prefix='lgpo_', suffix='.err') | |
if errorfile: | |
try: | |
__salt__['file.makedirs'](path=errorfile) | |
except Exception as exc: | |
raise CommandExecutionError('Error creating directory for ' | |
'errorfile "{0}". Exception: {1}' | |
.format(errorfile, exc)) | |
log.info('LGPO error file is "{0}"'.format(errorfile)) | |
command = ' '.join([command, '/error', errorfile]) | |
log.info('Applying LGPO policies') | |
log.debug('LGPO policy data: {0}'.format(valid_policies)) | |
try: | |
ret = __salt__['cmd.retcode'](command, python_shell=False) | |
except Exception as exc: | |
raise CommandExecutionError('Error applying LGPO policy template ' | |
'"{0}". Exception: {1}' | |
.format(valid_policies, exc)) | |
if ret: | |
raise CommandExecutionError('Non-zero exit [{0}] from {1}. We do not ' | |
'know what this means. Hopefully the error ' | |
'log contains details -- {2}' | |
.format(ret, LGPO_EXE, errorfile)) | |
for policy_file in policy_files.values(): | |
if os.path.isfile(policy_file): | |
os.remove(policy_file) | |
return valid_policies | |
def set_reg_value(key=None, value=None, vtype=None, logfile=True, | |
errorfile=True): | |
r''' | |
Use a Local Group Policy Object to set to a registry value. If the key | |
does not exist, it is created. | |
:param key: | |
Path to the registry setting managed by the policy. The path must be | |
in the form: ``<hive>\path\to\registry\key\value_name``. ``<hive>`` | |
may be one of ``Computer`` or ``User``. ``<hive>`` also supports | |
aliases the following aliases: | |
'Computer' : ['COMPUTER', 'HKLM', 'MACHINE', 'HKEY_LOCAL_MACHINE'] | |
'User' : ['USER', 'HKCU', 'HKEY_CURRENT_USER'] | |
``<hive>`` is case insensitive. | |
:param value: | |
Value to apply to the name. | |
:param vtype: | |
Type of registry entry required for this policy. Valid types include | |
``DWORD``, ``SZ``, or ``EXSZ``. These types also support the following | |
aliases: | |
'DWORD' : ['DWORD', 'REGDWORD', 'REG_DWORD'] | |
'SZ' : ['SZ', 'REGSZ', 'REG_SZ'] | |
'EXSZ' : ['EXSZ', 'REGEXPANDSZ', 'REG_EXPAND_SZ'] | |
``vtype`` is case insensitive. | |
:param logfile: | |
The path to the log file where the results of applying the policy will | |
be saved. If set to ``True`` (the Default), then the log file will be | |
created in the system temp directory. If set to ``False``, then no log | |
file will be created. | |
:param errorfile: | |
The path to the error file where errors resulting from applying the | |
policy will be saved. If set to ``True`` (the Default), then the error | |
file will be created in the system temp directory. If set to | |
``False``, then no error file will be created. | |
CLI Examples: | |
.. code-block:: bash | |
salt '*' lgpo.set_reg_value \ | |
key='HKLM\Software\Salt\Policies\Foo' \ | |
value='0' \ | |
vtype='DWORD' | |
salt '*' lgpo.set_reg_value \ | |
key='HKLM\Software\Salt\Policies\Bar' \ | |
value='baz' \ | |
vtype='SZ' | |
''' | |
return (apply_policies( | |
policies=[ | |
{ | |
'policy_type': 'regpol', | |
'key': key, | |
'value': value, | |
'vtype': vtype, | |
} | |
], | |
logfile=logfile, | |
errorfile=errorfile | |
)) | |
def create_reg_key(key=None, logfile=True, errorfile=True): | |
r''' | |
Use a Local Group Policy Object to create a registry key with no values. | |
:param key: | |
Path to the registry key managed by the policy. The path must be | |
in the form: ``<hive>\path\to\registry\key``. ``<hive>`` may be one of | |
``Computer`` or ``User``. ``<hive>`` also supports aliases the | |
following aliases: | |
'Computer' : ['COMPUTER', 'HKLM', 'MACHINE', 'HKEY_LOCAL_MACHINE'] | |
'User' : ['USER', 'HKCU', 'HKEY_CURRENT_USER'] | |
``<hive>`` is case insensitive. | |
:param logfile: | |
The path to the log file where the results of applying the policy will | |
be saved. If set to ``True`` (the Default), then the log file will be | |
created in the system temp directory. If set to ``False``, then no log | |
file will be created. | |
:param errorfile: | |
The path to the error file where errors resulting from applying the | |
policy will be saved. If set to ``True`` (the Default), then the error | |
file will be created in the system temp directory. If set to | |
``False``, then no error file will be created. | |
CLI Examples: | |
.. code-block:: bash | |
salt '*' lgpo.create_reg_key key='HKLM\Software\Salt\Policies\Foo' | |
salt '*' lgpo.create_reg_key key='HKLM\Software\Salt\Policies\Bar' | |
''' | |
return (apply_policies( | |
policies=[ | |
{ | |
'policy_type': 'regpol', | |
'key': key, | |
'action': 'CREATEKEY', | |
} | |
], | |
logfile=logfile, | |
errorfile=errorfile | |
)) | |
def delete_reg_value(key=None, logfile=True, errorfile=True): | |
r''' | |
Use a Local Group Policy Object to delete to a registry value. | |
:param key: | |
Path to the registry value to be removed by the policy. The path must | |
be in the form: ``<hive>\path\to\registry\key\value_name``. ``<hive>`` | |
may be one of ``Computer`` or ``User``. ``<hive>`` also supports | |
aliases the following aliases: | |
'Computer' : ['COMPUTER', 'HKLM', 'MACHINE', 'HKEY_LOCAL_MACHINE'] | |
'User' : ['USER', 'HKCU', 'HKEY_CURRENT_USER'] | |
``<hive>`` is case insensitive. | |
:param logfile: | |
The path to the log file where the results of applying the policy will | |
be saved. If set to ``True`` (the Default), then the log file will be | |
created in the system temp directory. If set to ``False``, then no log | |
file will be created. | |
:param errorfile: | |
The path to the error file where errors resulting from applying the | |
policy will be saved. If set to ``True`` (the Default), then the error | |
file will be created in the system temp directory. If set to | |
``False``, then no error file will be created. | |
CLI Examples: | |
.. code-block:: bash | |
salt '*' lgpo.delete_reg_value key='HKLM\Software\Salt\Policies\Foo' | |
salt '*' lgpo.delete_reg_value key='HKLM\Software\Salt\Policies\Bar' | |
''' | |
return (apply_policies( | |
policies=[ | |
{ | |
'policy_type': 'regpol', | |
'key': key, | |
'action': 'DELETE', | |
} | |
], | |
logfile=logfile, | |
errorfile=errorfile | |
)) | |
def delete_all_reg_values(key=None, logfile=True, errorfile=True): | |
r''' | |
Use a Local Group Policy Object to delete all values within a registry key. | |
:param key: | |
Path to the registry key containing the values to be removed. The path | |
must be in the form: ``<hive>\path\to\registry\key``. ``<hive>`` may be | |
one of ``Computer`` or ``User``. ``<hive>`` also supports aliases the | |
following aliases: | |
'Computer' : ['COMPUTER', 'HKLM', 'MACHINE', 'HKEY_LOCAL_MACHINE'] | |
'User' : ['USER', 'HKCU', 'HKEY_CURRENT_USER'] | |
``<hive>`` is case insensitive. | |
:param logfile: | |
The path to the log file where the results of applying the policy will | |
be saved. If set to ``True`` (the Default), then the log file will be | |
created in the system temp directory. If set to ``False``, then no log | |
file will be created. | |
:param errorfile: | |
The path to the error file where errors resulting from applying the | |
policy will be saved. If set to ``True`` (the Default), then the error | |
file will be created in the system temp directory. If set to | |
``False``, then no error file will be created. | |
CLI Examples: | |
.. code-block:: bash | |
salt '*' lgpo.delete_all_reg_values \ | |
key='HKLM\Software\Salt\Policies\Foo' | |
salt '*' lgpo.delete_all_reg_values \ | |
key='HKLM\Software\Salt\Policies\Bar' | |
''' | |
return (apply_policies( | |
policies=[ | |
{ | |
'policy_type': 'regpol', | |
'key': key, | |
'action': 'DELETEALLVALUES', | |
} | |
], | |
logfile=logfile, | |
errorfile=errorfile | |
)) | |
def set_secedit_value(name=None, value=None, logfile=True, errorfile=True): | |
r''' | |
Modify the value of a "System Access" or "Privilege Rights" security | |
policy. | |
:param name: | |
Name of the "System Access" or "Privilege Rights" policy to modify. | |
Parameter is case-insensitive. To get a list of known policy names, | |
use ``lgpo.get_secedit_names``. | |
:param value: | |
Value to apply to the policy. | |
:param logfile: | |
The path to the log file where the results of applying the policy will | |
be saved. If set to ``True`` (the Default), then the log file will be | |
created in the system temp directory. If set to ``False``, then no log | |
file will be created. | |
:param errorfile: | |
The path to the error file where errors resulting from applying the | |
policy will be saved. If set to ``True`` (the Default), then the error | |
file will be created in the system temp directory. If set to | |
``False``, then no error file will be created. | |
CLI Examples: | |
.. code-block:: bash | |
salt '*' lgpo.set_secedit_value name=MaximumPasswordAge value=60 | |
salt '*' lgpo.set_secedit_value name=SeDenyServiceLogonRight \ | |
value=Guests | |
salt '*' lgpo.set_secedit_value name=SeDenyNetworkLogonRight \ | |
value='*S-1-5-32-546' | |
''' | |
return (apply_policies( | |
policies=[ | |
{ | |
'policy_type': 'secedit', | |
'name': name, | |
'value': value, | |
} | |
], | |
logfile=logfile, | |
errorfile=errorfile | |
)) | |
def get_secedit_names(): | |
r''' | |
Returns all known "System Access" and "Privilege Rights" policy names. | |
''' | |
policy_helper = PolicyHelper() | |
system_access_names = [] | |
privilege_rights_names = [] | |
for policy in policy_helper.SECEDIT_MAP.values(): | |
if policy['type'] == 'SYSTEM_ACCESS': | |
system_access_names.append(policy['name']) | |
elif policy['type'] == 'PRIVILEGE_RIGHTS': | |
privilege_rights_names.append(policy['name']) | |
return ( | |
{ | |
'System Access': system_access_names, | |
'Privilege Rights': privilege_rights_names | |
} | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment