From a5f9429e69b60296b4297b466a340f3b62870df5 Mon Sep 17 00:00:00 2001 From: Twangboy Date: Fri, 21 Oct 2022 12:42:08 -0600 Subject: [PATCH] Added support for AD Policies --- changelog/62873.fixed | 1 + salt/modules/win_lgpo.py | 49 ++++++++ salt/utils/win_lgpo_reg.py | 3 - .../modules/win_lgpo/test_defined_policies.py | 119 ++++++++++++++++++ 4 files changed, 169 insertions(+), 3 deletions(-) create mode 100644 changelog/62873.fixed create mode 100644 tests/pytests/unit/modules/win_lgpo/test_defined_policies.py diff --git a/changelog/62873.fixed b/changelog/62873.fixed new file mode 100644 index 00000000000..10d1a8c573c --- /dev/null +++ b/changelog/62873.fixed @@ -0,0 +1 @@ +LGPO: Added support for missing domain controller policies: VulnerableChannelAllowList and LdapEnforceChannelBinding diff --git a/salt/modules/win_lgpo.py b/salt/modules/win_lgpo.py index 38aebc2c31b..99adf1ae298 100644 --- a/salt/modules/win_lgpo.py +++ b/salt/modules/win_lgpo.py @@ -496,6 +496,13 @@ class _policy_info: None: "Not Defined", "(value not set)": "Not Defined", } + self.ldap_server_binding_token_requirements = { + 0: "Never", + 1: "When supported", + 2: "Always", + None: "Not Defined", + "(value not set)": "Not Defined", + } self.ldap_server_signing_requirements = { 1: "None", 2: "Require signing", @@ -2698,6 +2705,48 @@ class _policy_info: }, "Transform": self.enabled_one_disabled_zero_strings_transform, }, + "VulnerableChannelAllowList": { + "Policy": ( + "Domain controller: Allow vulnerable Netlogon " + "secure channel connections" + ), + "lgpo_section": self.security_options_gpedit_path, + "Registry": { + "Hive": "HKEY_LOCAL_MACHINE", + "Path": ( + "SYSTEM\\CurrentControlSet\\Services\\" + "Netlogon\\Parameters" + ), + "Value": "VulnerableChannelAllowList", + "Type": "REG_SZ", + }, + "Transform": {"Put": "_string_put_transform"}, + }, + "LdapEnforceChannelBinding": { + "Policy": "Domain controller: LDAP server channel binding token requirements", + "Settings": self.ldap_server_binding_token_requirements.keys(), + "lgpo_section": self.security_options_gpedit_path, + "Registry": { + "Hive": "HKEY_LOCAL_MACHINE", + "Path": ( + "System\\CurrentControlSet\\Services\\NTDS\\Parameters" + ), + "Value": "LdapEnforceChannelBinding", + "Type": "REG_DWORD", + }, + "Transform": { + "Get": "_dict_lookup", + "Put": "_dict_lookup", + "GetArgs": { + "lookup": self.ldap_server_binding_token_requirements, + "value_lookup": False, + }, + "PutArgs": { + "lookup": self.ldap_server_binding_token_requirements, + "value_lookup": True, + }, + }, + }, "LDAPServerIntegrity": { "Policy": "Domain controller: LDAP server signing requirements", "Settings": self.ldap_server_signing_requirements.keys(), diff --git a/salt/utils/win_lgpo_reg.py b/salt/utils/win_lgpo_reg.py index cdd0086f427..da4c4377631 100644 --- a/salt/utils/win_lgpo_reg.py +++ b/salt/utils/win_lgpo_reg.py @@ -57,9 +57,6 @@ def __virtual__(): if not salt.utils.platform.is_windows(): return False, "LGPO_REG Util: Only available on Windows" - if "lgpo_reg.get_value" not in __salt__: - return False, "LGPO_REG Util: lgpo_reg module not available" - return __virtualname__ diff --git a/tests/pytests/unit/modules/win_lgpo/test_defined_policies.py b/tests/pytests/unit/modules/win_lgpo/test_defined_policies.py new file mode 100644 index 00000000000..06e91666775 --- /dev/null +++ b/tests/pytests/unit/modules/win_lgpo/test_defined_policies.py @@ -0,0 +1,119 @@ +""" +This tests policies that are defined in the giant dictionary in the LGPO module +""" +import pytest + +import salt.modules.win_file as win_file +import salt.modules.win_lgpo as win_lgpo +import salt.utils.win_reg as win_reg + +pytestmark = [ + pytest.mark.windows_whitelisted, + pytest.mark.skip_unless_on_windows, +] + + +@pytest.fixture +def configure_loader_modules(tmp_path): + cache_dir = tmp_path / "__test_admx_policy_cache_dir" + cache_dir.mkdir(parents=True, exist_ok=True) + return { + win_lgpo: { + "__salt__": { + "file.file_exists": win_file.file_exists, + "file.makedirs": win_file.makedirs_, + }, + "__opts__": { + "cachedir": str(cache_dir), + }, + "__utils__": { + "reg.set_value": win_reg.set_value, + "reg.read_value": win_reg.read_value, + "reg.delete_value": win_reg.delete_value, + }, + "__context__": {}, + }, + } + + +@pytest.mark.destructive_test +def test_vuln_channel_allow(): + key = "SYSTEM\\CurrentControlSet\\Services\\Netlogon\\Parameters" + vname = "VulnerableChannelAllowList" + setting = "O:BAG:BAD:(A;;RC;;;BA)" + win_reg.delete_value(hive="HKLM", key=key, vname=vname) + try: + win_lgpo.set_computer_policy(name=vname, setting=setting) + result = win_reg.read_value(hive="HKLM", key=key, vname=vname) + assert result["vdata"] == setting + finally: + win_reg.delete_value(hive="HKLM", key=key, vname=vname) + + +@pytest.mark.destructive_test +def test_vuln_channel_allow_not_defined(): + key = "SYSTEM\\CurrentControlSet\\Services\\Netlogon\\Parameters" + vname = "VulnerableChannelAllowList" + win_reg.set_value(hive="HKLM", key=key, vname=vname, vdata="junk", vtype="REG_SZ") + try: + win_lgpo.set_computer_policy(name=vname, setting="Not Defined") + assert not win_reg.value_exists(hive="HKLM", key=key, vname=vname) + finally: + win_reg.delete_value(hive="HKLM", key=key, vname=vname) + + +@pytest.mark.destructive_test +def test_ldap_channel_binding_never(): + key = "SYSTEM\\CurrentControlSet\\Services\\NTDS\\Parameters" + vname = "LdapEnforceChannelBinding" + setting = "Never" + win_reg.delete_value(hive="HKLM", key=key, vname=vname) + try: + win_lgpo.set_computer_policy(name=vname, setting=setting) + result = win_reg.read_value(hive="HKLM", key=key, vname=vname) + assert result["vdata"] == 0 + finally: + + win_reg.delete_value(hive="HKLM", key=key, vname=vname) + + +@pytest.mark.destructive_test +def test_ldap_channel_binding_when_supported(): + key = "SYSTEM\\CurrentControlSet\\Services\\NTDS\\Parameters" + vname = "LdapEnforceChannelBinding" + setting = "When supported" + win_reg.delete_value(hive="HKLM", key=key, vname=vname) + try: + win_lgpo.set_computer_policy(name=vname, setting=setting) + result = win_reg.read_value(hive="HKLM", key=key, vname=vname) + assert result["vdata"] == 1 + finally: + + win_reg.delete_value(hive="HKLM", key=key, vname=vname) + + +@pytest.mark.destructive_test +def test_ldap_channel_binding_always(): + key = "SYSTEM\\CurrentControlSet\\Services\\NTDS\\Parameters" + vname = "LdapEnforceChannelBinding" + setting = "Always" + win_reg.delete_value(hive="HKLM", key=key, vname=vname) + try: + win_lgpo.set_computer_policy(name=vname, setting=setting) + result = win_reg.read_value(hive="HKLM", key=key, vname=vname) + assert result["vdata"] == 2 + finally: + + win_reg.delete_value(hive="HKLM", key=key, vname=vname) + + +@pytest.mark.destructive_test +def test_ldap_channel_binding_not_defined(): + key = "SYSTEM\\CurrentControlSet\\Services\\NTDS\\Parameters" + vname = "LdapEnforceChannelBinding" + win_reg.set_value(hive="HKLM", key=key, vname=vname, vdata=1, vtype="REG_DWORD") + try: + win_lgpo.set_computer_policy(name=vname, setting="Not Defined") + assert not win_reg.value_exists(hive="HKLM", key=key, vname=vname) + finally: + win_reg.delete_value(hive="HKLM", key=key, vname=vname)