//
// Copyright © Nick Lowe 2009
//
// Nick Lowe
// nick@int-r.net
// http://processprivileges.codeplex.com/
namespace ProcessPrivileges
{
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Text;
internal static class Privileges
{
private const int PrivilegesCount = 35;
private const string SeAssignPrimaryTokenPrivilege = "SeAssignPrimaryTokenPrivilege";
private const string SeAuditPrivilege = "SeAuditPrivilege";
private const string SeBackupPrivilege = "SeBackupPrivilege";
private const string SeChangeNotifyPrivilege = "SeChangeNotifyPrivilege";
private const string SeCreateGlobalPrivilege = "SeCreateGlobalPrivilege";
private const string SeCreatePagefilePrivilege = "SeCreatePagefilePrivilege";
private const string SeCreatePermanentPrivilege = "SeCreatePermanentPrivilege";
private const string SeCreateSymbolicLinkPrivilege = "SeCreateSymbolicLinkPrivilege";
private const string SeCreateTokenPrivilege = "SeCreateTokenPrivilege";
private const string SeDebugPrivilege = "SeDebugPrivilege";
private const string SeEnableDelegationPrivilege = "SeEnableDelegationPrivilege";
private const string SeImpersonatePrivilege = "SeImpersonatePrivilege";
private const string SeIncreaseBasePriorityPrivilege = "SeIncreaseBasePriorityPrivilege";
private const string SeIncreaseQuotaPrivilege = "SeIncreaseQuotaPrivilege";
private const string SeIncreaseWorkingSetPrivilege = "SeIncreaseWorkingSetPrivilege";
private const string SeLoadDriverPrivilege = "SeLoadDriverPrivilege";
private const string SeLockMemoryPrivilege = "SeLockMemoryPrivilege";
private const string SeMachineAccountPrivilege = "SeMachineAccountPrivilege";
private const string SeManageVolumePrivilege = "SeManageVolumePrivilege";
private const string SeProfileSingleProcessPrivilege = "SeProfileSingleProcessPrivilege";
private const string SeRelabelPrivilege = "SeRelabelPrivilege";
private const string SeRemoteShutdownPrivilege = "SeRemoteShutdownPrivilege";
private const string SeRestorePrivilege = "SeRestorePrivilege";
private const string SeSecurityPrivilege = "SeSecurityPrivilege";
private const string SeShutdownPrivilege = "SeShutdownPrivilege";
private const string SeSyncAgentPrivilege = "SeSyncAgentPrivilege";
private const string SeSystemEnvironmentPrivilege = "SeSystemEnvironmentPrivilege";
private const string SeSystemProfilePrivilege = "SeSystemProfilePrivilege";
private const string SeSystemTimePrivilege = "SeSystemtimePrivilege";
private const string SeTakeOwnershipPrivilege = "SeTakeOwnershipPrivilege";
private const string SeTcbPrivilege = "SeTcbPrivilege";
private const string SeTimeZonePrivilege = "SeTimeZonePrivilege";
private const string SeTrustedCredManAccessPrivilege = "SeTrustedCredManAccessPrivilege";
private const string SeUndockPrivilege = "SeUndockPrivilege";
private const string SeUnsolicitedInputPrivilege = "SeUnsolicitedInputPrivilege";
private static readonly Dictionary luidDictionary =
new Dictionary(PrivilegesCount);
private static readonly Dictionary privilegeConstantsDictionary =
new Dictionary(PrivilegesCount)
{
{ Privilege.AssignPrimaryToken, SeAssignPrimaryTokenPrivilege },
{ Privilege.Audit, SeAuditPrivilege },
{ Privilege.Backup, SeBackupPrivilege },
{ Privilege.ChangeNotify, SeChangeNotifyPrivilege },
{ Privilege.CreateGlobal, SeCreateGlobalPrivilege },
{ Privilege.CreatePageFile, SeCreatePagefilePrivilege },
{ Privilege.CreatePermanent, SeCreatePermanentPrivilege },
{ Privilege.CreateSymbolicLink, SeCreateSymbolicLinkPrivilege },
{ Privilege.CreateToken, SeCreateTokenPrivilege },
{ Privilege.Debug, SeDebugPrivilege },
{ Privilege.EnableDelegation, SeEnableDelegationPrivilege },
{ Privilege.Impersonate, SeImpersonatePrivilege },
{ Privilege.IncreaseBasePriority, SeIncreaseBasePriorityPrivilege },
{ Privilege.IncreaseQuota, SeIncreaseQuotaPrivilege },
{ Privilege.IncreaseWorkingSet, SeIncreaseWorkingSetPrivilege },
{ Privilege.LoadDriver, SeLoadDriverPrivilege },
{ Privilege.LockMemory, SeLockMemoryPrivilege },
{ Privilege.MachineAccount, SeMachineAccountPrivilege },
{ Privilege.ManageVolume, SeManageVolumePrivilege },
{ Privilege.ProfileSingleProcess, SeProfileSingleProcessPrivilege },
{ Privilege.Relabel, SeRelabelPrivilege },
{ Privilege.RemoteShutdown, SeRemoteShutdownPrivilege },
{ Privilege.Restore, SeRestorePrivilege },
{ Privilege.Security, SeSecurityPrivilege },
{ Privilege.Shutdown, SeShutdownPrivilege },
{ Privilege.SyncAgent, SeSyncAgentPrivilege },
{ Privilege.SystemEnvironment, SeSystemEnvironmentPrivilege },
{ Privilege.SystemProfile, SeSystemProfilePrivilege },
{ Privilege.SystemTime, SeSystemTimePrivilege },
{ Privilege.TakeOwnership, SeTakeOwnershipPrivilege },
{ Privilege.TrustedComputerBase, SeTcbPrivilege },
{ Privilege.TimeZone, SeTimeZonePrivilege },
{ Privilege.TrustedCredentialManagerAccess, SeTrustedCredManAccessPrivilege },
{ Privilege.Undock, SeUndockPrivilege },
{ Privilege.UnsolicitedInput, SeUnsolicitedInputPrivilege }
};
private static readonly Dictionary privilegesDictionary =
new Dictionary(PrivilegesCount)
{
{ SeAssignPrimaryTokenPrivilege, Privilege.AssignPrimaryToken },
{ SeAuditPrivilege, Privilege.Audit },
{ SeBackupPrivilege, Privilege.Backup },
{ SeChangeNotifyPrivilege, Privilege.ChangeNotify },
{ SeCreateGlobalPrivilege, Privilege.CreateGlobal },
{ SeCreatePagefilePrivilege, Privilege.CreatePageFile },
{ SeCreatePermanentPrivilege, Privilege.CreatePermanent },
{ SeCreateSymbolicLinkPrivilege, Privilege.CreateSymbolicLink },
{ SeCreateTokenPrivilege, Privilege.CreateToken },
{ SeDebugPrivilege, Privilege.Debug },
{ SeEnableDelegationPrivilege, Privilege.EnableDelegation },
{ SeImpersonatePrivilege, Privilege.Impersonate },
{ SeIncreaseBasePriorityPrivilege, Privilege.IncreaseBasePriority },
{ SeIncreaseQuotaPrivilege, Privilege.IncreaseQuota },
{ SeIncreaseWorkingSetPrivilege, Privilege.IncreaseWorkingSet },
{ SeLoadDriverPrivilege, Privilege.LoadDriver },
{ SeLockMemoryPrivilege, Privilege.LockMemory },
{ SeMachineAccountPrivilege, Privilege.MachineAccount },
{ SeManageVolumePrivilege, Privilege.ManageVolume },
{ SeProfileSingleProcessPrivilege, Privilege.ProfileSingleProcess },
{ SeRelabelPrivilege, Privilege.Relabel },
{ SeRemoteShutdownPrivilege, Privilege.RemoteShutdown },
{ SeRestorePrivilege, Privilege.Restore },
{ SeSecurityPrivilege, Privilege.Security },
{ SeShutdownPrivilege, Privilege.Shutdown },
{ SeSyncAgentPrivilege, Privilege.SyncAgent },
{ SeSystemEnvironmentPrivilege, Privilege.SystemEnvironment },
{ SeSystemProfilePrivilege, Privilege.SystemProfile },
{ SeSystemTimePrivilege, Privilege.SystemTime },
{ SeTakeOwnershipPrivilege, Privilege.TakeOwnership },
{ SeTcbPrivilege, Privilege.TrustedComputerBase },
{ SeTimeZonePrivilege, Privilege.TimeZone },
{ SeTrustedCredManAccessPrivilege, Privilege.TrustedCredentialManagerAccess },
{ SeUndockPrivilege, Privilege.Undock },
{ SeUnsolicitedInputPrivilege, Privilege.UnsolicitedInput }
};
internal static AdjustPrivilegeResult DisablePrivilege(AccessTokenHandle accessTokenHandle, Privilege privilege)
{
return AdjustPrivilege(accessTokenHandle, privilege, PrivilegeAttributes.Disabled);
}
internal static AdjustPrivilegeResult EnablePrivilege(AccessTokenHandle accessTokenHandle, Privilege privilege)
{
return AdjustPrivilege(accessTokenHandle, privilege, PrivilegeAttributes.Enabled);
}
internal static AdjustPrivilegeResult RemovePrivilege(AccessTokenHandle accessTokenHandle, Privilege privilege)
{
return AdjustPrivilege(accessTokenHandle, privilege, PrivilegeAttributes.Removed);
}
internal static PrivilegeAttributes GetPrivilegeAttributes(Privilege privilege, PrivilegeAndAttributesCollection privileges)
{
foreach (PrivilegeAndAttributes privilegeAndAttributes in privileges)
{
if (privilegeAndAttributes.Privilege == privilege)
{
return privilegeAndAttributes.PrivilegeAttributes;
}
}
GetLuid(privilege);
return PrivilegeAttributes.Removed;
}
internal static PrivilegeAndAttributesCollection GetPrivileges(AccessTokenHandle accessTokenHandle)
{
LuidAndAttributes[] luidAndAttributesArray = GetTokenPrivileges(accessTokenHandle);
int length = luidAndAttributesArray.Length;
List privilegeAndAttributes = new List(length);
for (int i = 0; i < length; i++)
{
LuidAndAttributes luidAndAttributes = luidAndAttributesArray[i];
string name = GetPrivilegeName(luidAndAttributes.Luid);
if (privilegesDictionary.ContainsKey(name))
{
privilegeAndAttributes.Add(new PrivilegeAndAttributes(
privilegesDictionary[name],
luidAndAttributes.Attributes));
}
}
return new PrivilegeAndAttributesCollection(privilegeAndAttributes);
}
private static AdjustPrivilegeResult AdjustPrivilege(
AccessTokenHandle accessTokenHandle,
Luid luid,
PrivilegeAttributes privilegeAttributes)
{
TokenPrivilege newState = new TokenPrivilege
{
PrivilegeCount = 1,
Privilege = new LuidAndAttributes
{
Attributes = privilegeAttributes,
Luid = luid
}
};
TokenPrivilege previousState = new TokenPrivilege();
int returnLength = 0;
if (!NativeMethods.AdjustTokenPrivileges(
accessTokenHandle,
false,
ref newState,
Marshal.SizeOf(previousState),
ref previousState,
ref returnLength))
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
return (AdjustPrivilegeResult)previousState.PrivilegeCount;
}
private static AdjustPrivilegeResult AdjustPrivilege(
AccessTokenHandle accessTokenHandle,
Privilege privilege,
PrivilegeAttributes privilegeAttributes)
{
return AdjustPrivilege(accessTokenHandle, GetLuid(privilege), privilegeAttributes);
}
private static Luid GetLuid(Privilege privilege)
{
if (luidDictionary.ContainsKey(privilege))
{
return luidDictionary[privilege];
}
Luid luid = new Luid();
if (!NativeMethods.LookupPrivilegeValue(String.Empty, privilegeConstantsDictionary[privilege], ref luid))
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
luidDictionary.Add(privilege, luid);
return luid;
}
private static string GetPrivilegeName(Luid luid)
{
StringBuilder nameBuilder = new StringBuilder();
int nameLength = 0;
if (NativeMethods.LookupPrivilegeName(String.Empty, ref luid, nameBuilder, ref nameLength))
{
return String.Empty;
}
int lastWin32Error = Marshal.GetLastWin32Error();
if (lastWin32Error != NativeMethods.ErrorInsufficientBuffer)
{
throw new Win32Exception(lastWin32Error);
}
nameBuilder.EnsureCapacity(nameLength);
if (!NativeMethods.LookupPrivilegeName(String.Empty, ref luid, nameBuilder, ref nameLength))
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
return nameBuilder.ToString();
}
private static LuidAndAttributes[] GetTokenPrivileges(AccessTokenHandle accessTokenHandle)
{
int tokenInformationLength = 0;
int returnLength = 0;
if (NativeMethods.GetTokenInformation(
accessTokenHandle,
TokenInformationClass.TokenPrivileges,
IntPtr.Zero,
tokenInformationLength,
ref returnLength))
{
return new LuidAndAttributes[0];
}
int lastWin32Error = Marshal.GetLastWin32Error();
if (lastWin32Error != NativeMethods.ErrorInsufficientBuffer)
{
throw new Win32Exception(lastWin32Error);
}
tokenInformationLength = returnLength;
returnLength = 0;
using (AllocatedMemory allocatedMemory = new AllocatedMemory(tokenInformationLength))
{
if (!NativeMethods.GetTokenInformation(
accessTokenHandle,
TokenInformationClass.TokenPrivileges,
allocatedMemory.Pointer,
tokenInformationLength,
ref returnLength))
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
int privilegeCount = Marshal.ReadInt32(allocatedMemory.Pointer);
LuidAndAttributes[] luidAndAttributes = new LuidAndAttributes[privilegeCount];
long pointer = allocatedMemory.Pointer.ToInt64() + Marshal.SizeOf(privilegeCount);
Type type = typeof(LuidAndAttributes);
long size = Marshal.SizeOf(type);
for (int i = 0; i < privilegeCount; i++)
{
luidAndAttributes[i] = (LuidAndAttributes)Marshal.PtrToStructure(new IntPtr(pointer), type);
pointer += size;
}
return luidAndAttributes;
}
}
}
}