Thursday, June 17, 2010

C# ,Impersonation for Cross Domain access

C# , Impersonation to write to a file outside the domain in a shared network location
I had a scene wherein I had to write to a file in a network location outside the domain using a domain Id.
The regular values for LogonUser() didn't work for me. So I changed the values for Cross Domain access.

This is the snippet that was different:
enum LogonType
{
Interactive = 2,
Network = 3,
Batch = 4,
Service = 5,
Unlock = 7,
NetworkClearText = 8,
NewCredentials = 9
}
enum LogonProvider
{
Default = 0,
WinNT35 = 1,
WinNT40 = 2,
WinNT50 = 3
}
LogonUser(
userName,
domain,
password,
(int)LogonType.NewCredentials,
(int)LogonProvider.WinNT50,

//LOGON32_LOGON_INTERACTIVE,
//LOGON32_PROVIDER_DEFAULT,
ref token) != 0)


Here is my complete code:
namespace Tools
{
#region Using directives.
// ----------------------------------------------------------------------

using System;
using System.Security.Principal;
using System.Runtime.InteropServices;
using System.ComponentModel;

// ----------------------------------------------------------------------
#endregion

/////////////////////////////////////////////////////////////////////////

///
/// Impersonation of a user. Allows to execute code under another
/// user context.
/// Please note that the account that instantiates the Impersonator class
/// needs to have the 'Act as part of operating system' privilege set.
///

///
/// This class is based on the information in the Microsoft knowledge base
/// article http://support.microsoft.com/default.aspx?scid=kb;en-us;Q306158
///
/// Encapsulate an instance into a using-directive like e.g.:
///
/// ...
/// using ( new Impersonator( "myUsername", "myDomainname", "myPassword" ) )
/// {
/// ...
/// [code that executes under the new context]
/// ...
/// }
/// ...
///
///
///

public class Impersonator :
IDisposable
{
#region Public methods.
// ------------------------------------------------------------------

///
/// Constructor. Starts the impersonation with the given credentials.
/// Please note that the account that instantiates the Impersonator class
/// needs to have the 'Act as part of operating system' privilege set.
///

/// The name of the user to act as.
/// The domain name of the user to act as.
/// The password of the user to act as.
public Impersonator(
string userName,
string domainName,
string password)
{
ImpersonateValidUser(userName, domainName, password);
}

// ------------------------------------------------------------------
#endregion

#region IDisposable member.
// ------------------------------------------------------------------

public void Dispose()
{
UndoImpersonation();
}

// ------------------------------------------------------------------
#endregion

#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);

private const int LOGON32_LOGON_INTERACTIVE = 2;
private const int LOGON32_PROVIDER_DEFAULT = 0;
enum LogonType
{
Interactive = 2,
Network = 3,
Batch = 4,
Service = 5,
Unlock = 7,
NetworkClearText = 8,
NewCredentials = 9
}
enum LogonProvider
{
Default = 0,
WinNT35 = 1,
WinNT40 = 2,
WinNT50 = 3
}

// ------------------------------------------------------------------
#endregion

#region Private member.
// ------------------------------------------------------------------

///
/// Does the actual impersonation.
///

/// The name of the user to act as.
/// The domain name of the user to act as.
/// The password of the user to act as.
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,
(int)LogonType.NewCredentials,
(int)LogonProvider.WinNT50,

//LOGON32_LOGON_INTERACTIVE,
//LOGON32_PROVIDER_DEFAULT,
ref token) != 0)
{
if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
{
tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
impersonationContext = 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);
}
}
}

///
/// Reverts the impersonation.
///

private void UndoImpersonation()
{
if (impersonationContext != null)
{ impersonationContext.Undo(); }
}

private WindowsImpersonationContext impersonationContext = null;

// ------------------------------------------------------------------
#endregion
}

/////////////////////////////////////////////////////////////////////////
}


For more details refer to :
http://www.cstruter.com/blog/270 which helped me .

Cheers!

Wednesday, June 16, 2010

Could not load type 'System.Web.UI.ScriptReferenceBase' from assembly 'System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf385

Ajax Error :
Could not load type 'System.Web.UI.ScriptReferenceBase' from assembly 'System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf385

I got this error while trying to use the Calendar control extender from the Ajax Control Toolkit for one of my textboxes.
First I got an error "sys.extended.ui is null or not an object" . To fix this, I changed the ScriptManager control to use the "ToolkitScriptManager" .
Once I did that I started getting this new error:Could not load type 'System.Web.UI.ScriptReferenceBase' from assembly 'System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf385
This got resolved once I installled .Net Framework 3.5 SP1.
That got my Ajax calendar control working like a charm ;)