Tim Van Wassenhove home

One of the difficulties of using the WindowsIdentity class is the fact that it requires a handle (IntPtr) to a Windows Security Token. Using the LogonUser functionality we can get a hold of such a handle

[DllImport(Advapi32File, CharSet = DefaultCharSet, SetLastError = DefaultSetLastError)]
public static extern bool LogonUser( /* other parameters */, out IntPtr userTokenHandle);

The easiest way to avoid memory leaks is to implement a custom SafeHandle

public class SafeTokenHandle : SafeHandleZeroOrMinusOneIsInvalid
{
	protected internal SafeTokenHandle()
	: base(true)
	{
	}

	protected override bool ReleaseHandle()
	{
		if(!this.IsInvalid)
		{
			return NativeMethods.CloseHandle(this.handle);
		}

		return true;
	}
}

With that SafeHandle in place we can change the signature to

[DllImport(Advapi32File, CharSet = DefaultCharSet, SetLastError = DefaultSetLastError)]
public static extern bool LogonUser( /* other parameters */, out SafeTokenHandle userTokenHandle);

With the Be.Timvw.Framework.Security.Principal.WindowsIdentityHelper we can now easily obtain a WindowsIdentity and use it to do some impersonation

using(WindowsIdentityHelper windowsIdentityHelper = new WindowsIdentityHelper(username, domain, password))
using(windowsIdentityHelper.GetWindowsIdentity().Impersonate())
{
	File.WriteAllText(@"c:\temp\blah.txt", "hello there");
}