title: Creating a service for user (S4U) token
body: <p>The Windows Task Scheduler can create tasks that run with the account of a particular user, without storing the user password. They call it "S4U", service for user. This should work something like the scheduler creates such a token for the current user and can use it to run the scheduled process under that user account. They claim that it cannot access network or encrypted resources with this system. The scheduler itself runs with the SYSTEM account for it to work. Here's an <a href="http://msdn.microsoft.com/en-us/magazine/cc163350.aspx#S3" rel="noreferrer">article that describes it</a>. The relevant quote from it:</p>
  
  <blockquote>
    <p>TASK_LOGON_S4U is yet another option that provides a more secure
    alternative. It takes advantage of a service for user (S4U) logon to
    run the task on behalf of the specified user, but without having to
    store the password. Since the Task Scheduler runs within the local
    system account, it can create a S4U logon session and receive a token
    that can not only be used for identification, but also for
    impersonation on the local computer. Normally a S4U token is only good
    for identification.</p>
  </blockquote>
  
  <p>I need to use this authentication scheme in my application, but can't let the Task Scheduler do it but need to do it myself, because I need it for any number of accounts. Whenever a user registers a task with my application, any followup tasks must run under the same user. But since they cannot overlap, I need to do the serialisation myself.</p>
  
  <p>I cannot find any information about this "S4U" thing. How could I implement it in my application? C# preferred, but WINAPI and C is okay.</p>
  
  <p>Update: This is what I've tried, and it doesn't work.</p>
  
  <pre><code>// The WindowsIdentity(string) constructor uses the new
  // Kerberos S4U extension to get a logon for the user
  // without a password.
  WindowsIdentity wi = new WindowsIdentity(identity);
  WindowsImpersonationContext wic = null;
  try
  {
    wic = wi.Impersonate();
    // Code to access network resources goes here.
  }
  catch()
  {
    // Ensure that an exception is not propagated higher in the call stack.
  }
  finally
  {
    // Make sure to remove the impersonation token
    if( wic != null)
      wic.Undo();
  }
  </code></pre>
  
  <p>But I've got the impression now, that you can't just say you want to be a certain user. Not even as System. You need to be logged in as that user and can generate some token that allows you to become that user later again, without the password. So this must be a two-step thing, first I need to get the token and store it on disk; later I can use that token to impersonate. None of the examples explains this.</p>