In Windows, it is possible to logon as a different domain user without any credentials. This is known as a S4U or a Service For User Logon. This is a Microsoft Extension to Kerberos introduced with Windows Server 2003. There have been several articles and post on this topic but I thought it would be nice to go over this topic again. The official names for S4U are:
- Service for User to Self (S4U2self)
- S4UProxy (Constrained Delegation Extension) - For more information: https://technet.microsoft.com/en-us/library/cc739587%28v=ws.10%29.aspx
You can find more details on the extension in the following protocol doc:
[MS-S4U] - https://msdn.microsoft.com/en-us/library/cc246071.aspx
A S4U Logon allows an application to obtain a token to a domain user with just their User Principal Name (UPN). This is a powerful feature but there are some caveats to control the power of a S4U logon.
- The caller needs to have the SeTcbPrivilege to generate an SecurityImpersonation level token. If the caller doesn't have this privilege, the resultant token will be at a SecurityIdentification level. An Identification level token only allows you to get the identity and privileges of the user to Access Check against a secured resource. You can't actually access a secured resource with this token. (If you attempt to obtain a handle to a secured object while impersonating this token, the API will fail with a wrong impersonation level error).
- The token can only be used locally. In order to use the impersonation token on a remote server, delegation needs to be enabled for the application and on the targeted server. If you pass the token to another process (via CreateProcessAsUser() for example), even if delegation is enabled, the process can only access secured resources locally. The credentials used are associated with the process that generated the S4U token so when you create a new process with the S4U token, the token has no credentials to present to a remote server for authentication.
Ok, since I've provided the highlights of S4U, how can you programmatically generate an S4U token? There are 2 ways to do this.
1. LsaLogonUser + KERB_S4U_LOGON structure. https://msdn.microsoft.com/en-us/library/windows/desktop/aa378128(v=vs.85).aspx
2. An easier way to generate an S4U token is through the WindowsIdentity object by passing a User Principal Name (UPN) which is in the format of user@domain. Remember if the caller doesn't have the SeTcbPrivilege, the internal token stored in the WindowsIdentity object will be at an identification level instead of an impersonation level. The code is very simple:
WindowsIdentity s4u = new WindowsIdentity("user@domain");
You'll see that this code is much easier than calling LsaLogonUser().
I hope this posts provides some insight to understanding and using S4U.