Search content within the blog

Tuesday, April 19, 2011

Impersonate user to access network resources

This class can be used to perform impersonation of a user over the network and can be used to access resources that are shared.

copy paste the following class in a file,
public class NetworkSecurity
{
const string USER_NAME = "Imperson_FileShare_Username";
const string PASSWORD = "Imperson_FileShare_Password";
const string LOGON_TYPE = "Imperson_logon_Type";
const string LOGONPROVIDER = "Imperson_logon_Provider";

NetworkSecurity()
{
}

public static WindowsImpersonationContext GetWindowsImpersonationContext()
{
try
{
WindowsImpersonationContext impersonatedUser = null;
LogonType logonType = LogonType.LOGON32_LOGON_NETWORK;
LogonProvider logonProvider = LogonProvider.LOGON32_PROVIDER_DEFAULT;


string loginUserName = VestekAppSettings.GetInstance().GetSetting(USER_NAME, true);
string loginPassword = VestekAppSettings.GetInstance().GetSetting(PASSWORD, true);

string domainName = null;
if (loginUserName.Length > 0)
{
string[] splitteddomainAndUserName = loginUserName.Split('\\');
if (splitteddomainAndUserName.Length.Equals(2))
{
domainName = splitteddomainAndUserName[0];
loginUserName = splitteddomainAndUserName[1];
}

}
impersonatedUser = ImpersonateUser(domainName, loginUserName, loginPassword, logonType, logonProvider);
return impersonatedUser;
}
catch (Exception ex)
{
throw ex;
}
}


private static WindowsImpersonationContext ImpersonateUser(string strDomain,
string strLogin,
string strPwd,
LogonType logonType,
LogonProvider logonProvider)
{
IntPtr tokenHandle = new IntPtr(0);
IntPtr dupeTokenHandle = new IntPtr(0);
WindowsImpersonationContext impersonatedUser = null;

try
{
const int SecurityImpersonation = 2;

tokenHandle = IntPtr.Zero;
dupeTokenHandle = IntPtr.Zero;

// Call LogonUser to obtain a handle to an access token.
bool returnValue = SecuUtil32.LogonUser(
strLogin,
strDomain,
strPwd,
(int)logonType,
(int)logonProvider,
ref tokenHandle);
if (false == returnValue)
{
int ret = Marshal.GetLastWin32Error();
string strErr = String.Format("LogonUser failed with error code : {0}", ret);
throw new ApplicationException(strErr, null);
}

bool retVal = SecuUtil32.DuplicateToken(tokenHandle, SecurityImpersonation, ref dupeTokenHandle);
if (false == retVal)
{
SecuUtil32.CloseHandle(tokenHandle);
throw new ApplicationException("Failed to duplicate token", null);
}

// The token that is passed to the following constructor must
// be a primary token in order to use it for impersonation.
WindowsIdentity newId = new WindowsIdentity(dupeTokenHandle);
impersonatedUser = newId.Impersonate();


}
catch (Exception ex)
{
throw new ApplicationException(ex.Message, ex);
}

return impersonatedUser;
}

enum LogonType : int
{
LOGON32_LOGON_INTERACTIVE = 2,
LOGON32_LOGON_NETWORK = 3,
LOGON32_LOGON_BATCH = 4,
LOGON32_LOGON_SERVICE = 5,
LOGON32_LOGON_UNLOCK = 7,
LOGON32_LOGON_NETWORK_CLEARTEXT = 8, // Only for Win2K or higher
LOGON32_LOGON_NEW_CREDENTIALS = 9 // Only for Win2K or higher
};

enum LogonProvider : int
{
LOGON32_PROVIDER_DEFAULT = 0,
LOGON32_PROVIDER_WINNT35 = 1,
LOGON32_PROVIDER_WINNT40 = 2,
LOGON32_PROVIDER_WINNT50 = 3
};

class SecuUtil32
{
[DllImport("advapi32.dll", SetLastError=true)]
public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword,
int dwLogonType, int dwLogonProvider, ref IntPtr TokenHandle);

[DllImport("kernel32.dll", CharSet=CharSet.Auto)]
public extern static bool CloseHandle(IntPtr handle);

[DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
public extern static bool DuplicateToken(IntPtr ExistingTokenHandle,
int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle);
}

}




Now in order to access a resource over a network by a particular user we can call this class in the following way,

try
{
WindowsImpersonationContext impContext = null;
if (impContext == null)
impContext = NetworkSecurity.GetWindowsImpersonationContext();


if (impContext == null)
{
string msg = "Access denied : Error occured while accessing the file over the network.\n";
sLogger.Error("Could not create the impersonation object.");
throw new VestekException(msg);
}

---write code here to access network resource
}
catch (Exception error)
{
throw error;
}
finally
{
//check if the object was created and is not null
if (impContext != null)
impContext.Undo();
}

now if the impContext is not null that means the user was impersonated successfully. So continue to access and run the code under this user. Once the opreration is complete maintain a finally block where you would call impContext.Undo();.

No comments:

Post a Comment