dahall / TaskScheduler

Provides a .NET wrapper for the Windows Task Scheduler. It aggregates the multiple versions, provides an editor and allows for localization.
MIT License
1.2k stars 191 forks source link

Task registration error when specifying UserId of format user@domain #926

Closed firerain-fd closed 1 year ago

firerain-fd commented 2 years ago

Describe the bug The error occurs in the domain environment. When a task is logged on a remote computer using the Invoke-Command in powershell. The task registers with an interactive token and specifies the user name in user@domain format. If you register the task by specifying the username in domain\user format, the task registers successfully.

System.Security.SecurityException: A specified logon session does not exist. It may already have been terminated. at System.Security.Principal.WindowsIdentity.KerbS4ULogon(String upn, SafeAccessTokenHandle& safeTokenHandle) at System.Security.Principal.WindowsIdentity..ctor(String sUserPrincipalName, String type) at System.Security.Principal.WindowsIdentity..ctor(String sUserPrincipalName) at Microsoft.Win32.TaskScheduler.User..ctor(String userName) at Microsoft.Win32.TaskScheduler.TaskFolder.RegisterTaskDefinition(String path, TaskDefinition definition, TaskCreation createType, String userId, String password, TaskLogonType logonType, String sddl)

To Reproduce Run the command on the remote computer using Invoke-Command in powershell.

Invoke-Command -ComputerName TestServer -ScriptBlock {
    [Reflection.Assembly]::LoadFile("C:\bin\Microsoft.Win32.TaskScheduler.dll")

    $ts = [Microsoft.Win32.TaskScheduler.TaskService]::Instance

    $taskDefinition = $ts.NewTask()
    $taskDefinition.Actions.Add([Microsoft.Win32.TaskScheduler.ExecAction]::new("powershell"))
    $taskDefinition.Principal.RunLevel = [Microsoft.Win32.TaskScheduler.TaskRunLevel]::LUA
    $taskDefinition.Settings.Compatibility = [Microsoft.Win32.TaskScheduler.TaskCompatibility]::V2_2
    $taskDefinition.Settings.DisallowStartIfOnBatteries = $false
    $taskDefinition.Settings.ExecutionTimeLimit = [TimeSpan]::FromMinutes(5)

    $ts.RootFolder.RegisterTaskDefinition("Test",
        $taskDefinition,
        [Microsoft.Win32.TaskScheduler.TaskCreation]::CreateOrUpdate,
        "TestUser@test.local",
        [NullString]::Value,
        [Microsoft.Win32.TaskScheduler.TaskLogonType]::InteractiveToken)
}

Expected behavior Successful task registration.

Screenshots image

Environment (please complete the following information):

Additional context The error presumably occurs in the User class constructor on line 46 https://github.com/dahall/TaskScheduler/blob/270ba8f3553d003d0bf9776657d7ff5b461f0786/TaskService/User.cs#L46

It is most likely related to "double hop".

firerain-fd commented 2 years ago

If the AdminUser user from domain1.local logs on locally on computer server1 in domain2.local and tries to register a task with an interactive token for the TestUser user, the error A specified logon session does not exist. It may already have been terminated.

q

[Reflection.Assembly]::LoadFile("C:\bin\Microsoft.Win32.TaskScheduler.dll")

$ts = [Microsoft.Win32.TaskScheduler.TaskService]::Instance

$taskDefinition = $ts.NewTask()
$taskDefinition.Actions.Add([Microsoft.Win32.TaskScheduler.ExecAction]::new("powershell"))
$taskDefinition.Principal.RunLevel = [Microsoft.Win32.TaskScheduler.TaskRunLevel]::LUA
$taskDefinition.Settings.Compatibility = [Microsoft.Win32.TaskScheduler.TaskCompatibility]::V2_2
$taskDefinition.Settings.DisallowStartIfOnBatteries = $false
$taskDefinition.Settings.ExecutionTimeLimit = [TimeSpan]::FromMinutes(5)

$ts.RootFolder.RegisterTaskDefinition("Test",
    $taskDefinition,
    [Microsoft.Win32.TaskScheduler.TaskCreation]::CreateOrUpdate,
    "TestUser@domain2.local",
    [NullString]::Value,
    [Microsoft.Win32.TaskScheduler.TaskLogonType]::InteractiveToken)

image

firerain-fd commented 2 years ago

The same thing happens when executing code from a console application written in C#. Examples are given for powershell, as they are easier to reproduce.

firerain-fd commented 2 years ago

@dahall ?

dahall commented 2 years ago

Do you have the same problem if you use the Register-ScheduledTask PowerShell cmdlet? I don't have a way to replicate and test this, so I first want to rule out that it isn't a problem with the underlying Windows Task Scheduler API. The error appears to be in Microsoft's WindowsIdentity class when calling a Kerberos authentication. The cmdlet from Microsoft may have approached this authentication differently, so please try it in your environment and let me know.