вторник, 23 февраля 2010 г.

Выполнение кода под учетной записью другого пользователя

//-----------------------------------------------------------------------
//
// Copyright © Altoros Development. All rights reserved.
//

// Pavel Shkleinik
//-----------------------------------------------------------------------

namespace TeamExpand.Chrono.Install.InstallationHelper
{
using System;
using System.Runtime.InteropServices;
using System.Security.Authentication;
using System.Security.Principal;

///
/// Class for users personalisation.
///

public class ImpersonationHelper
{
#region Constants

///
/// Use the standard logon provider for the system.
/// The default security provider is negotiate, unless you pass NULL for the domain name and the user name
/// is not in UPN format. In this case, the default provider is NTLM.
/// NOTE: Windows 2000/NT: The default security provider is NTLM.
///

private const int LOGON32_PROVIDER_DEFAULT = 0;

///
/// This logon type is intended for users who will be interactively using the computer, such as a user being logged on
/// by a terminal server, remote shell, or similar process.
/// This logon type has the additional expense of caching logon information for disconnected operations;
/// therefore, it is inappropriate for some client/server applications,
/// such as a mail server.
///

private const int LOGON32_LOGON_INTERACTIVE = 2;

#endregion

#region Fields

///
/// Token for new user.
///

private IntPtr tokenHandle = IntPtr.Zero;

///
/// Context for newly impersonated user.
///

private WindowsImpersonationContext impersonatedUser;

///
/// Id for the newly impersonated user.
///

private WindowsIdentity newId;

#endregion

#region Constructors

///
/// Initializes a new instance of the class. Use this constructor to utilize .
///

/// User name which will be used during impersonating.
/// Password which will be used during user impersonating.
/// Specifies your Active Directory domain name(keep empty to use default domain).
public ImpersonationHelper(string userName, string password, string domainName)
{
this.UserName = userName;
this.Password = password;
this.DomainName = domainName;
}

///
/// Prevents a default instance of the class from being created.
///

private ImpersonationHelper()
{
}

#endregion

#region Properties

///
/// Gets or sets
///

public string UserName { get; set; }

///
/// Gets or sets
///

public string Password { get; set; }

///
/// Gets or sets
///

public string DomainName { get; set; }

#endregion

#region Methods
///
/// Impersonates user with provided , and .
///

public void ImpersonateUser()
{
if (this.impersonatedUser != null)
{
return;
}

if (!LogonUser(this.UserName, this.DomainName, this.Password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, out this.tokenHandle))
{
throw new InvalidCredentialException(String.Format("Impersonation failed for \"{0}\".", this.UserName));
}

this.newId = new WindowsIdentity(this.tokenHandle);

this.impersonatedUser = this.newId.Impersonate();
}

///
/// Use this method to return system in previous state.
///

public void UndoImpersonalisation()
{
if (this.impersonatedUser == null)
{
return;
}

this.impersonatedUser.Undo();
}

///
/// Performs full clean up.
///

public void CleanUp()
{
if (this.tokenHandle != IntPtr.Zero)
{
CloseHandle(this.tokenHandle);
}
}

#endregion

#region Imports

[DllImport("advapi32.dll", SetLastError = true)]
private static extern bool LogonUser(string username, string domain, string password, int logonType, int logonProvider, out IntPtr token);

[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool CloseHandle(IntPtr token);

#endregion
}
}

Комментариев нет:

Отправить комментарий