diff --git a/NSspi/Contexts/ImpersonationHandle.cs b/NSspi/Contexts/ImpersonationHandle.cs index d721930..8bdbdf0 100644 --- a/NSspi/Contexts/ImpersonationHandle.cs +++ b/NSspi/Contexts/ImpersonationHandle.cs @@ -1,4 +1,6 @@ using System; +using System.Security.Principal; +using System.Threading; namespace NSspi.Contexts { diff --git a/NSspi/Contexts/ServerContext.cs b/NSspi/Contexts/ServerContext.cs index c9b331f..686b4ee 100644 --- a/NSspi/Contexts/ServerContext.cs +++ b/NSspi/Contexts/ServerContext.cs @@ -1,5 +1,7 @@ using System; using System.Runtime.CompilerServices; +using System.Security.Principal; +using System.Threading; using NSspi.Buffers; using NSspi.Credentials; @@ -14,19 +16,25 @@ public class ServerContext : Context private ContextAttrib finalAttribs; private bool impersonating; + private bool impersonationSetsThreadPrinciple; /// - /// Performs basic initialization of a new instance of the ServerContext class. The ServerContext - /// is not ready for message manipulation until a security context has been established with a client. + /// Performs basic initialization of a new instance of the ServerContext class. The + /// ServerContext is not ready for message manipulation until a security context has been + /// established with a client. /// /// /// - public ServerContext( Credential cred, ContextAttrib requestedAttribs ) : base( cred ) + /// + /// If true, the `Thread.CurrentPrinciple` property will be modified by successful impersonation. + /// + public ServerContext( Credential cred, ContextAttrib requestedAttribs, bool impersonationSetsThreadPrinciple = false ) : base( cred ) { this.requestedAttribs = requestedAttribs; this.finalAttribs = ContextAttrib.Zero; this.impersonating = false; + this.impersonationSetsThreadPrinciple = impersonationSetsThreadPrinciple; this.SupportsImpersonate = this.Credential.PackageInfo.Capabilities.HasFlag( SecPkgCapability.Impersonation ); } @@ -220,7 +228,7 @@ ref this.ContextHandle.rawHandle this.ContextHandle.DangerousRelease(); - this.impersonating = true; + this.impersonating = status == SecurityStatus.OK; } } @@ -237,6 +245,11 @@ ref this.ContextHandle.rawHandle throw new SSPIException( "Failed to impersonate the client", status ); } + if( this.impersonating && this.impersonationSetsThreadPrinciple ) + { + SetThreadPrinciple(); + } + return handle; } @@ -299,5 +312,15 @@ protected override void Dispose( bool disposing ) base.Dispose( disposing ); } + + /// + /// Set the current thread security context to the impersonated identity. + /// + private void SetThreadPrinciple() + { + Thread.CurrentPrincipal = new WindowsPrincipal( + WindowsIdentity.GetCurrent( TokenAccessLevels.AllAccess ) + ); + } } } \ No newline at end of file diff --git a/NSspi/Credentials/AuthData.cs b/NSspi/Credentials/AuthData.cs index bfa3f9b..4e6ea21 100644 --- a/NSspi/Credentials/AuthData.cs +++ b/NSspi/Credentials/AuthData.cs @@ -50,6 +50,6 @@ internal enum NativeAuthDataFlag : int { Ansi = 1, - Unicode = 1 + Unicode = 2 } } \ No newline at end of file