Files
NSspi/NSspi/Contexts/ImpersonationHandle.cs
Kevin Thompson 002da1559b Fixed code style.
2019-06-16 17:22:21 -04:00

76 lines
2.6 KiB
C#

using System;
using System.Security.Principal;
using System.Threading;
namespace NSspi.Contexts
{
/// <summary>
/// Represents impersonation performed on a server on behalf of a client.
/// </summary>
/// <remarks>
/// The handle controls the lifetime of impersonation, and will revert the impersonation
/// if it is disposed, or if it is finalized ie by being leaked and garbage collected.
///
/// If the handle is accidentally leaked while operations are performed on behalf of the user,
/// impersonation may be reverted at any arbitrary time, perhaps during those operations.
/// This may lead to operations being performed in the security context of the server,
/// potentially leading to security vulnerabilities.
/// </remarks>
public class ImpersonationHandle : IDisposable
{
private readonly ServerContext server;
private bool disposed;
/// <summary>
/// Initializes a new instance of the ImpersonationHandle. Does not perform impersonation.
/// </summary>
/// <param name="server">The server context that is performing impersonation.</param>
internal ImpersonationHandle( ServerContext server )
{
this.server = server;
this.disposed = false;
}
/// <summary>
/// Finalizes the ImpersonationHandle by reverting the impersonation.
/// </summary>
~ImpersonationHandle()
{
Dispose( false );
}
/// <summary>
/// Reverts impersonation.
/// </summary>
public void Dispose()
{
Dispose( true );
GC.SuppressFinalize( this );
}
/// <summary>
/// Reverts impersonation.
/// </summary>
/// <param name="disposing">True if being disposed, false if being finalized.</param>
private void Dispose( bool disposing )
{
// This implements a variant of the typical dispose pattern. Always try to revert
// impersonation, even if finalizing. Don't do anything if we're already reverted.
if( this.disposed == false )
{
this.disposed = true;
// Just in case the reference is being pulled out from under us, pull a stable copy
// of the reference while we're null-checking.
var serverCopy = this.server;
if( serverCopy != null && serverCopy.Disposed == false )
{
serverCopy.RevertImpersonate();
}
}
}
}
}