10
WindowsIdentity identity = new WindowsIdentity(accessToken);
WindowsImpersonationContext context = identity.Impersonate();

 ...
context.Undo();

Where do i declare a administraotr UserName and Passowrd ?

the accessToken param doesn't help me too much...

Do I have to import DLL'S for it ?

Royi Namir
  • 144,742
  • 138
  • 468
  • 792

3 Answers3

22

You need to get the user's token. Use the p/invoke LogonUser from the advapi32.dll:

    [DllImport("advapi32.dll", SetLastError = true)]
    public static extern bool LogonUser(
            string lpszUsername,
            string lpszDomain,
            string lpszPassword,
            int dwLogonType,
            int dwLogonProvider,
            out IntPtr phToken);

Example:

IntPtr userToken = IntPtr.Zero;

bool success = External.LogonUser(
  "john.doe", 
  "domain.com", 
  "MyPassword", 
  (int) AdvApi32Utility.LogonType.LOGON32_LOGON_INTERACTIVE, //2
  (int) AdvApi32Utility.LogonProvider.LOGON32_PROVIDER_DEFAULT, //0
  out userToken);

if (!success)
{
  throw new SecurityException("Logon user failed");
}

using (WindowsIdentity.Impersonate(userToken))
{
  // do the stuff with john.doe's credentials
}
Royi Namir
  • 144,742
  • 138
  • 468
  • 792
Stefan
  • 14,530
  • 4
  • 55
  • 62
  • Is there a way to do so without the password? I have access to it as i'm creating right before impersonation, just thought i'd ask. – Doug Apr 11 '14 at 14:12
  • 2
    I guess one should call `CloseHandle` (as mentioned in the [docs for `LogonUser`](https://msdn.microsoft.com/en-us/library/windows/desktop/aa378184(v=vs.85).aspx)) for the `userToken` after the using block. Or is this called in some way by `WindowsIdentity`? – CodeFox Apr 04 '15 at 13:09
  • Hi If this is ASP.NET Application, what's the scope of this ? Should I call this function in every page ? – Yesudass Moses Apr 09 '15 at 06:21
  • You might want to use this code instead of throwing the SecurityException to get the error details nicely: throw new Win32Exception(Marshal.GetLastWin32Error()) – Bernd May 23 '18 at 11:42
5

its exactly the accesstoken you have to use. to get it you need to call the LogonUser method:

oops didnt realise that i just have the VB.net code just here. imagine it in C# ;) here in c#

external method declaration:

Private Declare Auto Function LogonUser Lib "advapi32.dll" (ByVal lpszUsername As [String], _
ByVal lpszDomain As [String], ByVal lpszPassword As [String], _
ByVal dwLogonType As Integer, ByVal dwLogonProvider As Integer, _
ByRef phToken As IntPtr) As Boolean

and the execution:

_Token = New IntPtr(0)

Const LOGON32_PROVIDER_DEFAULT As Integer = 0
'This parameter causes LogonUser to create a primary token.
Const LOGON32_LOGON_INTERACTIVE As Integer = 2
Const LOGON32_LOGON_NEWCREDENTIALS As Integer = 9

_Token = IntPtr.Zero

' Call LogonUser to obtain a handle to an access token.
Dim returnValue As Boolean = LogonUser(_User, _Domain, _Password, LOGON32_LOGON_NEWCREDENTIALS, LOGON32_PROVIDER_DEFAULT, _Token)

If False = returnValue Then
     Dim ret As Integer = Marshal.GetLastWin32Error()
     Console.WriteLine("LogonUser failed with error code : {0}", ret)
     Throw New System.ComponentModel.Win32Exception(ret)
End If

_Identity = New WindowsIdentity(_Token)
_Context = _Identity.Impersonate()
fixagon
  • 5,506
  • 22
  • 26
2

You need to P/invoke the LogonUser() API. That accepts username, domain and password and returns a token.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490