Make the win_function.get_sam_name function handle Everyone

This commit is contained in:
Shane Lee 2024-03-04 12:10:29 -07:00 committed by Daniel Wozniak
parent 0d6a8fb303
commit 8c86b5ec70
3 changed files with 44 additions and 14 deletions

1
changelog/63667.fixed.md Normal file
View file

@ -0,0 +1 @@
Fix user and group management on Windows to handle the Everyone group

View file

@ -184,11 +184,23 @@ def get_sam_name(username):
.. note:: Long computer names are truncated to 15 characters
"""
# Some special identity groups require special handling. They do not have
# the domain prepended to the name. They should be added here as they are
# discovered. Use the SID to be locale agnostic.
# Everyone: S-1-1-0
special_id_groups = ["S-1-1-0"]
try:
sid_obj = win32security.LookupAccountName(None, username)[0]
except pywintypes.error:
return "\\".join([platform.node()[:15].upper(), username])
sid = win32security.ConvertSidToStringSid(sid_obj)
username, domain, _ = win32security.LookupAccountSid(None, sid_obj)
if sid in special_id_groups:
return username
return "\\".join([domain, username])

View file

@ -1,3 +1,5 @@
import platform
import pytest
import salt.utils.win_functions as win_functions
@ -6,6 +8,11 @@ from tests.support.mock import MagicMock, patch
HAS_WIN32 = False
HAS_PYWIN = False
pytestmark = [
pytest.mark.windows_whitelisted,
pytest.mark.skip_unless_on_windows,
]
try:
import win32net
@ -32,7 +39,6 @@ except ImportError:
# Test cases for salt.utils.win_functions.
@pytest.mark.skip_unless_on_windows(reason="Test is only applicable to Windows.")
def test_escape_argument_simple():
"""
Test to make sure we encode simple arguments correctly
@ -41,7 +47,6 @@ def test_escape_argument_simple():
assert encoded == "simple"
@pytest.mark.skip_unless_on_windows(reason="Test is only applicable to Windows.")
def test_escape_argument_with_space():
"""
Test to make sure we encode arguments containing spaces correctly
@ -50,7 +55,6 @@ def test_escape_argument_with_space():
assert encoded == '^"with space^"'
@pytest.mark.skip_unless_on_windows(reason="Test is only applicable to Windows.")
def test_escape_argument_simple_path():
"""
Test to make sure we encode simple path arguments correctly
@ -59,7 +63,6 @@ def test_escape_argument_simple_path():
assert encoded == "C:\\some\\path"
@pytest.mark.skip_unless_on_windows(reason="Test is only applicable to Windows.")
def test_escape_argument_path_with_space():
"""
Test to make sure we encode path arguments containing spaces correctly
@ -68,7 +71,6 @@ def test_escape_argument_path_with_space():
assert encoded == '^"C:\\Some Path\\With Spaces^"'
@pytest.mark.skip_unless_on_windows(reason="Test is only applicable to Windows.")
def test_broadcast_setting_change():
"""
Test to rehash the Environment variables
@ -76,14 +78,12 @@ def test_broadcast_setting_change():
assert win_functions.broadcast_setting_change()
@pytest.mark.skip_unless_on_windows(reason="Test is only applicable to Windows.")
def test_get_user_groups():
groups = ["Administrators", "Users"]
with patch("win32net.NetUserGetLocalGroups", return_value=groups):
assert win_functions.get_user_groups("Administrator") == groups
@pytest.mark.skip_unless_on_windows(reason="Test is only applicable to Windows.")
def test_get_user_groups_sid():
groups = ["Administrators", "Users"]
expected = ["S-1-5-32-544", "S-1-5-32-545"]
@ -91,14 +91,12 @@ def test_get_user_groups_sid():
assert win_functions.get_user_groups("Administrator", sid=True) == expected
@pytest.mark.skip_unless_on_windows(reason="Test is only applicable to Windows.")
def test_get_user_groups_system():
groups = ["SYSTEM"]
with patch("win32net.NetUserGetLocalGroups", return_value=groups):
assert win_functions.get_user_groups("SYSTEM") == groups
@pytest.mark.skip_unless_on_windows(reason="Test is only applicable to Windows.")
@pytest.mark.skipif(not HAS_WIN32, reason="Requires Win32 libraries")
def test_get_user_groups_unavailable_dc():
groups = ["Administrators", "Users"]
@ -109,7 +107,6 @@ def test_get_user_groups_unavailable_dc():
assert win_functions.get_user_groups("Administrator") == groups
@pytest.mark.skip_unless_on_windows(reason="Test is only applicable to Windows.")
@pytest.mark.skipif(not HAS_WIN32, reason="Requires Win32 libraries")
def test_get_user_groups_unknown_dc():
groups = ["Administrators", "Users"]
@ -120,7 +117,6 @@ def test_get_user_groups_unknown_dc():
assert win_functions.get_user_groups("Administrator") == groups
@pytest.mark.skip_unless_on_windows(reason="Test is only applicable to Windows.")
@pytest.mark.skipif(not HAS_WIN32, reason="Requires Win32 libraries")
def test_get_user_groups_missing_permission():
groups = ["Administrators", "Users"]
@ -131,7 +127,6 @@ def test_get_user_groups_missing_permission():
assert win_functions.get_user_groups("Administrator") == groups
@pytest.mark.skip_unless_on_windows(reason="Test is only applicable to Windows.")
@pytest.mark.skipif(not HAS_WIN32, reason="Requires Win32 libraries")
def test_get_user_groups_error():
win_error = WinError()
@ -142,7 +137,6 @@ def test_get_user_groups_error():
win_functions.get_user_groups("Administrator")
@pytest.mark.skip_unless_on_windows(reason="Test is only applicable to Windows.")
@pytest.mark.skipif(not HAS_PYWIN, reason="Requires pywintypes libraries")
def test_get_user_groups_local_pywin_error():
win_error = PyWinError()
@ -153,7 +147,6 @@ def test_get_user_groups_local_pywin_error():
win_functions.get_user_groups("Administrator")
@pytest.mark.skip_unless_on_windows(reason="Test is only applicable to Windows.")
@pytest.mark.skipif(not HAS_PYWIN, reason="Requires pywintypes libraries")
def test_get_user_groups_pywin_error():
win_error = PyWinError()
@ -163,3 +156,27 @@ def test_get_user_groups_pywin_error():
with patch("win32net.NetUserGetGroups", side_effect=mock_error):
with pytest.raises(PyWinError):
win_functions.get_user_groups("Administrator")
@pytest.mark.skipif(not HAS_PYWIN, reason="Requires pywintypes libraries")
def test_get_sam_name_lookup_fails():
win_error = PyWinError()
mock_error = MagicMock(side_effect=win_error)
with patch("win32security.LookupAccountName", side_effect=mock_error):
expected = "\\".join([platform.node()[:15].upper(), "junk"])
result = win_functions.get_sam_name("junk")
assert result == expected
@pytest.mark.skipif(not HAS_PYWIN, reason="Requires pywintypes libraries")
def test_get_sam_name_everyone():
expected = "Everyone"
result = win_functions.get_sam_name("Everyone")
assert result == expected
@pytest.mark.skipif(not HAS_PYWIN, reason="Requires pywintypes libraries")
def test_get_sam_name():
expected = "\\".join([platform.node()[:15], "Administrator"])
result = win_functions.get_sam_name("Administrator")
assert result == expected