Unfortunately this does not meet our needs.
We currently use impersonation for other disk read and write functionality, but we do not want the entire application to use impersonation all of the time.
In code (just before a disk read/write) we initialise impersonation, perform the disk action, then end the impersonation, so that only during the disk activity does the application have more privileges than normal.
I have tried to attach a file to this forum post but keep receiving the error 'You do not have permission to upload or link to files. Please contact your system administrator.',
please find attached the class and pseudo code sample of how we currently implement impersonation.
public class ImpersonateUser
{
public const int LOGON32_LOGON_INTERACTIVE = 2;
public const int LOGON32_PROVIDER_DEFAULT = 0;
private string _userName = "";
public string UserName
{
get { return _userName; }
set { _userName = value; }
}
private string _domain = "";
public string Domain
{
get { return _domain; }
set { _domain = value; }
}
private string _password = "";
public string Password
{
get { return _password; }
set { _password = value; }
}
private bool _active = false;
public bool Active
{
get { return _active; }
}
WindowsImpersonationContext impersonationContext;
[DllImport("advapi32.dll")]
private 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)]
private static extern int DuplicateToken(IntPtr hToken,
int impersonationLevel,
ref IntPtr hNewToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern bool RevertToSelf();
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern bool CloseHandle(IntPtr handle);
public ImpersonateUser(string userName, string domain, string password)
{
this.UserName = userName;
this.Domain = domain;
this.Password = password;
}
public bool Begin(string userName, string domain, string password)
{
this.UserName = userName;
this.Domain = domain;
this.Password = password;
return Begin();
}
public bool Begin()
{
bool returnValue = false;
WindowsIdentity tempWindowsIdentity;
IntPtr token = IntPtr.Zero;
IntPtr tokenDuplicate = IntPtr.Zero;
if (RevertToSelf())
{
if (LogonUserA(this.UserName, this.Domain, this.Password, LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT, ref token) != 0)
{
if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
{
tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
impersonationContext = tempWindowsIdentity.Impersonate();
if (impersonationContext != null)
{
returnValue = true;
}
}
}
}
if (token != IntPtr.Zero)
CloseHandle(token);
if (tokenDuplicate != IntPtr.Zero)
CloseHandle(tokenDuplicate);
// Store the active status
this._active = returnValue;
return returnValue;
}
public void End()
{
if (this.Active)
{
impersonationContext.Undo();
}
this._active = false;
}
}
PSEUDO CODE EXAMPLE of usage
--------------------------
// Begin the impersonation
ImpersonateUser impersonateUser = new ImpersonateUser();
impersonateUser.Begin();
-- perform the disk access here!!!
// End impersonation
impersonateUser.End();