diff --git a/src/deadline_worker_agent/installer/win_installer.py b/src/deadline_worker_agent/installer/win_installer.py index b0e5be87..29ebdad3 100644 --- a/src/deadline_worker_agent/installer/win_installer.py +++ b/src/deadline_worker_agent/installer/win_installer.py @@ -66,6 +66,21 @@ def print_banner(): ) +def is_domain_user(username: str) -> bool: + # There are two formats for specifying domain users: + # + # 1. User Principal Name (UPN), e.g: + # + # @ + # + # 2. Down-Level Logon Name, e.g: + # + # \ + # + # See https://learn.microsoft.com/en-us/windows/win32/secauthn/user-name-formats + return "\\" in username or "@" in username + + def check_account_existence(account_name: str) -> bool: """ Checks if an account exists on the system by attempting to resolve the account's SID. @@ -851,11 +866,13 @@ def print_helping_info_and_exit(): logging.error(f"User does not have Administrator privileges: {os.environ['USERNAME']}") print_helping_info_and_exit() + # Validate that if a windows job user override is specified, that the user exists if windows_job_user is not None and not check_account_existence(windows_job_user): raise InstallerFailedException( f"Account {windows_job_user} provided for argument windows-job-user does not exist. " "Please create the account before proceeding." ) + # Validate that if a windows job user override is specified, that it is not the same as the worker agent user elif windows_job_user is not None and users_equal(windows_job_user, user_name): raise InstallerFailedException( f"Argument for windows-job-user cannot be the same as the worker agent user: {user_name}. " @@ -863,6 +880,14 @@ def print_helping_info_and_exit(): "configuration file." ) + # Validate that the --user argument is not a domain user. The installer does not currently support this. + if is_domain_user(user_name): + raise InstallerFailedException( + "running worker agent as a domain user is not currently supported. You can " + "have jobs run as a domain user by configuring the queue job run user to specify a " + "domain user account." + ) + # Print configuration print_banner() diff --git a/test/unit/install/test_windows_installer.py b/test/unit/install/test_windows_installer.py index 1809c2a0..8a370d63 100644 --- a/test/unit/install/test_windows_installer.py +++ b/test/unit/install/test_windows_installer.py @@ -121,6 +121,40 @@ def test_start_windows_installer_fails_when_windows_job_user_is_agent_user( ) +# Override the "user" fixture, which feeds into the parsed_kwargs fixture +# with Valid domain username formats. For valid domain user formats, see: +# https://learn.microsoft.com/en-us/windows/win32/secauthn/user-name-formats +@pytest.mark.parametrize( + argnames="user", + argvalues=( + pytest.param("user@domain", id="user principal name"), + pytest.param(r"domain\username", id="down-level logon name"), + ), +) +# No job user override +@pytest.mark.parametrize( + argnames="windows_job_user", + argvalues=(None,), +) +def test_start_windows_installer_fails_on_domain_worker_user( + parsed_kwargs: dict, +) -> None: + # GIVEN + with ( + patch.object(shell, "IsUserAnAdmin", return_value=True), + pytest.raises(win_installer.InstallerFailedException) as raise_ctx, + ): + # WHEN + win_installer.start_windows_installer(**parsed_kwargs) + + # THEN + assert str(raise_ctx.value) == ( + "running worker agent as a domain user is not currently supported. You can " + "have jobs run as a domain user by configuring the queue job run user to specify a " + "domain user account." + ) + + class TestCreateLocalQueueUserGroup: """Tests for the create_local_queue_user_group function"""