While investigating a customer issue, I needed code to impersonate a different user on the current thread.  A quick search of the msdn blogs turned up this post, which got me most of the way there.  I decided to wrap the code into a class that inherits from IDisposable just to make it easily usable in a using statement.  Here is what I came up with:

using System;

using System.ComponentModel;

using System.Runtime.InteropServices;

using System.Security.Principal;

 

public class ImpersonatedUser : IDisposable

{

    IntPtr userHandle;

    WindowsImpersonationContext impersonationContext;

 

    public ImpersonatedUser(string user, string domain, string password)

    {

        userHandle = IntPtr.Zero;

        bool loggedOn = LogonUser(

            user,

            domain,

            password,

            LogonType.Interactive,

            LogonProvider.Default,

            out userHandle);

 

        if (!loggedOn)

            throw new Win32Exception(Marshal.GetLastWin32Error());

 

        // Begin impersonating the user

        impersonationContext = WindowsIdentity.Impersonate(userHandle);

    }

 

    public void Dispose()

    {

        if (userHandle != IntPtr.Zero)

        {

            CloseHandle(userHandle);

            userHandle = IntPtr.Zero;

            impersonationContext.Undo();

        }

    } 

 

    [DllImport("advapi32.dll", SetLastError = true)]

    static extern bool LogonUser(

        string lpszUsername,

        string lpszDomain,

        string lpszPassword,

        LogonType dwLogonType,

        LogonProvider dwLogonProvider,

        out IntPtr phToken

        );

 

    [DllImport("kernel32.dll", SetLastError = true)]

    static extern bool CloseHandle(IntPtr hHandle);

 

    enum LogonType : int

    {

        Interactive = 2,

        Network = 3,

        Batch = 4,

        Service = 5,

        NetworkCleartext = 8,

        NewCredentials = 9,

    }

 

    enum LogonProvider : int

    {

        Default = 0,

    }

}