Subject: S4U for local user
Posted: 16 December 2013 at 11:08am
I need to develop an highly trusted application (executed as Local System) that executes some tasks within the security context of a local user account without knowing the local account user password, the tasks don’t need access to network resources or to local encrypted files, this on a stand-alone machine.
Impersonation of the local user account already logged in is not an option, I need to run the application even when the system restarts and the user doesn’t login to the system.
Reading the post at http://msdn.microsoft.com/en-us/magazine/cc188757.aspx and the one at http://technet.microsoft.com/en-us/library/cc722152.aspx it is clear that, in order to use the service-for-user extensions (S4U), the machine must be joined to a domain, the Kerberos protocol is required.
If the machine is joined to a domain, as the second link explains, when a domain user schedules a task with the options “Run whether user is logged on or not” and “Do not store password” both checked, the Task Scheduler service will not store the credentials supplied on the local computer, but will discard them after properly authenticating the user. When required to run the task, the Task Scheduler service will use the “Service-for-User” (S4U) extensions to the Kerberos authentication protocol to retrieve the user’s token.
As the first link explains this can be possible calling the function “LsaLogonUser” without needing to provide the client's password thanks to the S4U extension to the Kerberos Protocol. Kerberos protocol implies that the machine must be joined to a domain, in fact, in order to retrieve the user account access token, the “LsaLogonUser” function and its .Net wrapper “WindowsIdentity” function both require as a parameter the User Principal Name of the account, that exists only in a domain scenario.
So I come to my scenario.
I have a stand-alone machine in a workgroup scenario. With the task scheduler I created a task with the options “Run whether user is logged on or not” and “Do not store password” both checked.
The trigger of the scheduled task is “At startup” and the “Delay task for” is one minute.
So I restarted the machine and without logging in, so leaving the machine in the welcome screen, I waited for the task to be executed. (I did not log in the local user account to the system before the task executed in order to avoid the possible case where the task scheduler could impersonate the local user account after he logged in)
The task executed correctly, and, as the second links explains, I verified that the task can access only to local resources and can’t access to EFS encrypted files. So this means that the task scheduler service has been able to retrieve the local user account access token without supplying his password, in other words it seems to me that the task scheduler is able to replicate the exact same situation that happens in a domain scenario using the S4U Kerberos extension.
My question is, how can this be possible since the Kerberos protocol is absent?
Both the “LsaLogonUser” and the “WindowsIdentity” functions require the User Principal Name in order to retrieve the user access token without supplying the client’s password, and in a workgroup scenario the User Principal Name of a local user account in Null (This can be proved with the next lines of code, where the result is that the variable g is Null:
using System.DirectoryServices.AccountManagement;
PrincipalContext ctx = new PrincipalContext(ContextType.Machine);
UserPrincipal u = UserPrincipal.FindByIdentity(ctx, IdentityType.Name, "UserName");
string g = u.UserPrincipalName;)
How can the task scheduler get the user access token, does it use a different function from “LsaLogonUser”, if so what is the function it uses, if it uses the “LsaLogonUser” function what is the User Principal Name that it passes as a parameter for a local user account?
Any help you can give will be greatly appreciated.
Regards