public ThreadPrivilegeScope(ThreadTokenScope token, LUID_AND_ATTRIBUTES[] setTo) { this.OwnerThread = Thread.CurrentThread; this.Token = token ?? throw new ArgumentNullException(nameof(token)); this.RevertTo = AdjustTokenPrivileges2(token.Handle, setTo); }
public void Dispose() { if (OwnerThread != Thread.CurrentThread) { throw new InvalidOperationException("Wrong thread"); } if (Current != this) { throw new ObjectDisposedException(nameof(ThreadTokenScope)); } Current = null; if (IsImpersonating) { RevertToSelf(); } IsImpersonating = false; }
public ThreadTokenScope() { if (Current != null) { throw new InvalidOperationException("Reentrance to ThreadTokenScope"); } this.OwnerThread = Thread.CurrentThread; if (!OpenThreadToken(GetCurrentThread(), TokenAccessLevels.Query | TokenAccessLevels.AdjustPrivileges, true, out var token)) { var error = Marshal.GetLastWin32Error(); if (error != ERROR_NO_TOKEN) { throw new Win32Exception(error); } // No token is on the thread, copy from process if (!OpenProcessToken(GetCurrentProcess(), TokenAccessLevels.Duplicate, out var processToken)) { throw new Win32Exception(); } if (!DuplicateTokenEx(processToken, TokenAccessLevels.Impersonate | TokenAccessLevels.Query | TokenAccessLevels.AdjustPrivileges, IntPtr.Zero, SecurityImpersonationLevel.Impersonation, TokenType.Impersonation, out token)) { throw new Win32Exception(); } if (!SetThreadToken(IntPtr.Zero, token)) { throw new Win32Exception(); } this.IsImpersonating = true; } this.Handle = token; Current = this; }
public static void RunWithPrivileges(Action action, params string[] privs) { if (privs == null || privs.Length == 0) { throw new ArgumentNullException(nameof(privs)); } var luids = privs .Select(e => new LUID_AND_ATTRIBUTES { Luid = GetLuidForName(e), Attributes = SE_PRIVILEGE_ENABLED }) .ToArray(); RuntimeHelpers.PrepareConstrainedRegions(); try { /* CER */ } finally { using (var threadToken = new ThreadTokenScope()) using (new ThreadPrivilegeScope(threadToken, luids)) { action(); } } }