Reputation: 457
When I use WindowsIdentity Impersonation like this:
WindowsIdentity newId = null;
WindowsImpersonationContext impersonatedUser = null;
Console.WriteLine("Name of the identity BEFORE impersonation: "
+ WindowsIdentity.GetCurrent().Name + ".");
newId = new WindowsIdentity(_impersonationToken);
impersonatedUser = newId.Impersonate();
Console.WriteLine("Name of the identity AFTER impersonation: "
+ WindowsIdentity.GetCurrent().Name + ".");
(It's being used to copy files from my computer to a winCE machine.)
The Name Before and the Name after keep returning the same. When I look @ the newId Token after the impersonation it isn't the same as the one I use to Impersonate with. The Token I impersonate with is DEFINITELY not the same user as the one I'm logged in with.
Does anyone have any suggestions on why it does not want to use my token? (ow yeah, Yesterday It worked like a charm :s)
This is how I generate my token:
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword,
int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
LogonUser(Username, IPMachine, Password,
LOGON32_LOGON_NEW_CREDENTIALS, LOGON32_PROVIDER_DEFAULT,
ref _token);
It give a successfull bool, so there is nothing wrong with my token i think
Upvotes: 2
Views: 9051
Reputation: 61
I get this working:
/// <summary>
/// Summary description for Impersonate
/// </summary>
public class Impersonate
{
#region "Class Members"
public const int LOGON32_LOGON_INTERACTIVE = 2;
public const int LOGON32_PROVIDER_DEFAULT = 0;
WindowsImpersonationContext _impersonationContext;
#endregion
#region "Class Properties"
private string domainName { get; set; }
private string userName { get; set; }
private string userPassword { get; set; }
#endregion
public Impersonate(string domainName, string userName, string userPassword)
{
this.domainName = domainName;
this.userName = userName;
this.userPassword = userPassword;
}
#region "Impersonation Code"
[DllImport("advapi32.dll")]
public static extern int LogonUserA(String lpszUserName,
String lpszDomain,
String lpszPassword,
int dwLogonType,
int dwLogonProvider,
ref IntPtr phToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern int DuplicateToken(IntPtr hToken,
int impersonationLevel,
ref IntPtr hNewToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool RevertToSelf();
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern bool CloseHandle(IntPtr handle);
[PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
public bool ImpersonateValidUser()
{
var token = IntPtr.Zero;
var tokenDuplicate = IntPtr.Zero;
if (RevertToSelf())
{
if (LogonUserA(this.userName, this.domainName, this.userPassword, LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT, ref token) != 0)
{
if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
{
var tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
_impersonationContext = tempWindowsIdentity.Impersonate();
if (_impersonationContext != null)
{
CloseHandle(token);
CloseHandle(tokenDuplicate);
return true;
}
}
}
}
if (token != IntPtr.Zero)
CloseHandle(token);
if (tokenDuplicate != IntPtr.Zero)
CloseHandle(tokenDuplicate);
return false;
}
public void UndoImpersonation()
{
_impersonationContext.Undo();
}
#endregion
}
You can call it:
var impessonate = new Impersonate(".", "User", "Psw");
if (impessonate.ImpersonateValidUser())
{
// do stuff
impessonate.UndoImpersonation();
}
Upvotes: 0
Reputation: 6472
How do you generate your _impersonationToken
?
There's an excellent solution regarding impersonation over at CodeProject. Looking at that may give you some new ideas.
Upvotes: 0