Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog/68354.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Read auditpol /backup CSV using the Windows locale/ANSI encoding so ``lgpo.get`` works on non-English Windows (e.g. German).
14 changes: 13 additions & 1 deletion salt/utils/win_lgpo_auditpol.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
value='No Auditing')
"""

import locale
import logging
import re
import tempfile
Expand Down Expand Up @@ -277,6 +278,17 @@ def set_setting(name, value):
return True


def _auditpol_backup_encoding():
"""
Encoding used by ``auditpol /backup`` CSV files: the system ANSI / locale
encoding, not UTF-8 (see Salt issue #68354 on localized Windows).
"""
try:
return locale.getencoding()
except AttributeError:
return "mbcs"


def get_auditpol_dump():
"""
Gets the contents of an auditpol /backup. Used by the LGPO module to get
Expand All @@ -301,5 +313,5 @@ def get_auditpol_dump():
cmd = f"/backup /file:{csv_file}"
_auditpol_cmd(cmd)

with salt.utils.files.fopen(csv_file) as fp:
with salt.utils.files.fopen(csv_file, encoding=_auditpol_backup_encoding()) as fp:
return fp.readlines()
41 changes: 41 additions & 0 deletions tests/pytests/unit/utils/win_lgpo/test_auditpol.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import locale
import random
import sys

import pytest

Expand Down Expand Up @@ -109,3 +111,42 @@ def test_get_auditpol_dump():
found = True
break
assert found is True


def test_auditpol_backup_encoding_mbcs_fallback():
if sys.version_info < (3, 11):
# locale.getencoding does not exist; implementation falls back to mbcs.
assert win_lgpo_auditpol._auditpol_backup_encoding() == "mbcs"
else:
with patch.object(locale, "getencoding", side_effect=AttributeError):
assert win_lgpo_auditpol._auditpol_backup_encoding() == "mbcs"


def test_get_auditpol_dump_non_utf8_csv(tmp_path):
"""
auditpol /backup CSV uses system ANSI encoding (e.g. cp1252), not UTF-8.
"""
csv_path = tmp_path / "auditpol-backup.csv"
# 0xDC is "Ü" in cp1252 — invalid as UTF-8 alone (issue #68354).
csv_path.write_bytes(b"col1;col2\nMachine Name;\xdcber\n")

class FakeTmp:
name = str(csv_path)

def __enter__(self):
return self

def __exit__(self, *args):
return False

with patch.object(
win_lgpo_auditpol.tempfile, "NamedTemporaryFile", return_value=FakeTmp()
):
with patch.object(win_lgpo_auditpol, "_auditpol_cmd", MagicMock()):
with patch.object(
win_lgpo_auditpol,
"_auditpol_backup_encoding",
return_value="cp1252",
):
lines = win_lgpo_auditpol.get_auditpol_dump()
assert any("Über" in line for line in lines), lines
Loading