Last active
August 29, 2015 14:00
-
-
Save jjvdangelo/57e635b69d930964b58a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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