Skip to content

Instantly share code, notes, and snippets.

@jjvdangelo
Last active August 29, 2015 14:00
Show Gist options
  • Save jjvdangelo/57e635b69d930964b58a to your computer and use it in GitHub Desktop.
Save jjvdangelo/57e635b69d930964b58a to your computer and use it in GitHub Desktop.
open System
open System.ComponentModel
open System.Configuration
open System.Runtime.InteropServices
open System.Security.Permissions
open System.Security.Principal
[<AutoOpen>]
module private Helpers =
[<DllImport("advapi32.dll", SetLastError = true)>]
extern bool LogonUser(string username, string domain, string password, int logonType, int logonProvider, IntPtr& token)
[<DllImport("kernel32.dll", CharSet = CharSet.Auto)>]
extern bool CloseHandle(IntPtr handle)
let close = CloseHandle >> ignore
let dispose (disposable:#IDisposable) = disposable.Dispose()
let logon32ProviderDefault = 0
let logon32LogonInteractive = 2
type private Impersonator(handle, context) =
let mutable handle = handle
let mutable disposed = false
interface IDisposable with
member __.Dispose() =
if not disposed then
close handle
handle <- IntPtr.Zero
dispose context
disposed <- true
[<PermissionSet(SecurityAction.Demand, Name = "FullTrust")>]
static member BeginImpersonation(username, password, domain) : IDisposable =
let mutable handle = IntPtr.Zero
let successful = LogonUser(username, domain, password, logon32LogonInteractive, logon32ProviderDefault, &handle)
if not successful then
let error = Marshal.GetLastWin32Error()
Win32Exception(error, "Unable to impersonate") |> raise
let id = new WindowsIdentity(handle)
let context = id.Impersonate()
new Impersonator(handle, context) :> IDisposable
let whileImpersonated username password domain f x =
use handle = Impersonator.BeginImpersonation(username, password, domain)
f x
(*
let impersonatedWork() =
use handle = Impersonator.BeginImpersonation("foo", "bar", "domain")
ImportantWork.DoWork()
*)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment