Fix issue overwriting existing values in Registry.pol

This commit is contained in:
twangboy 2023-06-01 15:17:19 -06:00 committed by Megan Wilhite
parent c909a7293a
commit 7d765c5fcc
4 changed files with 125 additions and 12 deletions

5
changelog/64401.fixed.md Normal file
View file

@ -0,0 +1,5 @@
Fixed an issue with ``lgpo_reg`` where existing entries for the same key in
``Registry.pol`` were being overwritten in subsequent runs if the value name in
the subesequent run was contained in the existing value name. For example, a
key named ``SetUpdateNotificationLevel`` would be overwritten by a subsequent
run attempting to set ``UpdateNotificationLevel``

View file

@ -367,29 +367,40 @@ def set_value(
if key.lower() == p_key.lower():
found_key = p_key
for p_name in pol_data[p_key]:
if v_name.lower() in p_name.lower():
if v_name.lower() == p_name.lower().lstrip("**del."):
found_name = p_name
if found_key:
if found_name:
if "**del." in found_name:
log.debug(f"LGPO_REG Mod: Found disabled name: {found_name}")
pol_data[found_key][v_name] = pol_data[found_key].pop(found_name)
found_name = v_name
log.debug(f"LGPO_REG Mod: Updating value: {found_name}")
pol_data[found_key][found_name] = {"data": v_data, "type": v_type}
else:
log.debug(f"LGPO_REG Mod: Setting new value: {found_name}")
pol_data[found_key][v_name] = {"data": v_data, "type": v_type}
else:
log.debug(f"LGPO_REG Mod: Adding new key and value: {found_name}")
pol_data[key] = {v_name: {"data": v_data, "type": v_type}}
write_reg_pol(pol_data, policy_class=policy_class)
success = True
if not write_reg_pol(pol_data, policy_class=policy_class):
log.error("LGPO_REG Mod: Failed to write registry.pol file")
success = False
return salt.utils.win_reg.set_value(
if not salt.utils.win_reg.set_value(
hive=hive,
key=key,
vname=v_name,
vdata=v_data,
vtype=v_type,
)
):
log.error("LGPO_REG Mod: Failed to set registry entry")
success = False
return success
def disable_value(key, v_name, policy_class="machine"):
@ -445,28 +456,42 @@ def disable_value(key, v_name, policy_class="machine"):
if key.lower() == p_key.lower():
found_key = p_key
for p_name in pol_data[p_key]:
if v_name.lower() in p_name.lower():
if v_name.lower() == p_name.lower().lstrip("**del."):
found_name = p_name
if found_key:
if found_name:
if "**del." in found_name:
# Already set to delete... do nothing
log.debug(f"LGPO_REG Mod: Already disabled: {v_name}")
return None
log.debug(f"LGPO_REG Mod: Disabling value name: {v_name}")
pol_data[found_key].pop(found_name)
found_name = "**del.{}".format(found_name)
pol_data[found_key][found_name] = {"data": " ", "type": "REG_SZ"}
else:
log.debug(f"LGPO_REG Mod: Setting new disabled value name: {v_name}")
pol_data[found_key]["**del.{}".format(v_name)] = {
"data": " ",
"type": "REG_SZ",
}
else:
log.debug(f"LGPO_REG Mod: Adding new key and disabled value name: {found_name}")
pol_data[key] = {"**del.{}".format(v_name): {"data": " ", "type": "REG_SZ"}}
write_reg_pol(pol_data, policy_class=policy_class)
success = True
if not write_reg_pol(pol_data, policy_class=policy_class):
log.error("LGPO_REG Mod: Failed to write registry.pol file")
success = False
return salt.utils.win_reg.delete_value(hive=hive, key=key, vname=v_name)
ret = salt.utils.win_reg.delete_value(hive=hive, key=key, vname=v_name)
if not ret:
if ret is None:
log.debug("LGPO_REG Mod: Registry key/value already missing")
else:
log.error("LGPO_REG Mod: Failed to remove registry entry")
success = False
return success
def delete_value(key, v_name, policy_class="Machine"):
@ -523,20 +548,37 @@ def delete_value(key, v_name, policy_class="Machine"):
if key.lower() == p_key.lower():
found_key = p_key
for p_name in pol_data[p_key]:
if v_name.lower() in p_name.lower():
if v_name.lower() == p_name.lower().lstrip("**del."):
found_name = p_name
if found_key:
if found_name:
log.debug(f"LGPO_REG Mod: Removing value name: {found_name}")
pol_data[found_key].pop(found_name)
else:
log.debug(f"LGPO_REG Mod: Value name not found: {v_name}")
return None
if len(pol_data[found_key]) == 0:
log.debug(f"LGPO_REG Mod: Removing empty key: {found_key}")
pol_data.pop(found_key)
else:
log.debug(f"LGPO_REG Mod: Key not found: {key}")
return None
write_reg_pol(pol_data, policy_class=policy_class)
success = True
if not write_reg_pol(pol_data, policy_class=policy_class):
log.error("LGPO_REG Mod: Failed to write registry.pol file")
success = False
return salt.utils.win_reg.delete_value(hive=hive, key=key, vname=v_name)
ret = salt.utils.win_reg.delete_value(hive=hive, key=key, vname=v_name)
if not ret:
if ret is None:
log.debug("LGPO_REG Mod: Registry key/value already missing")
else:
log.error("LGPO_REG Mod: Failed to remove registry entry")
success = False
return success
# This is for testing different settings and verifying that we are writing the

View file

@ -96,7 +96,7 @@ def read_reg_pol_file(reg_pol_path):
"""
return_data = None
if os.path.exists(reg_pol_path):
log.debug("LGPO_REG Utils: Reading from %s", reg_pol_path)
log.debug("LGPO_REG Util: Reading from %s", reg_pol_path)
with salt.utils.files.fopen(reg_pol_path, "rb") as pol_file:
return_data = pol_file.read()
return return_data

View file

@ -217,6 +217,38 @@ def test_machine_value_present(empty_reg_pol_mach):
assert result == expected
def test_machine_value_present_similar_names(empty_reg_pol_mach):
"""
Test value.present in Machine policy
"""
lgpo_reg.value_present(
name="MyValueTwo",
key="SOFTWARE\\MyKey1",
v_data="1",
v_type="REG_DWORD",
)
lgpo_reg.value_present(
name="MyValue",
key="SOFTWARE\\MyKey1",
v_data="1",
v_type="REG_DWORD",
)
expected = {
"SOFTWARE\\MyKey1": {
"MyValue": {
"type": "REG_DWORD",
"data": 1,
},
"MyValueTwo": {
"type": "REG_DWORD",
"data": 1,
},
},
}
result = win_lgpo_reg.read_reg_pol(policy_class="Machine")
assert result == expected
def test_machine_value_present_enforce(reg_pol_mach):
"""
Issue #64222
@ -614,6 +646,40 @@ def test_user_value_present(empty_reg_pol_user):
assert result == expected
def test_user_value_present_similar_names(empty_reg_pol_user):
"""
Test value.present in User policy
"""
lgpo_reg.value_present(
name="MyValueTwo",
key="SOFTWARE\\MyKey1",
v_data="1",
v_type="REG_DWORD",
policy_class="User",
)
lgpo_reg.value_present(
name="MyValue",
key="SOFTWARE\\MyKey1",
v_data="1",
v_type="REG_DWORD",
policy_class="User",
)
expected = {
"SOFTWARE\\MyKey1": {
"MyValue": {
"type": "REG_DWORD",
"data": 1,
},
"MyValueTwo": {
"type": "REG_DWORD",
"data": 1,
},
},
}
result = win_lgpo_reg.read_reg_pol(policy_class="User")
assert result == expected
def test_user_value_present_existing_change(reg_pol_user):
"""
Test value.present with existing incorrect value in User policy