fix: WinRM NTLM username normalize and hostname-first targets (0.10.3)

This commit is contained in:
PTah
2026-06-20 00:10:52 +10:00
parent 2fe492b06b
commit c8e3eef9d7
8 changed files with 105 additions and 29 deletions
+39 -5
View File
@@ -29,12 +29,35 @@ class WinRmTestResult:
def resolve_windows_host_target(host: Host) -> str:
targets = iter_winrm_targets(host)
if not targets:
raise HostTargetMissingError("Host has no hostname or IPv4 for WinRM test")
return targets[0]
def iter_winrm_targets(host: Host) -> list[str]:
"""WinRM + NTLM: сначала имя машины (SPN), затем IPv4."""
if not is_windows_host(host):
raise HostNotWindowsError("Host is not Windows")
target = (host.ipv4 or "").strip() or (host.hostname or "").strip()
if not target:
raise HostTargetMissingError("Host has no IPv4 or hostname for WinRM test")
return target
seen: set[str] = set()
ordered: list[str] = []
def add(value: str | None) -> None:
text = (value or "").strip()
if not text or text in seen:
return
seen.add(text)
ordered.append(text)
inventory = host.inventory if isinstance(host.inventory, dict) else {}
computer_name = inventory.get("computer_name")
if isinstance(computer_name, str):
add(computer_name)
add(host.hostname)
add(host.display_name)
add(host.ipv4)
return ordered
def is_windows_host(host: Host) -> bool:
@@ -55,6 +78,10 @@ def test_winrm_connection(
if not target or not user or not password:
raise WinAdminNotConfiguredError("Windows admin credentials or target missing")
from app.services.win_admin_settings import normalize_win_admin_user
user = normalize_win_admin_user(user)
try:
import winrm
except ImportError as exc:
@@ -73,9 +100,16 @@ def test_winrm_connection(
)
result = session.run_cmd("hostname")
except winrm.exceptions.WinRMTransportError as exc:
detail = str(exc)
hint = ""
if "credentials were rejected" in detail.lower():
hint = (
" Проверьте логин (B26\\user), пароль и что учётка — admin на целевом ПК; "
"при подключении по IP NTLM часто отклоняет creds — используйте имя хоста."
)
return WinRmTestResult(
ok=False,
message=f"WinRM transport error: {exc}",
message=f"WinRM transport error ({target}): {detail}{hint}",
target=target,
)
except (socket.timeout, TimeoutError):