I am trying to use Process.Start () under impersonation, I have Google for several days, most of the answers that I met were in ASP.net, but I am developing a Window application, so I am having difficulty finding the root cause.
This is my personalized code.
private void impersonateValidUser(string userName, string domain, string password) { WindowsIdentity tempWindowsIdentity = null; IntPtr token = IntPtr.Zero; IntPtr tokenDuplicate = IntPtr.Zero; if ( LogonUser( userName, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref token) != 0) { if ( DuplicateToken( token, 2, ref tokenDuplicate ) != 0 ) { tempWindowsIdentity = new WindowsIdentity( tokenDuplicate ); mImpersonationContext = tempWindowsIdentity.Impersonate(); } } }
and I'm trying to open a document through my program (no .exe, e.g. .txt, .doc)
using (new Impersonator(DomainUserID, Domain, Password)) Process.Start(filePath);
Until now, I could find a directory / file with an impersonated user that would be invisible to my current login user, since I did not grant him access. But whenever I try to open a document, I get an error
System.ComponentModel.Win32Exception (0x80004005): Access is denied
Please correct me if I am wrong, so in this case I should not set UseShellExecute to false (and processStartInfo with username and password too?), Because it is for the executable (?) And I also encounter the CreateProcessAsUser function, and this function does not seem to apply to my case, from the example that I also read for the .exe file.
It would be nice if someone could enlighten me.
update: impersonating a class
public class Impersonator : IDisposable { #region P/Invoke [DllImport("advapi32.dll", SetLastError = true)] private static extern int LogonUser( 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); #endregion #region Constants private const int LOGON32_LOGON_INTERACTIVE = 2; private const int LOGON32_PROVIDER_DEFAULT = 0; #endregion #region Attributes private WindowsImpersonationContext mImpersonationContext = null; #endregion #region Public methods. public Impersonator( string userName, string domainName, string password) { impersonateValidUser(userName, domainName, password); } #endregion #region IDisposable member. public void Dispose() { undoImpersonation(); } #endregion #region Private member. private void impersonateValidUser(string userName, string domain, string password) { WindowsIdentity tempWindowsIdentity = null; IntPtr token = IntPtr.Zero; IntPtr tokenDuplicate = IntPtr.Zero; try { if ( RevertToSelf() ) { if ( LogonUser( userName, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref token) != 0) { if ( DuplicateToken( token, 2, ref tokenDuplicate ) != 0 ) { tempWindowsIdentity = new WindowsIdentity( tokenDuplicate ); mImpersonationContext = tempWindowsIdentity.Impersonate(); } else { throw new Win32Exception( Marshal.GetLastWin32Error() ); } } else { throw new Win32Exception( Marshal.GetLastWin32Error() ); } } else { throw new Win32Exception( Marshal.GetLastWin32Error() ); } } finally { if ( token != IntPtr.Zero ) { CloseHandle( token ); } if ( tokenDuplicate != IntPtr.Zero ) { CloseHandle( tokenDuplicate ); } } } /// <summary> /// Reverts the impersonation. /// </summary> private void undoImpersonation() { if ( mImpersonationContext != null ) { mImpersonationContext.Undo(); } } #endregion }